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 /* This has the problem that "test_method:argument:" and
79 "test:method_argument:" will generate the same name
80 ("_i_Test__test_method_argument_" for an instance method of the
81 class "Test"), so you can't have them both in the same class!
82 Moreover, the demangling (going from
83 "_i_Test__test_method_argument" back to the original name) is
84 undefined because there are two correct ways of demangling the
86 #ifndef OBJC_GEN_METHOD_LABEL
87 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
90 sprintf ((BUF), "_%s_%s_%s_%s", \
91 ((IS_INST) ? "i" : "c"), \
93 ((CAT_NAME)? (CAT_NAME) : ""), \
95 for (temp = (BUF); *temp; temp++) \
96 if (*temp == ':') *temp = '_'; \
100 /* These need specifying. */
101 #ifndef OBJC_FORWARDING_STACK_OFFSET
102 #define OBJC_FORWARDING_STACK_OFFSET 0
105 #ifndef OBJC_FORWARDING_MIN_OFFSET
106 #define OBJC_FORWARDING_MIN_OFFSET 0
109 /* Set up for use of obstacks. */
113 /* This obstack is used to accumulate the encoding of a data type. */
114 static struct obstack util_obstack;
116 /* This points to the beginning of obstack contents, so we can free
117 the whole contents. */
120 /* The version identifies which language generation and runtime
121 the module (file) was compiled for, and is recorded in the
122 module descriptor. */
124 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
125 #define PROTOCOL_VERSION 2
127 /* (Decide if these can ever be validly changed.) */
128 #define OBJC_ENCODE_INLINE_DEFS 0
129 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
131 /*** Private Interface (procedures) ***/
133 /* Used by compile_file. */
135 static void init_objc (void);
136 static void finish_objc (void);
138 /* Code generation. */
140 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
141 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
142 static tree get_proto_encoding (tree);
143 static tree lookup_interface (tree);
144 static tree objc_add_static_instance (tree, tree);
146 static tree start_class (enum tree_code, tree, tree, tree);
147 static tree continue_class (tree);
148 static void finish_class (tree);
149 static void start_method_def (tree);
151 static void objc_start_function (tree, tree, tree, tree);
153 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
155 static tree start_protocol (enum tree_code, tree, tree);
156 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
157 static tree objc_add_method (tree, tree, int, bool);
158 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
159 static tree build_ivar_reference (tree);
160 static tree is_ivar (tree, tree);
162 static void build_objc_exception_stuff (void);
163 static void build_next_objc_exception_stuff (void);
165 /* We only need the following for ObjC; ObjC++ will use C++'s definition
166 of DERIVED_FROM_P. */
168 static bool objc_derived_from_p (tree, tree);
169 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
173 static void objc_gen_property_data (tree, tree);
174 static void objc_synthesize_getter (tree, tree, tree);
175 static void objc_synthesize_setter (tree, tree, tree);
176 static char *objc_build_property_setter_name (tree);
177 static int match_proto_with_proto (tree, tree, int);
178 static tree lookup_property (tree, tree);
179 static tree lookup_property_in_list (tree, tree);
180 static tree lookup_property_in_protocol_list (tree, tree);
181 static void build_objc_property_accessor_helpers (void);
183 static void objc_xref_basetypes (tree, tree);
185 static void build_class_template (void);
186 static void build_selector_template (void);
187 static void build_category_template (void);
188 static void build_super_template (void);
189 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
190 static tree get_class_ivars (tree, bool);
191 static tree generate_protocol_list (tree);
192 static void build_protocol_reference (tree);
194 static void build_fast_enumeration_state_template (void);
197 static void objc_generate_cxx_cdtors (void);
201 static void objc_decl_method_attributes (tree*, tree, int);
202 static tree build_keyword_selector (tree);
203 static const char *synth_id_with_class_suffix (const char *, tree);
205 /* Hash tables to manage the global pool of method prototypes. */
207 hash *nst_method_hash_list = 0;
208 hash *cls_method_hash_list = 0;
210 /* Hash tables to manage the global pool of class names. */
212 hash *cls_name_hash_list = 0;
213 hash *als_name_hash_list = 0;
215 static void hash_class_name_enter (hash *, tree, tree);
216 static hash hash_class_name_lookup (hash *, tree);
218 static hash hash_lookup (hash *, tree);
219 static tree lookup_method (tree, tree);
220 static tree lookup_method_static (tree, tree, int);
222 static tree add_class (tree, tree);
223 static void add_category (tree, tree);
224 static inline tree lookup_category (tree, tree);
228 class_names, /* class, category, protocol, module names */
229 meth_var_names, /* method and variable names */
230 meth_var_types /* method and variable type descriptors */
233 static tree add_objc_string (tree, enum string_section);
234 static void build_selector_table_decl (void);
236 /* Protocol additions. */
238 static tree lookup_protocol (tree);
239 static tree lookup_and_install_protocols (tree);
243 static void encode_type_qualifiers (tree);
244 static void encode_type (tree, int, int);
245 static void encode_field_decl (tree, int, int);
248 static void really_start_method (tree, tree);
250 static void really_start_method (tree, struct c_arg_info *);
252 static int comp_proto_with_proto (tree, tree, int);
253 static tree get_arg_type_list (tree, int, int);
254 static tree objc_decay_parm_type (tree);
255 static void objc_push_parm (tree);
257 static tree objc_get_parm_info (int);
259 static struct c_arg_info *objc_get_parm_info (int);
262 /* Utilities for debugging and error diagnostics. */
264 static char *gen_type_name (tree);
265 static char *gen_type_name_0 (tree);
266 static char *gen_method_decl (tree);
267 static char *gen_declaration (tree);
269 /* Everything else. */
271 static tree create_field_decl (tree, const char *);
272 static void add_class_reference (tree);
273 static void build_protocol_template (void);
274 static tree encode_method_prototype (tree);
275 static void generate_classref_translation_entry (tree);
276 static void handle_class_ref (tree);
277 static void generate_struct_by_value_array (void)
279 static void mark_referenced_methods (void);
280 static void generate_objc_image_info (void);
281 static bool objc_type_valid_for_messaging (tree typ);
283 /*** Private Interface (data) ***/
285 /* Reserved tag definitions. */
287 #define OBJECT_TYPEDEF_NAME "id"
288 #define CLASS_TYPEDEF_NAME "Class"
290 #define TAG_OBJECT "objc_object"
291 #define TAG_CLASS "objc_class"
292 #define TAG_SUPER "objc_super"
293 #define TAG_SELECTOR "objc_selector"
295 #define UTAG_CLASS "_objc_class"
296 #define UTAG_IVAR "_objc_ivar"
297 #define UTAG_IVAR_LIST "_objc_ivar_list"
298 #define UTAG_METHOD "_objc_method"
299 #define UTAG_METHOD_LIST "_objc_method_list"
300 #define UTAG_CATEGORY "_objc_category"
301 #define UTAG_MODULE "_objc_module"
302 #define UTAG_SYMTAB "_objc_symtab"
303 #define UTAG_SUPER "_objc_super"
304 #define UTAG_SELECTOR "_objc_selector"
306 #define UTAG_PROTOCOL "_objc_protocol"
307 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
308 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
310 /* Note that the string object global name is only needed for the
312 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
314 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
316 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
317 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
319 static const char *TAG_GETCLASS;
320 static const char *TAG_GETMETACLASS;
321 static const char *TAG_MSGSEND;
322 static const char *TAG_MSGSENDSUPER;
323 /* The NeXT Objective-C messenger may have two extra entry points, for use
324 when returning a structure. */
325 static const char *TAG_MSGSEND_STRET;
326 static const char *TAG_MSGSENDSUPER_STRET;
327 static const char *default_constant_string_class_name;
329 /* Runtime metadata flags. */
330 #define CLS_FACTORY 0x0001L
331 #define CLS_META 0x0002L
332 #define CLS_HAS_CXX_STRUCTORS 0x2000L
334 #define OBJC_MODIFIER_STATIC 0x00000001
335 #define OBJC_MODIFIER_FINAL 0x00000002
336 #define OBJC_MODIFIER_PUBLIC 0x00000004
337 #define OBJC_MODIFIER_PRIVATE 0x00000008
338 #define OBJC_MODIFIER_PROTECTED 0x00000010
339 #define OBJC_MODIFIER_NATIVE 0x00000020
340 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
341 #define OBJC_MODIFIER_ABSTRACT 0x00000080
342 #define OBJC_MODIFIER_VOLATILE 0x00000100
343 #define OBJC_MODIFIER_TRANSIENT 0x00000200
344 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
346 /* NeXT-specific tags. */
348 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
349 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
350 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
351 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
352 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
353 #define TAG_EXCEPTIONMATCH "objc_exception_match"
354 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
355 #define TAG_SYNCENTER "objc_sync_enter"
356 #define TAG_SYNCEXIT "objc_sync_exit"
357 #define TAG_SETJMP "_setjmp"
358 #define UTAG_EXCDATA "_objc_exception_data"
360 #define TAG_ASSIGNIVAR "objc_assign_ivar"
361 #define TAG_ASSIGNGLOBAL "objc_assign_global"
362 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
364 /* Branch entry points. All that matters here are the addresses;
365 functions with these names do not really exist in libobjc. */
367 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
368 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
370 #define TAG_CXX_CONSTRUCT ".cxx_construct"
371 #define TAG_CXX_DESTRUCT ".cxx_destruct"
373 /* GNU-specific tags. */
375 #define TAG_EXECCLASS "__objc_exec_class"
376 #define TAG_GNUINIT "__objc_gnu_init"
378 /* Flags for lookup_method_static(). */
379 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
380 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
382 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
383 tree objc_global_trees[OCTI_MAX];
385 static void handle_impent (struct imp_entry *);
387 struct imp_entry *imp_list = 0;
388 int imp_count = 0; /* `@implementation' */
389 int cat_count = 0; /* `@category' */
391 objc_ivar_visibility_kind objc_ivar_visibility;
393 /* Use to generate method labels. */
394 static int method_slot = 0;
396 /* Flag to say whether methods in a protocol are optional or
398 static bool objc_method_optional_flag = false;
400 static int objc_collecting_ivars = 0;
404 static char *errbuf; /* Buffer for error diagnostics */
406 /* Data imported from tree.c. */
408 extern enum debug_info_type write_symbols;
410 /* Data imported from toplev.c. */
412 extern const char *dump_base_name;
414 static int flag_typed_selectors;
416 /* Store all constructed constant strings in a hash table so that
417 they get uniqued properly. */
419 struct GTY(()) string_descriptor {
420 /* The literal argument . */
423 /* The resulting constant string. */
427 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
429 FILE *gen_declaration_file;
431 /* Tells "encode_pointer/encode_aggregate" whether we are generating
432 type descriptors for instance variables (as opposed to methods).
433 Type descriptors for instance variables contain more information
434 than methods (for static typing and embedded structures). */
436 static int generating_instance_variables = 0;
438 /* For building an objc struct. These may not be used when this file
439 is compiled as part of obj-c++. */
441 static bool objc_building_struct;
442 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
444 /* Start building a struct for objc. */
447 objc_start_struct (tree name)
449 gcc_assert (!objc_building_struct);
450 objc_building_struct = true;
451 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
454 /* Finish building a struct for objc. */
457 objc_finish_struct (tree type, tree fieldlist)
459 gcc_assert (objc_building_struct);
460 objc_building_struct = false;
461 return finish_struct (input_location, type, fieldlist, NULL_TREE,
466 build_sized_array_type (tree base_type, int size)
468 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
469 return build_array_type (base_type, index_type);
473 add_field_decl (tree type, const char *name, tree **chain)
475 tree field = create_field_decl (type, name);
479 *chain = &DECL_CHAIN (field);
484 /* Some platforms pass small structures through registers versus
485 through an invisible pointer. Determine at what size structure is
486 the transition point between the two possibilities. */
489 generate_struct_by_value_array (void)
494 int aggregate_in_mem[32];
497 /* Presumably no platform passes 32 byte structures in a register. */
498 for (i = 1; i < 32; i++)
503 /* Create an unnamed struct that has `i' character components */
504 type = objc_start_struct (NULL_TREE);
506 strcpy (buffer, "c1");
507 decls = add_field_decl (char_type_node, buffer, &chain);
509 for (j = 1; j < i; j++)
511 sprintf (buffer, "c%d", j + 1);
512 add_field_decl (char_type_node, buffer, &chain);
514 objc_finish_struct (type, decls);
516 aggregate_in_mem[i] = aggregate_value_p (type, 0);
517 if (!aggregate_in_mem[i])
521 /* We found some structures that are returned in registers instead of memory
522 so output the necessary data. */
525 for (i = 31; i >= 0; i--)
526 if (!aggregate_in_mem[i])
528 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
530 /* The first member of the structure is always 0 because we don't handle
531 structures with 0 members */
532 printf ("static int struct_forward_array[] = {\n 0");
534 for (j = 1; j <= i; j++)
535 printf (", %d", aggregate_in_mem[j]);
546 if (cxx_init () == false)
548 if (c_objc_common_init () == false)
552 /* If gen_declaration desired, open the output file. */
553 if (flag_gen_declaration)
555 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
556 gen_declaration_file = fopen (dumpname, "w");
557 if (gen_declaration_file == 0)
558 fatal_error ("can't open %s: %m", dumpname);
562 if (flag_next_runtime)
564 TAG_GETCLASS = "objc_getClass";
565 TAG_GETMETACLASS = "objc_getMetaClass";
566 TAG_MSGSEND = "objc_msgSend";
567 TAG_MSGSENDSUPER = "objc_msgSendSuper";
568 TAG_MSGSEND_STRET = "objc_msgSend_stret";
569 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
570 default_constant_string_class_name = "NSConstantString";
574 TAG_GETCLASS = "objc_get_class";
575 TAG_GETMETACLASS = "objc_get_meta_class";
576 TAG_MSGSEND = "objc_msg_lookup";
577 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
578 /* GNU runtime does not provide special functions to support
579 structure-returning methods. */
580 default_constant_string_class_name = "NXConstantString";
581 flag_typed_selectors = 1;
582 /* GNU runtime does not need the compiler to change code
583 in order to do GC. */
586 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
593 if (print_struct_values && !flag_compare_debug)
594 generate_struct_by_value_array ();
599 /* This is called automatically (at the very end of compilation) by
600 c_write_global_declarations and cp_write_global_declarations. */
602 objc_write_global_declarations (void)
604 mark_referenced_methods ();
606 /* Finalize Objective-C runtime data. */
609 if (gen_declaration_file)
610 fclose (gen_declaration_file);
613 /* Return the first occurrence of a method declaration corresponding
614 to sel_name in rproto_list. Search rproto_list recursively.
615 If is_class is 0, search for instance methods, otherwise for class
618 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
624 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
626 p = TREE_VALUE (rproto);
628 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
630 if ((fnd = lookup_method (is_class
631 ? PROTOCOL_CLS_METHODS (p)
632 : PROTOCOL_NST_METHODS (p), sel_name)))
634 else if (PROTOCOL_LIST (p))
635 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
640 ; /* An identifier...if we could not find a protocol. */
651 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
655 /* Make sure the protocol is supported by the object on the rhs. */
656 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
659 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
661 p = TREE_VALUE (rproto);
663 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
668 else if (PROTOCOL_LIST (p))
669 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
678 ; /* An identifier...if we could not find a protocol. */
685 objc_start_class_interface (tree klass, tree super_class,
686 tree protos, tree attributes)
691 error_at (input_location, "class attributes are not available in Objective-C 1.0");
693 warning_at (input_location, OPT_Wattributes,
694 "class attributes are not available in this version"
695 " of the compiler, (ignored)");
697 objc_interface_context
699 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
700 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
704 objc_start_category_interface (tree klass, tree categ,
705 tree protos, tree attributes)
710 error_at (input_location, "category attributes are not available in Objective-C 1.0");
712 warning_at (input_location, OPT_Wattributes,
713 "category attributes are not available in this version"
714 " of the compiler, (ignored)");
716 objc_interface_context
717 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
719 = continue_class (objc_interface_context);
723 objc_start_protocol (tree name, tree protos, tree attributes)
728 error_at (input_location, "protocol attributes are not available in Objective-C 1.0");
730 warning_at (input_location, OPT_Wattributes,
731 "protocol attributes are not available in this version"
732 " of the compiler, (ignored)");
734 objc_interface_context
735 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
736 objc_method_optional_flag = false;
740 objc_continue_interface (void)
743 = continue_class (objc_interface_context);
747 objc_finish_interface (void)
749 finish_class (objc_interface_context);
750 objc_interface_context = NULL_TREE;
751 objc_method_optional_flag = false;
755 objc_start_class_implementation (tree klass, tree super_class)
757 objc_implementation_context
759 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
760 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
764 objc_start_category_implementation (tree klass, tree categ)
766 objc_implementation_context
767 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
769 = continue_class (objc_implementation_context);
773 objc_continue_implementation (void)
776 = continue_class (objc_implementation_context);
780 objc_finish_implementation (void)
783 if (flag_objc_call_cxx_cdtors)
784 objc_generate_cxx_cdtors ();
787 if (objc_implementation_context)
789 finish_class (objc_implementation_context);
790 objc_ivar_chain = NULL_TREE;
791 objc_implementation_context = NULL_TREE;
794 warning (0, "%<@end%> must appear in an @implementation context");
798 objc_set_visibility (objc_ivar_visibility_kind visibility)
800 if (visibility == OBJC_IVAR_VIS_PACKAGE)
803 error ("%<@package%> is not available in Objective-C 1.0");
805 warning (0, "%<@package%> presently has the same effect as %<@public%>");
807 objc_ivar_visibility = visibility;
811 objc_set_method_opt (bool optional)
814 error_at (input_location, "@optional/@required are not available in Objective-C 1.0");
816 objc_method_optional_flag = optional;
817 if (!objc_interface_context
818 || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
820 error ("@optional/@required is allowed in @protocol context only.");
821 objc_method_optional_flag = false;
825 /* This routine is called by the parser when a
826 @property... declaration is found. 'decl' is the declaration of
827 the property (type/identifier), and the other arguments represent
828 property attributes that may have been specified in the Objective-C
829 declaration. 'parsed_property_readonly' is 'true' if the attribute
830 'readonly' was specified, and 'false' if not; similarly for the
831 other bool parameters. 'parsed_property_getter_ident' is NULL_TREE
832 if the attribute 'getter' was not specified, and is the identifier
833 corresponding to the specified getter if it was; similarly for
834 'parsed_property_setter_ident'. */
836 objc_add_property_declaration (location_t location, tree decl,
837 bool parsed_property_readonly, bool parsed_property_readwrite,
838 bool parsed_property_assign, bool parsed_property_retain,
839 bool parsed_property_copy, bool parsed_property_nonatomic,
840 tree parsed_property_getter_ident, tree parsed_property_setter_ident)
844 /* 'property_readonly' and 'property_assign_semantics' are the final
845 attributes of the property after all parsed attributes have been
846 considered (eg, if we parsed no 'readonly' and no 'readwrite', ie
847 parsed_property_readonly = false and parsed_property_readwrite =
848 false, then property_readonly will be false because the default
850 bool property_readonly = false;
851 objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN;
854 error_at (input_location, "%<@property%> is not available in Objective-C 1.0");
856 if (parsed_property_readonly && parsed_property_readwrite)
858 error_at (location, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
859 /* In case of conflicting attributes (here and below), after
860 producing an error, we pick one of the attributes and keep
862 property_readonly = false;
866 if (parsed_property_readonly)
867 property_readonly = true;
869 if (parsed_property_readwrite)
870 property_readonly = false;
873 if (parsed_property_readonly && parsed_property_setter_ident)
875 /* Maybe this should be an error ? The Apple documentation says it is a warning. */
876 warning_at (location, 0, "%<readonly%> attribute conflicts with %<setter%> attribute");
877 property_readonly = false;
880 if (parsed_property_assign && parsed_property_retain)
882 error_at (location, "%<assign%> attribute conflicts with %<retain%> attribute");
883 property_assign_semantics = OBJC_PROPERTY_RETAIN;
885 else if (parsed_property_assign && parsed_property_copy)
887 error_at (location, "%<assign%> attribute conflicts with %<copy%> attribute");
888 property_assign_semantics = OBJC_PROPERTY_COPY;
890 else if (parsed_property_retain && parsed_property_copy)
892 error_at (location, "%<retain%> attribute conflicts with %<copy%> attribute");
893 property_assign_semantics = OBJC_PROPERTY_COPY;
897 if (parsed_property_assign)
898 property_assign_semantics = OBJC_PROPERTY_ASSIGN;
900 if (parsed_property_retain)
901 property_assign_semantics = OBJC_PROPERTY_RETAIN;
903 if (parsed_property_copy)
904 property_assign_semantics = OBJC_PROPERTY_COPY;
907 if (!objc_interface_context)
909 error_at (location, "property declaration not in @interface or @protocol context");
913 /* At this point we know that we are either in an interface, a
914 category, or a protocol. */
916 if (parsed_property_setter_ident)
918 /* The setter should be terminated by ':', but the parser only
919 gives us an identifier without ':'. So, we need to add ':'
921 const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident);
922 size_t length = strlen (parsed_setter);
923 char *final_setter = (char *)alloca (length + 2);
925 sprintf (final_setter, "%s:", parsed_setter);
926 parsed_property_setter_ident = get_identifier (final_setter);
929 /* Check that the property does not have an initial value specified.
930 This should never happen as the parser doesn't allow this, but
931 it's just in case. */
932 if (DECL_INITIAL (decl))
934 error_at (location, "property can not have an initial value");
938 /* TODO: Check that the property type is an Objective-C object or a "POD". */
940 if (property_assign_semantics == OBJC_PROPERTY_ASSIGN)
942 /* If garbage collection is not being used, then 'assign' is
943 valid for objects (and typically used for delegates) but it
944 is wrong in most cases (since most objects need to be
945 retained or copied in setters). Warn users when 'assign' is
947 /* Please note that it would make sense to default to 'assign'
948 for non-{Objective-C objects}, and to 'retain' for
949 Objective-C objects. But that would break compatibility with
953 if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy)
955 if (objc_type_valid_for_messaging (TREE_TYPE (decl)))
957 warning_at (location,
959 "object property %qD has no %<assign%>, %<retain%> or %<copy%> attribute; assuming %<assign%>",
962 "%<assign%> can be unsafe for Objective-C objects; please state explicitly if you need it");
968 if (property_assign_semantics == OBJC_PROPERTY_RETAIN
969 && !objc_type_valid_for_messaging (TREE_TYPE (decl)))
970 error_at (location, "%<retain%> attribute is only valid for Objective-C objects");
972 if (property_assign_semantics == OBJC_PROPERTY_COPY
973 && !objc_type_valid_for_messaging (TREE_TYPE (decl)))
974 error_at (location, "%<copy%> attribute is only valid for Objective-C objects");
976 /* Check for duplicate property declarations. We first check the
977 immediate context for a property with the same name. */
978 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
980 if (PROPERTY_NAME (x) == DECL_NAME (decl))
982 location_t original_location = DECL_SOURCE_LOCATION (x);
984 error_at (location, "redeclaration of property %qD", decl);
986 if (original_location != UNKNOWN_LOCATION)
987 inform (original_location, "originally declared here");
992 /* TODO: Shall we check here for other property declaractions (in
993 the superclass, other categories or protocols) with the same name
994 and conflicting types ? */
996 /* Create a PROPERTY_DECL node. */
997 property_decl = make_node (PROPERTY_DECL);
999 /* Copy the basic information from the original decl. */
1000 TREE_TYPE (property_decl) = TREE_TYPE (decl);
1001 DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
1002 TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
1004 /* Add property-specific information. */
1005 PROPERTY_NAME (property_decl) = DECL_NAME (decl);
1006 PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident;
1007 PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident;
1008 PROPERTY_READONLY (property_decl) = property_readonly;
1009 PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic;
1010 PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
1011 PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1012 PROPERTY_DYNAMIC (property_decl) = 0;
1014 /* Add the PROPERTY_DECL to the list of properties for the class. */
1015 TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
1016 CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
1019 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
1022 lookup_property_in_list (tree chain, tree property)
1025 for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
1026 if (PROPERTY_NAME (x) == property)
1031 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
1032 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
1035 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
1037 tree p = TREE_VALUE (rproto);
1038 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
1040 if ((x = lookup_property_in_list (p, property)))
1042 if (PROTOCOL_LIST (p))
1043 return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
1047 ; /* An identifier...if we could not find a protocol. */
1053 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1054 chain of interface hierarchy. */
1056 lookup_property (tree interface_type, tree property)
1058 tree inter = interface_type;
1062 if ((x = lookup_property_in_list (inter, property)))
1064 /* Failing that, look for the property in each category of the class. */
1066 while ((category = CLASS_CATEGORY_LIST (category)))
1067 if ((x = lookup_property_in_list (category, property)))
1070 /* Failing to find in categories, look for property in protocol list. */
1071 if (CLASS_PROTOCOL_LIST (inter)
1072 && (x = lookup_property_in_protocol_list (
1073 CLASS_PROTOCOL_LIST (inter), property)))
1076 /* Failing that, climb up the inheritance hierarchy. */
1077 inter = lookup_interface (CLASS_SUPER_NAME (inter));
1082 /* This is a subroutine of objc_maybe_build_component_ref. Search the
1083 list of methods in the interface (and, failing that, protocol list)
1084 provided for a 'setter' or 'getter' for 'component' with default
1085 names (ie, if 'component' is "name", then search for "name" and
1086 "setName:"). If any is found, then create an artificial property
1087 that uses them. Return NULL_TREE if 'getter' or 'setter' could not
1090 maybe_make_artificial_property_decl (tree interface, tree protocol_list, tree component, bool is_class)
1092 tree getter_name = component;
1093 tree setter_name = get_identifier (objc_build_property_setter_name (component));
1094 tree getter = NULL_TREE;
1095 tree setter = NULL_TREE;
1102 flags = OBJC_LOOKUP_CLASS;
1104 getter = lookup_method_static (interface, getter_name, flags);
1105 setter = lookup_method_static (interface, setter_name, flags);
1108 /* Try the protocol_list if we didn't find anything in the interface. */
1109 if (!getter && !setter)
1111 getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
1112 setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
1115 /* There needs to be at least a getter or setter for this to be a
1116 valid 'object.component' syntax. */
1117 if (getter || setter)
1119 /* Yes ... determine the type of the expression. */
1124 type = TREE_VALUE (TREE_TYPE (getter));
1126 type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
1128 /* Create an artificial property declaration with the
1129 information we collected on the type and getter/setter
1131 property_decl = make_node (PROPERTY_DECL);
1133 TREE_TYPE (property_decl) = type;
1134 DECL_SOURCE_LOCATION (property_decl) = input_location;
1135 TREE_DEPRECATED (property_decl) = 0;
1136 DECL_ARTIFICIAL (property_decl) = 1;
1138 /* Add property-specific information. Note that one of
1139 PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
1140 non-existing method; this will generate an error when the
1141 expression is later compiled. At this stage we don't know if
1142 the getter or setter will be used, so we can't generate an
1144 PROPERTY_NAME (property_decl) = component;
1145 PROPERTY_GETTER_NAME (property_decl) = getter_name;
1146 PROPERTY_SETTER_NAME (property_decl) = setter_name;
1147 PROPERTY_READONLY (property_decl) = 0;
1148 PROPERTY_NONATOMIC (property_decl) = 0;
1149 PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
1150 PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1151 PROPERTY_DYNAMIC (property_decl) = 0;
1154 PROPERTY_HAS_NO_GETTER (property_decl) = 1;
1156 /* The following is currently unused, but it's nice to have
1157 there. We may use it if we need in the future. */
1159 PROPERTY_HAS_NO_SETTER (property_decl) = 1;
1161 return property_decl;
1167 /* This hook routine is invoked by the parser when an expression such
1168 as 'xxx.yyy' is parsed. We get a chance to process these
1169 expressions in a way that is specified to Objective-C (to implement
1170 the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
1171 If the expression is not an Objective-C specified expression, we
1172 should return NULL_TREE; else we return the expression.
1174 At the moment this only implements dot-syntax and properties (not
1175 non-fragile ivars yet), ie 'object.property' or 'object.component'
1176 where 'component' is not a declared property, but a valid getter or
1177 setter for it could be found. */
1179 objc_maybe_build_component_ref (tree object, tree property_ident)
1184 /* If we are in Objective-C 1.0 mode, properties are not
1186 if (flag_objc1_only)
1189 /* Try to determine quickly if 'object' is an Objective-C object or
1190 not. If not, return. */
1191 if (object == NULL_TREE || object == error_mark_node
1192 || (rtype = TREE_TYPE (object)) == NULL_TREE)
1195 if (property_ident == NULL_TREE || property_ident == error_mark_node
1196 || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1199 /* TODO: Implement super.property. */
1201 /* TODO: Carefully review the following code. */
1202 if (objc_is_id (rtype))
1204 tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
1205 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
1208 x = lookup_property_in_protocol_list (rprotos, property_ident);
1212 /* Ok, no property. Maybe it was an object.component
1213 dot-syntax without a declared property. Look for
1214 getter/setter methods and internally declare an artifical
1215 property based on them if found. */
1216 x = maybe_make_artificial_property_decl (NULL_TREE, rprotos,
1223 tree basetype = TYPE_MAIN_VARIANT (rtype);
1225 if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1226 basetype = TREE_TYPE (basetype);
1230 while (basetype != NULL_TREE
1231 && TREE_CODE (basetype) == RECORD_TYPE
1232 && OBJC_TYPE_NAME (basetype)
1233 && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1234 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1235 basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1237 if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1239 tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1240 tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
1242 x = lookup_property (interface_type, property_ident);
1245 x = lookup_property_in_protocol_list (protocol_list, property_ident);
1249 /* Ok, no property. Try the dot-syntax without a
1250 declared property. */
1251 x = maybe_make_artificial_property_decl (interface_type, protocol_list,
1252 property_ident, false);
1261 if (TREE_DEPRECATED (x))
1262 warn_deprecated_use (x, NULL_TREE);
1264 expression = build2 (PROPERTY_REF, TREE_TYPE(x), object, x);
1265 SET_EXPR_LOCATION (expression, input_location);
1266 TREE_SIDE_EFFECTS (expression) = 1;
1268 /* We have an additional nasty problem here; if this
1269 PROPERTY_REF needs to become a 'getter', then the conversion
1270 from PROPERTY_REF into a getter call happens in gimplify,
1271 after the selector table has already been generated and it is
1272 too late to add another selector to it. To work around the
1273 problem, we always put the selector in the table at this
1274 stage, as if we were building the method call here. And the
1275 easiest way to do this is precisely to build the method call,
1276 then discard it. Note that if the PROPERTY_REF becomes a
1277 'setter' instead of a 'getter', then we have added a selector
1278 too many to the selector table. This is a little
1281 TODO: This can be made more efficient; in particular we don't
1282 need to build the whole message call, we could just work on
1285 If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
1286 property decl created to deal with a dotsyntax not really
1287 referring to an existing property) then do not try to build a
1288 call to the getter as there is no getter. */
1289 if (!PROPERTY_HAS_NO_GETTER (x))
1290 objc_finish_message_expr (object,
1291 PROPERTY_GETTER_NAME (x),
1300 /* This is used because we don't want to expose PROPERTY_REF to the
1301 C/C++ frontends. Maybe we should! */
1303 objc_is_property_ref (tree node)
1305 if (node && TREE_CODE (node) == PROPERTY_REF)
1311 /* This hook routine is called when a MODIFY_EXPR is being built. We
1312 check what is being modified; if it is a PROPERTY_REF, we need to
1313 generate a 'setter' function call for the property. If this is not
1314 a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
1315 on creating their MODIFY_EXPR.
1317 This is used for example if you write
1321 where 'count' is a property. The left-hand side creates a
1322 PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
1323 to assign something to it. We intercept that here, and generate a
1324 call to the 'setter' method instead. */
1326 objc_maybe_build_modify_expr (tree lhs, tree rhs)
1328 if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
1330 tree object_expr = PROPERTY_REF_OBJECT (lhs);
1331 tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
1333 if (PROPERTY_READONLY (property_decl))
1335 error ("readonly property can not be set");
1336 return error_mark_node;
1340 tree setter_argument = build_tree_list (NULL_TREE, rhs);
1343 /* TODO: Check that the setter return type is 'void'. */
1345 /* TODO: Decay argument in C. */
1346 setter = objc_finish_message_expr (object_expr,
1347 PROPERTY_SETTER_NAME (property_decl),
1357 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1358 tree optparms, bool ellipsis)
1360 if (is_class_method)
1361 return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
1362 optparms, ellipsis);
1364 return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
1365 optparms, ellipsis);
1369 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
1371 if (!objc_interface_context)
1373 /* PS: At the moment, due to how the parser works, it should be
1374 impossible to get here. But it's good to have the check in
1375 case the parser changes.
1377 fatal_error ("method declaration not in @interface context");
1380 if (flag_objc1_only && attributes)
1381 error_at (input_location, "method attributes are not available in Objective-C 1.0");
1383 objc_decl_method_attributes (&decl, attributes, 0);
1384 objc_add_method (objc_interface_context,
1387 objc_method_optional_flag);
1390 /* Return 'true' if the method definition could be started, and
1391 'false' if not (because we are outside an @implementation context).
1394 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
1396 if (!objc_implementation_context)
1398 error ("method definition not in @implementation context");
1402 if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node)
1406 /* Indicate no valid break/continue context by setting these variables
1407 to some non-null, non-label value. We'll notice and emit the proper
1408 error message in c_finish_bc_stmt. */
1409 c_break_label = c_cont_label = size_zero_node;
1413 warning_at (input_location, 0, "method attributes can not be specified in @implementation context");
1415 objc_decl_method_attributes (&decl, attributes, 0);
1417 objc_add_method (objc_implementation_context,
1420 /* is optional */ false);
1421 start_method_def (decl);
1426 objc_add_instance_variable (tree decl)
1428 (void) add_instance_variable (objc_ivar_context,
1429 objc_ivar_visibility,
1433 /* Return true if TYPE is 'id'. */
1436 objc_is_object_id (tree type)
1438 return OBJC_TYPE_NAME (type) == objc_object_id;
1442 objc_is_class_id (tree type)
1444 return OBJC_TYPE_NAME (type) == objc_class_id;
1447 /* Construct a C struct with same name as KLASS, a base struct with tag
1448 SUPER_NAME (if any), and FIELDS indicated. */
1451 objc_build_struct (tree klass, tree fields, tree super_name)
1453 tree name = CLASS_NAME (klass);
1454 tree s = objc_start_struct (name);
1455 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
1457 VEC(tree,heap) *objc_info = NULL;
1462 /* Prepend a packed variant of the base class into the layout. This
1463 is necessary to preserve ObjC ABI compatibility. */
1464 tree base = build_decl (input_location,
1465 FIELD_DECL, NULL_TREE, super);
1466 tree field = TYPE_FIELDS (super);
1468 while (field && DECL_CHAIN (field)
1469 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
1470 field = DECL_CHAIN (field);
1472 /* For ObjC ABI purposes, the "packed" size of a base class is
1473 the sum of the offset and the size (in bits) of the last field
1476 = (field && TREE_CODE (field) == FIELD_DECL
1477 ? size_binop (PLUS_EXPR,
1478 size_binop (PLUS_EXPR,
1481 convert (bitsizetype,
1482 DECL_FIELD_OFFSET (field)),
1483 bitsize_int (BITS_PER_UNIT)),
1484 DECL_FIELD_BIT_OFFSET (field)),
1486 : bitsize_zero_node);
1487 DECL_SIZE_UNIT (base)
1488 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
1489 size_int (BITS_PER_UNIT));
1490 DECL_ARTIFICIAL (base) = 1;
1491 DECL_ALIGN (base) = 1;
1492 DECL_FIELD_CONTEXT (base) = s;
1494 DECL_FIELD_IS_BASE (base) = 1;
1497 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
1498 #endif /* are following the ObjC ABI here. */
1499 DECL_CHAIN (base) = fields;
1503 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1504 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1505 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1506 Hence, we must squirrel away the ObjC-specific information before calling
1507 finish_struct(), and then reinstate it afterwards. */
1509 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
1511 if (!TYPE_HAS_OBJC_INFO (t))
1513 INIT_TYPE_OBJC_INFO (t);
1514 TYPE_OBJC_INTERFACE (t) = klass;
1516 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
1519 /* Point the struct at its related Objective-C class. */
1520 INIT_TYPE_OBJC_INFO (s);
1521 TYPE_OBJC_INTERFACE (s) = klass;
1523 s = objc_finish_struct (s, fields);
1525 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
1527 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
1528 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1529 TYPE_OBJC_INTERFACE (t) = klass;
1531 VEC_free (tree, heap, objc_info);
1533 /* Use TYPE_BINFO structures to point at the super class, if any. */
1534 objc_xref_basetypes (s, super);
1536 /* Mark this struct as a class template. */
1537 CLASS_STATIC_TEMPLATE (klass) = s;
1542 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1543 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1546 objc_build_volatilized_type (tree type)
1550 /* Check if we have not constructed the desired variant already. */
1551 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1553 /* The type qualifiers must (obviously) match up. */
1554 if (!TYPE_VOLATILE (t)
1555 || (TYPE_READONLY (t) != TYPE_READONLY (type))
1556 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
1559 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1560 info, if any) must match up. */
1561 if (POINTER_TYPE_P (t)
1562 && (TREE_TYPE (t) != TREE_TYPE (type)))
1565 /* Only match up the types which were previously volatilized in similar fashion and not
1566 because they were declared as such. */
1567 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
1570 /* Everything matches up! */
1574 /* Ok, we could not re-use any of the pre-existing variants. Create
1576 t = build_variant_type_copy (type);
1577 TYPE_VOLATILE (t) = 1;
1579 TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
1580 tree_cons (get_identifier ("objc_volatilized"),
1583 if (TREE_CODE (t) == ARRAY_TYPE)
1584 TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
1586 /* Set up the canonical type information. */
1587 if (TYPE_STRUCTURAL_EQUALITY_P (type))
1588 SET_TYPE_STRUCTURAL_EQUALITY (t);
1589 else if (TYPE_CANONICAL (type) != type)
1590 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
1592 TYPE_CANONICAL (t) = t;
1597 /* Mark DECL as being 'volatile' for purposes of Darwin
1598 _setjmp()/_longjmp() exception handling. Called from
1599 objc_mark_locals_volatile(). */
1601 objc_volatilize_decl (tree decl)
1603 /* Do not mess with variables that are 'static' or (already)
1605 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
1606 && (TREE_CODE (decl) == VAR_DECL
1607 || TREE_CODE (decl) == PARM_DECL))
1609 tree t = TREE_TYPE (decl);
1611 t = objc_build_volatilized_type (t);
1613 TREE_TYPE (decl) = t;
1614 TREE_THIS_VOLATILE (decl) = 1;
1615 TREE_SIDE_EFFECTS (decl) = 1;
1616 DECL_REGISTER (decl) = 0;
1618 C_DECL_REGISTER (decl) = 0;
1623 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1624 (including its categories and superclasses) or by object type TYP.
1625 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1628 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
1630 bool class_type = (cls != NULL_TREE);
1636 /* Check protocols adopted by the class and its categories. */
1637 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1639 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1643 /* Repeat for superclasses. */
1644 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1647 /* Check for any protocols attached directly to the object type. */
1648 if (TYPE_HAS_OBJC_INFO (typ))
1650 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1657 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1658 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1659 "implementing" a given protocol, since they do not have an
1662 warning (0, "class %qs does not implement the %qE protocol",
1663 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1665 warning (0, "type %qs does not conform to the %qE protocol",
1666 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1672 /* Check if class RCLS and instance struct type RTYP conform to at least the
1673 same protocols that LCLS and LTYP conform to. */
1676 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1679 bool have_lproto = false;
1683 /* NB: We do _not_ look at categories defined for LCLS; these may or
1684 may not get loaded in, and therefore it is unreasonable to require
1685 that RCLS/RTYP must implement any of their protocols. */
1686 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1690 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1694 /* Repeat for superclasses. */
1695 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1698 /* Check for any protocols attached directly to the object type. */
1699 if (TYPE_HAS_OBJC_INFO (ltyp))
1701 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1705 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1710 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1711 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1712 away with simply checking for 'id' or 'Class' (!RCLS), since this
1713 routine will not get called in other cases. */
1714 return have_lproto || (rcls != NULL_TREE);
1717 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1718 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1719 compatible by objc_compare_types() below. */
1722 objc_common_type (tree type1, tree type2)
1724 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
1726 while (POINTER_TYPE_P (inner1))
1728 inner1 = TREE_TYPE (inner1);
1729 inner2 = TREE_TYPE (inner2);
1732 /* If one type is derived from another, return the base type. */
1733 if (DERIVED_FROM_P (inner1, inner2))
1735 else if (DERIVED_FROM_P (inner2, inner1))
1738 /* If both types are 'Class', return 'Class'. */
1739 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
1740 return objc_class_type;
1742 /* Otherwise, return 'id'. */
1743 return objc_object_type;
1746 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1747 an instance of RTYP to an instance of LTYP or to compare the two
1748 (if ARGNO is equal to -3), per ObjC type system rules. Before
1749 returning 'true', this routine may issue warnings related to, e.g.,
1750 protocol conformance. When returning 'false', the routine must
1751 produce absolutely no warnings; the C or C++ front-end will do so
1752 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1753 the routine must return 'false'.
1755 The ARGNO parameter is encoded as follows:
1756 >= 1 Parameter number (CALLEE contains function being called);
1760 -3 Comparison (LTYP and RTYP may match in either direction);
1761 -4 Silent comparison (for C++ overload resolution).
1765 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1767 tree lcls, rcls, lproto, rproto;
1768 bool pointers_compatible;
1770 /* We must be dealing with pointer types */
1771 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1776 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1777 rtyp = TREE_TYPE (rtyp);
1779 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1781 /* We must also handle function pointers, since ObjC is a bit more
1782 lenient than C or C++ on this. */
1783 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
1785 /* Return types must be covariant. */
1786 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
1787 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
1791 /* Argument types must be contravariant. */
1792 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
1793 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
1795 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
1796 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
1801 return (ltyp == rtyp);
1804 /* Past this point, we are only interested in ObjC class instances,
1805 or 'id' or 'Class'. */
1806 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1809 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1810 && !TYPE_HAS_OBJC_INFO (ltyp))
1813 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1814 && !TYPE_HAS_OBJC_INFO (rtyp))
1817 /* Past this point, we are committed to returning 'true' to the caller
1818 (unless performing a silent comparison; see below). However, we can
1819 still warn about type and/or protocol mismatches. */
1821 if (TYPE_HAS_OBJC_INFO (ltyp))
1823 lcls = TYPE_OBJC_INTERFACE (ltyp);
1824 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1827 lcls = lproto = NULL_TREE;
1829 if (TYPE_HAS_OBJC_INFO (rtyp))
1831 rcls = TYPE_OBJC_INTERFACE (rtyp);
1832 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1835 rcls = rproto = NULL_TREE;
1837 /* If we could not find an @interface declaration, we must have
1838 only seen a @class declaration; for purposes of type comparison,
1839 treat it as a stand-alone (root) class. */
1841 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1844 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1847 /* If either type is an unqualified 'id', we're done. */
1848 if ((!lproto && objc_is_object_id (ltyp))
1849 || (!rproto && objc_is_object_id (rtyp)))
1852 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1854 /* If the underlying types are the same, and at most one of them has
1855 a protocol list, we do not need to issue any diagnostics. */
1856 if (pointers_compatible && (!lproto || !rproto))
1859 /* If exactly one of the types is 'Class', issue a diagnostic; any
1860 exceptions of this rule have already been handled. */
1861 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1862 pointers_compatible = false;
1863 /* Otherwise, check for inheritance relations. */
1866 if (!pointers_compatible)
1868 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1870 if (!pointers_compatible)
1871 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1873 if (!pointers_compatible && argno <= -3)
1874 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1877 /* If the pointers match modulo protocols, check for protocol conformance
1879 if (pointers_compatible)
1881 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1884 if (!pointers_compatible && argno == -3)
1885 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1889 if (!pointers_compatible)
1891 /* The two pointers are not exactly compatible. Issue a warning, unless
1892 we are performing a silent comparison, in which case return 'false'
1894 /* NB: For the time being, we shall make our warnings look like their
1895 C counterparts. In the future, we may wish to make them more
1903 warning (0, "comparison of distinct Objective-C types lacks a cast");
1907 warning (0, "initialization from distinct Objective-C type");
1911 warning (0, "assignment from distinct Objective-C type");
1915 warning (0, "distinct Objective-C type in return");
1919 warning (0, "passing argument %d of %qE from distinct "
1920 "Objective-C type", argno, callee);
1928 /* This routine is similar to objc_compare_types except that function-pointers are
1929 excluded. This is because, caller assumes that common types are of (id, Object*)
1930 variety and calls objc_common_type to obtain a common type. There is no commonolty
1931 between two function-pointers in this regard. */
1934 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
1936 if (objc_compare_types (ltyp, rtyp, argno, callee))
1938 /* exclude function-pointer types. */
1941 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1942 rtyp = TREE_TYPE (rtyp);
1944 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1945 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
1950 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1951 lives in the volatilized hash table, ignore the 'volatile' bit when
1952 making the comparison. */
1955 objc_type_quals_match (tree ltyp, tree rtyp)
1957 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1959 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
1960 lquals &= ~TYPE_QUAL_VOLATILE;
1962 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
1963 rquals &= ~TYPE_QUAL_VOLATILE;
1965 return (lquals == rquals);
1969 /* Determine if CHILD is derived from PARENT. The routine assumes that
1970 both parameters are RECORD_TYPEs, and is non-reflexive. */
1973 objc_derived_from_p (tree parent, tree child)
1975 parent = TYPE_MAIN_VARIANT (parent);
1977 for (child = TYPE_MAIN_VARIANT (child);
1978 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1980 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1981 (TYPE_BINFO (child),
1984 if (child == parent)
1993 objc_build_component_ref (tree datum, tree component)
1995 /* If COMPONENT is NULL, the caller is referring to the anonymous
1996 base class field. */
1999 tree base = TYPE_FIELDS (TREE_TYPE (datum));
2001 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
2004 /* The 'build_component_ref' routine has been removed from the C++
2005 front-end, but 'finish_class_member_access_expr' seems to be
2006 a worthy substitute. */
2008 return finish_class_member_access_expr (datum, component, false,
2009 tf_warning_or_error);
2011 return build_component_ref (input_location, datum, component);
2015 /* Recursively copy inheritance information rooted at BINFO. To do this,
2016 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
2019 objc_copy_binfo (tree binfo)
2021 tree btype = BINFO_TYPE (binfo);
2022 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
2026 BINFO_TYPE (binfo2) = btype;
2027 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
2028 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
2030 /* Recursively copy base binfos of BINFO. */
2031 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
2033 tree base_binfo2 = objc_copy_binfo (base_binfo);
2035 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
2036 BINFO_BASE_APPEND (binfo2, base_binfo2);
2042 /* Record superclass information provided in BASETYPE for ObjC class REF.
2043 This is loosely based on cp/decl.c:xref_basetypes(). */
2046 objc_xref_basetypes (tree ref, tree basetype)
2048 tree binfo = make_tree_binfo (basetype ? 1 : 0);
2050 TYPE_BINFO (ref) = binfo;
2051 BINFO_OFFSET (binfo) = size_zero_node;
2052 BINFO_TYPE (binfo) = ref;
2056 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
2058 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
2059 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
2060 BINFO_BASE_APPEND (binfo, base_binfo);
2061 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
2065 /* Called from finish_decl. */
2068 objc_check_decl (tree decl)
2070 tree type = TREE_TYPE (decl);
2072 if (TREE_CODE (type) != RECORD_TYPE)
2074 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
2075 error ("statically allocated instance of Objective-C class %qE",
2080 objc_check_global_decl (tree decl)
2082 tree id = DECL_NAME (decl);
2083 if (objc_is_class_name (id) && global_bindings_p())
2084 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2087 /* Return a non-volatalized version of TYPE. */
2090 objc_non_volatilized_type (tree type)
2092 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
2093 type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
2097 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2098 either name an Objective-C class, or refer to the special 'id' or 'Class'
2099 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2102 objc_get_protocol_qualified_type (tree interface, tree protocols)
2104 /* If INTERFACE is not provided, default to 'id'. */
2105 tree type = (interface ? objc_is_id (interface) : objc_object_type);
2106 bool is_ptr = (type != NULL_TREE);
2110 type = objc_is_class_name (interface);
2114 /* If looking at a typedef, retrieve the precise type it
2116 if (TREE_CODE (interface) == IDENTIFIER_NODE)
2117 interface = identifier_global_value (interface);
2119 type = ((interface && TREE_CODE (interface) == TYPE_DECL
2120 && DECL_ORIGINAL_TYPE (interface))
2121 ? DECL_ORIGINAL_TYPE (interface)
2122 : xref_tag (RECORD_TYPE, type));
2130 type = build_variant_type_copy (type);
2132 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2136 tree orig_pointee_type = TREE_TYPE (type);
2137 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2139 /* Set up the canonical type information. */
2140 TYPE_CANONICAL (type)
2141 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2143 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2144 type = TREE_TYPE (type);
2147 /* Look up protocols and install in lang specific list. */
2148 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2149 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2151 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2152 return the pointer to the new pointee variant. */
2154 type = TYPE_POINTER_TO (type);
2156 TYPE_OBJC_INTERFACE (type)
2157 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2163 /* Check for circular dependencies in protocols. The arguments are
2164 PROTO, the protocol to check, and LIST, a list of protocol it
2168 check_protocol_recursively (tree proto, tree list)
2172 for (p = list; p; p = TREE_CHAIN (p))
2174 tree pp = TREE_VALUE (p);
2176 if (TREE_CODE (pp) == IDENTIFIER_NODE)
2177 pp = lookup_protocol (pp);
2180 fatal_error ("protocol %qE has circular dependency",
2181 PROTOCOL_NAME (pp));
2183 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2187 /* Look up PROTOCOLS, and return a list of those that are found.
2188 If none are found, return NULL. */
2191 lookup_and_install_protocols (tree protocols)
2194 tree return_value = NULL_TREE;
2196 if (protocols == error_mark_node)
2199 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2201 tree ident = TREE_VALUE (proto);
2202 tree p = lookup_protocol (ident);
2205 return_value = chainon (return_value,
2206 build_tree_list (NULL_TREE, p));
2207 else if (ident != error_mark_node)
2208 error ("cannot find protocol declaration for %qE",
2212 return return_value;
2215 /* Create a declaration for field NAME of a given TYPE. */
2218 create_field_decl (tree type, const char *name)
2220 return build_decl (input_location,
2221 FIELD_DECL, get_identifier (name), type);
2224 /* Create a global, static declaration for variable NAME of a given TYPE. The
2225 finish_var_decl() routine will need to be called on it afterwards. */
2228 start_var_decl (tree type, const char *name)
2230 tree var = build_decl (input_location,
2231 VAR_DECL, get_identifier (name), type);
2233 TREE_STATIC (var) = 1;
2234 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
2235 DECL_IGNORED_P (var) = 1;
2236 DECL_ARTIFICIAL (var) = 1;
2237 DECL_CONTEXT (var) = NULL_TREE;
2239 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2245 /* Finish off the variable declaration created by start_var_decl(). */
2248 finish_var_decl (tree var, tree initializer)
2250 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2253 /* Find the decl for the constant string class reference. This is only
2254 used for the NeXT runtime. */
2257 setup_string_decl (void)
2262 /* %s in format will provide room for terminating null */
2263 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2264 + strlen (constant_string_class_name);
2265 name = XNEWVEC (char, length);
2266 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2267 constant_string_class_name);
2268 constant_string_global_id = get_identifier (name);
2269 string_class_decl = lookup_name (constant_string_global_id);
2271 return string_class_decl;
2274 /* Purpose: "play" parser, creating/installing representations
2275 of the declarations that are required by Objective-C.
2279 type_spec--------->sc_spec
2280 (tree_list) (tree_list)
2283 identifier_node identifier_node */
2286 synth_module_prologue (void)
2289 enum debug_info_type save_write_symbols = write_symbols;
2290 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2292 /* Suppress outputting debug symbols, because
2293 dbxout_init hasn't been called yet. */
2294 write_symbols = NO_DEBUG;
2295 debug_hooks = &do_nothing_debug_hooks;
2298 push_lang_context (lang_name_c); /* extern "C" */
2301 /* The following are also defined in <objc/objc.h> and friends. */
2303 objc_object_id = get_identifier (TAG_OBJECT);
2304 objc_class_id = get_identifier (TAG_CLASS);
2306 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2307 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2309 objc_object_type = build_pointer_type (objc_object_reference);
2310 objc_class_type = build_pointer_type (objc_class_reference);
2312 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2313 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2315 /* Declare the 'id' and 'Class' typedefs. */
2317 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2321 TREE_NO_WARNING (type) = 1;
2322 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2326 TREE_NO_WARNING (type) = 1;
2328 /* Forward-declare '@interface Protocol'. */
2330 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
2331 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
2332 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
2335 /* Declare type of selector-objects that represent an operation name. */
2337 if (flag_next_runtime)
2338 /* `struct objc_selector *' */
2340 = build_pointer_type (xref_tag (RECORD_TYPE,
2341 get_identifier (TAG_SELECTOR)));
2343 /* `const struct objc_selector *' */
2345 = build_pointer_type
2346 (build_qualified_type (xref_tag (RECORD_TYPE,
2347 get_identifier (TAG_SELECTOR)),
2350 /* Declare receiver type used for dispatching messages to 'super'. */
2352 /* `struct objc_super *' */
2353 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
2354 get_identifier (TAG_SUPER)));
2356 /* Declare pointers to method and ivar lists. */
2357 objc_method_list_ptr = build_pointer_type
2358 (xref_tag (RECORD_TYPE,
2359 get_identifier (UTAG_METHOD_LIST)));
2360 objc_method_proto_list_ptr
2361 = build_pointer_type (xref_tag (RECORD_TYPE,
2362 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2363 objc_ivar_list_ptr = build_pointer_type
2364 (xref_tag (RECORD_TYPE,
2365 get_identifier (UTAG_IVAR_LIST)));
2367 /* TREE_NOTHROW is cleared for the message-sending functions,
2368 because the function that gets called can throw in Obj-C++, or
2369 could itself call something that can throw even in Obj-C. */
2371 if (flag_next_runtime)
2373 /* NB: In order to call one of the ..._stret (struct-returning)
2374 functions, the function *MUST* first be cast to a signature that
2375 corresponds to the actual ObjC method being invoked. This is
2376 what is done by the build_objc_method_call() routine below. */
2378 /* id objc_msgSend (id, SEL, ...); */
2379 /* id objc_msgSendNonNil (id, SEL, ...); */
2380 /* id objc_msgSend_stret (id, SEL, ...); */
2381 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2383 = build_varargs_function_type_list (objc_object_type,
2387 umsg_decl = add_builtin_function (TAG_MSGSEND,
2388 type, 0, NOT_BUILT_IN,
2390 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
2391 type, 0, NOT_BUILT_IN,
2393 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
2394 type, 0, NOT_BUILT_IN,
2396 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
2397 type, 0, NOT_BUILT_IN,
2400 /* These can throw, because the function that gets called can throw
2401 in Obj-C++, or could itself call something that can throw even
2403 TREE_NOTHROW (umsg_decl) = 0;
2404 TREE_NOTHROW (umsg_nonnil_decl) = 0;
2405 TREE_NOTHROW (umsg_stret_decl) = 0;
2406 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
2408 /* id objc_msgSend_Fast (id, SEL, ...)
2409 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2410 #ifdef OFFS_MSGSEND_FAST
2411 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
2412 type, 0, NOT_BUILT_IN,
2414 TREE_NOTHROW (umsg_fast_decl) = 0;
2415 DECL_ATTRIBUTES (umsg_fast_decl)
2416 = tree_cons (get_identifier ("hard_coded_address"),
2417 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
2420 /* No direct dispatch available. */
2421 umsg_fast_decl = umsg_decl;
2424 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2425 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2427 = build_varargs_function_type_list (objc_object_type,
2431 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2432 type, 0, NOT_BUILT_IN,
2434 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
2435 type, 0, NOT_BUILT_IN, 0,
2437 TREE_NOTHROW (umsg_super_decl) = 0;
2438 TREE_NOTHROW (umsg_super_stret_decl) = 0;
2442 /* GNU runtime messenger entry points. */
2444 /* typedef id (*IMP)(id, SEL, ...); */
2446 build_varargs_function_type_list (objc_object_type,
2450 tree IMP_type = build_pointer_type (ftype);
2452 /* IMP objc_msg_lookup (id, SEL); */
2453 type = build_function_type_list (IMP_type,
2457 umsg_decl = add_builtin_function (TAG_MSGSEND,
2458 type, 0, NOT_BUILT_IN,
2460 TREE_NOTHROW (umsg_decl) = 0;
2462 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2464 = build_function_type_list (IMP_type,
2468 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2469 type, 0, NOT_BUILT_IN,
2471 TREE_NOTHROW (umsg_super_decl) = 0;
2473 /* The following GNU runtime entry point is called to initialize
2476 __objc_exec_class (void *); */
2478 = build_function_type_list (void_type_node,
2481 execclass_decl = add_builtin_function (TAG_EXECCLASS,
2482 type, 0, NOT_BUILT_IN,
2486 /* id objc_getClass (const char *); */
2488 type = build_function_type_list (objc_object_type,
2489 const_string_type_node,
2493 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
2496 /* id objc_getMetaClass (const char *); */
2498 objc_get_meta_class_decl
2499 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
2501 build_class_template ();
2502 build_super_template ();
2503 build_protocol_template ();
2504 build_category_template ();
2505 build_objc_exception_stuff ();
2507 /* Declare objc_getProperty, object_setProperty and other property
2508 accessor helpers. */
2509 build_objc_property_accessor_helpers ();
2511 if (flag_next_runtime)
2512 build_next_objc_exception_stuff ();
2514 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2516 if (! flag_next_runtime)
2517 build_selector_table_decl ();
2519 /* Forward declare constant_string_id and constant_string_type. */
2520 if (!constant_string_class_name)
2521 constant_string_class_name = default_constant_string_class_name;
2523 constant_string_id = get_identifier (constant_string_class_name);
2524 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
2526 /* Pre-build the following entities - for speed/convenience. */
2527 self_id = get_identifier ("self");
2528 ucmd_id = get_identifier ("_cmd");
2530 /* Declare struct _objc_fast_enumeration_state { ... }; */
2531 build_fast_enumeration_state_template ();
2533 /* void objc_enumeration_mutation (id) */
2534 type = build_function_type (void_type_node,
2535 tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
2536 objc_enumeration_mutation_decl
2537 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
2539 TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
2542 pop_lang_context ();
2545 write_symbols = save_write_symbols;
2546 debug_hooks = save_hooks;
2549 /* Ensure that the ivar list for NSConstantString/NXConstantString
2550 (or whatever was specified via `-fconstant-string-class')
2551 contains fields at least as large as the following three, so that
2552 the runtime can stomp on them with confidence:
2554 struct STRING_OBJECT_CLASS_NAME
2558 unsigned int length;
2562 check_string_class_template (void)
2564 tree field_decl = objc_get_class_ivars (constant_string_id);
2566 #define AT_LEAST_AS_LARGE_AS(F, T) \
2567 (F && TREE_CODE (F) == FIELD_DECL \
2568 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2569 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2571 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2574 field_decl = DECL_CHAIN (field_decl);
2575 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2578 field_decl = DECL_CHAIN (field_decl);
2579 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
2581 #undef AT_LEAST_AS_LARGE_AS
2584 /* Avoid calling `check_string_class_template ()' more than once. */
2585 static GTY(()) int string_layout_checked;
2587 /* Construct an internal string layout to be used as a template for
2588 creating NSConstantString/NXConstantString instances. */
2591 objc_build_internal_const_str_type (void)
2593 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
2594 tree fields = build_decl (input_location,
2595 FIELD_DECL, NULL_TREE, ptr_type_node);
2596 tree field = build_decl (input_location,
2597 FIELD_DECL, NULL_TREE, ptr_type_node);
2599 DECL_CHAIN (field) = fields; fields = field;
2600 field = build_decl (input_location,
2601 FIELD_DECL, NULL_TREE, unsigned_type_node);
2602 DECL_CHAIN (field) = fields; fields = field;
2603 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2605 finish_builtin_struct (type, "__builtin_ObjCString",
2611 /* Custom build_string which sets TREE_TYPE! */
2614 my_build_string (int len, const char *str)
2616 return fix_string_type (build_string (len, str));
2619 /* Build a string with contents STR and length LEN and convert it to a
2623 my_build_string_pointer (int len, const char *str)
2625 tree string = my_build_string (len, str);
2626 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
2627 return build1 (ADDR_EXPR, ptrtype, string);
2631 string_hash (const void *ptr)
2633 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
2634 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
2635 int i, len = TREE_STRING_LENGTH (str);
2638 for (i = 0; i < len; i++)
2639 h = ((h * 613) + p[i]);
2645 string_eq (const void *ptr1, const void *ptr2)
2647 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
2648 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
2649 int len1 = TREE_STRING_LENGTH (str1);
2651 return (len1 == TREE_STRING_LENGTH (str2)
2652 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
2656 /* Given a chain of STRING_CST's, build a static instance of
2657 NXConstantString which points at the concatenation of those
2658 strings. We place the string object in the __string_objects
2659 section of the __OBJC segment. The Objective-C runtime will
2660 initialize the isa pointers of the string objects to point at the
2661 NXConstantString class object. */
2664 objc_build_string_object (tree string)
2666 tree constant_string_class;
2669 struct string_descriptor *desc, key;
2672 /* Prep the string argument. */
2673 string = fix_string_type (string);
2674 TREE_SET_CODE (string, STRING_CST);
2675 length = TREE_STRING_LENGTH (string) - 1;
2677 /* The target may have different ideas on how to construct an ObjC string
2678 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
2679 constant CFString reference instead.
2680 At present, this is only supported for the NeXT runtime. */
2681 if (flag_next_runtime && targetcm.objc_construct_string)
2683 tree constructor = (*targetcm.objc_construct_string) (string);
2685 return build1 (NOP_EXPR, objc_object_type, constructor);
2688 /* Check whether the string class being used actually exists and has the
2689 correct ivar layout. */
2690 if (!string_layout_checked)
2692 string_layout_checked = -1;
2693 constant_string_class = lookup_interface (constant_string_id);
2694 internal_const_str_type = objc_build_internal_const_str_type ();
2696 if (!constant_string_class
2697 || !(constant_string_type
2698 = CLASS_STATIC_TEMPLATE (constant_string_class)))
2699 error ("cannot find interface declaration for %qE",
2700 constant_string_id);
2701 /* The NSConstantString/NXConstantString ivar layout is now known. */
2702 else if (!check_string_class_template ())
2703 error ("interface %qE does not have valid constant string layout",
2704 constant_string_id);
2705 /* For the NeXT runtime, we can generate a literal reference
2706 to the string class, don't need to run a constructor. */
2707 else if (flag_next_runtime && !setup_string_decl ())
2708 error ("cannot find reference tag for class %qE",
2709 constant_string_id);
2712 string_layout_checked = 1; /* Success! */
2713 add_class_reference (constant_string_id);
2717 if (string_layout_checked == -1)
2718 return error_mark_node;
2720 /* Perhaps we already constructed a constant string just like this one? */
2721 key.literal = string;
2722 loc = htab_find_slot (string_htab, &key, INSERT);
2723 desc = (struct string_descriptor *) *loc;
2727 tree var, constructor;
2728 VEC(constructor_elt,gc) *v = NULL;
2729 *loc = desc = ggc_alloc_string_descriptor ();
2730 desc->literal = string;
2732 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2733 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2734 fields = TYPE_FIELDS (internal_const_str_type);
2735 CONSTRUCTOR_APPEND_ELT (v, fields,
2737 ? build_unary_op (input_location,
2738 ADDR_EXPR, string_class_decl, 0)
2739 : build_int_cst (NULL_TREE, 0));
2740 fields = DECL_CHAIN (fields);
2741 CONSTRUCTOR_APPEND_ELT (v, fields,
2742 build_unary_op (input_location,
2743 ADDR_EXPR, string, 1));
2744 fields = DECL_CHAIN (fields);
2745 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
2746 constructor = objc_build_constructor (internal_const_str_type, v);
2748 if (!flag_next_runtime)
2750 = objc_add_static_instance (constructor, constant_string_type);
2753 var = build_decl (input_location,
2754 CONST_DECL, NULL, TREE_TYPE (constructor));
2755 DECL_INITIAL (var) = constructor;
2756 TREE_STATIC (var) = 1;
2757 pushdecl_top_level (var);
2760 desc->constructor = constructor;
2763 addr = convert (build_pointer_type (constant_string_type),
2764 build_unary_op (input_location,
2765 ADDR_EXPR, desc->constructor, 1));
2770 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2772 static GTY(()) int num_static_inst;
2775 objc_add_static_instance (tree constructor, tree class_decl)
2780 /* Find the list of static instances for the CLASS_DECL. Create one if
2782 for (chain = &objc_static_instances;
2783 *chain && TREE_VALUE (*chain) != class_decl;
2784 chain = &TREE_CHAIN (*chain));
2787 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2788 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2791 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2792 decl = build_decl (input_location,
2793 VAR_DECL, get_identifier (buf), class_decl);
2794 TREE_STATIC (decl) = 1;
2795 DECL_ARTIFICIAL (decl) = 1;
2796 TREE_USED (decl) = 1;
2797 DECL_INITIAL (decl) = constructor;
2799 /* We may be writing something else just now.
2800 Postpone till end of input. */
2801 DECL_DEFER_OUTPUT (decl) = 1;
2802 pushdecl_top_level (decl);
2803 rest_of_decl_compilation (decl, 1, 0);
2805 /* Add the DECL to the head of this CLASS' list. */
2806 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2811 /* Build a static constant CONSTRUCTOR
2812 with type TYPE and elements ELTS. */
2815 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
2817 tree constructor = build_constructor (type, elts);
2819 TREE_CONSTANT (constructor) = 1;
2820 TREE_STATIC (constructor) = 1;
2821 TREE_READONLY (constructor) = 1;
2824 /* Adjust for impedance mismatch. We should figure out how to build
2825 CONSTRUCTORs that consistently please both the C and C++ gods. */
2826 if (!VEC_index (constructor_elt, elts, 0)->index)
2827 TREE_TYPE (constructor) = init_list_type_node;
2833 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2835 /* Predefine the following data type:
2843 void *defs[cls_def_cnt + cat_def_cnt];
2847 build_objc_symtab_template (void)
2849 tree fields, *chain = NULL;
2851 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2853 /* long sel_ref_cnt; */
2854 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
2857 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
2859 /* short cls_def_cnt; */
2860 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
2862 /* short cat_def_cnt; */
2863 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2865 if (imp_count || cat_count || !flag_next_runtime)
2867 /* void *defs[imp_count + cat_count (+ 1)]; */
2868 /* NB: The index is one less than the size of the array. */
2869 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
2870 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
2871 add_field_decl (array_type, "defs", &chain);
2874 objc_finish_struct (objc_symtab_template, fields);
2877 /* Create the initial value for the `defs' field of _objc_symtab.
2878 This is a CONSTRUCTOR. */
2881 init_def_list (tree type)
2884 struct imp_entry *impent;
2885 VEC(constructor_elt,gc) *v = NULL;
2888 for (impent = imp_list; impent; impent = impent->next)
2890 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2892 expr = build_unary_op (input_location,
2893 ADDR_EXPR, impent->class_decl, 0);
2894 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2899 for (impent = imp_list; impent; impent = impent->next)
2901 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2903 expr = build_unary_op (input_location,
2904 ADDR_EXPR, impent->class_decl, 0);
2905 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2909 if (!flag_next_runtime)
2911 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2912 if (static_instances_decl)
2913 expr = build_unary_op (input_location,
2914 ADDR_EXPR, static_instances_decl, 0);
2916 expr = integer_zero_node;
2918 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2921 return objc_build_constructor (type, v);
2924 /* Construct the initial value for all of _objc_symtab. */
2927 init_objc_symtab (tree type)
2929 VEC(constructor_elt,gc) *v = NULL;
2931 /* sel_ref_cnt = { ..., 5, ... } */
2933 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2934 build_int_cst (long_integer_type_node, 0));
2936 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2938 if (flag_next_runtime || ! sel_ref_chain)
2939 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
2940 build_pointer_type (objc_selector_type),
2941 integer_zero_node));
2944 tree expr = build_unary_op (input_location, ADDR_EXPR,
2945 UOBJC_SELECTOR_TABLE_decl, 1);
2947 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2948 convert (build_pointer_type (objc_selector_type),
2952 /* cls_def_cnt = { ..., 5, ... } */
2954 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2955 build_int_cst (short_integer_type_node, imp_count));
2957 /* cat_def_cnt = { ..., 5, ... } */
2959 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2960 build_int_cst (short_integer_type_node, cat_count));
2962 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2964 if (imp_count || cat_count || !flag_next_runtime)
2967 tree field = TYPE_FIELDS (type);
2968 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2970 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2973 return objc_build_constructor (type, v);
2976 /* Generate forward declarations for metadata such as
2977 'OBJC_CLASS_...'. */
2980 build_metadata_decl (const char *name, tree type)
2984 /* struct TYPE NAME_<name>; */
2985 decl = start_var_decl (type, synth_id_with_class_suffix
2987 objc_implementation_context));
2992 /* Push forward-declarations of all the categories so that
2993 init_def_list can use them in a CONSTRUCTOR. */
2996 forward_declare_categories (void)
2998 struct imp_entry *impent;
2999 tree sav = objc_implementation_context;
3001 for (impent = imp_list; impent; impent = impent->next)
3003 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3005 /* Set an invisible arg to synth_id_with_class_suffix. */
3006 objc_implementation_context = impent->imp_context;
3007 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
3008 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
3009 objc_category_template);
3012 objc_implementation_context = sav;
3015 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
3016 and initialized appropriately. */
3019 generate_objc_symtab_decl (void)
3022 build_objc_symtab_template ();
3023 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
3024 finish_var_decl (UOBJC_SYMBOLS_decl,
3025 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
3029 init_module_descriptor (tree type)
3032 VEC(constructor_elt,gc) *v = NULL;
3034 /* version = { 1, ... } */
3036 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
3037 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3039 /* size = { ..., sizeof (struct _objc_module), ... } */
3041 expr = convert (long_integer_type_node,
3042 size_in_bytes (objc_module_template));
3043 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3045 /* Don't provide any file name for security reasons. */
3046 /* name = { ..., "", ... } */
3048 expr = add_objc_string (get_identifier (""), class_names);
3049 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3051 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3053 if (UOBJC_SYMBOLS_decl)
3054 expr = build_unary_op (input_location,
3055 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
3057 expr = null_pointer_node;
3058 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3060 return objc_build_constructor (type, v);
3063 /* Write out the data structures to describe Objective C classes defined.
3065 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
3068 build_module_descriptor (void)
3070 tree decls, *chain = NULL;
3073 push_lang_context (lang_name_c); /* extern "C" */
3076 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
3079 decls = add_field_decl (long_integer_type_node, "version", &chain);
3082 add_field_decl (long_integer_type_node, "size", &chain);
3085 add_field_decl (string_type_node, "name", &chain);
3087 /* struct _objc_symtab *symtab; */
3088 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3089 get_identifier (UTAG_SYMTAB))),
3092 objc_finish_struct (objc_module_template, decls);
3094 /* Create an instance of "_objc_module". */
3095 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3096 /* This is the root of the metadata for defined classes and categories, it
3097 is referenced by the runtime and, therefore, needed. */
3098 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3099 finish_var_decl (UOBJC_MODULES_decl,
3100 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3103 pop_lang_context ();
3107 /* The GNU runtime requires us to provide a static initializer function
3110 static void __objc_gnu_init (void) {
3111 __objc_exec_class (&L_OBJC_MODULES);
3115 build_module_initializer_routine (void)
3120 push_lang_context (lang_name_c); /* extern "C" */
3123 objc_push_parm (build_decl (input_location,
3124 PARM_DECL, NULL_TREE, void_type_node));
3126 objc_start_function (get_identifier (TAG_GNUINIT),
3127 build_function_type_list (void_type_node, NULL_TREE),
3128 NULL_TREE, NULL_TREE);
3130 objc_start_function (get_identifier (TAG_GNUINIT),
3131 build_function_type_list (void_type_node, NULL_TREE),
3132 NULL_TREE, objc_get_parm_info (0));
3134 body = c_begin_compound_stmt (true);
3135 add_stmt (build_function_call
3140 build_unary_op (input_location, ADDR_EXPR,
3141 UOBJC_MODULES_decl, 0))));
3142 add_stmt (c_end_compound_stmt (input_location, body, true));
3144 TREE_PUBLIC (current_function_decl) = 0;
3147 /* For Objective-C++, we will need to call __objc_gnu_init
3148 from objc_generate_static_init_call() below. */
3149 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3152 GNU_INIT_decl = current_function_decl;
3156 pop_lang_context ();
3161 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3162 to be called by the module initializer routine. */
3165 objc_static_init_needed_p (void)
3167 return (GNU_INIT_decl != NULL_TREE);
3170 /* Generate a call to the __objc_gnu_init initializer function. */
3173 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3175 add_stmt (build_stmt (input_location, EXPR_STMT,
3176 build_function_call (input_location,
3177 GNU_INIT_decl, NULL_TREE)));
3181 #endif /* OBJCPLUS */
3183 /* Return the DECL of the string IDENT in the SECTION. */
3186 get_objc_string_decl (tree ident, enum string_section section)
3193 chain = class_names_chain;
3195 case meth_var_names:
3196 chain = meth_var_names_chain;
3198 case meth_var_types:
3199 chain = meth_var_types_chain;
3205 for (; chain != 0; chain = TREE_CHAIN (chain))
3206 if (TREE_VALUE (chain) == ident)
3207 return (TREE_PURPOSE (chain));
3213 /* Output references to all statically allocated objects. Return the DECL
3214 for the array built. */
3217 generate_static_references (void)
3219 tree expr = NULL_TREE;
3220 tree class_name, klass, decl;
3221 tree cl_chain, in_chain, type
3222 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3223 int num_inst, num_class;
3225 VEC(constructor_elt,gc) *decls = NULL;
3227 if (flag_next_runtime)
3230 for (cl_chain = objc_static_instances, num_class = 0;
3231 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3233 VEC(constructor_elt,gc) *v = NULL;
3235 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3236 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3238 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3239 decl = start_var_decl (type, buf);
3241 /* Output {class_name, ...}. */
3242 klass = TREE_VALUE (cl_chain);
3243 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3244 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3245 build_unary_op (input_location,
3246 ADDR_EXPR, class_name, 1));
3248 /* Output {..., instance, ...}. */
3249 for (in_chain = TREE_PURPOSE (cl_chain);
3250 in_chain; in_chain = TREE_CHAIN (in_chain))
3252 expr = build_unary_op (input_location,
3253 ADDR_EXPR, TREE_VALUE (in_chain), 1);
3254 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3257 /* Output {..., NULL}. */
3258 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3260 expr = objc_build_constructor (TREE_TYPE (decl), v);
3261 finish_var_decl (decl, expr);
3262 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3263 build_unary_op (input_location,
3264 ADDR_EXPR, decl, 1));
3267 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3268 expr = objc_build_constructor (type, decls);
3269 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3270 finish_var_decl (static_instances_decl, expr);
3273 static GTY(()) int selector_reference_idx;
3276 build_selector_reference_decl (void)
3281 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3282 decl = start_var_decl (objc_selector_type, buf);
3288 build_selector_table_decl (void)
3292 if (flag_typed_selectors)
3294 build_selector_template ();
3295 temp = build_array_type (objc_selector_template, NULL_TREE);
3298 temp = build_array_type (objc_selector_type, NULL_TREE);
3300 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3303 /* Just a handy wrapper for add_objc_string. */
3306 build_selector (tree ident)
3308 return convert (objc_selector_type,
3309 add_objc_string (ident, meth_var_names));
3312 /* Used only by build_*_selector_translation_table (). */
3314 diagnose_missing_method (tree meth, location_t here)
3318 for (method_chain = meth_var_names_chain;
3320 method_chain = TREE_CHAIN (method_chain))
3322 if (TREE_VALUE (method_chain) == meth)
3330 warning_at (here, 0, "creating selector for nonexistent method %qE",
3335 build_next_selector_translation_table (void)
3338 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3341 tree decl = TREE_PURPOSE (chain);
3342 if (warn_selector && objc_implementation_context)
3346 loc = DECL_SOURCE_LOCATION (decl);
3348 loc = input_location;
3349 diagnose_missing_method (TREE_VALUE (chain), loc);
3352 expr = build_selector (TREE_VALUE (chain));
3356 /* Entries of this form are used for references to methods.
3357 The runtime re-writes these on start-up, but the compiler can't see
3358 that and optimizes it away unless we force it. */
3359 DECL_PRESERVE_P (decl) = 1;
3360 finish_var_decl (decl, expr);
3366 build_gnu_selector_translation_table (void)
3370 tree decl = NULL_TREE;*/
3371 VEC(constructor_elt,gc) *inits = NULL;
3373 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3377 if (warn_selector && objc_implementation_context)
3378 diagnose_missing_method (TREE_VALUE (chain), input_location);
3380 expr = build_selector (TREE_VALUE (chain));
3381 /* add one for the '\0' character
3382 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3385 if (flag_typed_selectors)
3387 VEC(constructor_elt,gc) *v = NULL;
3388 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
3389 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3390 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
3391 expr = objc_build_constructor (objc_selector_template, v);
3394 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3396 } /* each element in the chain */
3399 /* Cause the selector table (previously forward-declared)
3400 to be actually output. */
3403 if (flag_typed_selectors)
3405 VEC(constructor_elt,gc) *v = NULL;
3406 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3407 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3408 expr = objc_build_constructor (objc_selector_template, v);
3411 expr = integer_zero_node;
3413 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3414 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
3416 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
3421 get_proto_encoding (tree proto)
3426 if (! METHOD_ENCODING (proto))
3428 encoding = encode_method_prototype (proto);
3429 METHOD_ENCODING (proto) = encoding;
3432 encoding = METHOD_ENCODING (proto);
3434 return add_objc_string (encoding, meth_var_types);
3437 return build_int_cst (NULL_TREE, 0);
3440 /* sel_ref_chain is a list whose "value" fields will be instances of
3441 identifier_node that represent the selector. LOC is the location of
3445 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
3447 tree *chain = &sel_ref_chain;
3453 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
3454 goto return_at_index;
3457 chain = &TREE_CHAIN (*chain);
3460 *chain = tree_cons (prototype, ident, NULL_TREE);
3463 expr = build_unary_op (loc, ADDR_EXPR,
3464 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3465 build_int_cst (NULL_TREE, index)),
3467 return convert (objc_selector_type, expr);
3471 build_selector_reference (location_t loc, tree ident)
3473 tree *chain = &sel_ref_chain;
3479 if (TREE_VALUE (*chain) == ident)
3480 return (flag_next_runtime
3481 ? TREE_PURPOSE (*chain)
3482 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3483 build_int_cst (NULL_TREE, index)));
3486 chain = &TREE_CHAIN (*chain);
3489 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
3491 *chain = tree_cons (expr, ident, NULL_TREE);
3493 return (flag_next_runtime
3495 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3496 build_int_cst (NULL_TREE, index)));
3499 static GTY(()) int class_reference_idx;
3502 build_class_reference_decl (void)
3507 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
3508 decl = start_var_decl (objc_class_type, buf);
3513 /* Create a class reference, but don't create a variable to reference
3517 add_class_reference (tree ident)
3521 if ((chain = cls_ref_chain))
3526 if (ident == TREE_VALUE (chain))
3530 chain = TREE_CHAIN (chain);
3534 /* Append to the end of the list */
3535 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
3538 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
3541 /* Get a class reference, creating it if necessary. Also create the
3542 reference variable. */
3545 objc_get_class_reference (tree ident)
3547 tree orig_ident = (DECL_P (ident)
3550 ? OBJC_TYPE_NAME (ident)
3552 bool local_scope = false;
3555 if (processing_template_decl)
3556 /* Must wait until template instantiation time. */
3557 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
3560 if (TREE_CODE (ident) == TYPE_DECL)
3561 ident = (DECL_ORIGINAL_TYPE (ident)
3562 ? DECL_ORIGINAL_TYPE (ident)
3563 : TREE_TYPE (ident));
3567 && CP_TYPE_CONTEXT (ident) != global_namespace)
3571 if (local_scope || !(ident = objc_is_class_name (ident)))
3573 error ("%qE is not an Objective-C class name or alias",
3575 return error_mark_node;
3578 if (flag_next_runtime && !flag_zero_link)
3583 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
3584 if (TREE_VALUE (*chain) == ident)
3586 if (! TREE_PURPOSE (*chain))
3587 TREE_PURPOSE (*chain) = build_class_reference_decl ();
3589 return TREE_PURPOSE (*chain);
3592 decl = build_class_reference_decl ();
3593 *chain = tree_cons (decl, ident, NULL_TREE);
3600 add_class_reference (ident);
3602 params = build_tree_list (NULL_TREE,
3603 my_build_string_pointer
3604 (IDENTIFIER_LENGTH (ident) + 1,
3605 IDENTIFIER_POINTER (ident)));
3607 assemble_external (objc_get_class_decl);
3608 return build_function_call (input_location, objc_get_class_decl, params);
3612 /* For each string section we have a chain which maps identifier nodes
3613 to decls for the strings. */
3615 static GTY(()) int class_names_idx;
3616 static GTY(()) int meth_var_names_idx;
3617 static GTY(()) int meth_var_types_idx;
3620 add_objc_string (tree ident, enum string_section section)
3622 tree *chain, decl, type, string_expr;
3629 chain = &class_names_chain;
3630 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
3632 case meth_var_names:
3633 chain = &meth_var_names_chain;
3634 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
3636 case meth_var_types:
3637 chain = &meth_var_types_chain;
3638 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
3646 if (TREE_VALUE (*chain) == ident)
3647 return convert (string_type_node,
3648 build_unary_op (input_location,
3649 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
3651 chain = &TREE_CHAIN (*chain);
3654 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
3655 decl = start_var_decl (type, buf);
3656 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
3657 IDENTIFIER_POINTER (ident));
3658 TREE_CONSTANT (decl) = 1;
3659 finish_var_decl (decl, string_expr);
3661 *chain = tree_cons (decl, ident, NULL_TREE);
3663 return convert (string_type_node, build_unary_op (input_location,
3664 ADDR_EXPR, decl, 1));
3668 objc_declare_alias (tree alias_ident, tree class_ident)
3670 tree underlying_class;
3673 if (current_namespace != global_namespace) {
3674 error ("Objective-C declarations may only appear in global scope");
3676 #endif /* OBJCPLUS */
3678 if (!(underlying_class = objc_is_class_name (class_ident)))
3679 warning (0, "cannot find class %qE", class_ident);
3680 else if (objc_is_class_name (alias_ident))
3681 warning (0, "class %qE already exists", alias_ident);
3684 /* Implement @compatibility_alias as a typedef. */
3686 push_lang_context (lang_name_c); /* extern "C" */
3688 lang_hooks.decls.pushdecl (build_decl
3692 xref_tag (RECORD_TYPE, underlying_class)));
3694 pop_lang_context ();
3696 hash_class_name_enter (als_name_hash_list, alias_ident,
3702 objc_declare_class (tree ident_list)
3706 if (current_namespace != global_namespace) {
3707 error ("Objective-C declarations may only appear in global scope");
3709 #endif /* OBJCPLUS */
3711 for (list = ident_list; list; list = TREE_CHAIN (list))
3713 tree ident = TREE_VALUE (list);
3715 if (! objc_is_class_name (ident))
3717 tree record = lookup_name (ident), type = record;
3721 if (TREE_CODE (record) == TYPE_DECL)
3722 type = DECL_ORIGINAL_TYPE (record) ?
3723 DECL_ORIGINAL_TYPE (record) :
3726 if (!TYPE_HAS_OBJC_INFO (type)
3727 || !TYPE_OBJC_INTERFACE (type))
3729 error ("%qE redeclared as different kind of symbol",
3731 error ("previous declaration of %q+D",
3736 record = xref_tag (RECORD_TYPE, ident);
3737 INIT_TYPE_OBJC_INFO (record);
3738 TYPE_OBJC_INTERFACE (record) = ident;
3739 hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
3745 objc_is_class_name (tree ident)
3749 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3750 && identifier_global_value (ident))
3751 ident = identifier_global_value (ident);
3752 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3753 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3755 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3756 ident = OBJC_TYPE_NAME (ident);
3758 if (ident && TREE_CODE (ident) == TYPE_DECL)
3760 tree type = TREE_TYPE (ident);
3761 if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
3763 ident = DECL_NAME (ident);
3766 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3769 if (lookup_interface (ident))
3772 target = hash_class_name_lookup (cls_name_hash_list, ident);
3776 target = hash_class_name_lookup (als_name_hash_list, ident);
3779 gcc_assert (target->list && target->list->value);
3780 return target->list->value;
3786 /* Check whether TYPE is either 'id' or 'Class'. */
3789 objc_is_id (tree type)
3791 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3792 && identifier_global_value (type))
3793 type = identifier_global_value (type);
3795 if (type && TREE_CODE (type) == TYPE_DECL)
3796 type = TREE_TYPE (type);
3798 /* NB: This function may be called before the ObjC front-end has
3799 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3800 return (objc_object_type && type
3801 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3806 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3807 class instance. This is needed by other parts of the compiler to
3808 handle ObjC types gracefully. */
3811 objc_is_object_ptr (tree type)
3815 type = TYPE_MAIN_VARIANT (type);
3816 if (!POINTER_TYPE_P (type))
3819 ret = objc_is_id (type);
3821 ret = objc_is_class_name (TREE_TYPE (type));
3827 objc_is_gcable_type (tree type, int or_strong_p)
3833 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3835 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3837 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3839 type = TREE_TYPE (type);
3840 if (TREE_CODE (type) != RECORD_TYPE)
3842 name = TYPE_NAME (type);
3843 return (objc_is_class_name (name) != NULL_TREE);
3847 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3849 if (expr == oldexpr)
3852 switch (TREE_CODE (expr))
3855 return objc_build_component_ref
3856 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3859 DECL_NAME (TREE_OPERAND (expr, 1)));
3861 return build_array_ref (input_location,
3862 objc_substitute_decl (TREE_OPERAND (expr, 0),
3865 TREE_OPERAND (expr, 1));
3867 return build_indirect_ref (input_location,
3868 objc_substitute_decl (TREE_OPERAND (expr, 0),
3870 newexpr), RO_ARROW);
3877 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3880 /* The LHS parameter contains the expression 'outervar->memberspec';
3881 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3882 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3885 = objc_substitute_decl
3886 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3888 = (flag_objc_direct_dispatch
3889 ? objc_assign_ivar_fast_decl
3890 : objc_assign_ivar_decl);
3892 offs = convert (integer_type_node, build_unary_op (input_location,
3893 ADDR_EXPR, offs, 0));
3895 func_params = tree_cons (NULL_TREE,
3896 convert (objc_object_type, rhs),
3897 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3898 tree_cons (NULL_TREE, offs,
3901 assemble_external (func);
3902 return build_function_call (input_location, func, func_params);
3906 objc_build_global_assignment (tree lhs, tree rhs)
3908 tree func_params = tree_cons (NULL_TREE,
3909 convert (objc_object_type, rhs),
3910 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3911 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3914 assemble_external (objc_assign_global_decl);
3915 return build_function_call (input_location,
3916 objc_assign_global_decl, func_params);
3920 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3922 tree func_params = tree_cons (NULL_TREE,
3923 convert (objc_object_type, rhs),
3924 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3925 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3928 assemble_external (objc_assign_strong_cast_decl);
3929 return build_function_call (input_location,
3930 objc_assign_strong_cast_decl, func_params);
3934 objc_is_gcable_p (tree expr)
3936 return (TREE_CODE (expr) == COMPONENT_REF
3937 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3938 : TREE_CODE (expr) == ARRAY_REF
3939 ? (objc_is_gcable_p (TREE_TYPE (expr))
3940 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3941 : TREE_CODE (expr) == ARRAY_TYPE
3942 ? objc_is_gcable_p (TREE_TYPE (expr))
3944 ? objc_is_gcable_type (expr, 1)
3945 : (objc_is_gcable_p (TREE_TYPE (expr))
3947 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3951 objc_is_ivar_reference_p (tree expr)
3953 return (TREE_CODE (expr) == ARRAY_REF
3954 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3955 : TREE_CODE (expr) == COMPONENT_REF
3956 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3961 objc_is_global_reference_p (tree expr)
3963 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3964 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3966 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
3971 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3973 tree result = NULL_TREE, outer;
3974 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3976 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3977 will have been transformed to the form '*(type *)&expr'. */
3978 if (TREE_CODE (lhs) == INDIRECT_REF)
3980 outer = TREE_OPERAND (lhs, 0);
3982 while (!strong_cast_p
3983 && (CONVERT_EXPR_P (outer)
3984 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3986 tree lhstype = TREE_TYPE (outer);
3988 /* Descend down the cast chain, and record the first objc_gc
3990 if (POINTER_TYPE_P (lhstype))
3993 = lookup_attribute ("objc_gc",
3994 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
4000 outer = TREE_OPERAND (outer, 0);
4004 /* If we have a __strong cast, it trumps all else. */
4007 if (modifycode != NOP_EXPR)
4008 goto invalid_pointer_arithmetic;
4010 if (warn_assign_intercept)
4011 warning (0, "strong-cast assignment has been intercepted");
4013 result = objc_build_strong_cast_assignment (lhs, rhs);
4018 /* the lhs must be of a suitable type, regardless of its underlying
4020 if (!objc_is_gcable_p (lhs))
4026 && (TREE_CODE (outer) == COMPONENT_REF
4027 || TREE_CODE (outer) == ARRAY_REF))
4028 outer = TREE_OPERAND (outer, 0);
4030 if (TREE_CODE (outer) == INDIRECT_REF)
4032 outer = TREE_OPERAND (outer, 0);
4036 outer_gc_p = objc_is_gcable_p (outer);
4038 /* Handle ivar assignments. */
4039 if (objc_is_ivar_reference_p (lhs))
4041 /* if the struct to the left of the ivar is not an Objective-C object (__strong
4042 doesn't cut it here), the best we can do here is suggest a cast. */
4043 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
4045 /* We may still be able to use the global write barrier... */
4046 if (!indirect_p && objc_is_global_reference_p (outer))
4047 goto global_reference;
4050 if (modifycode == NOP_EXPR)
4052 if (warn_assign_intercept)
4053 warning (0, "strong-cast may possibly be needed");
4059 if (modifycode != NOP_EXPR)
4060 goto invalid_pointer_arithmetic;
4062 if (warn_assign_intercept)
4063 warning (0, "instance variable assignment has been intercepted");
4065 result = objc_build_ivar_assignment (outer, lhs, rhs);
4070 /* Likewise, intercept assignment to global/static variables if their type is
4072 if (objc_is_global_reference_p (outer))
4078 if (modifycode != NOP_EXPR)
4080 invalid_pointer_arithmetic:
4082 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4087 if (warn_assign_intercept)
4088 warning (0, "global/static variable assignment has been intercepted");
4090 result = objc_build_global_assignment (lhs, rhs);
4093 /* In all other cases, fall back to the normal mechanism. */
4098 struct GTY(()) interface_tuple {
4103 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4106 hash_interface (const void *p)
4108 const struct interface_tuple *d = (const struct interface_tuple *) p;
4109 return IDENTIFIER_HASH_VALUE (d->id);
4113 eq_interface (const void *p1, const void *p2)
4115 const struct interface_tuple *d = (const struct interface_tuple *) p1;
4120 lookup_interface (tree ident)
4123 if (ident && TREE_CODE (ident) == TYPE_DECL)
4124 ident = DECL_NAME (ident);
4127 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4131 struct interface_tuple **slot;
4136 slot = (struct interface_tuple **)
4137 htab_find_slot_with_hash (interface_htab, ident,
4138 IDENTIFIER_HASH_VALUE (ident),
4141 i = (*slot)->class_name;
4147 /* Implement @defs (<classname>) within struct bodies. */
4150 objc_get_class_ivars (tree class_name)
4152 tree interface = lookup_interface (class_name);
4155 return get_class_ivars (interface, true);
4157 error ("cannot find interface declaration for %qE",
4160 return error_mark_node;
4163 /* Called when checking the variables in a struct. If we are not
4164 doing the ivars list inside an @interface context, then returns
4165 fieldlist unchanged. Else, returns the list of class ivars.
4168 objc_get_interface_ivars (tree fieldlist)
4170 if (!objc_collecting_ivars || !objc_interface_context
4171 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4172 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4175 return get_class_ivars (objc_interface_context, true);
4178 /* Used by: build_private_template, continue_class,
4179 and for @defs constructs. */
4182 get_class_ivars (tree interface, bool inherited)
4184 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4186 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4187 by the current class (i.e., they do not include super-class ivars).
4188 However, the CLASS_IVARS list will be side-effected by a call to
4189 finish_struct(), which will fill in field offsets. */
4190 if (!CLASS_IVARS (interface))
4191 CLASS_IVARS (interface) = ivar_chain;
4196 while (CLASS_SUPER_NAME (interface))
4198 /* Prepend super-class ivars. */
4199 interface = lookup_interface (CLASS_SUPER_NAME (interface));
4200 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4207 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4208 the specified name, else use no name. Returns the declaration of
4209 the type. The 'name' is mostly useful for debugging.
4212 objc_create_temporary_var (tree type, const char *name)
4218 decl = build_decl (input_location,
4219 VAR_DECL, get_identifier (name), type);
4223 decl = build_decl (input_location,
4224 VAR_DECL, NULL_TREE, type);
4226 TREE_USED (decl) = 1;
4227 DECL_ARTIFICIAL (decl) = 1;
4228 DECL_IGNORED_P (decl) = 1;
4229 DECL_CONTEXT (decl) = current_function_decl;
4234 /* Exception handling constructs. We begin by having the parser do most
4235 of the work and passing us blocks. What we do next depends on whether
4236 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4237 We abstract all of this in a handful of appropriately named routines. */
4239 /* Stack of open try blocks. */
4241 struct objc_try_context
4243 struct objc_try_context *outer;
4245 /* Statements (or statement lists) as processed by the parser. */
4249 /* Some file position locations. */
4250 location_t try_locus;
4251 location_t end_try_locus;
4252 location_t end_catch_locus;
4253 location_t finally_locus;
4254 location_t end_finally_locus;
4256 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4257 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4260 /* The CATCH_EXPR of an open @catch clause. */
4263 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4269 static struct objc_try_context *cur_try_context;
4271 static GTY(()) tree objc_eh_personality_decl;
4273 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4274 that represents TYPE. For Objective-C, this is just the class name. */
4275 /* ??? Isn't there a class object or some such? Is it easy to get? */
4279 objc_eh_runtime_type (tree type)
4281 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4285 objc_eh_personality (void)
4287 if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4288 objc_eh_personality_decl = build_personality_function ("gnu_objc");
4289 return objc_eh_personality_decl;
4293 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4294 of Darwin, we'll arrange for it to be initialized (and associated
4295 with a binding) later. */
4298 objc_build_exc_ptr (void)
4300 if (flag_objc_sjlj_exceptions)
4302 tree var = cur_try_context->caught_decl;
4305 var = objc_create_temporary_var (objc_object_type, NULL);
4306 cur_try_context->caught_decl = var;
4313 t = built_in_decls[BUILT_IN_EH_POINTER];
4314 t = build_call_expr (t, 1, integer_zero_node);
4315 return fold_convert (objc_object_type, t);
4319 /* Build "objc_exception_try_exit(&_stack)". */
4322 next_sjlj_build_try_exit (void)
4325 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4326 t = tree_cons (NULL, t, NULL);
4327 t = build_function_call (input_location,
4328 objc_exception_try_exit_decl, t);
4333 objc_exception_try_enter (&_stack);
4334 if (_setjmp(&_stack.buf))
4338 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4339 empty, ready for the caller to fill them in. */
4342 next_sjlj_build_enter_and_setjmp (void)
4344 tree t, enter, sj, cond;
4346 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4347 t = tree_cons (NULL, t, NULL);
4348 enter = build_function_call (input_location,
4349 objc_exception_try_enter_decl, t);
4351 t = objc_build_component_ref (cur_try_context->stack_decl,
4352 get_identifier ("buf"));
4353 t = build_fold_addr_expr_loc (input_location, t);
4355 /* Convert _setjmp argument to type that is expected. */
4356 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
4357 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
4359 t = convert (ptr_type_node, t);
4361 t = convert (ptr_type_node, t);
4363 t = tree_cons (NULL, t, NULL);
4364 sj = build_function_call (input_location,
4365 objc_setjmp_decl, t);
4367 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
4368 cond = c_common_truthvalue_conversion (input_location, cond);
4370 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
4375 DECL = objc_exception_extract(&_stack); */
4378 next_sjlj_build_exc_extract (tree decl)
4382 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4383 t = tree_cons (NULL, t, NULL);
4384 t = build_function_call (input_location,
4385 objc_exception_extract_decl, t);
4386 t = convert (TREE_TYPE (decl), t);
4387 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4393 if (objc_exception_match(obj_get_class(TYPE), _caught)
4400 objc_exception_try_exit(&_stack);
4402 from the sequence of CATCH_EXPRs in the current try context. */
4405 next_sjlj_build_catch_list (void)
4407 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4409 tree *last = &catch_seq;
4410 bool saw_id = false;
4412 for (; !tsi_end_p (i); tsi_next (&i))
4414 tree stmt = tsi_stmt (i);
4415 tree type = CATCH_TYPES (stmt);
4416 tree body = CATCH_BODY (stmt);
4428 if (type == error_mark_node)
4429 cond = error_mark_node;
4432 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
4433 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
4434 args = tree_cons (NULL, t, args);
4435 t = build_function_call (input_location,
4436 objc_exception_match_decl, args);
4437 cond = c_common_truthvalue_conversion (input_location, t);
4439 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
4440 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
4443 last = &COND_EXPR_ELSE (t);
4449 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
4450 cur_try_context->caught_decl);
4451 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4452 append_to_statement_list (t, last);
4454 t = next_sjlj_build_try_exit ();
4455 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4456 append_to_statement_list (t, last);
4462 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4463 exception handling. We aim to build:
4466 struct _objc_exception_data _stack;
4470 objc_exception_try_enter (&_stack);
4471 if (_setjmp(&_stack.buf))
4473 id _caught = objc_exception_extract(&_stack);
4474 objc_exception_try_enter (&_stack);
4475 if (_setjmp(&_stack.buf))
4476 _rethrow = objc_exception_extract(&_stack);
4486 objc_exception_try_exit(&_stack);
4489 objc_exception_throw(_rethrow);
4493 If CATCH-LIST is empty, we can omit all of the block containing
4494 "_caught" except for the setting of _rethrow. Note the use of
4495 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4496 but handles goto and other exits from the block. */
4499 next_sjlj_build_try_catch_finally (void)
4501 tree rethrow_decl, stack_decl, t;
4502 tree catch_seq, try_fin, bind;
4504 /* Create the declarations involved. */
4505 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
4506 stack_decl = objc_create_temporary_var (t, NULL);
4507 cur_try_context->stack_decl = stack_decl;
4509 rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
4510 cur_try_context->rethrow_decl = rethrow_decl;
4511 TREE_CHAIN (rethrow_decl) = stack_decl;
4513 /* Build the outermost variable binding level. */
4514 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
4515 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
4516 TREE_SIDE_EFFECTS (bind) = 1;
4518 /* Initialize rethrow_decl. */
4519 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
4520 convert (objc_object_type, null_pointer_node));
4521 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4522 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4524 /* Build the outermost TRY_FINALLY_EXPR. */
4525 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
4526 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
4527 TREE_SIDE_EFFECTS (try_fin) = 1;
4528 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
4530 /* Create the complete catch sequence. */
4531 if (cur_try_context->catch_list)
4533 tree caught_decl = objc_build_exc_ptr ();
4534 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
4535 TREE_SIDE_EFFECTS (catch_seq) = 1;
4537 t = next_sjlj_build_exc_extract (caught_decl);
4538 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4540 t = next_sjlj_build_enter_and_setjmp ();
4541 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
4542 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
4543 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4546 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
4547 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
4549 /* Build the main register-and-try if statement. */
4550 t = next_sjlj_build_enter_and_setjmp ();
4551 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4552 COND_EXPR_THEN (t) = catch_seq;
4553 COND_EXPR_ELSE (t) = cur_try_context->try_body;
4554 TREE_OPERAND (try_fin, 0) = t;
4556 /* Build the complete FINALLY statement list. */
4557 t = next_sjlj_build_try_exit ();
4558 t = build_stmt (input_location, COND_EXPR,
4559 c_common_truthvalue_conversion
4560 (input_location, rethrow_decl),
4562 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
4563 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4565 append_to_statement_list (cur_try_context->finally_body,
4566 &TREE_OPERAND (try_fin, 1));
4568 t = tree_cons (NULL, rethrow_decl, NULL);
4569 t = build_function_call (input_location,
4570 objc_exception_throw_decl, t);
4571 t = build_stmt (input_location, COND_EXPR,
4572 c_common_truthvalue_conversion (input_location,
4575 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
4576 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4581 /* Called just after parsing the @try and its associated BODY. We now
4582 must prepare for the tricky bits -- handling the catches and finally. */
4585 objc_begin_try_stmt (location_t try_locus, tree body)
4587 struct objc_try_context *c = XCNEW (struct objc_try_context);
4588 c->outer = cur_try_context;
4590 c->try_locus = try_locus;
4591 c->end_try_locus = input_location;
4592 cur_try_context = c;
4594 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4595 For example, on Darwin, ObjC exceptions require a sufficiently
4596 recent version of the runtime, so the user must ask for them
4597 explicitly. On other platforms, at the moment -fobjc-exceptions
4598 triggers -fexceptions which again is required for exceptions to
4601 if (!flag_objc_exceptions)
4603 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4606 if (flag_objc_sjlj_exceptions)
4607 objc_mark_locals_volatile (NULL);
4610 /* Called just after parsing "@catch (parm)". Open a binding level,
4611 enter DECL into the binding level, and initialize it. Leave the
4612 binding level open while the body of the compound statement is parsed. */
4615 objc_begin_catch_clause (tree decl)
4617 tree compound, type, t;
4619 /* Begin a new scope that the entire catch clause will live in. */
4620 compound = c_begin_compound_stmt (true);
4622 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4623 decl = build_decl (input_location,
4624 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
4625 lang_hooks.decls.pushdecl (decl);
4627 /* Since a decl is required here by syntax, don't warn if its unused. */
4628 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4629 be what the previous objc implementation did. */
4630 TREE_USED (decl) = 1;
4631 DECL_READ_P (decl) = 1;
4633 /* Verify that the type of the catch is valid. It must be a pointer
4634 to an Objective-C class, or "id" (which is catch-all). */
4635 type = TREE_TYPE (decl);
4637 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
4639 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
4641 error ("@catch parameter is not a known Objective-C class type");
4642 type = error_mark_node;
4644 else if (cur_try_context->catch_list)
4646 /* Examine previous @catch clauses and see if we've already
4647 caught the type in question. */
4648 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4649 for (; !tsi_end_p (i); tsi_next (&i))
4651 tree stmt = tsi_stmt (i);
4652 t = CATCH_TYPES (stmt);
4653 if (t == error_mark_node)
4655 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
4657 warning (0, "exception of type %<%T%> will be caught",
4659 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
4660 TREE_TYPE (t ? t : objc_object_type));
4666 /* Record the data for the catch in the try context so that we can
4667 finalize it later. */
4668 t = build_stmt (input_location, CATCH_EXPR, type, compound);
4669 cur_try_context->current_catch = t;
4671 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4672 t = objc_build_exc_ptr ();
4673 t = convert (TREE_TYPE (decl), t);
4674 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4678 /* Called just after parsing the closing brace of a @catch clause. Close
4679 the open binding level, and record a CATCH_EXPR for it. */
4682 objc_finish_catch_clause (void)
4684 tree c = cur_try_context->current_catch;
4685 cur_try_context->current_catch = NULL;
4686 cur_try_context->end_catch_locus = input_location;
4688 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
4689 append_to_statement_list (c, &cur_try_context->catch_list);
4692 /* Called after parsing a @finally clause and its associated BODY.
4693 Record the body for later placement. */
4696 objc_build_finally_clause (location_t finally_locus, tree body)
4698 cur_try_context->finally_body = body;
4699 cur_try_context->finally_locus = finally_locus;
4700 cur_try_context->end_finally_locus = input_location;
4703 /* Called to finalize a @try construct. */
4706 objc_finish_try_stmt (void)
4708 struct objc_try_context *c = cur_try_context;
4711 if (c->catch_list == NULL && c->finally_body == NULL)
4712 error ("%<@try%> without %<@catch%> or %<@finally%>");
4714 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4715 if (flag_objc_sjlj_exceptions)
4717 bool save = in_late_binary_op;
4718 in_late_binary_op = true;
4719 if (!cur_try_context->finally_body)
4721 cur_try_context->finally_locus = input_location;
4722 cur_try_context->end_finally_locus = input_location;
4724 stmt = next_sjlj_build_try_catch_finally ();
4725 in_late_binary_op = save;
4729 /* Otherwise, nest the CATCH inside a FINALLY. */
4733 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
4734 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4736 if (c->finally_body)
4738 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
4739 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4744 cur_try_context = c->outer;
4750 objc_build_throw_stmt (location_t loc, tree throw_expr)
4754 if (!flag_objc_exceptions)
4756 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4759 if (throw_expr == NULL)
4761 /* If we're not inside a @catch block, there is no "current
4762 exception" to be rethrown. */
4763 if (cur_try_context == NULL
4764 || cur_try_context->current_catch == NULL)
4766 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
4770 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4771 value that we get from the runtime. */
4772 throw_expr = objc_build_exc_ptr ();
4775 /* A throw is just a call to the runtime throw function with the
4776 object as a parameter. */
4777 args = tree_cons (NULL, throw_expr, NULL);
4778 return add_stmt (build_function_call (loc,
4779 objc_exception_throw_decl, args));
4783 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4787 /* First lock the mutex. */
4788 mutex = save_expr (mutex);
4789 args = tree_cons (NULL, mutex, NULL);
4790 call = build_function_call (input_location,
4791 objc_sync_enter_decl, args);
4792 SET_EXPR_LOCATION (call, start_locus);
4795 /* Build the mutex unlock. */
4796 args = tree_cons (NULL, mutex, NULL);
4797 call = build_function_call (input_location,
4798 objc_sync_exit_decl, args);
4799 SET_EXPR_LOCATION (call, input_location);
4801 /* Put the that and the body in a TRY_FINALLY. */
4802 objc_begin_try_stmt (start_locus, body);
4803 objc_build_finally_clause (input_location, call);
4804 return objc_finish_try_stmt ();
4808 /* Predefine the following data type:
4810 struct _objc_exception_data
4812 int buf[OBJC_JBLEN];
4816 /* The following yuckiness should prevent users from having to #include
4817 <setjmp.h> in their code... */
4819 /* Define to a harmless positive value so the below code doesn't die. */
4821 #define OBJC_JBLEN 18
4825 build_next_objc_exception_stuff (void)
4827 tree decls, temp_type, *chain = NULL;
4829 objc_exception_data_template
4830 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4832 /* int buf[OBJC_JBLEN]; */
4834 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
4835 decls = add_field_decl (temp_type, "buf", &chain);
4837 /* void *pointers[4]; */
4839 temp_type = build_sized_array_type (ptr_type_node, 4);
4840 add_field_decl (temp_type, "pointers", &chain);
4842 objc_finish_struct (objc_exception_data_template, decls);
4844 /* int _setjmp(...); */
4845 /* If the user includes <setjmp.h>, this shall be superseded by
4846 'int _setjmp(jmp_buf);' */
4847 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
4849 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4851 /* id objc_exception_extract(struct _objc_exception_data *); */
4853 = build_function_type_list (objc_object_type,
4854 build_pointer_type (objc_exception_data_template),
4856 objc_exception_extract_decl
4857 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4859 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4860 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4862 = build_function_type_list (void_type_node,
4863 build_pointer_type (objc_exception_data_template),
4865 objc_exception_try_enter_decl
4866 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4868 objc_exception_try_exit_decl
4869 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4872 /* int objc_exception_match(id, id); */
4874 = build_function_type_list (integer_type_node,
4875 objc_object_type, objc_object_type, NULL_TREE);
4876 objc_exception_match_decl
4877 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4880 /* id objc_assign_ivar (id, id, unsigned int); */
4881 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4882 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4884 = build_function_type_list (objc_object_type,
4889 objc_assign_ivar_decl
4890 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4892 #ifdef OFFS_ASSIGNIVAR_FAST
4893 objc_assign_ivar_fast_decl
4894 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4895 NOT_BUILT_IN, NULL, NULL_TREE);
4896 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4897 = tree_cons (get_identifier ("hard_coded_address"),
4898 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4901 /* Default to slower ivar method. */
4902 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4905 /* id objc_assign_global (id, id *); */
4906 /* id objc_assign_strongCast (id, id *); */
4907 temp_type = build_function_type_list (objc_object_type,
4909 build_pointer_type (objc_object_type),
4911 objc_assign_global_decl
4912 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4914 objc_assign_strong_cast_decl
4915 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4920 build_objc_exception_stuff (void)
4922 tree noreturn_list, nothrow_list, temp_type;
4924 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4925 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4927 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4928 /* void objc_sync_enter(id); */
4929 /* void objc_sync_exit(id); */
4930 temp_type = build_function_type_list (void_type_node,
4933 objc_exception_throw_decl
4934 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4936 objc_sync_enter_decl
4937 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4938 NULL, nothrow_list);
4940 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4941 NULL, nothrow_list);
4944 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4947 struct <classname> {
4948 struct _objc_class *isa;
4953 build_private_template (tree klass)
4955 if (!CLASS_STATIC_TEMPLATE (klass))
4957 tree record = objc_build_struct (klass,
4958 get_class_ivars (klass, false),
4959 CLASS_SUPER_NAME (klass));
4961 /* Set the TREE_USED bit for this struct, so that stab generator
4962 can emit stabs for this struct type. */
4963 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4964 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4968 /* Begin code generation for protocols... */
4970 /* struct _objc_protocol {
4971 struct _objc_class *isa;
4972 char *protocol_name;
4973 struct _objc_protocol **protocol_list;
4974 struct _objc__method_prototype_list *instance_methods;
4975 struct _objc__method_prototype_list *class_methods;
4979 build_protocol_template (void)
4981 tree ptype, decls, *chain = NULL;
4983 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4985 /* struct _objc_class *isa; */
4986 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4987 get_identifier (UTAG_CLASS)));
4988 decls = add_field_decl (ptype, "isa", &chain);
4990 /* char *protocol_name; */
4991 add_field_decl (string_type_node, "protocol_name", &chain);
4993 /* struct _objc_protocol **protocol_list; */
4994 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4995 add_field_decl (ptype, "protocol_list", &chain);
4997 /* struct _objc__method_prototype_list *instance_methods; */
4998 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
5000 /* struct _objc__method_prototype_list *class_methods; */
5001 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
5003 objc_finish_struct (objc_protocol_template, decls);
5007 build_descriptor_table_initializer (tree type, tree entries)
5009 VEC(constructor_elt,gc) *inits = NULL;
5013 VEC(constructor_elt,gc) *elts = NULL;
5015 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5016 build_selector (METHOD_SEL_NAME (entries)));
5017 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5018 add_objc_string (METHOD_ENCODING (entries),
5021 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5022 objc_build_constructor (type, elts));
5024 entries = DECL_CHAIN (entries);
5028 return objc_build_constructor (build_array_type (type, 0), inits);
5031 /* struct objc_method_prototype_list {
5033 struct objc_method_prototype {
5040 build_method_prototype_list_template (tree list_type, int size)
5042 tree objc_ivar_list_record;
5043 tree array_type, decls, *chain = NULL;
5045 /* Generate an unnamed struct definition. */
5047 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5049 /* int method_count; */
5050 decls = add_field_decl (integer_type_node, "method_count", &chain);
5052 /* struct objc_method method_list[]; */
5053 array_type = build_sized_array_type (list_type, size);
5054 add_field_decl (array_type, "method_list", &chain);
5056 objc_finish_struct (objc_ivar_list_record, decls);
5058 return objc_ivar_list_record;
5062 build_method_prototype_template (void)
5065 tree decls, *chain = NULL;
5067 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
5070 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5072 /* char *method_types; */
5073 add_field_decl (string_type_node, "method_types", &chain);
5075 objc_finish_struct (proto_record, decls);
5077 return proto_record;
5081 objc_method_parm_type (tree type)
5083 type = TREE_VALUE (TREE_TYPE (type));
5084 if (TREE_CODE (type) == TYPE_DECL)
5085 type = TREE_TYPE (type);
5090 objc_encoded_type_size (tree type)
5092 int sz = int_size_in_bytes (type);
5094 /* Make all integer and enum types at least as large
5096 if (sz > 0 && INTEGRAL_TYPE_P (type))
5097 sz = MAX (sz, int_size_in_bytes (integer_type_node));
5098 /* Treat arrays as pointers, since that's how they're
5100 else if (TREE_CODE (type) == ARRAY_TYPE)
5101 sz = int_size_in_bytes (ptr_type_node);
5105 /* Encode a method prototype.
5107 The format is described in gcc/doc/objc.texi, section 'Method
5111 encode_method_prototype (tree method_decl)
5118 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5119 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5121 /* Encode return type. */
5122 encode_type (objc_method_parm_type (method_decl),
5123 obstack_object_size (&util_obstack),
5124 OBJC_ENCODE_INLINE_DEFS);
5127 /* The first two arguments (self and _cmd) are pointers; account for
5129 i = int_size_in_bytes (ptr_type_node);
5130 parm_offset = 2 * i;
5131 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5132 parms = DECL_CHAIN (parms))
5134 tree type = objc_method_parm_type (parms);
5135 int sz = objc_encoded_type_size (type);
5137 /* If a type size is not known, bail out. */
5140 error ("type %q+D does not have a known size",
5142 /* Pretend that the encoding succeeded; the compilation will
5143 fail nevertheless. */
5144 goto finish_encoding;
5149 sprintf (buf, "%d@0:%d", parm_offset, i);
5150 obstack_grow (&util_obstack, buf, strlen (buf));
5152 /* Argument types. */
5153 parm_offset = 2 * i;
5154 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5155 parms = DECL_CHAIN (parms))
5157 tree type = objc_method_parm_type (parms);
5159 /* Process argument qualifiers for user supplied arguments. */
5160 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5163 encode_type (type, obstack_object_size (&util_obstack),
5164 OBJC_ENCODE_INLINE_DEFS);
5166 /* Compute offset. */
5167 sprintf (buf, "%d", parm_offset);
5168 parm_offset += objc_encoded_type_size (type);
5170 obstack_grow (&util_obstack, buf, strlen (buf));
5174 obstack_1grow (&util_obstack, '\0');
5175 result = get_identifier (XOBFINISH (&util_obstack, char *));
5176 obstack_free (&util_obstack, util_firstobj);
5181 generate_descriptor_table (tree type, const char *name, int size, tree list,
5185 VEC(constructor_elt,gc) *v = NULL;
5187 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5189 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5190 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5192 finish_var_decl (decl, objc_build_constructor (type, v));
5198 generate_method_descriptors (tree protocol)
5200 tree initlist, chain, method_list_template;
5203 if (!objc_method_prototype_template)
5204 objc_method_prototype_template = build_method_prototype_template ();
5206 chain = PROTOCOL_CLS_METHODS (protocol);
5209 size = list_length (chain);
5211 method_list_template
5212 = build_method_prototype_list_template (objc_method_prototype_template,
5216 = build_descriptor_table_initializer (objc_method_prototype_template,
5219 UOBJC_CLASS_METHODS_decl
5220 = generate_descriptor_table (method_list_template,
5221 "_OBJC_PROTOCOL_CLASS_METHODS",
5222 size, initlist, protocol);
5225 UOBJC_CLASS_METHODS_decl = 0;
5227 chain = PROTOCOL_NST_METHODS (protocol);
5230 size = list_length (chain);
5232 method_list_template
5233 = build_method_prototype_list_template (objc_method_prototype_template,
5236 = build_descriptor_table_initializer (objc_method_prototype_template,
5239 UOBJC_INSTANCE_METHODS_decl
5240 = generate_descriptor_table (method_list_template,
5241 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5242 size, initlist, protocol);
5245 UOBJC_INSTANCE_METHODS_decl = 0;
5249 generate_protocol_references (tree plist)
5253 /* Forward declare protocols referenced. */
5254 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5256 tree proto = TREE_VALUE (lproto);
5258 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5259 && PROTOCOL_NAME (proto))
5261 if (! PROTOCOL_FORWARD_DECL (proto))
5262 build_protocol_reference (proto);
5264 if (PROTOCOL_LIST (proto))
5265 generate_protocol_references (PROTOCOL_LIST (proto));
5270 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5274 objc_generate_cxx_ctor_or_dtor (bool dtor)
5276 tree fn, body, compound_stmt, ivar;
5278 /* - (id) .cxx_construct { ... return self; } */
5279 /* - (void) .cxx_construct { ... } */
5281 objc_start_method_definition
5282 (false /* is_class_method */,
5283 objc_build_method_signature (false /* is_class_method */,
5284 build_tree_list (NULL_TREE,
5287 : objc_object_type),
5288 get_identifier (dtor
5290 : TAG_CXX_CONSTRUCT),
5291 make_node (TREE_LIST),
5293 body = begin_function_body ();
5294 compound_stmt = begin_compound_stmt (0);
5296 ivar = CLASS_IVARS (implementation_template);
5297 /* Destroy ivars in reverse order. */
5299 ivar = nreverse (copy_list (ivar));
5301 for (; ivar; ivar = TREE_CHAIN (ivar))
5303 if (TREE_CODE (ivar) == FIELD_DECL)
5305 tree type = TREE_TYPE (ivar);
5307 /* Call the ivar's default constructor or destructor. Do not
5308 call the destructor unless a corresponding constructor call
5309 has also been made (or is not needed). */
5310 if (MAYBE_CLASS_TYPE_P (type)
5312 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5313 && (!TYPE_NEEDS_CONSTRUCTING (type)
5314 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5315 : (TYPE_NEEDS_CONSTRUCTING (type)
5316 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5318 (build_special_member_call
5319 (build_ivar_reference (DECL_NAME (ivar)),
5320 dtor ? complete_dtor_identifier : complete_ctor_identifier,
5321 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5325 /* The constructor returns 'self'. */
5327 finish_return_stmt (self_decl);
5329 finish_compound_stmt (compound_stmt);
5330 finish_function_body (body);
5331 fn = current_function_decl;
5333 objc_finish_method_definition (fn);
5336 /* The following routine will examine the current @interface for any
5337 non-POD C++ ivars requiring non-trivial construction and/or
5338 destruction, and then synthesize special '- .cxx_construct' and/or
5339 '- .cxx_destruct' methods which will run the appropriate
5340 construction or destruction code. Note that ivars inherited from
5341 super-classes are _not_ considered. */
5343 objc_generate_cxx_cdtors (void)
5345 bool need_ctor = false, need_dtor = false;
5348 /* Error case, due to possibly an extra @end. */
5349 if (!objc_implementation_context)
5352 /* We do not want to do this for categories, since they do not have
5355 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
5358 /* First, determine if we even need a constructor and/or destructor. */
5360 for (ivar = CLASS_IVARS (implementation_template); ivar;
5361 ivar = TREE_CHAIN (ivar))
5363 if (TREE_CODE (ivar) == FIELD_DECL)
5365 tree type = TREE_TYPE (ivar);
5367 if (MAYBE_CLASS_TYPE_P (type))
5369 if (TYPE_NEEDS_CONSTRUCTING (type)
5370 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
5371 /* NB: If a default constructor is not available, we will not
5372 be able to initialize this ivar; the add_instance_variable()
5373 routine will already have warned about this. */
5376 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5377 && (!TYPE_NEEDS_CONSTRUCTING (type)
5378 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5379 /* NB: If a default constructor is not available, we will not
5380 call the destructor either, for symmetry. */
5386 /* Generate '- .cxx_construct' if needed. */
5389 objc_generate_cxx_ctor_or_dtor (false);
5391 /* Generate '- .cxx_destruct' if needed. */
5394 objc_generate_cxx_ctor_or_dtor (true);
5396 /* The 'imp_list' variable points at an imp_entry record for the current
5397 @implementation. Record the existence of '- .cxx_construct' and/or
5398 '- .cxx_destruct' methods therein; it will be included in the
5399 metadata for the class. */
5400 if (flag_next_runtime)
5401 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
5405 /* For each protocol which was referenced either from a @protocol()
5406 expression, or because a class/category implements it (then a
5407 pointer to the protocol is stored in the struct describing the
5408 class/category), we create a statically allocated instance of the
5409 Protocol class. The code is written in such a way as to generate
5410 as few Protocol objects as possible; we generate a unique Protocol
5411 instance for each protocol, and we don't generate a Protocol
5412 instance if the protocol is never referenced (either from a
5413 @protocol() or from a class/category implementation). These
5414 statically allocated objects can be referred to via the static
5415 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5417 The statically allocated Protocol objects that we generate here
5418 need to be fixed up at runtime in order to be used: the 'isa'
5419 pointer of the objects need to be set up to point to the 'Protocol'
5420 class, as known at runtime.
5422 The NeXT runtime fixes up all protocols at program startup time,
5423 before main() is entered. It uses a low-level trick to look up all
5424 those symbols, then loops on them and fixes them up.
5426 The GNU runtime as well fixes up all protocols before user code
5427 from the module is executed; it requires pointers to those symbols
5428 to be put in the objc_symtab (which is then passed as argument to
5429 the function __objc_exec_class() which the compiler sets up to be
5430 executed automatically when the module is loaded); setup of those
5431 Protocol objects happen in two ways in the GNU runtime: all
5432 Protocol objects referred to by a class or category implementation
5433 are fixed up when the class/category is loaded; all Protocol
5434 objects referred to by a @protocol() expression are added by the
5435 compiler to the list of statically allocated instances to fixup
5436 (the same list holding the statically allocated constant string
5437 objects). Because, as explained above, the compiler generates as
5438 few Protocol objects as possible, some Protocol object might end up
5439 being referenced multiple times when compiled with the GNU runtime,
5440 and end up being fixed up multiple times at runtime initialization.
5441 But that doesn't hurt, it's just a little inefficient. */
5444 generate_protocols (void)
5448 tree initlist, protocol_name_expr, refs_decl, refs_expr;
5450 /* If a protocol was directly referenced, pull in indirect references. */
5451 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5452 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
5453 generate_protocol_references (PROTOCOL_LIST (p));
5455 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5457 tree nst_methods = PROTOCOL_NST_METHODS (p);
5458 tree cls_methods = PROTOCOL_CLS_METHODS (p);
5460 /* If protocol wasn't referenced, don't generate any code. */
5461 decl = PROTOCOL_FORWARD_DECL (p);
5466 /* Make sure we link in the Protocol class. */
5467 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5471 if (! METHOD_ENCODING (nst_methods))
5473 encoding = encode_method_prototype (nst_methods);
5474 METHOD_ENCODING (nst_methods) = encoding;
5476 nst_methods = DECL_CHAIN (nst_methods);
5481 if (! METHOD_ENCODING (cls_methods))
5483 encoding = encode_method_prototype (cls_methods);
5484 METHOD_ENCODING (cls_methods) = encoding;
5487 cls_methods = DECL_CHAIN (cls_methods);
5489 generate_method_descriptors (p);
5491 if (PROTOCOL_LIST (p))
5492 refs_decl = generate_protocol_list (p);
5496 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5497 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
5500 refs_expr = convert (build_pointer_type (build_pointer_type
5501 (objc_protocol_template)),
5502 build_unary_op (input_location,
5503 ADDR_EXPR, refs_decl, 0));
5505 refs_expr = build_int_cst (NULL_TREE, 0);
5507 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5508 by generate_method_descriptors, which is called above. */
5509 initlist = build_protocol_initializer (TREE_TYPE (decl),
5510 protocol_name_expr, refs_expr,
5511 UOBJC_INSTANCE_METHODS_decl,
5512 UOBJC_CLASS_METHODS_decl);
5513 finish_var_decl (decl, initlist);
5518 build_protocol_initializer (tree type, tree protocol_name,
5519 tree protocol_list, tree instance_methods,
5523 tree cast_type = build_pointer_type
5524 (xref_tag (RECORD_TYPE,
5525 get_identifier (UTAG_CLASS)));
5526 VEC(constructor_elt,gc) *inits = NULL;
5528 /* Filling the "isa" in with one allows the runtime system to
5529 detect that the version change...should remove before final release. */
5531 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
5532 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5533 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
5534 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
5536 if (!instance_methods)
5537 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5540 expr = convert (objc_method_proto_list_ptr,
5541 build_unary_op (input_location,
5542 ADDR_EXPR, instance_methods, 0));
5543 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5547 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5550 expr = convert (objc_method_proto_list_ptr,
5551 build_unary_op (input_location,
5552 ADDR_EXPR, class_methods, 0));
5553 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5556 return objc_build_constructor (type, inits);
5559 /* struct _objc_category {
5560 char *category_name;
5562 struct _objc_method_list *instance_methods;
5563 struct _objc_method_list *class_methods;
5564 struct _objc_protocol_list *protocols;
5568 build_category_template (void)
5570 tree ptype, decls, *chain = NULL;
5572 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
5574 /* char *category_name; */
5575 decls = add_field_decl (string_type_node, "category_name", &chain);
5577 /* char *class_name; */
5578 add_field_decl (string_type_node, "class_name", &chain);
5580 /* struct _objc_method_list *instance_methods; */
5581 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
5583 /* struct _objc_method_list *class_methods; */
5584 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
5586 /* struct _objc_protocol **protocol_list; */
5587 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5588 add_field_decl (ptype, "protocol_list", &chain);
5590 objc_finish_struct (objc_category_template, decls);
5593 /* struct _objc_selector {
5599 build_selector_template (void)
5601 tree decls, *chain = NULL;
5603 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
5606 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
5608 /* char *sel_type; */
5609 add_field_decl (string_type_node, "sel_type", &chain);
5611 objc_finish_struct (objc_selector_template, decls);
5614 /* struct _objc_class {
5615 struct _objc_class *isa;
5616 struct _objc_class *super_class;
5621 struct _objc_ivar_list *ivars;
5622 struct _objc_method_list *methods;
5623 #ifdef __NEXT_RUNTIME__
5624 struct objc_cache *cache;
5626 struct sarray *dtable;
5627 struct _objc_class *subclass_list;
5628 struct _objc_class *sibling_class;
5630 struct _objc_protocol_list *protocols;
5631 #ifdef __NEXT_RUNTIME__
5634 void *gc_object_type;
5637 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5638 the NeXT/Apple runtime; still, the compiler must generate them to
5639 maintain backward binary compatibility (and to allow for future
5643 build_class_template (void)
5645 tree ptype, decls, *chain = NULL;
5647 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
5649 /* struct _objc_class *isa; */
5650 decls = add_field_decl (build_pointer_type (objc_class_template),
5653 /* struct _objc_class *super_class; */
5654 add_field_decl (build_pointer_type (objc_class_template),
5655 "super_class", &chain);
5658 add_field_decl (string_type_node, "name", &chain);
5661 add_field_decl (long_integer_type_node, "version", &chain);
5664 add_field_decl (long_integer_type_node, "info", &chain);
5666 /* long instance_size; */
5667 add_field_decl (long_integer_type_node, "instance_size", &chain);
5669 /* struct _objc_ivar_list *ivars; */
5670 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
5672 /* struct _objc_method_list *methods; */
5673 add_field_decl (objc_method_list_ptr, "methods", &chain);
5675 if (flag_next_runtime)
5677 /* struct objc_cache *cache; */
5678 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5679 get_identifier ("objc_cache")));
5680 add_field_decl (ptype, "cache", &chain);
5684 /* struct sarray *dtable; */
5685 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
5686 get_identifier ("sarray")));
5687 add_field_decl (ptype, "dtable", &chain);
5689 /* struct objc_class *subclass_list; */
5690 ptype = build_pointer_type (objc_class_template);
5691 add_field_decl (ptype, "subclass_list", &chain);
5693 /* struct objc_class *sibling_class; */
5694 ptype = build_pointer_type (objc_class_template);
5695 add_field_decl (ptype, "sibling_class", &chain);
5698 /* struct _objc_protocol **protocol_list; */
5699 ptype = build_pointer_type (build_pointer_type
5700 (xref_tag (RECORD_TYPE,
5701 get_identifier (UTAG_PROTOCOL))));
5702 add_field_decl (ptype, "protocol_list", &chain);
5704 if (flag_next_runtime)
5707 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
5710 /* void *gc_object_type; */
5711 add_field_decl (build_pointer_type (void_type_node),
5712 "gc_object_type", &chain);
5714 objc_finish_struct (objc_class_template, decls);
5717 /* Generate appropriate forward declarations for an implementation. */
5720 synth_forward_declarations (void)
5724 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5725 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5726 objc_class_template);
5728 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5729 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5730 objc_class_template);
5732 /* Pre-build the following entities - for speed/convenience. */
5734 an_id = get_identifier ("super_class");
5735 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5736 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5740 error_with_ivar (const char *message, tree decl)
5742 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5743 message, identifier_to_locale (gen_declaration (decl)));
5748 check_ivars (tree inter, tree imp)
5750 tree intdecls = CLASS_RAW_IVARS (inter);
5751 tree impdecls = CLASS_RAW_IVARS (imp);
5758 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5759 intdecls = TREE_CHAIN (intdecls);
5761 if (intdecls == 0 && impdecls == 0)
5763 if (intdecls == 0 || impdecls == 0)
5765 error ("inconsistent instance variable specification");
5769 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5771 if (!comptypes (t1, t2)
5772 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5773 DECL_INITIAL (impdecls)))
5775 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5777 error_with_ivar ("conflicting instance variable type",
5779 error_with_ivar ("previous declaration of",
5782 else /* both the type and the name don't match */
5784 error ("inconsistent instance variable specification");
5789 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5791 error_with_ivar ("conflicting instance variable name",
5793 error_with_ivar ("previous declaration of",
5797 intdecls = DECL_CHAIN (intdecls);
5798 impdecls = DECL_CHAIN (impdecls);
5802 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5803 This needs to be done just once per compilation. */
5805 /* struct _objc_super {
5806 struct _objc_object *self;
5807 struct _objc_class *super_class;
5811 build_super_template (void)
5813 tree decls, *chain = NULL;
5815 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5817 /* struct _objc_object *self; */
5818 decls = add_field_decl (objc_object_type, "self", &chain);
5820 /* struct _objc_class *super_class; */
5821 add_field_decl (build_pointer_type (objc_class_template),
5822 "super_class", &chain);
5824 objc_finish_struct (objc_super_template, decls);
5827 /* struct _objc_ivar {
5834 build_ivar_template (void)
5836 tree objc_ivar_id, objc_ivar_record;
5837 tree decls, *chain = NULL;
5839 objc_ivar_id = get_identifier (UTAG_IVAR);
5840 objc_ivar_record = objc_start_struct (objc_ivar_id);
5842 /* char *ivar_name; */
5843 decls = add_field_decl (string_type_node, "ivar_name", &chain);
5845 /* char *ivar_type; */
5846 add_field_decl (string_type_node, "ivar_type", &chain);
5848 /* int ivar_offset; */
5849 add_field_decl (integer_type_node, "ivar_offset", &chain);
5851 objc_finish_struct (objc_ivar_record, decls);
5853 return objc_ivar_record;
5858 struct objc_ivar ivar_list[ivar_count];
5862 build_ivar_list_template (tree list_type, int size)
5864 tree objc_ivar_list_record;
5865 tree array_type, decls, *chain = NULL;
5867 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5869 /* int ivar_count; */
5870 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
5872 /* struct objc_ivar ivar_list[]; */
5873 array_type = build_sized_array_type (list_type, size);
5874 add_field_decl (array_type, "ivar_list", &chain);
5876 objc_finish_struct (objc_ivar_list_record, decls);
5878 return objc_ivar_list_record;
5882 struct _objc__method_prototype_list *method_next;
5884 struct objc_method method_list[method_count];
5888 build_method_list_template (tree list_type, int size)
5890 tree objc_ivar_list_record;
5891 tree array_type, decls, *chain = NULL;
5893 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5895 /* struct _objc__method_prototype_list *method_next; */
5896 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
5898 /* int method_count; */
5899 add_field_decl (integer_type_node, "method_count", &chain);
5901 /* struct objc_method method_list[]; */
5902 array_type = build_sized_array_type (list_type, size);
5903 add_field_decl (array_type, "method_list", &chain);
5905 objc_finish_struct (objc_ivar_list_record, decls);
5907 return objc_ivar_list_record;
5911 build_ivar_list_initializer (tree type, tree field_decl)
5913 VEC(constructor_elt,gc) *inits = NULL;
5917 VEC(constructor_elt,gc) *ivar = NULL;
5921 if (DECL_NAME (field_decl))
5922 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
5923 add_objc_string (DECL_NAME (field_decl),
5926 /* Unnamed bit-field ivar (yuck). */
5927 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
5930 encode_field_decl (field_decl,
5931 obstack_object_size (&util_obstack),
5932 OBJC_ENCODE_DONT_INLINE_DEFS);
5934 /* Null terminate string. */
5935 obstack_1grow (&util_obstack, 0);
5936 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5938 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
5939 obstack_free (&util_obstack, util_firstobj);
5942 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
5943 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5944 objc_build_constructor (type, ivar));
5946 field_decl = DECL_CHAIN (field_decl);
5947 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5951 return objc_build_constructor (build_array_type (type, 0), inits);
5955 generate_ivars_list (tree type, const char *name, int size, tree list)
5958 VEC(constructor_elt,gc) *inits = NULL;
5960 decl = start_var_decl (type, synth_id_with_class_suffix
5961 (name, objc_implementation_context));
5963 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
5964 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
5966 finish_var_decl (decl,
5967 objc_build_constructor (TREE_TYPE (decl), inits));
5972 /* Count only the fields occurring in T. */
5975 ivar_list_length (tree t)
5979 for (; t; t = DECL_CHAIN (t))
5980 if (TREE_CODE (t) == FIELD_DECL)
5987 generate_ivar_lists (void)
5989 tree initlist, ivar_list_template, chain;
5992 generating_instance_variables = 1;
5994 if (!objc_ivar_template)
5995 objc_ivar_template = build_ivar_template ();
5997 /* Only generate class variables for the root of the inheritance
5998 hierarchy since these will be the same for every class. */
6000 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
6001 && (chain = TYPE_FIELDS (objc_class_template)))
6003 size = ivar_list_length (chain);
6005 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6006 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6008 UOBJC_CLASS_VARIABLES_decl
6009 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
6013 UOBJC_CLASS_VARIABLES_decl = 0;
6015 chain = CLASS_IVARS (implementation_template);
6018 size = ivar_list_length (chain);
6019 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6020 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6022 UOBJC_INSTANCE_VARIABLES_decl
6023 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
6027 UOBJC_INSTANCE_VARIABLES_decl = 0;
6029 generating_instance_variables = 0;
6033 build_dispatch_table_initializer (tree type, tree entries)
6035 VEC(constructor_elt,gc) *inits = NULL;
6039 VEC(constructor_elt,gc) *elems = NULL;
6042 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6043 build_selector (METHOD_SEL_NAME (entries)));
6045 /* Generate the method encoding if we don't have one already. */
6046 if (! METHOD_ENCODING (entries))
6047 METHOD_ENCODING (entries) =
6048 encode_method_prototype (entries);
6050 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6051 add_objc_string (METHOD_ENCODING (entries),
6054 expr = convert (ptr_type_node,
6055 build_unary_op (input_location, ADDR_EXPR,
6056 METHOD_DEFINITION (entries), 1));
6057 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
6059 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6060 objc_build_constructor (type, elems));
6062 entries = DECL_CHAIN (entries);
6066 return objc_build_constructor (build_array_type (type, 0), inits);
6069 /* To accomplish method prototyping without generating all kinds of
6070 inane warnings, the definition of the dispatch table entries were
6073 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
6075 struct objc_method { SEL _cmd; ...; void *_imp; }; */
6078 build_method_template (void)
6081 tree decls, *chain = NULL;
6083 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
6086 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6088 /* char *method_types; */
6089 add_field_decl (string_type_node, "method_types", &chain);
6092 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6094 objc_finish_struct (_SLT_record, decls);
6101 generate_dispatch_table (tree type, const char *name, int size, tree list)
6104 VEC(constructor_elt,gc) *v = NULL;
6106 decl = start_var_decl (type, synth_id_with_class_suffix
6107 (name, objc_implementation_context));
6109 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6110 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6111 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6113 finish_var_decl (decl,
6114 objc_build_constructor (TREE_TYPE (decl), v));
6120 mark_referenced_methods (void)
6122 struct imp_entry *impent;
6125 for (impent = imp_list; impent; impent = impent->next)
6127 chain = CLASS_CLS_METHODS (impent->imp_context);
6130 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6131 chain = DECL_CHAIN (chain);
6134 chain = CLASS_NST_METHODS (impent->imp_context);
6137 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6138 chain = DECL_CHAIN (chain);
6144 generate_dispatch_tables (void)
6146 tree initlist, chain, method_list_template;
6149 if (!objc_method_template)
6150 objc_method_template = build_method_template ();
6152 chain = CLASS_CLS_METHODS (objc_implementation_context);
6155 size = list_length (chain);
6157 method_list_template
6158 = build_method_list_template (objc_method_template, size);
6160 = build_dispatch_table_initializer (objc_method_template, chain);
6162 UOBJC_CLASS_METHODS_decl
6163 = generate_dispatch_table (method_list_template,
6164 ((TREE_CODE (objc_implementation_context)
6165 == CLASS_IMPLEMENTATION_TYPE)
6166 ? "_OBJC_CLASS_METHODS"
6167 : "_OBJC_CATEGORY_CLASS_METHODS"),
6171 UOBJC_CLASS_METHODS_decl = 0;
6173 chain = CLASS_NST_METHODS (objc_implementation_context);
6176 size = list_length (chain);
6178 method_list_template
6179 = build_method_list_template (objc_method_template, size);
6181 = build_dispatch_table_initializer (objc_method_template, chain);
6183 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6184 UOBJC_INSTANCE_METHODS_decl
6185 = generate_dispatch_table (method_list_template,
6186 "_OBJC_INSTANCE_METHODS",
6189 /* We have a category. */
6190 UOBJC_INSTANCE_METHODS_decl
6191 = generate_dispatch_table (method_list_template,
6192 "_OBJC_CATEGORY_INSTANCE_METHODS",
6196 UOBJC_INSTANCE_METHODS_decl = 0;
6200 generate_protocol_list (tree i_or_p)
6202 tree array_type, ptype, refs_decl, lproto, e, plist;
6204 const char *ref_name;
6205 VEC(constructor_elt,gc) *v = NULL;
6207 switch (TREE_CODE (i_or_p))
6209 case CLASS_INTERFACE_TYPE:
6210 case CATEGORY_INTERFACE_TYPE:
6211 plist = CLASS_PROTOCOL_LIST (i_or_p);
6213 case PROTOCOL_INTERFACE_TYPE:
6214 plist = PROTOCOL_LIST (i_or_p);
6221 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6222 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6223 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6226 /* Build initializer. */
6227 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6228 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6229 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6231 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6233 tree pval = TREE_VALUE (lproto);
6235 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6236 && PROTOCOL_FORWARD_DECL (pval))
6238 e = build_unary_op (input_location, ADDR_EXPR,
6239 PROTOCOL_FORWARD_DECL (pval), 0);
6240 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6244 /* static struct objc_protocol *refs[n]; */
6246 switch (TREE_CODE (i_or_p))
6248 case PROTOCOL_INTERFACE_TYPE:
6249 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6251 case CLASS_INTERFACE_TYPE:
6252 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6254 case CATEGORY_INTERFACE_TYPE:
6255 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6261 ptype = build_pointer_type (objc_protocol_template);
6262 array_type = build_sized_array_type (ptype, size + 3);
6263 refs_decl = start_var_decl (array_type, ref_name);
6265 finish_var_decl (refs_decl,
6266 objc_build_constructor (TREE_TYPE (refs_decl), v));
6272 build_category_initializer (tree type, tree cat_name, tree class_name,
6273 tree instance_methods, tree class_methods,
6277 VEC(constructor_elt,gc) *v = NULL;
6279 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6280 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6282 if (!instance_methods)
6283 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6286 expr = convert (objc_method_list_ptr,
6287 build_unary_op (input_location, ADDR_EXPR,
6288 instance_methods, 0));
6289 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6292 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6295 expr = convert (objc_method_list_ptr,
6296 build_unary_op (input_location, ADDR_EXPR,
6298 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6301 /* protocol_list = */
6303 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6306 expr = convert (build_pointer_type
6308 (objc_protocol_template)),
6309 build_unary_op (input_location, ADDR_EXPR,
6311 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6314 return objc_build_constructor (type, v);
6317 /* struct _objc_class {
6318 struct objc_class *isa;
6319 struct objc_class *super_class;
6324 struct objc_ivar_list *ivars;
6325 struct objc_method_list *methods;
6326 if (flag_next_runtime)
6327 struct objc_cache *cache;
6329 struct sarray *dtable;
6330 struct objc_class *subclass_list;
6331 struct objc_class *sibling_class;
6333 struct objc_protocol_list *protocols;
6334 if (flag_next_runtime)
6336 void *gc_object_type;
6340 build_shared_structure_initializer (tree type, tree isa, tree super,
6341 tree name, tree size, int status,
6342 tree dispatch_table, tree ivar_list,
6346 VEC(constructor_elt,gc) *v = NULL;
6349 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
6352 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
6355 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
6358 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6359 build_int_cst (long_integer_type_node, 0));
6362 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6363 build_int_cst (long_integer_type_node, status));
6365 /* instance_size = */
6366 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6367 convert (long_integer_type_node, size));
6369 /* objc_ivar_list = */
6371 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6374 expr = convert (objc_ivar_list_ptr,
6375 build_unary_op (input_location, ADDR_EXPR,
6377 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6380 /* objc_method_list = */
6381 if (!dispatch_table)
6382 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6385 expr = convert (objc_method_list_ptr,
6386 build_unary_op (input_location, ADDR_EXPR,
6387 dispatch_table, 0));
6388 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6391 if (flag_next_runtime)
6392 /* method_cache = */
6393 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6397 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6399 /* subclass_list = */
6400 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6402 /* sibling_class = */
6403 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6406 /* protocol_list = */
6407 if (! protocol_list)
6408 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6411 expr = convert (build_pointer_type
6413 (objc_protocol_template)),
6414 build_unary_op (input_location, ADDR_EXPR,
6416 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6419 if (flag_next_runtime)
6421 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6423 /* gc_object_type = NULL */
6424 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6426 return objc_build_constructor (type, v);
6429 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6432 lookup_category (tree klass, tree cat_name)
6434 tree category = CLASS_CATEGORY_LIST (klass);
6436 while (category && CLASS_SUPER_NAME (category) != cat_name)
6437 category = CLASS_CATEGORY_LIST (category);
6441 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6444 generate_category (struct imp_entry *impent)
6446 tree initlist, cat_name_expr, class_name_expr;
6447 tree protocol_decl, category;
6448 tree cat = impent->imp_context;
6450 implementation_template = impent->imp_template;
6451 UOBJC_CLASS_decl = impent->class_decl;
6452 UOBJC_METACLASS_decl = impent->meta_decl;
6454 add_class_reference (CLASS_NAME (cat));
6455 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
6457 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
6459 category = lookup_category (implementation_template,
6460 CLASS_SUPER_NAME (cat));
6462 if (category && CLASS_PROTOCOL_LIST (category))
6464 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
6465 protocol_decl = generate_protocol_list (category);
6470 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
6471 cat_name_expr, class_name_expr,
6472 UOBJC_INSTANCE_METHODS_decl,
6473 UOBJC_CLASS_METHODS_decl,
6475 /* Finish and initialize the forward decl. */
6476 finish_var_decl (UOBJC_CLASS_decl, initlist);
6479 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6480 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6483 generate_shared_structures (struct imp_entry *impent)
6485 tree name_expr, super_expr, root_expr;
6486 tree my_root_id, my_super_id;
6487 tree cast_type, initlist, protocol_decl;
6490 objc_implementation_context = impent->imp_context;
6491 implementation_template = impent->imp_template;
6492 UOBJC_CLASS_decl = impent->class_decl;
6493 UOBJC_METACLASS_decl = impent->meta_decl;
6494 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
6496 my_super_id = CLASS_SUPER_NAME (implementation_template);
6499 add_class_reference (my_super_id);
6501 /* Compute "my_root_id" - this is required for code generation.
6502 the "isa" for all meta class structures points to the root of
6503 the inheritance hierarchy (e.g. "__Object")... */
6504 my_root_id = my_super_id;
6507 tree my_root_int = lookup_interface (my_root_id);
6509 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
6510 my_root_id = CLASS_SUPER_NAME (my_root_int);
6517 /* No super class. */
6518 my_root_id = CLASS_NAME (implementation_template);
6520 cast_type = build_pointer_type (objc_class_template);
6521 name_expr = add_objc_string (CLASS_NAME (implementation_template),
6524 /* Install class `isa' and `super' pointers at runtime. */
6526 super_expr = add_objc_string (my_super_id, class_names);
6528 super_expr = integer_zero_node;
6530 super_expr = build_c_cast (input_location,
6531 cast_type, super_expr); /* cast! */
6533 root_expr = add_objc_string (my_root_id, class_names);
6534 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
6536 if (CLASS_PROTOCOL_LIST (implementation_template))
6538 generate_protocol_references
6539 (CLASS_PROTOCOL_LIST (implementation_template));
6540 protocol_decl = generate_protocol_list (implementation_template);
6545 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6548 = build_shared_structure_initializer
6549 (TREE_TYPE (UOBJC_METACLASS_decl),
6550 root_expr, super_expr, name_expr,
6551 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
6553 UOBJC_CLASS_METHODS_decl,
6554 UOBJC_CLASS_VARIABLES_decl,
6557 finish_var_decl (UOBJC_METACLASS_decl, initlist);
6559 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6562 = build_shared_structure_initializer
6563 (TREE_TYPE (UOBJC_CLASS_decl),
6564 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
6565 super_expr, name_expr,
6566 convert (integer_type_node,
6567 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6568 (implementation_template))),
6569 1 /*CLS_FACTORY*/ | cls_flags,
6570 UOBJC_INSTANCE_METHODS_decl,
6571 UOBJC_INSTANCE_VARIABLES_decl,
6574 finish_var_decl (UOBJC_CLASS_decl, initlist);
6579 synth_id_with_class_suffix (const char *preamble, tree ctxt)
6581 static char string[BUFSIZE];
6583 switch (TREE_CODE (ctxt))
6585 case CLASS_IMPLEMENTATION_TYPE:
6586 case CLASS_INTERFACE_TYPE:
6587 sprintf (string, "%s_%s", preamble,
6588 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
6590 case CATEGORY_IMPLEMENTATION_TYPE:
6591 case CATEGORY_INTERFACE_TYPE:
6593 /* We have a category. */
6594 const char *const class_name
6595 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6596 const char *const class_super_name
6597 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
6598 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
6601 case PROTOCOL_INTERFACE_TYPE:
6603 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
6604 sprintf (string, "%s_%s", preamble, protocol_name);
6614 /* If type is empty or only type qualifiers are present, add default
6615 type of id (otherwise grokdeclarator will default to int). */
6617 adjust_type_for_id_default (tree type)
6620 type = make_node (TREE_LIST);
6622 if (!TREE_VALUE (type))
6623 TREE_VALUE (type) = objc_object_type;
6624 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
6625 && TYPED_OBJECT (TREE_VALUE (type)))
6626 error ("can not use an object as parameter to a method");
6631 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
6632 arg_name and attributes. (TODO: Rename KEYWORD_DECL to
6633 OBJC_METHOD_PARM_DECL ?)
6635 A KEYWORD_DECL is a tree representing the declaration of a
6636 parameter of an Objective-C method. It is produced when parsing a
6637 fragment of Objective-C method declaration of the form
6640 selector ':' '(' typename ')' identifier
6642 For example, take the Objective-C method
6644 -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
6646 the two fragments "pathForResource:(NSString *)resource" and
6647 "ofType:(NSString *)type" will generate a KEYWORD_DECL each. The
6648 KEYWORD_DECL stores the 'key_name' (eg, identifier for
6649 "pathForResource"), the 'arg_type' (eg, tree representing a
6650 NSString *), the 'arg_name' (eg identifier for "resource") and
6651 potentially some attributes (for example, a tree representing
6652 __attribute__ ((unused)) if such an attribute was attached to a
6653 certain parameter). You can access this information using the
6654 TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
6655 KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
6657 'key_name' is an identifier node (and is optional as you can omit
6658 it in Objective-C methods).
6659 'arg_type' is a tree list (and is optional too if no parameter type
6661 'arg_name' is an identifier node and is required.
6662 'attributes' is an optional tree containing parameter attributes. */
6664 objc_build_keyword_decl (tree key_name, tree arg_type,
6665 tree arg_name, tree attributes)
6669 if (flag_objc1_only && attributes)
6670 error_at (input_location, "method argument attributes are not available in Objective-C 1.0");
6672 /* If no type is specified, default to "id". */
6673 arg_type = adjust_type_for_id_default (arg_type);
6675 keyword_decl = make_node (KEYWORD_DECL);
6677 TREE_TYPE (keyword_decl) = arg_type;
6678 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
6679 KEYWORD_KEY_NAME (keyword_decl) = key_name;
6680 DECL_ATTRIBUTES (keyword_decl) = attributes;
6682 return keyword_decl;
6685 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6687 build_keyword_selector (tree selector)
6690 tree key_chain, key_name;
6693 /* Scan the selector to see how much space we'll need. */
6694 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6696 switch (TREE_CODE (selector))
6699 key_name = KEYWORD_KEY_NAME (key_chain);
6702 key_name = TREE_PURPOSE (key_chain);
6709 len += IDENTIFIER_LENGTH (key_name) + 1;
6711 /* Just a ':' arg. */
6715 buf = (char *) alloca (len + 1);
6716 /* Start the buffer out as an empty string. */
6719 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6721 switch (TREE_CODE (selector))
6724 key_name = KEYWORD_KEY_NAME (key_chain);
6727 key_name = TREE_PURPOSE (key_chain);
6728 /* The keyword decl chain will later be used as a function
6729 argument chain. Unhook the selector itself so as to not
6730 confuse other parts of the compiler. */
6731 TREE_PURPOSE (key_chain) = NULL_TREE;
6738 strcat (buf, IDENTIFIER_POINTER (key_name));
6742 return get_identifier (buf);
6745 /* Used for declarations and definitions. */
6748 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6749 tree add_args, bool ellipsis)
6753 /* If no type is specified, default to "id". */
6754 ret_type = adjust_type_for_id_default (ret_type);
6756 /* Note how a method_decl has a TREE_TYPE which is not the function
6757 type of the function implementing the method, but only the return
6758 type of the method. We may want to change this, and store the
6759 entire function type in there (eg, it may be used to simplify
6760 dealing with attributes below). */
6761 method_decl = make_node (code);
6762 TREE_TYPE (method_decl) = ret_type;
6764 /* If we have a keyword selector, create an identifier_node that
6765 represents the full selector name (`:' included)... */
6766 if (TREE_CODE (selector) == KEYWORD_DECL)
6768 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6769 METHOD_SEL_ARGS (method_decl) = selector;
6770 METHOD_ADD_ARGS (method_decl) = add_args;
6771 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6775 METHOD_SEL_NAME (method_decl) = selector;
6776 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6777 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6783 #define METHOD_DEF 0
6784 #define METHOD_REF 1
6786 /* This routine processes objective-c method attributes. */
6789 objc_decl_method_attributes (tree *node, tree attributes, int flags)
6791 /* TODO: Replace the hackery below. An idea would be to store the
6792 full function type in the method declaration (for example in
6793 TREE_TYPE) and then expose ObjC method declarations to c-family
6794 and they could deal with them by simply treating them as
6797 /* Because of the dangers in the hackery below, we filter out any
6798 attribute that we do not know about. For the ones we know about,
6799 we know that they work with the hackery. For the other ones,
6800 there is no guarantee, so we have to filter them out. */
6801 tree filtered_attributes = NULL_TREE;
6806 for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
6808 tree name = TREE_PURPOSE (attribute);
6810 if (is_attribute_p ("deprecated", name)
6811 || is_attribute_p ("sentinel", name)
6812 || is_attribute_p ("noreturn", name))
6814 /* An attribute that we support; add it to the filtered
6816 filtered_attributes = chainon (filtered_attributes,
6817 copy_node (attribute));
6819 else if (is_attribute_p ("format", name))
6821 /* "format" is special because before adding it to the
6822 filtered attributes we need to adjust the specified
6823 format by adding the hidden function parameters for
6824 an Objective-C method (self, _cmd). */
6825 tree new_attribute = copy_node (attribute);
6827 /* Check the arguments specified with the attribute, and
6828 modify them adding 2 for the two hidden arguments.
6829 Note how this differs from C++; according to the
6830 specs, C++ does not do it so you have to add the +1
6831 yourself. For Objective-C, instead, the compiler
6832 adds the +2 for you. */
6834 /* The attribute arguments have not been checked yet, so
6835 we need to be careful as they could be missing or
6836 invalid. If anything looks wrong, we skip the
6837 process and the compiler will complain about it later
6838 when it validates the attribute. */
6839 /* Check that we have at least three arguments. */
6840 if (TREE_VALUE (new_attribute)
6841 && TREE_CHAIN (TREE_VALUE (new_attribute))
6842 && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
6844 tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
6845 tree third_argument = TREE_CHAIN (second_argument);
6848 /* This is the second argument, the "string-index",
6849 which specifies the index of the format string
6851 number = TREE_VALUE (second_argument);
6853 && TREE_CODE (number) == INTEGER_CST
6854 && TREE_INT_CST_HIGH (number) == 0)
6856 TREE_VALUE (second_argument)
6857 = build_int_cst (integer_type_node,
6858 TREE_INT_CST_LOW (number) + 2);
6861 /* This is the third argument, the "first-to-check",
6862 which specifies the index of the first argument to
6863 check. This could be 0, meaning it is not available,
6864 in which case we don't need to add 2. Add 2 if not
6866 number = TREE_VALUE (third_argument);
6868 && TREE_CODE (number) == INTEGER_CST
6869 && TREE_INT_CST_HIGH (number) == 0
6870 && TREE_INT_CST_LOW (number) != 0)
6872 TREE_VALUE (third_argument)
6873 = build_int_cst (integer_type_node,
6874 TREE_INT_CST_LOW (number) + 2);
6877 filtered_attributes = chainon (filtered_attributes,
6881 warning (OPT_Wattributes, "%qE attribute directive ignored", name);
6885 if (filtered_attributes)
6887 /* This hackery changes the TREE_TYPE of the ObjC method
6888 declaration to be a function type, so that decl_attributes
6889 will treat the ObjC method as if it was a function. Some
6890 attributes (sentinel, format) will be applied to the function
6891 type, changing it in place; so after calling decl_attributes,
6892 we extract the function type attributes and store them in
6893 METHOD_TYPE_ATTRIBUTES. Some other attributes (noreturn,
6894 deprecated) are applied directly to the method declaration
6895 (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
6896 is nothing to do. */
6897 tree saved_type = TREE_TYPE (*node);
6898 TREE_TYPE (*node) = build_function_type
6899 (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
6900 decl_attributes (node, filtered_attributes, flags);
6901 METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
6902 TREE_TYPE (*node) = saved_type;
6907 objc_method_decl (enum tree_code opcode)
6909 return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
6912 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6913 an argument list for method METH. CONTEXT is either METHOD_DEF or
6914 METHOD_REF, saying whether we are trying to define a method or call
6915 one. SUPERFLAG says this is for a send to super; this makes a
6916 difference for the NeXT calling sequence in which the lookup and
6917 the method call are done together. If METH is null, user-defined
6918 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6921 get_arg_type_list (tree meth, int context, int superflag)
6925 /* Receiver type. */
6926 if (flag_next_runtime && superflag)
6927 arglist = build_tree_list (NULL_TREE, objc_super_type);
6928 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6929 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6931 arglist = build_tree_list (NULL_TREE, objc_object_type);
6933 /* Selector type - will eventually change to `int'. */
6934 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6936 /* No actual method prototype given -- assume that remaining arguments
6941 /* Build a list of argument types. */
6942 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
6944 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6946 /* Decay argument types for the underlying C function as appropriate. */
6947 arg_type = objc_decay_parm_type (arg_type);
6949 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6952 if (METHOD_ADD_ARGS (meth))
6954 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6955 akey; akey = TREE_CHAIN (akey))
6957 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6959 arg_type = objc_decay_parm_type (arg_type);
6961 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6964 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6965 goto lack_of_ellipsis;
6970 chainon (arglist, OBJC_VOID_AT_END);
6977 check_duplicates (hash hsh, int methods, int is_class)
6979 tree meth = NULL_TREE;
6987 /* We have two or more methods with the same name but
6991 /* But just how different are those types? If
6992 -Wno-strict-selector-match is specified, we shall not
6993 complain if the differences are solely among types with
6994 identical size and alignment. */
6995 if (!warn_strict_selector_match)
6997 for (loop = hsh->list; loop; loop = loop->next)
6998 if (!comp_proto_with_proto (meth, loop->value, 0))
7007 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7009 warning_at (input_location, 0,
7010 "multiple methods named %<%c%E%> found",
7011 (is_class ? '+' : '-'),
7012 METHOD_SEL_NAME (meth));
7013 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
7015 identifier_to_locale (gen_method_decl (meth)));
7019 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7021 warning_at (input_location, 0,
7022 "multiple selectors named %<%c%E%> found",
7023 (is_class ? '+' : '-'),
7024 METHOD_SEL_NAME (meth));
7025 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
7027 identifier_to_locale (gen_method_decl (meth)));
7030 for (loop = hsh->list; loop; loop = loop->next)
7032 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
7034 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
7036 identifier_to_locale (gen_method_decl (loop->value)));
7043 /* If RECEIVER is a class reference, return the identifier node for
7044 the referenced class. RECEIVER is created by objc_get_class_reference,
7045 so we check the exact form created depending on which runtimes are
7049 receiver_is_class_object (tree receiver, int self, int super)
7051 tree chain, exp, arg;
7053 /* The receiver is 'self' or 'super' in the context of a class method. */
7054 if (objc_method_context
7055 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
7058 ? CLASS_SUPER_NAME (implementation_template)
7059 : CLASS_NAME (implementation_template));
7061 if (flag_next_runtime)
7063 /* The receiver is a variable created by
7064 build_class_reference_decl. */
7065 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
7066 /* Look up the identifier. */
7067 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7068 if (TREE_PURPOSE (chain) == receiver)
7069 return TREE_VALUE (chain);
7072 /* The receiver is a function call that returns an id. Check if
7073 it is a call to objc_getClass, if so, pick up the class name. */
7074 if (TREE_CODE (receiver) == CALL_EXPR
7075 && (exp = CALL_EXPR_FN (receiver))
7076 && TREE_CODE (exp) == ADDR_EXPR
7077 && (exp = TREE_OPERAND (exp, 0))
7078 && TREE_CODE (exp) == FUNCTION_DECL
7079 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
7080 prototypes for objc_get_class(). Thankfully, they seem to share the
7081 same function type. */
7082 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
7083 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
7084 /* We have a call to objc_get_class/objc_getClass! */
7085 && (arg = CALL_EXPR_ARG (receiver, 0)))
7088 if (TREE_CODE (arg) == ADDR_EXPR
7089 && (arg = TREE_OPERAND (arg, 0))
7090 && TREE_CODE (arg) == STRING_CST)
7091 /* Finally, we have the class name. */
7092 return get_identifier (TREE_STRING_POINTER (arg));
7097 /* If we are currently building a message expr, this holds
7098 the identifier of the selector of the message. This is
7099 used when printing warnings about argument mismatches. */
7101 static tree current_objc_message_selector = 0;
7104 objc_message_selector (void)
7106 return current_objc_message_selector;
7109 /* Construct an expression for sending a message.
7110 MESS has the object to send to in TREE_PURPOSE
7111 and the argument list (including selector) in TREE_VALUE.
7113 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
7114 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
7117 objc_build_message_expr (tree mess)
7119 tree receiver = TREE_PURPOSE (mess);
7122 tree args = TREE_PURPOSE (TREE_VALUE (mess));
7124 tree args = TREE_VALUE (mess);
7126 tree method_params = NULL_TREE;
7128 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
7129 return error_mark_node;
7131 /* Obtain the full selector name. */
7132 switch (TREE_CODE (args))
7134 case IDENTIFIER_NODE:
7135 /* A unary selector. */
7139 sel_name = build_keyword_selector (args);
7145 /* Build the parameter list to give to the method. */
7146 if (TREE_CODE (args) == TREE_LIST)
7148 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
7151 tree chain = args, prev = NULL_TREE;
7153 /* We have a keyword selector--check for comma expressions. */
7156 tree element = TREE_VALUE (chain);
7158 /* We have a comma expression, must collapse... */
7159 if (TREE_CODE (element) == TREE_LIST)
7162 TREE_CHAIN (prev) = element;
7167 chain = TREE_CHAIN (chain);
7169 method_params = args;
7174 if (processing_template_decl)
7175 /* Must wait until template instantiation time. */
7176 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
7180 return objc_finish_message_expr (receiver, sel_name, method_params);
7183 /* Look up method SEL_NAME that would be suitable for receiver
7184 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
7185 nonzero), and report on any duplicates. */
7188 lookup_method_in_hash_lists (tree sel_name, int is_class)
7190 hash method_prototype = NULL;
7193 method_prototype = hash_lookup (nst_method_hash_list,
7196 if (!method_prototype)
7198 method_prototype = hash_lookup (cls_method_hash_list,
7203 return check_duplicates (method_prototype, 1, is_class);
7206 /* The 'objc_finish_message_expr' routine is called from within
7207 'objc_build_message_expr' for non-template functions. In the case of
7208 C++ template functions, it is called from 'build_expr_from_tree'
7209 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
7212 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7214 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7215 tree selector, retval, class_tree;
7216 int self, super, have_cast;
7218 /* We have used the receiver, so mark it as read. */
7219 mark_exp_read (receiver);
7221 /* Extract the receiver of the message, as well as its type
7222 (where the latter may take the form of a cast or be inferred
7223 from the implementation context). */
7225 while (TREE_CODE (rtype) == COMPOUND_EXPR
7226 || TREE_CODE (rtype) == MODIFY_EXPR
7227 || CONVERT_EXPR_P (rtype)
7228 || TREE_CODE (rtype) == COMPONENT_REF)
7229 rtype = TREE_OPERAND (rtype, 0);
7231 self = (rtype == self_decl);
7232 super = (rtype == UOBJC_SUPER_decl);
7233 rtype = TREE_TYPE (receiver);
7235 have_cast = (TREE_CODE (receiver) == NOP_EXPR
7236 || (TREE_CODE (receiver) == COMPOUND_EXPR
7237 && !IS_SUPER (rtype)));
7239 /* If we are calling [super dealloc], reset our warning flag. */
7240 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7241 should_call_super_dealloc = 0;
7243 /* If the receiver is a class object, retrieve the corresponding
7244 @interface, if one exists. */
7245 class_tree = receiver_is_class_object (receiver, self, super);
7247 /* Now determine the receiver type (if an explicit cast has not been
7252 rtype = lookup_interface (class_tree);
7253 /* Handle `self' and `super'. */
7256 if (!CLASS_SUPER_NAME (implementation_template))
7258 error ("no super class declared in @interface for %qE",
7259 CLASS_NAME (implementation_template));
7260 return error_mark_node;
7262 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7265 rtype = lookup_interface (CLASS_NAME (implementation_template));
7268 /* If receiver is of type `id' or `Class' (or if the @interface for a
7269 class is not visible), we shall be satisfied with the existence of
7270 any instance or class method. */
7271 if (objc_is_id (rtype))
7273 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7274 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7275 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7281 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7282 in protocols themselves for the method prototype. */
7284 = lookup_method_in_protocol_list (rprotos, sel_name,
7285 class_tree != NULL_TREE);
7287 /* If messaging 'Class <Proto>' but did not find a class method
7288 prototype, search for an instance method instead, and warn
7289 about having done so. */
7290 if (!method_prototype && !rtype && class_tree != NULL_TREE)
7293 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7295 if (method_prototype)
7296 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7297 sel_name, sel_name);
7303 tree orig_rtype = rtype;
7305 if (TREE_CODE (rtype) == POINTER_TYPE)
7306 rtype = TREE_TYPE (rtype);
7307 /* Traverse typedef aliases */
7308 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7309 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7310 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7311 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7312 if (TYPED_OBJECT (rtype))
7314 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7315 rtype = TYPE_OBJC_INTERFACE (rtype);
7317 /* If we could not find an @interface declaration, we must have
7318 only seen a @class declaration; so, we cannot say anything
7319 more intelligent about which methods the receiver will
7321 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7324 /* We could not find an @interface declaration, yet Message maybe in a
7325 @class's protocol. */
7326 if (!method_prototype && rprotos)
7328 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7330 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7331 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7333 /* We have a valid ObjC class name. Look up the method name
7334 in the published @interface for the class (and its
7337 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7339 /* If the method was not found in the @interface, it may still
7340 exist locally as part of the @implementation. */
7341 if (!method_prototype && objc_implementation_context
7342 && CLASS_NAME (objc_implementation_context)
7343 == OBJC_TYPE_NAME (rtype))
7347 ? CLASS_CLS_METHODS (objc_implementation_context)
7348 : CLASS_NST_METHODS (objc_implementation_context)),
7351 /* If we haven't found a candidate method by now, try looking for
7352 it in the protocol list. */
7353 if (!method_prototype && rprotos)
7355 = lookup_method_in_protocol_list (rprotos, sel_name,
7356 class_tree != NULL_TREE);
7360 warning (0, "invalid receiver type %qs",
7361 identifier_to_locale (gen_type_name (orig_rtype)));
7362 /* After issuing the "invalid receiver" warning, perform method
7363 lookup as if we were messaging 'id'. */
7364 rtype = rprotos = NULL_TREE;
7369 /* For 'id' or 'Class' receivers, search in the global hash table
7370 as a last resort. For all receivers, warn if protocol searches
7372 if (!method_prototype)
7375 warning (0, "%<%c%E%> not found in protocol(s)",
7376 (class_tree ? '+' : '-'),
7381 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
7384 if (!method_prototype)
7386 static bool warn_missing_methods = false;
7389 warning (0, "%qE may not respond to %<%c%E%>",
7390 OBJC_TYPE_NAME (rtype),
7391 (class_tree ? '+' : '-'),
7393 /* If we are messaging an 'id' or 'Class' object and made it here,
7394 then we have failed to find _any_ instance or class method,
7397 warning (0, "no %<%c%E%> method found",
7398 (class_tree ? '+' : '-'),
7401 if (!warn_missing_methods)
7403 warning_at (input_location,
7404 0, "(Messages without a matching method signature");
7405 warning_at (input_location,
7406 0, "will be assumed to return %<id%> and accept");
7407 warning_at (input_location,
7408 0, "%<...%> as arguments.)");
7409 warn_missing_methods = true;
7414 /* Warn if the method is deprecated, but not if the receiver is
7415 a generic 'id'. 'id' is used to cast an object to a generic
7416 object of an unspecified class; in that case, we'll use
7417 whatever method prototype we can find to get the method
7418 argument and return types, but it is not appropriate to
7419 produce deprecation warnings since we don't know the class
7420 that the object will be of at runtime. The @interface(s) for
7421 that class may not even be available to the compiler right
7422 now, and it is perfectly possible that the method is marked
7423 as non-deprecated in such @interface(s).
7425 In practice this makes sense since casting an object to 'id'
7426 is often used precisely to turn off warnings associated with
7427 the object being of a particular class. */
7428 if (TREE_DEPRECATED (method_prototype) && rtype != NULL_TREE)
7429 warn_deprecated_use (method_prototype, NULL_TREE);
7433 /* Save the selector name for printing error messages. */
7434 current_objc_message_selector = sel_name;
7436 /* Build the parameters list for looking up the method.
7437 These are the object itself and the selector. */
7439 if (flag_typed_selectors)
7440 selector = build_typed_selector_reference (input_location,
7441 sel_name, method_prototype);
7443 selector = build_selector_reference (input_location, sel_name);
7445 retval = build_objc_method_call (input_location, super, method_prototype,
7447 selector, method_params);
7449 current_objc_message_selector = 0;
7454 /* Build a tree expression to send OBJECT the operation SELECTOR,
7455 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7456 assuming the method has prototype METHOD_PROTOTYPE.
7457 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7458 LOC is the location of the expression to build.
7459 Use METHOD_PARAMS as list of args to pass to the method.
7460 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7463 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
7464 tree lookup_object, tree selector,
7467 tree sender = (super_flag ? umsg_super_decl :
7468 (!flag_next_runtime || flag_nil_receivers
7469 ? (flag_objc_direct_dispatch
7472 : umsg_nonnil_decl));
7473 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
7474 VEC(tree, gc) *parms = NULL;
7475 unsigned nparm = (method_params ? list_length (method_params) : 0);
7477 /* If a prototype for the method to be called exists, then cast
7478 the sender's return type and arguments to match that of the method.
7479 Otherwise, leave sender as is. */
7482 ? TREE_VALUE (TREE_TYPE (method_prototype))
7483 : objc_object_type);
7485 tree method_param_types =
7486 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
7487 tree ftype = build_function_type (ret_type, method_param_types);
7491 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
7492 ftype = build_type_attribute_variant (ftype,
7493 METHOD_TYPE_ATTRIBUTES
7494 (method_prototype));
7496 sender_cast = build_pointer_type (ftype);
7498 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
7500 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7501 lookup_object = save_expr (lookup_object);
7503 /* Param list + 2 slots for object and selector. */
7504 parms = VEC_alloc (tree, gc, nparm + 2);
7506 if (flag_next_runtime)
7508 /* If we are returning a struct in memory, and the address
7509 of that memory location is passed as a hidden first
7510 argument, then change which messenger entry point this
7511 expr will call. NB: Note that sender_cast remains
7512 unchanged (it already has a struct return type). */
7513 if (!targetm.calls.struct_value_rtx (0, 0)
7514 && (TREE_CODE (ret_type) == RECORD_TYPE
7515 || TREE_CODE (ret_type) == UNION_TYPE)
7516 && targetm.calls.return_in_memory (ret_type, 0))
7517 sender = (super_flag ? umsg_super_stret_decl :
7518 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
7520 method = build_fold_addr_expr_loc (input_location, sender);
7521 /* Pass the object to the method. */
7522 VEC_quick_push (tree, parms, lookup_object);
7526 /* This is the portable (GNU) way. */
7527 /* First, call the lookup function to get a pointer to the method,
7528 then cast the pointer, then call it with the method arguments. */
7529 VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
7530 VEC_quick_push (tree, tv, lookup_object);
7531 VEC_quick_push (tree, tv, selector);
7532 method = build_function_call_vec (loc, sender, tv, NULL);
7533 VEC_free (tree, gc, tv);
7535 /* Pass the appropriate object to the method. */
7536 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
7539 /* Pass the selector to the method. */
7540 VEC_quick_push (tree, parms, selector);
7541 /* Now append the remainder of the parms. */
7543 for (; method_params; method_params = TREE_CHAIN (method_params))
7544 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
7546 /* Build an obj_type_ref, with the correct cast for the method call. */
7547 t = build3 (OBJ_TYPE_REF, sender_cast, method,
7548 lookup_object, size_zero_node);
7549 t = build_function_call_vec (loc, t, parms, NULL);\
7550 VEC_free (tree, gc, parms);
7555 build_protocol_reference (tree p)
7558 const char *proto_name;
7560 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7562 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
7563 decl = start_var_decl (objc_protocol_template, proto_name);
7565 PROTOCOL_FORWARD_DECL (p) = decl;
7568 /* This function is called by the parser when (and only when) a
7569 @protocol() expression is found, in order to compile it. */
7571 objc_build_protocol_expr (tree protoname)
7574 tree p = lookup_protocol (protoname);
7578 error ("cannot find protocol declaration for %qE",
7580 return error_mark_node;
7583 if (!PROTOCOL_FORWARD_DECL (p))
7584 build_protocol_reference (p);
7586 expr = build_unary_op (input_location,
7587 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
7589 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7590 if we have it, rather than converting it here. */
7591 expr = convert (objc_protocol_type, expr);
7593 /* The @protocol() expression is being compiled into a pointer to a
7594 statically allocated instance of the Protocol class. To become
7595 usable at runtime, the 'isa' pointer of the instance need to be
7596 fixed up at runtime by the runtime library, to point to the
7597 actual 'Protocol' class. */
7599 /* For the GNU runtime, put the static Protocol instance in the list
7600 of statically allocated instances, so that we make sure that its
7601 'isa' pointer is fixed up at runtime by the GNU runtime library
7602 to point to the Protocol class (at runtime, when loading the
7603 module, the GNU runtime library loops on the statically allocated
7604 instances (as found in the defs field in objc_symtab) and fixups
7605 all the 'isa' pointers of those objects). */
7606 if (! flag_next_runtime)
7608 /* This type is a struct containing the fields of a Protocol
7609 object. (Cfr. objc_protocol_type instead is the type of a pointer
7610 to such a struct). */
7611 tree protocol_struct_type = xref_tag
7612 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
7615 /* Look for the list of Protocol statically allocated instances
7616 to fixup at runtime. Create a new list to hold Protocol
7617 statically allocated instances, if the list is not found. At
7618 present there is only another list, holding NSConstantString
7619 static instances to be fixed up at runtime. */
7620 for (chain = &objc_static_instances;
7621 *chain && TREE_VALUE (*chain) != protocol_struct_type;
7622 chain = &TREE_CHAIN (*chain));
7625 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
7626 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
7630 /* Add this statically allocated instance to the Protocol list. */
7631 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
7632 PROTOCOL_FORWARD_DECL (p),
7633 TREE_PURPOSE (*chain));
7640 /* This function is called by the parser when a @selector() expression
7641 is found, in order to compile it. It is only called by the parser
7642 and only to compile a @selector(). LOC is the location of the
7645 objc_build_selector_expr (location_t loc, tree selnamelist)
7649 /* Obtain the full selector name. */
7650 switch (TREE_CODE (selnamelist))
7652 case IDENTIFIER_NODE:
7653 /* A unary selector. */
7654 selname = selnamelist;
7657 selname = build_keyword_selector (selnamelist);
7663 /* If we are required to check @selector() expressions as they
7664 are found, check that the selector has been declared. */
7665 if (warn_undeclared_selector)
7667 /* Look the selector up in the list of all known class and
7668 instance methods (up to this line) to check that the selector
7672 /* First try with instance methods. */
7673 hsh = hash_lookup (nst_method_hash_list, selname);
7675 /* If not found, try with class methods. */
7678 hsh = hash_lookup (cls_method_hash_list, selname);
7681 /* If still not found, print out a warning. */
7684 warning (0, "undeclared selector %qE", selname);
7689 if (flag_typed_selectors)
7690 return build_typed_selector_reference (loc, selname, 0);
7692 return build_selector_reference (loc, selname);
7695 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7696 section '@encode'. */
7698 objc_build_encode_expr (tree type)
7703 encode_type (type, obstack_object_size (&util_obstack),
7704 OBJC_ENCODE_INLINE_DEFS);
7705 obstack_1grow (&util_obstack, 0); /* null terminate string */
7706 string = XOBFINISH (&util_obstack, const char *);
7708 /* Synthesize a string that represents the encoded struct/union. */
7709 result = my_build_string (strlen (string) + 1, string);
7710 obstack_free (&util_obstack, util_firstobj);
7715 build_ivar_reference (tree id)
7717 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7719 /* Historically, a class method that produced objects (factory
7720 method) would assign `self' to the instance that it
7721 allocated. This would effectively turn the class method into
7722 an instance method. Following this assignment, the instance
7723 variables could be accessed. That practice, while safe,
7724 violates the simple rule that a class method should not refer
7725 to an instance variable. It's better to catch the cases
7726 where this is done unknowingly than to support the above
7728 warning (0, "instance variable %qE accessed in class method",
7730 self_decl = convert (objc_instance_type, self_decl); /* cast */
7733 return objc_build_component_ref (build_indirect_ref (input_location,
7734 self_decl, RO_ARROW),
7738 /* Compute a hash value for a given method SEL_NAME. */
7741 hash_func (tree sel_name)
7743 const unsigned char *s
7744 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
7748 h = h * 67 + *s++ - 113;
7755 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7756 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7758 cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7759 als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7761 /* Initialize the hash table used to hold the constant string objects. */
7762 string_htab = htab_create_ggc (31, string_hash,
7766 /* This routine adds sel_name to the hash list. sel_name is a class or alias
7767 name for the class. If alias name, then value is its underlying class.
7768 If class, the value is NULL_TREE. */
7771 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
7774 int slot = hash_func (sel_name) % SIZEHASHTABLE;
7776 obj = ggc_alloc_hashed_entry ();
7777 if (value != NULL_TREE)
7779 /* Save the underlying class for the 'alias' in the hash table */
7780 attr obj_attr = ggc_alloc_hashed_attribute ();
7781 obj_attr->value = value;
7782 obj->list = obj_attr;
7786 obj->next = hashlist[slot];
7787 obj->key = sel_name;
7789 hashlist[slot] = obj; /* append to front */
7794 Searches in the hash table looking for a match for class or alias name.
7798 hash_class_name_lookup (hash *hashlist, tree sel_name)
7802 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7806 if (sel_name == target->key)
7809 target = target->next;
7814 /* WARNING!!!! hash_enter is called with a method, and will peek
7815 inside to find its selector! But hash_lookup is given a selector
7816 directly, and looks for the selector that's inside the found
7817 entry's key (method) for comparison. */
7820 hash_enter (hash *hashlist, tree method)
7823 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
7825 obj = ggc_alloc_hashed_entry ();
7827 obj->next = hashlist[slot];
7830 hashlist[slot] = obj; /* append to front */
7834 hash_lookup (hash *hashlist, tree sel_name)
7838 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7842 if (sel_name == METHOD_SEL_NAME (target->key))
7845 target = target->next;
7851 hash_add_attr (hash entry, tree value)
7855 obj = ggc_alloc_hashed_attribute ();
7856 obj->next = entry->list;
7859 entry->list = obj; /* append to front */
7863 lookup_method (tree mchain, tree method)
7867 if (TREE_CODE (method) == IDENTIFIER_NODE)
7870 key = METHOD_SEL_NAME (method);
7874 if (METHOD_SEL_NAME (mchain) == key)
7877 mchain = DECL_CHAIN (mchain);
7882 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7883 in INTERFACE, along with any categories and protocols attached thereto.
7884 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7885 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7886 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7887 be found in INTERFACE or any of its superclasses, look for an _instance_
7888 method of the same name in the root class as a last resort.
7890 If a suitable method cannot be found, return NULL_TREE. */
7893 lookup_method_static (tree interface, tree ident, int flags)
7895 tree meth = NULL_TREE, root_inter = NULL_TREE;
7896 tree inter = interface;
7897 int is_class = (flags & OBJC_LOOKUP_CLASS);
7898 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
7902 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
7903 tree category = inter;
7905 /* First, look up the method in the class itself. */
7906 if ((meth = lookup_method (chain, ident)))
7909 /* Failing that, look for the method in each category of the class. */
7910 while ((category = CLASS_CATEGORY_LIST (category)))
7912 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
7914 /* Check directly in each category. */
7915 if ((meth = lookup_method (chain, ident)))
7918 /* Failing that, check in each category's protocols. */
7919 if (CLASS_PROTOCOL_LIST (category))
7921 if ((meth = (lookup_method_in_protocol_list
7922 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
7927 /* If not found in categories, check in protocols of the main class. */
7928 if (CLASS_PROTOCOL_LIST (inter))
7930 if ((meth = (lookup_method_in_protocol_list
7931 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
7935 /* If we were instructed not to look in superclasses, don't. */
7936 if (no_superclasses)
7939 /* Failing that, climb up the inheritance hierarchy. */
7941 inter = lookup_interface (CLASS_SUPER_NAME (inter));
7945 /* If no class (factory) method was found, check if an _instance_
7946 method of the same name exists in the root class. This is what
7947 the Objective-C runtime will do. If an instance method was not
7949 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
7952 /* Add the method to the hash list if it doesn't contain an identical
7956 add_method_to_hash_list (hash *hash_list, tree method)
7960 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7962 /* Install on a global chain. */
7963 hash_enter (hash_list, method);
7967 /* Check types against those; if different, add to a list. */
7969 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7970 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7971 already_there |= comp_proto_with_proto (method, loop->value, 1);
7973 hash_add_attr (hsh, method);
7978 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
7982 /* @optional methods are added to protocol's OPTIONAL list */
7985 gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
7986 if (!(mth = lookup_method (is_class
7987 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
7988 : PROTOCOL_OPTIONAL_NST_METHODS (klass),
7993 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
7994 PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
7998 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
7999 PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
8003 else if (!(mth = lookup_method (is_class
8004 ? CLASS_CLS_METHODS (klass)
8005 : CLASS_NST_METHODS (klass), method)))
8007 /* put method on list in reverse order */
8010 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
8011 CLASS_CLS_METHODS (klass) = method;
8015 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
8016 CLASS_NST_METHODS (klass) = method;
8021 /* When processing an @interface for a class or category, give hard
8022 errors on methods with identical selectors but differing argument
8023 and/or return types. We do not do this for @implementations, because
8024 C/C++ will do it for us (i.e., there will be duplicate function
8025 definition errors). */
8026 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
8027 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
8028 && !comp_proto_with_proto (method, mth, 1))
8029 error ("duplicate declaration of method %<%c%E%>",
8030 is_class ? '+' : '-',
8031 METHOD_SEL_NAME (mth));
8035 add_method_to_hash_list (cls_method_hash_list, method);
8038 add_method_to_hash_list (nst_method_hash_list, method);
8040 /* Instance methods in root classes (and categories thereof)
8041 may act as class methods as a last resort. We also add
8042 instance methods listed in @protocol declarations to
8043 the class hash table, on the assumption that @protocols
8044 may be adopted by root classes or categories. */
8045 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
8046 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
8047 klass = lookup_interface (CLASS_NAME (klass));
8049 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
8050 || !CLASS_SUPER_NAME (klass))
8051 add_method_to_hash_list (cls_method_hash_list, method);
8058 add_class (tree class_name, tree name)
8060 struct interface_tuple **slot;
8062 /* Put interfaces on list in reverse order. */
8063 TREE_CHAIN (class_name) = interface_chain;
8064 interface_chain = class_name;
8066 if (interface_htab == NULL)
8067 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
8068 slot = (struct interface_tuple **)
8069 htab_find_slot_with_hash (interface_htab, name,
8070 IDENTIFIER_HASH_VALUE (name),
8074 *slot = ggc_alloc_cleared_interface_tuple ();
8077 (*slot)->class_name = class_name;
8079 return interface_chain;
8083 add_category (tree klass, tree category)
8085 /* Put categories on list in reverse order. */
8086 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
8090 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
8092 CLASS_SUPER_NAME (category));
8096 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
8097 CLASS_CATEGORY_LIST (klass) = category;
8101 /* Called after parsing each instance variable declaration. Necessary to
8102 preserve typedefs and implement public/private...
8104 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
8107 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
8110 tree field_type = TREE_TYPE (field_decl);
8111 const char *ivar_name = DECL_NAME (field_decl)
8112 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
8116 if (TREE_CODE (field_type) == REFERENCE_TYPE)
8118 error ("illegal reference type specified for instance variable %qs",
8120 /* Return class as is without adding this ivar. */
8125 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
8126 || TYPE_SIZE (field_type) == error_mark_node)
8127 /* 'type[0]' is allowed, but 'type[]' is not! */
8129 error ("instance variable %qs has unknown size", ivar_name);
8130 /* Return class as is without adding this ivar. */
8135 /* Check if the ivar being added has a non-POD C++ type. If so, we will
8136 need to either (1) warn the user about it or (2) generate suitable
8137 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
8138 methods (if '-fobjc-call-cxx-cdtors' was specified). */
8139 if (MAYBE_CLASS_TYPE_P (field_type)
8140 && (TYPE_NEEDS_CONSTRUCTING (field_type)
8141 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
8142 || TYPE_POLYMORPHIC_P (field_type)))
8144 tree type_name = OBJC_TYPE_NAME (field_type);
8146 if (flag_objc_call_cxx_cdtors)
8148 /* Since the ObjC runtime will be calling the constructors and
8149 destructors for us, the only thing we can't handle is the lack
8150 of a default constructor. */
8151 if (TYPE_NEEDS_CONSTRUCTING (field_type)
8152 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
8154 warning (0, "type %qE has no default constructor to call",
8157 /* If we cannot call a constructor, we should also avoid
8158 calling the destructor, for symmetry. */
8159 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8160 warning (0, "destructor for %qE shall not be run either",
8166 static bool warn_cxx_ivars = false;
8168 if (TYPE_POLYMORPHIC_P (field_type))
8170 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
8172 error ("type %qE has virtual member functions", type_name);
8173 error ("illegal aggregate type %qE specified "
8174 "for instance variable %qs",
8175 type_name, ivar_name);
8176 /* Return class as is without adding this ivar. */
8180 /* User-defined constructors and destructors are not known to Obj-C
8181 and hence will not be called. This may or may not be a problem. */
8182 if (TYPE_NEEDS_CONSTRUCTING (field_type))
8183 warning (0, "type %qE has a user-defined constructor", type_name);
8184 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8185 warning (0, "type %qE has a user-defined destructor", type_name);
8187 if (!warn_cxx_ivars)
8189 warning (0, "C++ constructors and destructors will not "
8190 "be invoked for Objective-C fields");
8191 warn_cxx_ivars = true;
8197 /* Overload the public attribute, it is not used for FIELD_DECLs. */
8200 case OBJC_IVAR_VIS_PROTECTED:
8201 TREE_PUBLIC (field_decl) = 0;
8202 TREE_PRIVATE (field_decl) = 0;
8203 TREE_PROTECTED (field_decl) = 1;
8206 case OBJC_IVAR_VIS_PACKAGE:
8207 /* TODO: Implement the package variant. */
8208 case OBJC_IVAR_VIS_PUBLIC:
8209 TREE_PUBLIC (field_decl) = 1;
8210 TREE_PRIVATE (field_decl) = 0;
8211 TREE_PROTECTED (field_decl) = 0;
8214 case OBJC_IVAR_VIS_PRIVATE:
8215 TREE_PUBLIC (field_decl) = 0;
8216 TREE_PRIVATE (field_decl) = 1;
8217 TREE_PROTECTED (field_decl) = 0;
8222 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
8229 is_ivar (tree decl_chain, tree ident)
8231 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8232 if (DECL_NAME (decl_chain) == ident)
8237 /* True if the ivar is private and we are not in its implementation. */
8240 is_private (tree decl)
8242 return (TREE_PRIVATE (decl)
8243 && ! is_ivar (CLASS_IVARS (implementation_template),
8247 /* We have an instance variable reference;, check to see if it is public. */
8250 objc_is_public (tree expr, tree identifier)
8252 tree basetype, decl;
8255 if (processing_template_decl)
8259 if (TREE_TYPE (expr) == error_mark_node)
8262 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8264 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8266 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8268 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8272 error ("cannot find interface declaration for %qE",
8273 OBJC_TYPE_NAME (basetype));
8277 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8279 if (TREE_PUBLIC (decl))
8282 /* Important difference between the Stepstone translator:
8283 all instance variables should be public within the context
8284 of the implementation. */
8285 if (objc_implementation_context
8286 && ((TREE_CODE (objc_implementation_context)
8287 == CLASS_IMPLEMENTATION_TYPE)
8288 || (TREE_CODE (objc_implementation_context)
8289 == CATEGORY_IMPLEMENTATION_TYPE)))
8291 tree curtype = TYPE_MAIN_VARIANT
8292 (CLASS_STATIC_TEMPLATE
8293 (implementation_template));
8295 if (basetype == curtype
8296 || DERIVED_FROM_P (basetype, curtype))
8298 int priv = is_private (decl);
8301 error ("instance variable %qE is declared private",
8308 /* The 2.95.2 compiler sometimes allowed C functions to access
8309 non-@public ivars. We will let this slide for now... */
8310 if (!objc_method_context)
8312 warning (0, "instance variable %qE is %s; "
8313 "this will be a hard error in the future",
8315 TREE_PRIVATE (decl) ? "@private" : "@protected");
8319 error ("instance variable %qE is declared %s",
8321 TREE_PRIVATE (decl) ? "private" : "protected");
8330 /* Make sure all entries in CHAIN are also in LIST. */
8333 check_methods (tree chain, tree list, int mtype)
8339 /* If the method is associated with a dynamic property, then it
8340 is Ok not to have the method implementation, as it will be
8341 generated dynamically at runtime. */
8342 tree property = METHOD_PROPERTY_CONTEXT (chain);
8343 if (property != NULL_TREE && PROPERTY_DYNAMIC (property))
8345 chain = TREE_CHAIN (chain); /* next method... */
8349 if (!lookup_method (list, chain))
8353 switch (TREE_CODE (objc_implementation_context))
8355 case CLASS_IMPLEMENTATION_TYPE:
8356 warning (0, "incomplete implementation of class %qE",
8357 CLASS_NAME (objc_implementation_context));
8359 case CATEGORY_IMPLEMENTATION_TYPE:
8360 warning (0, "incomplete implementation of category %qE",
8361 CLASS_SUPER_NAME (objc_implementation_context));
8369 warning (0, "method definition for %<%c%E%> not found",
8370 mtype, METHOD_SEL_NAME (chain));
8373 chain = DECL_CHAIN (chain);
8379 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8382 conforms_to_protocol (tree klass, tree protocol)
8384 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
8386 tree p = CLASS_PROTOCOL_LIST (klass);
8387 while (p && TREE_VALUE (p) != protocol)
8392 tree super = (CLASS_SUPER_NAME (klass)
8393 ? lookup_interface (CLASS_SUPER_NAME (klass))
8395 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
8404 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8405 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8408 check_methods_accessible (tree chain, tree context, int mtype)
8412 tree base_context = context;
8416 /* If the method is associated with a dynamic property, then it
8417 is Ok not to have the method implementation, as it will be
8418 generated dynamically at runtime. */
8419 tree property = METHOD_PROPERTY_CONTEXT (chain);
8420 if (property != NULL_TREE && PROPERTY_DYNAMIC (property))
8422 chain = TREE_CHAIN (chain); /* next method... */
8426 context = base_context;
8430 list = CLASS_CLS_METHODS (context);
8432 list = CLASS_NST_METHODS (context);
8434 if (lookup_method (list, chain))
8437 switch (TREE_CODE (context))
8439 case CLASS_IMPLEMENTATION_TYPE:
8440 case CLASS_INTERFACE_TYPE:
8441 context = (CLASS_SUPER_NAME (context)
8442 ? lookup_interface (CLASS_SUPER_NAME (context))
8445 case CATEGORY_IMPLEMENTATION_TYPE:
8446 case CATEGORY_INTERFACE_TYPE:
8447 context = (CLASS_NAME (context)
8448 ? lookup_interface (CLASS_NAME (context))
8456 if (context == NULL_TREE)
8460 switch (TREE_CODE (objc_implementation_context))
8462 case CLASS_IMPLEMENTATION_TYPE:
8463 warning (0, "incomplete implementation of class %qE",
8464 CLASS_NAME (objc_implementation_context));
8466 case CATEGORY_IMPLEMENTATION_TYPE:
8467 warning (0, "incomplete implementation of category %qE",
8468 CLASS_SUPER_NAME (objc_implementation_context));
8475 warning (0, "method definition for %<%c%E%> not found",
8476 mtype, METHOD_SEL_NAME (chain));
8479 chain = TREE_CHAIN (chain); /* next method... */
8484 /* Check whether the current interface (accessible via
8485 'objc_implementation_context') actually implements protocol P, along
8486 with any protocols that P inherits. */
8489 check_protocol (tree p, const char *type, tree name)
8491 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
8495 /* Ensure that all protocols have bodies! */
8498 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
8499 CLASS_CLS_METHODS (objc_implementation_context),
8501 f2 = check_methods (PROTOCOL_NST_METHODS (p),
8502 CLASS_NST_METHODS (objc_implementation_context),
8507 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
8508 objc_implementation_context,
8510 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
8511 objc_implementation_context,
8516 warning (0, "%s %qE does not fully implement the %qE protocol",
8517 type, name, PROTOCOL_NAME (p));
8520 /* Check protocols recursively. */
8521 if (PROTOCOL_LIST (p))
8523 tree subs = PROTOCOL_LIST (p);
8525 lookup_interface (CLASS_SUPER_NAME (implementation_template));
8529 tree sub = TREE_VALUE (subs);
8531 /* If the superclass does not conform to the protocols
8532 inherited by P, then we must! */
8533 if (!super_class || !conforms_to_protocol (super_class, sub))
8534 check_protocol (sub, type, name);
8535 subs = TREE_CHAIN (subs);
8540 /* Check whether the current interface (accessible via
8541 'objc_implementation_context') actually implements the protocols listed
8545 check_protocols (tree proto_list, const char *type, tree name)
8547 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
8549 tree p = TREE_VALUE (proto_list);
8551 check_protocol (p, type, name);
8555 /* Make sure that the class CLASS_NAME is defined
8556 CODE says which kind of thing CLASS_NAME ought to be.
8557 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8558 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8561 start_class (enum tree_code code, tree class_name, tree super_name,
8567 if (current_namespace != global_namespace) {
8568 error ("Objective-C declarations may only appear in global scope");
8570 #endif /* OBJCPLUS */
8572 if (objc_implementation_context)
8574 warning (0, "%<@end%> missing in implementation context");
8575 finish_class (objc_implementation_context);
8576 objc_ivar_chain = NULL_TREE;
8577 objc_implementation_context = NULL_TREE;
8580 klass = make_node (code);
8581 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
8583 /* Check for existence of the super class, if one was specified. Note
8584 that we must have seen an @interface, not just a @class. If we
8585 are looking at a @compatibility_alias, traverse it first. */
8586 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
8589 tree super = objc_is_class_name (super_name);
8591 if (!super || !lookup_interface (super))
8593 error ("cannot find interface declaration for %qE, superclass of %qE",
8594 super ? super : super_name,
8596 super_name = NULL_TREE;
8602 CLASS_NAME (klass) = class_name;
8603 CLASS_SUPER_NAME (klass) = super_name;
8604 CLASS_CLS_METHODS (klass) = NULL_TREE;
8606 if (! objc_is_class_name (class_name)
8607 && (decl = lookup_name (class_name)))
8609 error ("%qE redeclared as different kind of symbol",
8611 error ("previous declaration of %q+D",
8617 case CLASS_IMPLEMENTATION_TYPE:
8621 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
8622 if (TREE_VALUE (chain) == class_name)
8624 error ("reimplementation of class %qE",
8626 return error_mark_node;
8628 implemented_classes = tree_cons (NULL_TREE, class_name,
8629 implemented_classes);
8632 /* Reset for multiple classes per file. */
8635 objc_implementation_context = klass;
8637 /* Lookup the interface for this implementation. */
8639 if (!(implementation_template = lookup_interface (class_name)))
8641 warning (0, "cannot find interface declaration for %qE",
8643 add_class (implementation_template = objc_implementation_context,
8647 /* If a super class has been specified in the implementation,
8648 insure it conforms to the one specified in the interface. */
8651 && (super_name != CLASS_SUPER_NAME (implementation_template)))
8653 tree previous_name = CLASS_SUPER_NAME (implementation_template);
8654 error ("conflicting super class name %qE",
8657 error ("previous declaration of %qE", previous_name);
8659 error ("previous declaration");
8662 else if (! super_name)
8664 CLASS_SUPER_NAME (objc_implementation_context)
8665 = CLASS_SUPER_NAME (implementation_template);
8669 case CLASS_INTERFACE_TYPE:
8670 if (lookup_interface (class_name))
8672 error ("duplicate interface declaration for class %qE", class_name);
8674 warning (0, "duplicate interface declaration for class %qE", class_name);
8677 add_class (klass, class_name);
8680 CLASS_PROTOCOL_LIST (klass)
8681 = lookup_and_install_protocols (protocol_list);
8684 case CATEGORY_INTERFACE_TYPE:
8686 tree class_category_is_assoc_with;
8688 /* For a category, class_name is really the name of the class that
8689 the following set of methods will be associated with. We must
8690 find the interface so that can derive the objects template. */
8691 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
8693 error ("cannot find interface declaration for %qE",
8695 exit (FATAL_EXIT_CODE);
8698 add_category (class_category_is_assoc_with, klass);
8701 CLASS_PROTOCOL_LIST (klass)
8702 = lookup_and_install_protocols (protocol_list);
8706 case CATEGORY_IMPLEMENTATION_TYPE:
8707 /* Reset for multiple classes per file. */
8710 objc_implementation_context = klass;
8712 /* For a category, class_name is really the name of the class that
8713 the following set of methods will be associated with. We must
8714 find the interface so that can derive the objects template. */
8716 if (!(implementation_template = lookup_interface (class_name)))
8718 error ("cannot find interface declaration for %qE",
8720 exit (FATAL_EXIT_CODE);
8730 continue_class (tree klass)
8732 switch (TREE_CODE (klass))
8734 case CLASS_IMPLEMENTATION_TYPE:
8735 case CATEGORY_IMPLEMENTATION_TYPE:
8737 struct imp_entry *imp_entry;
8739 /* Check consistency of the instance variables. */
8741 if (CLASS_RAW_IVARS (klass))
8742 check_ivars (implementation_template, klass);
8744 /* code generation */
8746 push_lang_context (lang_name_c);
8748 build_private_template (implementation_template);
8749 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
8750 objc_instance_type = build_pointer_type (uprivate_record);
8752 imp_entry = ggc_alloc_imp_entry ();
8754 imp_entry->next = imp_list;
8755 imp_entry->imp_context = klass;
8756 imp_entry->imp_template = implementation_template;
8758 synth_forward_declarations ();
8759 imp_entry->class_decl = UOBJC_CLASS_decl;
8760 imp_entry->meta_decl = UOBJC_METACLASS_decl;
8761 imp_entry->has_cxx_cdtors = 0;
8763 /* Append to front and increment count. */
8764 imp_list = imp_entry;
8765 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
8770 pop_lang_context ();
8771 #endif /* OBJCPLUS */
8773 return get_class_ivars (implementation_template, true);
8776 case CLASS_INTERFACE_TYPE:
8779 push_lang_context (lang_name_c);
8780 #endif /* OBJCPLUS */
8781 objc_collecting_ivars = 1;
8782 build_private_template (klass);
8783 objc_collecting_ivars = 0;
8785 pop_lang_context ();
8786 #endif /* OBJCPLUS */
8791 return error_mark_node;
8795 /* This routine builds name of the setter synthesized function. */
8797 objc_build_property_setter_name (tree ident)
8799 /* TODO: Use alloca to allocate buffer of appropriate size. */
8800 static char string[BUFSIZE];
8801 sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
8802 string[3] = TOUPPER (string[3]);
8806 /* This routine prepares the declarations of the property accessor
8807 helper functions (objc_getProperty(), etc) that are used when
8808 @synthesize is used. */
8810 build_objc_property_accessor_helpers (void)
8814 /* Declare the following function:
8816 objc_getProperty (id self, SEL _cmd,
8817 ptrdiff_t offset, BOOL is_atomic); */
8818 type = build_function_type_list (objc_object_type,
8824 objc_getProperty_decl = add_builtin_function ("objc_getProperty",
8825 type, 0, NOT_BUILT_IN,
8827 TREE_NOTHROW (objc_getProperty_decl) = 0;
8829 /* Declare the following function:
8831 objc_setProperty (id self, SEL _cmd,
8832 ptrdiff_t offset, id new_value,
8833 BOOL is_atomic, BOOL should_copy); */
8834 type = build_function_type_list (void_type_node,
8842 objc_setProperty_decl = add_builtin_function ("objc_setProperty",
8843 type, 0, NOT_BUILT_IN,
8845 TREE_NOTHROW (objc_setProperty_decl) = 0;
8847 /* This is the type of all of the following functions
8848 (objc_copyStruct(), objc_getPropertyStruct() and
8849 objc_setPropertyStruct()). */
8850 type = build_function_type_list (void_type_node,
8852 const_ptr_type_node,
8858 if (flag_next_runtime)
8860 /* Declare the following function:
8862 objc_copyStruct (void *destination, const void *source,
8863 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
8864 objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
8865 type, 0, NOT_BUILT_IN,
8867 TREE_NOTHROW (objc_copyStruct_decl) = 0;
8868 objc_getPropertyStruct_decl = NULL_TREE;
8869 objc_setPropertyStruct_decl = NULL_TREE;
8873 objc_copyStruct_decl = NULL_TREE;
8875 /* Declare the following function:
8877 objc_getPropertyStruct (void *destination, const void *source,
8878 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
8879 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
8880 type, 0, NOT_BUILT_IN,
8882 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
8883 /* Declare the following function:
8885 objc_setPropertyStruct (void *destination, const void *source,
8886 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
8887 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
8888 type, 0, NOT_BUILT_IN,
8890 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
8894 /* This looks up an ivar in a class (including superclasses). */
8896 lookup_ivar (tree interface, tree instance_variable_name)
8902 for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8903 if (DECL_NAME (decl_chain) == instance_variable_name)
8906 /* Not found. Search superclass if any. */
8907 if (CLASS_SUPER_NAME (interface))
8908 interface = lookup_interface (CLASS_SUPER_NAME (interface));
8914 /* This routine synthesizes a 'getter' method. This is only called
8915 for @synthesize properties. */
8917 objc_synthesize_getter (tree klass, tree class_method, tree property)
8919 location_t location = DECL_SOURCE_LOCATION (property);
8924 /* If user has implemented a getter with same name then do nothing. */
8925 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8926 PROPERTY_GETTER_NAME (property)))
8929 /* Find declaration of the property getter in the interface. There
8930 must be one. TODO: Search superclasses as well. */
8931 decl = lookup_method (CLASS_NST_METHODS (class_method), PROPERTY_GETTER_NAME (property));
8933 /* If one not declared in the interface, this condition has already
8934 been reported as user error (because property was not declared in
8939 /* Adapt the 'decl'. Use the source location of the @synthesize
8940 statement for error messages. */
8941 decl = copy_node (decl);
8942 DECL_SOURCE_LOCATION (decl) = location;
8944 objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
8945 body = c_begin_compound_stmt (true);
8947 /* Now we need to decide how we build the getter. There are three
8950 for 'copy' or 'retain' properties we need to use the
8951 objc_getProperty() accessor helper which knows about retain and
8952 copy. It supports both 'nonatomic' and 'atomic' access.
8954 for 'nonatomic, assign' properties we can access the instance
8955 variable directly. 'nonatomic' means we don't have to use locks,
8956 and 'assign' means we don't have to worry about retain or copy.
8957 If you combine the two, it means we can just access the instance
8960 for 'atomic, assign' properties we use objc_copyStruct() (for the
8961 next runtime) or objc_getPropertyStruct() (for the GNU runtime). */
8962 switch (PROPERTY_ASSIGN_SEMANTICS (property))
8964 case OBJC_PROPERTY_RETAIN:
8965 case OBJC_PROPERTY_COPY:
8967 /* We build "return objc_getProperty (self, _cmd, offset, is_atomic);" */
8968 tree cmd, ivar, offset, is_atomic;
8969 cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
8971 /* Find the ivar to compute the offset. */
8972 ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
8973 if (!ivar || is_private (ivar))
8975 /* This should never happen. */
8977 "can not find instance variable associated with property");
8978 ret_val = error_mark_node;
8981 offset = byte_position (ivar);
8983 if (PROPERTY_NONATOMIC (property))
8984 is_atomic = boolean_false_node;
8986 is_atomic = boolean_true_node;
8988 ret_val = build_function_call
8990 /* Function prototype. */
8991 objc_getProperty_decl,
8993 tree_cons /* self */
8994 (NULL_TREE, self_decl,
8995 tree_cons /* _cmd */
8997 tree_cons /* offset */
8999 tree_cons /* is_atomic */
9000 (NULL_TREE, is_atomic, NULL_TREE)))));
9003 case OBJC_PROPERTY_ASSIGN:
9004 if (PROPERTY_NONATOMIC (property))
9006 /* We build "return self->PROPERTY_IVAR_NAME;" */
9007 ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
9013 <property type> __objc_property_temp;
9014 objc_getPropertyStruct (&__objc_property_temp,
9015 &(self->PROPERTY_IVAR_NAME),
9016 sizeof (type of self->PROPERTY_IVAR_NAME),
9019 return __objc_property_temp;
9021 For the NeXT runtime, we need to use objc_copyStruct
9022 instead of objc_getPropertyStruct. */
9023 tree objc_property_temp_decl, function_decl, function_call;
9024 tree size_of, is_atomic;
9026 objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
9027 DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
9028 objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
9030 /* sizeof (ivar type). Since the ivar and the property have
9031 the same type, there is no need to lookup the ivar. */
9032 size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9033 true /* is_sizeof */,
9034 false /* complain */);
9036 if (PROPERTY_NONATOMIC (property))
9037 is_atomic = boolean_false_node;
9039 is_atomic = boolean_true_node;
9041 if (flag_next_runtime)
9042 function_decl = objc_copyStruct_decl;
9044 function_decl = objc_getPropertyStruct_decl;
9046 function_call = build_function_call
9048 /* Function prototype. */
9051 tree_cons /* &__objc_property_temp_decl */
9052 /* Warning: note that using build_fold_addr_expr_loc()
9053 here causes invalid code to be generated. */
9054 (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
9055 tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9056 (NULL_TREE, build_fold_addr_expr_loc (location,
9058 (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9059 tree_cons /* sizeof (PROPERTY_IVAR) */
9060 (NULL_TREE, size_of,
9061 tree_cons /* is_atomic */
9062 (NULL_TREE, is_atomic,
9063 /* TODO: This is currently ignored by the GNU
9064 runtime, but what about the next one ? */
9065 tree_cons /* has_strong */
9066 (NULL_TREE, boolean_true_node, NULL_TREE))))));
9068 add_stmt (function_call);
9070 ret_val = objc_property_temp_decl;
9077 gcc_assert (ret_val);
9080 finish_return_stmt (ret_val);
9082 c_finish_return (location, ret_val, NULL_TREE);
9085 add_stmt (c_end_compound_stmt (location, body, true));
9086 fn = current_function_decl;
9090 objc_finish_method_definition (fn);
9093 /* This routine synthesizes a 'setter' method. */
9096 objc_synthesize_setter (tree klass ATTRIBUTE_UNUSED, tree class_method, tree property)
9098 location_t location = DECL_SOURCE_LOCATION (property);
9101 tree new_value, statement;
9103 /* If user has implemented a setter with same name then do nothing. */
9104 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9105 PROPERTY_SETTER_NAME (property)))
9108 /* Find declaration of the property setter in the interface. There
9109 must be one. TODO: Search superclasses as well. */
9110 decl = lookup_method (CLASS_NST_METHODS (class_method), PROPERTY_SETTER_NAME (property));
9112 /* If one not declared in the interface, this condition has already
9113 been reported as user error (because property was not declared in
9118 /* Adapt the 'decl'. Use the source location of the @synthesize
9119 statement for error messages. */
9120 decl = copy_node (decl);
9121 DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
9123 objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9125 body = c_begin_compound_stmt (true);
9127 /* The 'new_value' is the only argument to the method, which is the
9128 3rd argument of the function, after self and _cmd. We use twice
9129 TREE_CHAIN to move forward two arguments. */
9130 new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
9132 /* This would presumably happen if the user has specified a
9133 prototype for the setter that does not have an argument! */
9134 if (new_value == NULL_TREE)
9136 /* TODO: This should be caught much earlier than this. */
9137 error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
9138 /* Try to recover somehow. */
9139 new_value = error_mark_node;
9142 /* Now we need to decide how we build the setter. There are three
9145 for 'copy' or 'retain' properties we need to use the
9146 objc_setProperty() accessor helper which knows about retain and
9147 copy. It supports both 'nonatomic' and 'atomic' access.
9149 for 'nonatomic, assign' properties we can access the instance
9150 variable directly. 'nonatomic' means we don't have to use locks,
9151 and 'assign' means we don't have to worry about retain or copy.
9152 If you combine the two, it means we can just access the instance
9155 for 'atomic, assign' properties we use objc_copyStruct() (for the
9156 next runtime) or objc_setPropertyStruct() (for the GNU runtime). */
9157 switch (PROPERTY_ASSIGN_SEMANTICS (property))
9159 case OBJC_PROPERTY_RETAIN:
9160 case OBJC_PROPERTY_COPY:
9162 /* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);" */
9163 tree cmd, ivar, offset, is_atomic, should_copy;
9164 cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9166 /* Find the ivar to compute the offset. */
9167 ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9168 if (!ivar || is_private (ivar))
9171 "can not find instance variable associated with property");
9172 statement = error_mark_node;
9175 offset = byte_position (ivar);
9177 if (PROPERTY_NONATOMIC (property))
9178 is_atomic = boolean_false_node;
9180 is_atomic = boolean_true_node;
9182 if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
9183 should_copy = boolean_true_node;
9185 should_copy = boolean_false_node;
9187 statement = build_function_call
9189 /* Function prototype. */
9190 objc_setProperty_decl,
9192 tree_cons /* self */
9193 (NULL_TREE, self_decl,
9194 tree_cons /* _cmd */
9196 tree_cons /* offset */
9198 tree_cons /* new_value */
9199 (NULL_TREE, new_value,
9200 tree_cons /* is_atomic */
9201 (NULL_TREE, is_atomic,
9202 tree_cons /* should_copy */
9203 (NULL_TREE, should_copy, NULL_TREE)))))));
9206 case OBJC_PROPERTY_ASSIGN:
9207 if (PROPERTY_NONATOMIC (property))
9209 /* We build "self->PROPERTY_IVAR_NAME = new_value;" */
9210 statement = build_modify_expr
9212 objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
9213 NULL_TREE, NOP_EXPR,
9214 location, new_value, NULL_TREE);
9220 objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
9222 sizeof (type of self->PROPERTY_IVAR_NAME),
9226 For the NeXT runtime, we need to use objc_copyStruct
9227 instead of objc_getPropertyStruct. */
9228 tree function_decl, size_of, is_atomic;
9230 /* sizeof (ivar type). Since the ivar and the property have
9231 the same type, there is no need to lookup the ivar. */
9232 size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9233 true /* is_sizeof */,
9234 false /* complain */);
9236 if (PROPERTY_NONATOMIC (property))
9237 is_atomic = boolean_false_node;
9239 is_atomic = boolean_true_node;
9241 if (flag_next_runtime)
9242 function_decl = objc_copyStruct_decl;
9244 function_decl = objc_setPropertyStruct_decl;
9246 statement = build_function_call
9248 /* Function prototype. */
9251 tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9252 (NULL_TREE, build_fold_addr_expr_loc (location,
9254 (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9255 tree_cons /* &new_value */
9256 (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
9257 tree_cons /* sizeof (PROPERTY_IVAR) */
9258 (NULL_TREE, size_of,
9259 tree_cons /* is_atomic */
9260 (NULL_TREE, is_atomic,
9261 /* TODO: This is currently ignored by the GNU
9262 runtime, but what about the next one ? */
9263 tree_cons /* has_strong */
9264 (NULL_TREE, boolean_true_node, NULL_TREE))))));
9270 gcc_assert (statement);
9272 add_stmt (statement);
9273 add_stmt (c_end_compound_stmt (location, body, true));
9274 fn = current_function_decl;
9278 objc_finish_method_definition (fn);
9281 /* This function is a sub-routine of objc_add_synthesize_declaration.
9282 It is called for each property to synthesize once we have
9283 determined that the context is Ok. */
9285 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
9286 tree property_name, tree ivar_name)
9288 /* Find the @property declaration. */
9291 /* Check that synthesize or dynamic has not already been used for
9292 the same property. */
9293 for (property = CLASS_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
9294 if (PROPERTY_NAME (property) == property_name)
9296 location_t original_location = DECL_SOURCE_LOCATION (property);
9298 if (PROPERTY_DYNAMIC (property))
9299 error_at (location, "property %qs already specified in %<@dynamic%>",
9300 IDENTIFIER_POINTER (property_name));
9302 error_at (location, "property %qs already specified in %<@synthesize%>",
9303 IDENTIFIER_POINTER (property_name));
9305 if (original_location != UNKNOWN_LOCATION)
9306 inform (original_location, "originally specified here");
9310 /* Check that the property is declared in the interface. */
9311 /* TODO: This only check the immediate class; we need to check the
9312 superclass (and categories ?) as well. */
9313 for (property = CLASS_PROPERTY_DECL (interface); property; property = TREE_CHAIN (property))
9314 if (PROPERTY_NAME (property) == property_name)
9319 error_at (location, "no declaration of property %qs found in the interface",
9320 IDENTIFIER_POINTER (property_name));
9325 /* We have to copy the property, because we want to chain it to
9326 the implementation context, and we want to store the source
9327 location of the @synthesize, not of the original
9329 property = copy_node (property);
9330 DECL_SOURCE_LOCATION (property) = location;
9333 /* Determine PROPERTY_IVAR_NAME. */
9334 if (ivar_name == NULL_TREE)
9335 ivar_name = property_name;
9337 /* Check that the instance variable exists. You can only use an
9338 instance variable from the same class, not one from the
9340 if (!is_ivar (CLASS_IVARS (interface), ivar_name))
9341 error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar",
9342 IDENTIFIER_POINTER (property_name));
9344 /* TODO: Check that the types of the instance variable and of the
9347 /* TODO: Check that no other property is using the same instance
9350 /* Note that a @synthesize (and only a @synthesize) always sets
9351 PROPERTY_IVAR_NAME to a non-NULL_TREE. You can recognize a
9352 @synthesize by that. */
9353 PROPERTY_IVAR_NAME (property) = ivar_name;
9355 /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
9356 original declaration; they are always set (with the exception of
9357 PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1). */
9359 /* Add the property to the list of properties for current implementation. */
9360 TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
9361 IMPL_PROPERTY_DECL (objc_implementation_context) = property;
9363 /* Note how we don't actually synthesize the getter/setter here; it
9364 would be very natural, but we may miss the fact that the user has
9365 implemented his own getter/setter later on in the @implementation
9366 (in which case we shouldn't generate getter/setter). We wait
9367 until we have parsed it all before generating the code. */
9370 /* This function is called by the parser after a @synthesize
9371 expression is parsed. 'location' is the location of the
9372 @synthesize expression, and 'property_and_ivar_list' is a chained
9373 list of the property and ivar names. */
9375 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
9377 tree interface, chain;
9379 if (flag_objc1_only)
9380 error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
9382 if (property_and_ivar_list == error_mark_node)
9385 if (!objc_implementation_context)
9387 /* We can get here only in Objective-C; the Objective-C++ parser
9388 detects the problem while parsing, outputs the error
9389 "misplaced '@synthesize' Objective-C++ construct" and skips
9391 error_at (location, "%<@synthesize%> not in @implementation context");
9395 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
9397 /* TODO: Maybe we should allow @synthesize in categories ? */
9398 error_at (location, "%<@synthesize%> can not be used in categories");
9402 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
9405 /* I can't see how this could happen, but it is good as a safety check. */
9407 "%<@synthesize%> requires the @interface of the class to be available");
9411 /* Now, iterate over the properties and do each of them. */
9412 for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
9414 objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain),
9415 TREE_PURPOSE (chain));
9419 /* This function is a sub-routine of objc_add_dynamic_declaration. It
9420 is called for each property to mark as dynamic once we have
9421 determined that the context is Ok. */
9423 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
9426 /* Find the @property declaration. */
9429 /* Check that synthesize or dynamic has not already been used for
9430 the same property. */
9431 for (property = CLASS_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
9432 if (PROPERTY_NAME (property) == property_name)
9434 location_t original_location = DECL_SOURCE_LOCATION (property);
9436 if (PROPERTY_DYNAMIC (property))
9437 error_at (location, "property %qs already specified in %<@dynamic%>",
9438 IDENTIFIER_POINTER (property_name));
9440 error_at (location, "property %qs already specified in %<@synthesize%>",
9441 IDENTIFIER_POINTER (property_name));
9443 if (original_location != UNKNOWN_LOCATION)
9444 inform (original_location, "originally specified here");
9448 /* Check that the property is declared in the interface. */
9449 /* TODO: This only check the immediate class; we need to check the
9450 superclass (and categories ?) as well. */
9451 for (property = CLASS_PROPERTY_DECL (interface); property; property = TREE_CHAIN (property))
9452 if (PROPERTY_NAME (property) == property_name)
9457 error_at (location, "no declaration of property %qs found in the interface",
9458 IDENTIFIER_POINTER (property_name));
9463 /* Mark the original PROPERTY_DECL as dynamic. The reason is
9464 that the setter and getter methods in the interface have a
9465 METHOD_PROPERTY_CONTEXT that points to the original
9466 PROPERTY_DECL; when we check that these methods have been
9467 implemented, we need to easily find that they are associated
9468 with a dynamic property. TODO: Clean this up; maybe the
9469 @property PROPERTY_DECL should contain a reference to the
9470 @dynamic PROPERTY_DECL ? */
9471 PROPERTY_DYNAMIC (property) = 1;
9473 /* We have to copy the property, because we want to chain it to
9474 the implementation context, and we want to store the source
9475 location of the @synthesize, not of the original
9477 property = copy_node (property);
9478 DECL_SOURCE_LOCATION (property) = location;
9481 /* Note that a @dynamic (and only a @dynamic) always sets
9482 PROPERTY_DYNAMIC to 1. You can recognize a @dynamic by that.
9483 (actually, as explained above, PROPERTY_DECL generated by
9484 @property and associated with a @dynamic property are also marked
9485 as PROPERTY_DYNAMIC). */
9486 PROPERTY_DYNAMIC (property) = 1;
9488 /* Add the property to the list of properties for current implementation. */
9489 TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
9490 IMPL_PROPERTY_DECL (objc_implementation_context) = property;
9493 /* This function is called by the parser after a @dynamic expression
9494 is parsed. 'location' is the location of the @dynamic expression,
9495 and 'property_list' is a chained list of all the property
9498 objc_add_dynamic_declaration (location_t location, tree property_list)
9500 tree interface, chain;
9502 if (flag_objc1_only)
9503 error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
9505 if (property_list == error_mark_node)
9508 if (!objc_implementation_context)
9510 /* We can get here only in Objective-C; the Objective-C++ parser
9511 detects the problem while parsing, outputs the error
9512 "misplaced '@dynamic' Objective-C++ construct" and skips the
9514 error_at (location, "%<@dynamic%> not in @implementation context");
9518 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
9520 /* TODO: Maybe we should allow @dynamic in categories ? */
9521 error_at (location, "%<@dynamic%> can not be used in categories");
9525 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
9528 /* I can't see how this could happen, but it is good as a safety check. */
9530 "%<@dynamic%> requires the @interface of the class to be available");
9534 /* Now, iterate over the properties and do each of them. */
9535 for (chain = property_list; chain; chain = TREE_CHAIN (chain))
9537 objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
9541 /* Main routine to generate code/data for all the property information for
9542 current implementation (class or category). CLASS is the interface where
9543 ivars are declared. CLASS_METHODS is where methods are found which
9544 could be a class or a category depending on whether we are implementing
9545 property of a class or a category. */
9548 objc_gen_property_data (tree klass, tree class_methods)
9552 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
9554 /* @dynamic property - nothing to check or synthesize. */
9555 if (PROPERTY_DYNAMIC (x))
9558 /* @synthesize property - need to synthesize the accessors. */
9559 if (PROPERTY_IVAR_NAME (x))
9561 objc_synthesize_getter (klass, class_methods, x);
9563 if (PROPERTY_READONLY (x) == 0)
9564 objc_synthesize_setter (klass, class_methods, x);
9573 /* This is called once we see the "@end" in an interface/implementation. */
9576 finish_class (tree klass)
9578 switch (TREE_CODE (klass))
9580 case CLASS_IMPLEMENTATION_TYPE:
9582 /* All code generation is done in finish_objc. */
9584 /* Generate what needed for property; setters, getters, etc. */
9585 objc_gen_property_data (implementation_template, implementation_template);
9587 if (implementation_template != objc_implementation_context)
9589 /* Ensure that all method listed in the interface contain bodies. */
9590 check_methods (CLASS_CLS_METHODS (implementation_template),
9591 CLASS_CLS_METHODS (objc_implementation_context), '+');
9592 check_methods (CLASS_NST_METHODS (implementation_template),
9593 CLASS_NST_METHODS (objc_implementation_context), '-');
9595 if (CLASS_PROTOCOL_LIST (implementation_template))
9596 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
9598 CLASS_NAME (objc_implementation_context));
9602 case CATEGORY_IMPLEMENTATION_TYPE:
9604 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
9608 /* Generate what needed for property; setters, getters, etc. */
9609 objc_gen_property_data (implementation_template, category);
9611 /* Ensure all method listed in the interface contain bodies. */
9612 check_methods (CLASS_CLS_METHODS (category),
9613 CLASS_CLS_METHODS (objc_implementation_context), '+');
9614 check_methods (CLASS_NST_METHODS (category),
9615 CLASS_NST_METHODS (objc_implementation_context), '-');
9617 if (CLASS_PROTOCOL_LIST (category))
9618 check_protocols (CLASS_PROTOCOL_LIST (category),
9620 CLASS_SUPER_NAME (objc_implementation_context));
9624 case CLASS_INTERFACE_TYPE:
9625 case CATEGORY_INTERFACE_TYPE:
9626 case PROTOCOL_INTERFACE_TYPE:
9628 /* Process properties of the class. */
9630 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
9632 /* Store the getter name that we used into the property.
9633 It is used to generate the right getter calls;
9634 moreover, when a @synthesize is processed, it copies
9635 everything from the property, including the
9636 PROPERTY_GETTER_NAME. We want to be sure that
9637 @synthesize will get exactly the right
9638 PROPERTY_GETTER_NAME. */
9639 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
9640 PROPERTY_GETTER_NAME (x) = PROPERTY_NAME (x);
9642 /* Now we check that the appropriate getter is declared,
9643 and if not, we declare one ourselves. */
9645 tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
9646 PROPERTY_GETTER_NAME (x));
9650 /* TODO: Check that the declaration is consistent with the property. */
9655 /* Generate an instance method declaration for the
9656 getter; for example "- (id) name;". In general
9657 it will be of the form
9658 -(type)property_getter_name; */
9659 tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
9660 getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
9661 rettype, PROPERTY_GETTER_NAME (x),
9663 objc_add_method (objc_interface_context, getter_decl, false, false);
9664 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
9668 if (PROPERTY_READONLY (x) == 0)
9670 /* Store the setter name that we used into the
9671 property. It is used when generating setter calls;
9672 moreover, when a @synthesize is processed, it
9673 copies everything from the property, including the
9674 PROPERTY_SETTER_NAME. We want to be sure that
9675 @synthesize will get exactly the right
9676 PROPERTY_SETTER_NAME. */
9677 if (PROPERTY_SETTER_NAME (x) == NULL_TREE)
9678 PROPERTY_SETTER_NAME (x) = get_identifier (objc_build_property_setter_name
9679 (PROPERTY_NAME (x)));
9681 /* Now we check that the appropriate setter is declared,
9682 and if not, we declare on ourselves. */
9684 tree setter_decl = lookup_method (CLASS_NST_METHODS (klass),
9685 PROPERTY_SETTER_NAME (x));
9689 /* TODO: Check that the declaration is consistent with the property. */
9694 /* The setter name is something like 'setName:'.
9695 We need the substring 'setName' to build the
9696 method declaration due to how the declaration
9697 works. TODO: build_method_decl() will then
9698 generate back 'setName:' from 'setName'; it
9699 would be more efficient to hook into
9701 const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
9702 size_t length = strlen (full_setter_name);
9703 char *setter_name = (char *) alloca (length);
9704 tree ret_type, selector, arg_type, arg_name;
9706 strcpy (setter_name, full_setter_name);
9707 setter_name[length - 1] = '\0';
9708 ret_type = build_tree_list (NULL_TREE, void_type_node);
9709 arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
9710 arg_name = get_identifier ("_value");
9711 selector = objc_build_keyword_decl (get_identifier (setter_name),
9712 arg_type, arg_name, NULL);
9713 setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
9715 build_tree_list (NULL_TREE, NULL_TREE),
9717 objc_add_method (objc_interface_context, setter_decl, false, false);
9718 METHOD_PROPERTY_CONTEXT (setter_decl) = x;
9722 /* Note how at this point (once an @interface or @protocol
9723 have been processed), PROPERTY_GETTER_NAME is always
9724 set for all PROPERTY_DECLs, and PROPERTY_SETTER_NAME is
9725 always set for all PROPERTY_DECLs where
9726 PROPERTY_READONLY == 0. Any time we deal with a getter
9727 or setter, we should get the PROPERTY_DECL and use
9728 PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know
9729 the correct names. */
9741 add_protocol (tree protocol)
9743 /* Put protocol on list in reverse order. */
9744 TREE_CHAIN (protocol) = protocol_chain;
9745 protocol_chain = protocol;
9746 return protocol_chain;
9750 lookup_protocol (tree ident)
9754 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
9755 if (ident == PROTOCOL_NAME (chain))
9761 /* This function forward declares the protocols named by NAMES. If
9762 they are already declared or defined, the function has no effect. */
9765 objc_declare_protocols (tree names)
9770 if (current_namespace != global_namespace) {
9771 error ("Objective-C declarations may only appear in global scope");
9773 #endif /* OBJCPLUS */
9775 for (list = names; list; list = TREE_CHAIN (list))
9777 tree name = TREE_VALUE (list);
9779 if (lookup_protocol (name) == NULL_TREE)
9781 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
9783 TYPE_LANG_SLOT_1 (protocol)
9784 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9785 PROTOCOL_NAME (protocol) = name;
9786 PROTOCOL_LIST (protocol) = NULL_TREE;
9787 add_protocol (protocol);
9788 PROTOCOL_DEFINED (protocol) = 0;
9789 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9795 start_protocol (enum tree_code code, tree name, tree list)
9800 if (current_namespace != global_namespace) {
9801 error ("Objective-C declarations may only appear in global scope");
9803 #endif /* OBJCPLUS */
9805 protocol = lookup_protocol (name);
9809 protocol = make_node (code);
9810 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9812 PROTOCOL_NAME (protocol) = name;
9813 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9814 add_protocol (protocol);
9815 PROTOCOL_DEFINED (protocol) = 1;
9816 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9818 check_protocol_recursively (protocol, list);
9820 else if (! PROTOCOL_DEFINED (protocol))
9822 PROTOCOL_DEFINED (protocol) = 1;
9823 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9825 check_protocol_recursively (protocol, list);
9829 warning (0, "duplicate declaration for protocol %qE",
9836 /* "Encode" a data type into a string, which grows in util_obstack.
9838 The format is described in gcc/doc/objc.texi, section 'Type
9841 Most of the encode_xxx functions have a 'type' argument, which is
9842 the type to encode, and an integer 'curtype' argument, which is the
9843 index in the encoding string of the beginning of the encoding of
9844 the current type, and allows you to find what characters have
9845 already been written for the current type (they are the ones in the
9846 current encoding string starting from 'curtype').
9848 For example, if we are encoding a method which returns 'int' and
9849 takes a 'char **' argument, then when we get to the point of
9850 encoding the 'char **' argument, the encoded string already
9851 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9852 'curtype' will be set to 7 when starting to encode 'char **'.
9853 During the whole of the encoding of 'char **', 'curtype' will be
9854 fixed at 7, so the routine encoding the second pointer can find out
9855 that it's actually encoding a pointer to a pointer by looking
9856 backwards at what has already been encoded for the current type,
9857 and seeing there is a "^" (meaning a pointer) in there.
9861 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9862 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9863 'const', instead, is encoded directly as part of the type.
9867 encode_type_qualifiers (tree declspecs)
9871 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
9873 /* FIXME: Shouldn't we use token->keyword here ? */
9874 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
9875 obstack_1grow (&util_obstack, 'n');
9876 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
9877 obstack_1grow (&util_obstack, 'N');
9878 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
9879 obstack_1grow (&util_obstack, 'o');
9880 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
9881 obstack_1grow (&util_obstack, 'O');
9882 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
9883 obstack_1grow (&util_obstack, 'R');
9884 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
9885 obstack_1grow (&util_obstack, 'V');
9891 /* Determine if a pointee is marked read-only. Only used by the NeXT
9892 runtime to be compatible with gcc-3.3. */
9895 pointee_is_readonly (tree pointee)
9897 while (POINTER_TYPE_P (pointee))
9898 pointee = TREE_TYPE (pointee);
9900 return TYPE_READONLY (pointee);
9903 /* Encode a pointer type. */
9906 encode_pointer (tree type, int curtype, int format)
9908 tree pointer_to = TREE_TYPE (type);
9910 if (flag_next_runtime)
9912 /* This code is used to be compatible with gcc-3.3. */
9913 /* For historical/compatibility reasons, the read-only qualifier
9914 of the pointee gets emitted _before_ the '^'. The read-only
9915 qualifier of the pointer itself gets ignored, _unless_ we are
9916 looking at a typedef! Also, do not emit the 'r' for anything
9917 but the outermost type! */
9918 if (!generating_instance_variables
9919 && (obstack_object_size (&util_obstack) - curtype <= 1)
9920 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
9921 ? TYPE_READONLY (type)
9922 : pointee_is_readonly (pointer_to)))
9923 obstack_1grow (&util_obstack, 'r');
9926 if (TREE_CODE (pointer_to) == RECORD_TYPE)
9928 if (OBJC_TYPE_NAME (pointer_to)
9929 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
9931 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
9933 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
9935 obstack_1grow (&util_obstack, '@');
9938 else if (TYPE_HAS_OBJC_INFO (pointer_to)
9939 && TYPE_OBJC_INTERFACE (pointer_to))
9941 if (generating_instance_variables)
9943 obstack_1grow (&util_obstack, '@');
9944 obstack_1grow (&util_obstack, '"');
9945 obstack_grow (&util_obstack, name, strlen (name));
9946 obstack_1grow (&util_obstack, '"');
9951 obstack_1grow (&util_obstack, '@');
9955 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
9957 obstack_1grow (&util_obstack, '#');
9960 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
9962 obstack_1grow (&util_obstack, ':');
9967 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
9968 && TYPE_MODE (pointer_to) == QImode)
9970 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
9971 ? OBJC_TYPE_NAME (pointer_to)
9972 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
9974 /* (BOOL *) are an exception and are encoded as ^c, while all
9975 other pointers to char are encoded as *. */
9976 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
9978 if (!flag_next_runtime)
9980 /* The NeXT runtime adds the 'r' before getting here. */
9982 /* It appears that "r*" means "const char *" rather than
9983 "char *const". "char *const" is encoded as "*",
9984 which is identical to "char *", so the "const" is
9985 unfortunately lost. */
9986 if (TYPE_READONLY (pointer_to))
9987 obstack_1grow (&util_obstack, 'r');
9990 obstack_1grow (&util_obstack, '*');
9995 /* We have a normal pointer type that does not get special treatment. */
9996 obstack_1grow (&util_obstack, '^');
9997 encode_type (pointer_to, curtype, format);
10001 encode_array (tree type, int curtype, int format)
10003 tree an_int_cst = TYPE_SIZE (type);
10004 tree array_of = TREE_TYPE (type);
10007 if (an_int_cst == NULL)
10009 /* We are trying to encode an incomplete array. An incomplete
10010 array is forbidden as part of an instance variable. */
10011 if (generating_instance_variables)
10013 /* TODO: Detect this error earlier. */
10014 error ("instance variable has unknown size");
10018 /* So the only case in which an incomplete array could occur is
10019 if we are encoding the arguments or return value of a method.
10020 In that case, an incomplete array argument or return value
10021 (eg, -(void)display: (char[])string) is treated like a
10022 pointer because that is how the compiler does the function
10023 call. A special, more complicated case, is when the
10024 incomplete array is the last member of a struct (eg, if we
10025 are encoding "struct { unsigned long int a;double b[];}"),
10026 which is again part of a method argument/return value. In
10027 that case, we really need to communicate to the runtime that
10028 there is an incomplete array (not a pointer!) there. So, we
10029 detect that special case and encode it as a zero-length
10032 Try to detect that we are part of a struct. We do this by
10033 searching for '=' in the type encoding for the current type.
10034 NB: This hack assumes that you can't use '=' as part of a C
10038 char *enc = obstack_base (&util_obstack) + curtype;
10039 if (memchr (enc, '=',
10040 obstack_object_size (&util_obstack) - curtype) == NULL)
10042 /* We are not inside a struct. Encode the array as a
10044 encode_pointer (type, curtype, format);
10049 /* Else, we are in a struct, and we encode it as a zero-length
10051 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10053 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
10054 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10056 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
10057 TREE_INT_CST_LOW (an_int_cst)
10058 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
10060 obstack_grow (&util_obstack, buffer, strlen (buffer));
10061 encode_type (array_of, curtype, format);
10062 obstack_1grow (&util_obstack, ']');
10066 /* Encode a vector. The vector type is a GCC extension to C. */
10068 encode_vector (tree type, int curtype, int format)
10070 tree vector_of = TREE_TYPE (type);
10073 /* Vectors are like simple fixed-size arrays. */
10075 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
10076 alignment of the vector, and <code> is the base type. Eg, int
10077 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
10078 assuming that the alignment is 32 bytes. We include size and
10079 alignment in bytes so that the runtime does not have to have any
10080 knowledge of the actual types.
10082 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
10083 /* We want to compute the equivalent of sizeof (<vector>).
10084 Code inspired by c_sizeof_or_alignof_type. */
10085 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
10086 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
10087 /* We want to compute the equivalent of __alignof__
10088 (<vector>). Code inspired by
10089 c_sizeof_or_alignof_type. */
10090 TYPE_ALIGN_UNIT (type));
10091 obstack_grow (&util_obstack, buffer, strlen (buffer));
10092 encode_type (vector_of, curtype, format);
10093 obstack_1grow (&util_obstack, ']');
10098 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
10100 tree field = TYPE_FIELDS (type);
10102 for (; field; field = DECL_CHAIN (field))
10105 /* C++ static members, and things that are not field at all,
10106 should not appear in the encoding. */
10107 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
10111 /* Recursively encode fields of embedded base classes. */
10112 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
10113 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
10115 encode_aggregate_fields (TREE_TYPE (field),
10116 pointed_to, curtype, format);
10120 if (generating_instance_variables && !pointed_to)
10122 tree fname = DECL_NAME (field);
10124 obstack_1grow (&util_obstack, '"');
10126 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
10127 obstack_grow (&util_obstack,
10128 IDENTIFIER_POINTER (fname),
10129 strlen (IDENTIFIER_POINTER (fname)));
10131 obstack_1grow (&util_obstack, '"');
10134 encode_field_decl (field, curtype, format);
10139 encode_aggregate_within (tree type, int curtype, int format, int left,
10143 /* NB: aggregates that are pointed to have slightly different encoding
10144 rules in that you never encode the names of instance variables. */
10145 int ob_size = obstack_object_size (&util_obstack);
10146 bool inline_contents = false;
10147 bool pointed_to = false;
10149 if (flag_next_runtime)
10151 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
10154 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10155 && (!pointed_to || ob_size - curtype == 1
10156 || (ob_size - curtype == 2
10157 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
10158 inline_contents = true;
10162 /* c0 and c1 are the last two characters in the encoding of the
10163 current type; if the last two characters were '^' or '^r',
10164 then we are encoding an aggregate that is "pointed to". The
10165 comment above applies: in that case we should avoid encoding
10166 the names of instance variables.
10168 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
10169 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
10171 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
10174 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10177 inline_contents = true;
10180 /* Note that the check (ob_size - curtype < 2) prevents
10181 infinite recursion when encoding a structure which is
10182 a linked list (eg, struct node { struct node *next;
10183 }). Each time we follow a pointer, we add one
10184 character to ob_size, and curtype is fixed, so after
10185 at most two pointers we stop inlining contents and
10188 The other case where we don't inline is "^r", which
10189 is a pointer to a constant struct.
10191 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
10192 inline_contents = true;
10197 /* Traverse struct aliases; it is important to get the
10198 original struct and its tag name (if any). */
10199 type = TYPE_MAIN_VARIANT (type);
10200 name = OBJC_TYPE_NAME (type);
10201 /* Open parenth/bracket. */
10202 obstack_1grow (&util_obstack, left);
10204 /* Encode the struct/union tag name, or '?' if a tag was
10205 not provided. Typedef aliases do not qualify. */
10207 /* For compatibility with the NeXT runtime, ObjC++ encodes template
10208 args as a composite struct tag name. */
10209 if (name && TREE_CODE (name) == IDENTIFIER_NODE
10210 /* Did this struct have a tag? */
10211 && !TYPE_WAS_ANONYMOUS (type))
10212 obstack_grow (&util_obstack,
10213 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
10214 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
10216 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
10217 obstack_grow (&util_obstack,
10218 IDENTIFIER_POINTER (name),
10219 strlen (IDENTIFIER_POINTER (name)));
10222 obstack_1grow (&util_obstack, '?');
10224 /* Encode the types (and possibly names) of the inner fields,
10226 if (inline_contents)
10228 obstack_1grow (&util_obstack, '=');
10229 encode_aggregate_fields (type, pointed_to, curtype, format);
10231 /* Close parenth/bracket. */
10232 obstack_1grow (&util_obstack, right);
10235 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
10239 encode_next_bitfield (int width)
10242 sprintf (buffer, "b%d", width);
10243 obstack_grow (&util_obstack, buffer, strlen (buffer));
10247 /* Encodes 'type', ignoring type qualifiers (which you should encode
10248 beforehand if needed) with the exception of 'const', which is
10249 encoded by encode_type. See above for the explanation of
10250 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
10251 OBJC_ENCODE_DONT_INLINE_DEFS.
10254 encode_type (tree type, int curtype, int format)
10256 enum tree_code code = TREE_CODE (type);
10258 /* Ignore type qualifiers other than 'const' when encoding a
10261 if (type == error_mark_node)
10264 if (!flag_next_runtime)
10266 if (TYPE_READONLY (type))
10267 obstack_1grow (&util_obstack, 'r');
10272 case ENUMERAL_TYPE:
10273 if (flag_next_runtime)
10275 /* Kludge for backwards-compatibility with gcc-3.3: enums
10276 are always encoded as 'i' no matter what type they
10277 actually are (!). */
10278 obstack_1grow (&util_obstack, 'i');
10281 /* Else, they are encoded exactly like the integer type that is
10282 used by the compiler to store them. */
10286 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10288 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
10289 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
10292 tree int_type = type;
10293 if (flag_next_runtime)
10295 /* Another legacy kludge for compatiblity with
10296 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
10297 but not always. For typedefs, we need to use 'i'
10298 or 'I' instead if encoding a struct field, or a
10300 int_type = ((!generating_instance_variables
10301 && (obstack_object_size (&util_obstack)
10302 == (unsigned) curtype))
10303 ? TYPE_MAIN_VARIANT (type)
10306 if (int_type == long_unsigned_type_node
10307 || int_type == long_integer_type_node)
10308 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
10310 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
10313 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
10314 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
10315 default: gcc_unreachable ();
10317 obstack_1grow (&util_obstack, c);
10323 /* Floating point types. */
10324 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10326 case 32: c = 'f'; break;
10327 case 64: c = 'd'; break;
10329 case 128: c = 'D'; break;
10330 default: gcc_unreachable ();
10332 obstack_1grow (&util_obstack, c);
10336 obstack_1grow (&util_obstack, 'v');
10340 obstack_1grow (&util_obstack, 'B');
10344 encode_array (type, curtype, format);
10349 case REFERENCE_TYPE:
10351 encode_pointer (type, curtype, format);
10355 encode_aggregate_within (type, curtype, format, '{', '}');
10359 encode_aggregate_within (type, curtype, format, '(', ')');
10362 case FUNCTION_TYPE: /* '?' means an unknown type. */
10363 obstack_1grow (&util_obstack, '?');
10367 /* A complex is encoded as 'j' followed by the inner type (eg,
10368 "_Complex int" is encoded as 'ji'). */
10369 obstack_1grow (&util_obstack, 'j');
10370 encode_type (TREE_TYPE (type), curtype, format);
10374 encode_vector (type, curtype, format);
10378 warning (0, "unknown type %s found during Objective-C encoding",
10379 gen_type_name (type));
10380 obstack_1grow (&util_obstack, '?');
10384 if (flag_next_runtime)
10386 /* Super-kludge. Some ObjC qualifier and type combinations need
10387 to be rearranged for compatibility with gcc-3.3. */
10388 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
10390 char *enc = obstack_base (&util_obstack) + curtype;
10392 /* Rewrite "in const" from "nr" to "rn". */
10393 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
10394 strncpy (enc - 1, "rn", 2);
10400 encode_gnu_bitfield (int position, tree type, int size)
10402 enum tree_code code = TREE_CODE (type);
10404 char charType = '?';
10406 /* This code is only executed for the GNU runtime, so we can ignore
10407 the NeXT runtime kludge of always encoding enums as 'i' no matter
10408 what integers they actually are. */
10409 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
10411 if (integer_zerop (TYPE_MIN_VALUE (type)))
10412 /* Unsigned integer types. */
10414 switch (TYPE_MODE (type))
10417 charType = 'C'; break;
10419 charType = 'S'; break;
10422 if (type == long_unsigned_type_node)
10429 charType = 'Q'; break;
10431 gcc_unreachable ();
10435 /* Signed integer types. */
10437 switch (TYPE_MODE (type))
10440 charType = 'c'; break;
10442 charType = 's'; break;
10445 if (type == long_integer_type_node)
10452 charType = 'q'; break;
10454 gcc_unreachable ();
10460 /* Do not do any encoding, produce an error and keep going. */
10461 error ("trying to encode non-integer type as a bitfield");
10465 sprintf (buffer, "b%d%c%d", position, charType, size);
10466 obstack_grow (&util_obstack, buffer, strlen (buffer));
10470 encode_field_decl (tree field_decl, int curtype, int format)
10473 /* C++ static members, and things that are not fields at all,
10474 should not appear in the encoding. */
10475 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
10479 /* Generate the bitfield typing information, if needed. Note the difference
10480 between GNU and NeXT runtimes. */
10481 if (DECL_BIT_FIELD_TYPE (field_decl))
10483 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
10485 if (flag_next_runtime)
10486 encode_next_bitfield (size);
10488 encode_gnu_bitfield (int_bit_position (field_decl),
10489 DECL_BIT_FIELD_TYPE (field_decl), size);
10492 encode_type (TREE_TYPE (field_decl), curtype, format);
10495 /* Decay array and function parameters into pointers. */
10498 objc_decay_parm_type (tree type)
10500 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
10501 type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
10508 static GTY(()) tree objc_parmlist = NULL_TREE;
10510 /* Append PARM to a list of formal parameters of a method, making a necessary
10511 array-to-pointer adjustment along the way. */
10514 objc_push_parm (tree parm)
10518 if (TREE_TYPE (parm) == error_mark_node)
10520 objc_parmlist = chainon (objc_parmlist, parm);
10524 /* Decay arrays and functions into pointers. */
10525 type = objc_decay_parm_type (TREE_TYPE (parm));
10527 /* If the parameter type has been decayed, a new PARM_DECL needs to be
10529 if (type != TREE_TYPE (parm))
10530 parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
10532 DECL_ARG_TYPE (parm)
10533 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
10535 /* Record constancy and volatility. */
10536 c_apply_type_quals_to_decl
10537 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
10538 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
10539 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
10541 objc_parmlist = chainon (objc_parmlist, parm);
10544 /* Retrieve the formal parameter list constructed via preceding calls to
10545 objc_push_parm(). */
10549 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
10551 static struct c_arg_info *
10552 objc_get_parm_info (int have_ellipsis)
10556 tree parm_info = objc_parmlist;
10557 objc_parmlist = NULL_TREE;
10561 tree parm_info = objc_parmlist;
10562 struct c_arg_info *arg_info;
10563 /* The C front-end requires an elaborate song and dance at
10566 declare_parm_level ();
10569 tree next = DECL_CHAIN (parm_info);
10571 DECL_CHAIN (parm_info) = NULL_TREE;
10572 parm_info = pushdecl (parm_info);
10573 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
10576 arg_info = get_parm_info (have_ellipsis);
10578 objc_parmlist = NULL_TREE;
10583 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
10584 method definitions. In the case of instance methods, we can be more
10585 specific as to the type of 'self'. */
10588 synth_self_and_ucmd_args (void)
10592 if (objc_method_context
10593 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
10594 self_type = objc_instance_type;
10596 /* Really a `struct objc_class *'. However, we allow people to
10597 assign to self, which changes its type midstream. */
10598 self_type = objc_object_type;
10601 objc_push_parm (build_decl (input_location,
10602 PARM_DECL, self_id, self_type));
10605 objc_push_parm (build_decl (input_location,
10606 PARM_DECL, ucmd_id, objc_selector_type));
10609 /* Transform an Objective-C method definition into a static C function
10610 definition, synthesizing the first two arguments, "self" and "_cmd",
10614 start_method_def (tree method)
10620 struct c_arg_info *parm_info;
10622 int have_ellipsis = 0;
10624 /* If we are defining a "dealloc" method in a non-root class, we
10625 will need to check if a [super dealloc] is missing, and warn if
10627 if(CLASS_SUPER_NAME (objc_implementation_context)
10628 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
10629 should_call_super_dealloc = 1;
10631 should_call_super_dealloc = 0;
10633 /* Required to implement _msgSuper. */
10634 objc_method_context = method;
10635 UOBJC_SUPER_decl = NULL_TREE;
10637 /* Generate prototype declarations for arguments..."new-style". */
10638 synth_self_and_ucmd_args ();
10640 /* Generate argument declarations if a keyword_decl. */
10641 parmlist = METHOD_SEL_ARGS (method);
10644 /* parmlist is a KEYWORD_DECL. */
10645 tree type = TREE_VALUE (TREE_TYPE (parmlist));
10648 parm = build_decl (input_location,
10649 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
10650 decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
10651 objc_push_parm (parm);
10652 parmlist = DECL_CHAIN (parmlist);
10655 if (METHOD_ADD_ARGS (method))
10659 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
10660 akey; akey = TREE_CHAIN (akey))
10662 objc_push_parm (TREE_VALUE (akey));
10665 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
10669 parm_info = objc_get_parm_info (have_ellipsis);
10671 really_start_method (objc_method_context, parm_info);
10674 /* Return 1 if TYPE1 is equivalent to TYPE2
10675 for purposes of method overloading. */
10678 objc_types_are_equivalent (tree type1, tree type2)
10680 if (type1 == type2)
10683 /* Strip away indirections. */
10684 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
10685 && (TREE_CODE (type1) == TREE_CODE (type2)))
10686 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
10687 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
10690 type1 = (TYPE_HAS_OBJC_INFO (type1)
10691 ? TYPE_OBJC_PROTOCOL_LIST (type1)
10693 type2 = (TYPE_HAS_OBJC_INFO (type2)
10694 ? TYPE_OBJC_PROTOCOL_LIST (type2)
10697 if (list_length (type1) == list_length (type2))
10699 for (; type2; type2 = TREE_CHAIN (type2))
10700 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
10707 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
10710 objc_types_share_size_and_alignment (tree type1, tree type2)
10712 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
10713 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
10716 /* Return 1 if PROTO1 is equivalent to PROTO2
10717 for purposes of method overloading. Ordinarily, the type signatures
10718 should match up exactly, unless STRICT is zero, in which case we
10719 shall allow differences in which the size and alignment of a type
10723 comp_proto_with_proto (tree proto1, tree proto2, int strict)
10725 /* The following test is needed in case there are hashing
10727 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
10730 return match_proto_with_proto (proto1, proto2, strict);
10734 match_proto_with_proto (tree proto1, tree proto2, int strict)
10738 /* Compare return types. */
10739 type1 = TREE_VALUE (TREE_TYPE (proto1));
10740 type2 = TREE_VALUE (TREE_TYPE (proto2));
10742 if (!objc_types_are_equivalent (type1, type2)
10743 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
10746 /* Compare argument types. */
10747 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
10748 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
10750 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
10752 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
10754 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
10755 TREE_VALUE (type2))))
10759 return (!type1 && !type2);
10762 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
10763 this occurs. ObjC method dispatches are _not_ like C++ virtual
10764 member function dispatches, and we account for the difference here. */
10767 objc_fold_obj_type_ref (tree ref, tree known_type)
10769 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
10770 tree known_type ATTRIBUTE_UNUSED)
10774 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
10776 /* If the receiver does not have virtual member functions, there
10777 is nothing we can (or need to) do here. */
10781 /* Let C++ handle C++ virtual functions. */
10782 return cp_fold_obj_type_ref (ref, known_type);
10784 /* For plain ObjC, we currently do not need to do anything. */
10790 objc_start_function (tree name, tree type, tree attrs,
10794 struct c_arg_info *params
10798 tree fndecl = build_decl (input_location,
10799 FUNCTION_DECL, name, type);
10802 DECL_ARGUMENTS (fndecl) = params;
10803 DECL_INITIAL (fndecl) = error_mark_node;
10804 DECL_EXTERNAL (fndecl) = 0;
10805 TREE_STATIC (fndecl) = 1;
10806 retrofit_lang_decl (fndecl);
10807 cplus_decl_attributes (&fndecl, attrs, 0);
10808 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
10810 current_function_returns_value = 0; /* Assume, until we see it does. */
10811 current_function_returns_null = 0;
10812 decl_attributes (&fndecl, attrs, 0);
10813 announce_function (fndecl);
10814 DECL_INITIAL (fndecl) = error_mark_node;
10815 DECL_EXTERNAL (fndecl) = 0;
10816 TREE_STATIC (fndecl) = 1;
10817 current_function_decl = pushdecl (fndecl);
10819 declare_parm_level ();
10820 DECL_RESULT (current_function_decl)
10821 = build_decl (input_location,
10822 RESULT_DECL, NULL_TREE,
10823 TREE_TYPE (TREE_TYPE (current_function_decl)));
10824 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
10825 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
10826 start_fname_decls ();
10827 store_parm_decls_from (params);
10830 TREE_USED (current_function_decl) = 1;
10833 /* - Generate an identifier for the function. the format is "_n_cls",
10834 where 1 <= n <= nMethods, and cls is the name the implementation we
10836 - Install the return type from the method declaration.
10837 - If we have a prototype, check for type consistency. */
10840 really_start_method (tree method,
10844 struct c_arg_info *parmlist
10848 tree ret_type, meth_type;
10850 const char *sel_name, *class_name, *cat_name;
10853 /* Synth the storage class & assemble the return type. */
10854 ret_type = TREE_VALUE (TREE_TYPE (method));
10856 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
10857 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
10858 cat_name = ((TREE_CODE (objc_implementation_context)
10859 == CLASS_IMPLEMENTATION_TYPE)
10861 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
10864 /* Make sure this is big enough for any plausible method label. */
10865 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
10866 + (cat_name ? strlen (cat_name) : 0));
10868 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
10869 class_name, cat_name, sel_name, method_slot);
10871 method_id = get_identifier (buf);
10874 /* Objective-C methods cannot be overloaded, so we don't need
10875 the type encoding appended. It looks bad anyway... */
10876 push_lang_context (lang_name_c);
10880 = build_function_type (ret_type,
10881 get_arg_type_list (method, METHOD_DEF, 0));
10882 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
10884 /* Set self_decl from the first argument. */
10885 self_decl = DECL_ARGUMENTS (current_function_decl);
10887 /* Suppress unused warnings. */
10888 TREE_USED (self_decl) = 1;
10889 DECL_READ_P (self_decl) = 1;
10890 TREE_USED (DECL_CHAIN (self_decl)) = 1;
10891 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
10893 pop_lang_context ();
10896 METHOD_DEFINITION (method) = current_function_decl;
10898 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10900 if (implementation_template != objc_implementation_context)
10903 = lookup_method_static (implementation_template,
10904 METHOD_SEL_NAME (method),
10905 ((TREE_CODE (method) == CLASS_METHOD_DECL)
10906 | OBJC_LOOKUP_NO_SUPER));
10910 if (!comp_proto_with_proto (method, proto, 1))
10912 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
10914 warning_at (DECL_SOURCE_LOCATION (method), 0,
10915 "conflicting types for %<%c%s%>",
10916 (type ? '-' : '+'),
10917 identifier_to_locale (gen_method_decl (method)));
10918 inform (DECL_SOURCE_LOCATION (proto),
10919 "previous declaration of %<%c%s%>",
10920 (type ? '-' : '+'),
10921 identifier_to_locale (gen_method_decl (proto)));
10925 /* If the method in the @interface was deprecated, mark
10926 the implemented method as deprecated too. It should
10927 never be used for messaging (when the deprecation
10928 warnings are produced), but just in case. */
10929 if (TREE_DEPRECATED (proto))
10930 TREE_DEPRECATED (method) = 1;
10932 /* If the method in the @interface was marked as
10933 'noreturn', mark the function implementing the method
10934 as 'noreturn' too. */
10935 TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
10940 /* We have a method @implementation even though we did not
10941 see a corresponding @interface declaration (which is allowed
10942 by Objective-C rules). Go ahead and place the method in
10943 the @interface anyway, so that message dispatch lookups
10945 tree interface = implementation_template;
10947 if (TREE_CODE (objc_implementation_context)
10948 == CATEGORY_IMPLEMENTATION_TYPE)
10949 interface = lookup_category
10951 CLASS_SUPER_NAME (objc_implementation_context));
10954 objc_add_method (interface, copy_node (method),
10955 TREE_CODE (method) == CLASS_METHOD_DECL,
10956 /* is_optional= */ false);
10961 static void *UOBJC_SUPER_scope = 0;
10963 /* _n_Method (id self, SEL sel, ...)
10965 struct objc_super _S;
10966 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10970 get_super_receiver (void)
10972 if (objc_method_context)
10974 tree super_expr, super_expr_list;
10976 if (!UOBJC_SUPER_decl)
10978 UOBJC_SUPER_decl = build_decl (input_location,
10979 VAR_DECL, get_identifier (TAG_SUPER),
10980 objc_super_template);
10981 /* This prevents `unused variable' warnings when compiling with -Wall. */
10982 TREE_USED (UOBJC_SUPER_decl) = 1;
10983 DECL_READ_P (UOBJC_SUPER_decl) = 1;
10984 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
10985 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
10987 UOBJC_SUPER_scope = objc_get_current_scope ();
10990 /* Set receiver to self. */
10991 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
10992 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
10993 NOP_EXPR, input_location, self_decl,
10995 super_expr_list = super_expr;
10997 /* Set class to begin searching. */
10998 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
10999 get_identifier ("super_class"));
11001 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
11003 /* [_cls, __cls]Super are "pre-built" in
11004 synth_forward_declarations. */
11006 super_expr = build_modify_expr (input_location, super_expr,
11007 NULL_TREE, NOP_EXPR,
11009 ((TREE_CODE (objc_method_context)
11010 == INSTANCE_METHOD_DECL)
11012 : uucls_super_ref),
11017 /* We have a category. */
11019 tree super_name = CLASS_SUPER_NAME (implementation_template);
11022 /* Barf if super used in a category of Object. */
11025 error ("no super class declared in interface for %qE",
11026 CLASS_NAME (implementation_template));
11027 return error_mark_node;
11030 if (flag_next_runtime && !flag_zero_link)
11032 super_class = objc_get_class_reference (super_name);
11033 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
11034 /* If we are in a class method, we must retrieve the
11035 _metaclass_ for the current class, pointed at by
11036 the class's "isa" pointer. The following assumes that
11037 "isa" is the first ivar in a class (which it must be). */
11039 = build_indirect_ref
11041 build_c_cast (input_location,
11042 build_pointer_type (objc_class_type),
11043 super_class), RO_UNARY_STAR);
11047 add_class_reference (super_name);
11048 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11049 ? objc_get_class_decl : objc_get_meta_class_decl);
11050 assemble_external (super_class);
11052 = build_function_call
11057 my_build_string_pointer
11058 (IDENTIFIER_LENGTH (super_name) + 1,
11059 IDENTIFIER_POINTER (super_name))));
11063 = build_modify_expr (input_location, super_expr, NULL_TREE,
11066 build_c_cast (input_location,
11067 TREE_TYPE (super_expr),
11072 super_expr_list = build_compound_expr (input_location,
11073 super_expr_list, super_expr);
11075 super_expr = build_unary_op (input_location,
11076 ADDR_EXPR, UOBJC_SUPER_decl, 0);
11077 super_expr_list = build_compound_expr (input_location,
11078 super_expr_list, super_expr);
11080 return super_expr_list;
11084 error ("[super ...] must appear in a method context");
11085 return error_mark_node;
11089 /* When exiting a scope, sever links to a 'super' declaration (if any)
11090 therein contained. */
11093 objc_clear_super_receiver (void)
11095 if (objc_method_context
11096 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
11097 UOBJC_SUPER_decl = 0;
11098 UOBJC_SUPER_scope = 0;
11103 objc_finish_method_definition (tree fndecl)
11105 /* We cannot validly inline ObjC methods, at least not without a language
11106 extension to declare that a method need not be dynamically
11107 dispatched, so suppress all thoughts of doing so. */
11108 DECL_UNINLINABLE (fndecl) = 1;
11111 /* The C++ front-end will have called finish_function() for us. */
11112 finish_function ();
11115 METHOD_ENCODING (objc_method_context)
11116 = encode_method_prototype (objc_method_context);
11118 /* Required to implement _msgSuper. This must be done AFTER finish_function,
11119 since the optimizer may find "may be used before set" errors. */
11120 objc_method_context = NULL_TREE;
11122 if (should_call_super_dealloc)
11123 warning (0, "method possibly missing a [super dealloc] call");
11126 /* Given a tree DECL node, produce a printable description of it in the given
11127 buffer, overwriting the buffer. */
11130 gen_declaration (tree decl)
11136 gen_type_name_0 (TREE_TYPE (decl));
11138 if (DECL_NAME (decl))
11140 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
11141 strcat (errbuf, " ");
11143 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
11146 if (DECL_INITIAL (decl)
11147 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
11148 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
11149 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
11155 /* Given a tree TYPE node, produce a printable description of it in the given
11156 buffer, overwriting the buffer. */
11159 gen_type_name_0 (tree type)
11161 tree orig = type, proto;
11163 if (TYPE_P (type) && TYPE_NAME (type))
11164 type = TYPE_NAME (type);
11165 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
11167 tree inner = TREE_TYPE (type);
11169 while (TREE_CODE (inner) == ARRAY_TYPE)
11170 inner = TREE_TYPE (inner);
11172 gen_type_name_0 (inner);
11174 if (!POINTER_TYPE_P (inner))
11175 strcat (errbuf, " ");
11177 if (POINTER_TYPE_P (type))
11178 strcat (errbuf, "*");
11180 while (type != inner)
11182 strcat (errbuf, "[");
11184 if (TYPE_DOMAIN (type))
11188 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
11190 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
11191 strcat (errbuf, sz);
11194 strcat (errbuf, "]");
11195 type = TREE_TYPE (type);
11198 goto exit_function;
11201 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
11202 type = DECL_NAME (type);
11204 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
11205 ? IDENTIFIER_POINTER (type)
11208 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
11209 if (objc_is_id (orig))
11210 orig = TREE_TYPE (orig);
11212 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
11216 strcat (errbuf, " <");
11220 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
11221 proto = TREE_CHAIN (proto);
11222 strcat (errbuf, proto ? ", " : ">");
11231 gen_type_name (tree type)
11235 return gen_type_name_0 (type);
11238 /* Given a method tree, put a printable description into the given
11239 buffer (overwriting) and return a pointer to the buffer. */
11242 gen_method_decl (tree method)
11246 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
11247 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
11248 strcat (errbuf, ")");
11249 chain = METHOD_SEL_ARGS (method);
11253 /* We have a chain of keyword_decls. */
11256 if (KEYWORD_KEY_NAME (chain))
11257 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
11259 strcat (errbuf, ":(");
11260 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
11261 strcat (errbuf, ")");
11263 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
11264 if ((chain = DECL_CHAIN (chain)))
11265 strcat (errbuf, " ");
11269 if (METHOD_ADD_ARGS (method))
11271 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
11273 /* Know we have a chain of parm_decls. */
11276 strcat (errbuf, ", ");
11277 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
11278 chain = TREE_CHAIN (chain);
11281 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11282 strcat (errbuf, ", ...");
11287 /* We have a unary selector. */
11288 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
11296 /* Dump an @interface declaration of the supplied class CHAIN to the
11297 supplied file FP. Used to implement the -gen-decls option (which
11298 prints out an @interface declaration of all classes compiled in
11299 this run); potentially useful for debugging the compiler too. */
11301 dump_interface (FILE *fp, tree chain)
11303 /* FIXME: A heap overflow here whenever a method (or ivar)
11304 declaration is so long that it doesn't fit in the buffer. The
11305 code and all the related functions should be rewritten to avoid
11306 using fixed size buffers. */
11307 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
11308 tree ivar_decls = CLASS_RAW_IVARS (chain);
11309 tree nst_methods = CLASS_NST_METHODS (chain);
11310 tree cls_methods = CLASS_CLS_METHODS (chain);
11312 fprintf (fp, "\n@interface %s", my_name);
11314 /* CLASS_SUPER_NAME is used to store the superclass name for
11315 classes, and the category name for categories. */
11316 if (CLASS_SUPER_NAME (chain))
11318 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
11320 switch (TREE_CODE (chain))
11322 case CATEGORY_IMPLEMENTATION_TYPE:
11323 case CATEGORY_INTERFACE_TYPE:
11324 fprintf (fp, " (%s)\n", name);
11327 fprintf (fp, " : %s\n", name);
11332 fprintf (fp, "\n");
11334 /* FIXME - the following doesn't seem to work at the moment. */
11337 fprintf (fp, "{\n");
11340 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
11341 ivar_decls = TREE_CHAIN (ivar_decls);
11343 while (ivar_decls);
11344 fprintf (fp, "}\n");
11347 while (nst_methods)
11349 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
11350 nst_methods = TREE_CHAIN (nst_methods);
11353 while (cls_methods)
11355 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
11356 cls_methods = TREE_CHAIN (cls_methods);
11359 fprintf (fp, "@end\n");
11363 /* Produce the pretty printing for an Objective-C method. This is
11364 currently unused, but could be handy while reorganizing the pretty
11365 printing to be more robust. */
11366 static const char *
11367 objc_pretty_print_method (bool is_class_method,
11368 const char *class_name,
11369 const char *category_name,
11370 const char *selector)
11374 char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
11375 + strlen (selector) + 7);
11377 if (is_class_method)
11378 sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
11380 sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
11386 char *result = XNEWVEC (char, strlen (class_name)
11387 + strlen (selector) + 5);
11389 if (is_class_method)
11390 sprintf (result, "+[%s %s]", class_name, selector);
11392 sprintf (result, "-[%s %s]", class_name, selector);
11399 /* Demangle function for Objective-C. Attempt to demangle the
11400 function name associated with a method (eg, going from
11401 "_i_NSObject__class" to "-[NSObject class]"); usually for the
11402 purpose of pretty printing or error messages. Return the demangled
11403 name, or NULL if the string is not an Objective-C mangled method
11406 Because of how the mangling is done, any method that has a '_' in
11407 its original name is at risk of being demangled incorrectly. In
11408 some cases there are multiple valid ways to demangle a method name
11409 and there is no way we can decide.
11411 TODO: objc_demangle() can't always get it right; the right way to
11412 get this correct for all method names would be to store the
11413 Objective-C method name somewhere in the function decl. Then,
11414 there is no demangling to do; we'd just pull the method name out of
11415 the decl. As an additional bonus, when printing error messages we
11416 could check for such a method name, and if we find it, we know the
11417 function is actually an Objective-C method and we could print error
11418 messages saying "In method '+[NSObject class]" instead of "In
11419 function '+[NSObject class]" as we do now. */
11420 static const char *
11421 objc_demangle (const char *mangled)
11423 char *demangled, *cp;
11425 if (mangled[0] == '_' &&
11426 (mangled[1] == 'i' || mangled[1] == 'c') &&
11429 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
11430 if (mangled[1] == 'i')
11431 *cp++ = '-'; /* for instance method */
11433 *cp++ = '+'; /* for class method */
11434 *cp++ = '['; /* opening left brace */
11435 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
11436 while (*cp && *cp == '_')
11437 cp++; /* skip any initial underbars in class name */
11438 cp = strchr(cp, '_'); /* find first non-initial underbar */
11441 free(demangled); /* not mangled name */
11444 if (cp[1] == '_') /* easy case: no category name */
11446 *cp++ = ' '; /* replace two '_' with one ' ' */
11447 strcpy(cp, mangled + (cp - demangled) + 2);
11451 *cp++ = '('; /* less easy case: category name */
11452 cp = strchr(cp, '_');
11455 free(demangled); /* not mangled name */
11459 *cp++ = ' '; /* overwriting 1st char of method name... */
11460 strcpy(cp, mangled + (cp - demangled)); /* get it back */
11462 /* Now we have the method name. We need to generally replace
11463 '_' with ':' but trying to preserve '_' if it could only have
11464 been in the mangled string because it was already in the
11465 original name. In cases where it's ambiguous, we assume that
11466 any '_' originated from a ':'. */
11468 /* Initial '_'s in method name can't have been generating by
11469 converting ':'s. Skip them. */
11470 while (*cp && *cp == '_')
11473 /* If the method name does not end with '_', then it has no
11474 arguments and there was no replacement of ':'s with '_'s
11475 during mangling. Check for that case, and skip any
11476 replacement if so. This at least guarantees that methods
11477 with no arguments are always demangled correctly (unless the
11478 original name ends with '_'). */
11479 if (*(mangled + strlen (mangled) - 1) != '_')
11481 /* Skip to the end. */
11487 /* Replace remaining '_' with ':'. This may get it wrong if
11488 there were '_'s in the original name. In most cases it
11489 is impossible to disambiguate. */
11494 *cp++ = ']'; /* closing right brace */
11495 *cp++ = 0; /* string terminator */
11499 return NULL; /* not an objc mangled name */
11502 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
11503 specific decl, return the printable name for it. If not, return
11506 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
11508 switch (TREE_CODE (decl))
11510 case FUNCTION_DECL:
11511 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
11514 /* The following happens when we are printing a deprecation
11515 warning for a method. The warn_deprecation() will end up
11516 trying to print the decl for INSTANCE_METHOD_DECL or
11517 CLASS_METHOD_DECL. It would be nice to be able to print
11518 "-[NSObject autorelease] is deprecated", but to do that, we'd
11519 need to store the class and method name in the method decl,
11520 which we currently don't do. For now, just return the name
11521 of the method. We don't return NULL, because that may
11522 trigger further attempts to pretty-print the decl in C/C++,
11523 but they wouldn't know how to pretty-print it. */
11524 case INSTANCE_METHOD_DECL:
11525 case CLASS_METHOD_DECL:
11526 return IDENTIFIER_POINTER (DECL_NAME (decl));
11528 /* This happens when printing a deprecation warning for a
11529 property. We may want to consider some sort of pretty
11530 printing (eg, include the class name where it was declared
11532 case PROPERTY_DECL:
11533 return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
11541 /* Return a printable name for 'decl'. This first tries
11542 objc_maybe_printable_name(), and if that fails, it returns the name
11543 in the decl. This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
11544 Objective-C; in Objective-C++, setting the hook is not enough
11545 because lots of C++ Front-End code calls cxx_printable_name,
11546 dump_decl and other C++ functions directly. So instead we have
11547 modified dump_decl to call objc_maybe_printable_name directly. */
11549 objc_printable_name (tree decl, int v)
11551 const char *demangled_name = objc_maybe_printable_name (decl, v);
11553 if (demangled_name != NULL)
11554 return demangled_name;
11556 return IDENTIFIER_POINTER (DECL_NAME (decl));
11562 gcc_obstack_init (&util_obstack);
11563 util_firstobj = (char *) obstack_finish (&util_obstack);
11565 errbuf = XNEWVEC (char, 1024 * 10);
11567 synth_module_prologue ();
11573 struct imp_entry *impent;
11575 /* The internally generated initializers appear to have missing braces.
11576 Don't warn about this. */
11577 int save_warn_missing_braces = warn_missing_braces;
11578 warn_missing_braces = 0;
11580 /* A missing @end may not be detected by the parser. */
11581 if (objc_implementation_context)
11583 warning (0, "%<@end%> missing in implementation context");
11584 finish_class (objc_implementation_context);
11585 objc_ivar_chain = NULL_TREE;
11586 objc_implementation_context = NULL_TREE;
11589 /* Process the static instances here because initialization of objc_symtab
11590 depends on them. */
11591 if (objc_static_instances)
11592 generate_static_references ();
11594 /* forward declare categories */
11596 forward_declare_categories ();
11598 for (impent = imp_list; impent; impent = impent->next)
11600 objc_implementation_context = impent->imp_context;
11601 implementation_template = impent->imp_template;
11603 /* FIXME: This needs reworking to be more obvious. */
11605 UOBJC_CLASS_decl = impent->class_decl;
11606 UOBJC_METACLASS_decl = impent->meta_decl;
11608 /* Dump the @interface of each class as we compile it, if the
11609 -gen-decls option is in use. TODO: Dump the classes in the
11610 order they were found, rather than in reverse order as we
11612 if (flag_gen_declaration)
11614 dump_interface (gen_declaration_file, objc_implementation_context);
11617 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
11619 /* all of the following reference the string pool... */
11620 generate_ivar_lists ();
11621 generate_dispatch_tables ();
11622 generate_shared_structures (impent);
11626 generate_dispatch_tables ();
11627 generate_category (impent);
11630 impent->class_decl = UOBJC_CLASS_decl;
11631 impent->meta_decl = UOBJC_METACLASS_decl;
11634 /* If we are using an array of selectors, we must always
11635 finish up the array decl even if no selectors were used. */
11636 if (flag_next_runtime)
11637 build_next_selector_translation_table ();
11639 build_gnu_selector_translation_table ();
11641 if (protocol_chain)
11642 generate_protocols ();
11644 if (flag_next_runtime)
11645 generate_objc_image_info ();
11647 if (imp_list || class_names_chain
11648 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
11649 generate_objc_symtab_decl ();
11651 /* Arrange for ObjC data structures to be initialized at run time. */
11652 if (objc_implementation_context || class_names_chain || objc_static_instances
11653 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
11655 build_module_descriptor ();
11657 if (!flag_next_runtime)
11658 build_module_initializer_routine ();
11661 /* Dump the class references. This forces the appropriate classes
11662 to be linked into the executable image, preserving unix archive
11663 semantics. This can be removed when we move to a more dynamically
11664 linked environment. */
11666 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
11668 handle_class_ref (chain);
11669 if (TREE_PURPOSE (chain))
11670 generate_classref_translation_entry (chain);
11673 for (impent = imp_list; impent; impent = impent->next)
11674 handle_impent (impent);
11681 /* Run through the selector hash tables and print a warning for any
11682 selector which has multiple methods. */
11684 for (slot = 0; slot < SIZEHASHTABLE; slot++)
11686 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
11687 check_duplicates (hsh, 0, 1);
11688 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
11689 check_duplicates (hsh, 0, 1);
11693 warn_missing_braces = save_warn_missing_braces;
11696 /* Subroutines of finish_objc. */
11699 generate_classref_translation_entry (tree chain)
11701 tree expr, decl, type;
11703 decl = TREE_PURPOSE (chain);
11704 type = TREE_TYPE (decl);
11706 expr = add_objc_string (TREE_VALUE (chain), class_names);
11707 expr = convert (type, expr); /* cast! */
11709 /* This is a class reference. It is re-written by the runtime,
11710 but will be optimized away unless we force it. */
11711 DECL_PRESERVE_P (decl) = 1;
11712 finish_var_decl (decl, expr);
11717 handle_class_ref (tree chain)
11719 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
11720 char *string = (char *) alloca (strlen (name) + 30);
11724 sprintf (string, "%sobjc_class_name_%s",
11725 (flag_next_runtime ? "." : "__"), name);
11727 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
11728 if (flag_next_runtime)
11730 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
11735 /* Make a decl for this name, so we can use its address in a tree. */
11736 decl = build_decl (input_location,
11737 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
11738 DECL_EXTERNAL (decl) = 1;
11739 TREE_PUBLIC (decl) = 1;
11741 finish_var_decl (decl, 0);
11743 /* Make a decl for the address. */
11744 sprintf (string, "%sobjc_class_ref_%s",
11745 (flag_next_runtime ? "." : "__"), name);
11746 exp = build1 (ADDR_EXPR, string_type_node, decl);
11747 decl = build_decl (input_location,
11748 VAR_DECL, get_identifier (string), string_type_node);
11749 TREE_STATIC (decl) = 1;
11750 TREE_USED (decl) = 1;
11751 DECL_READ_P (decl) = 1;
11752 DECL_ARTIFICIAL (decl) = 1;
11753 DECL_INITIAL (decl) = error_mark_node;
11755 /* We must force the reference. */
11756 DECL_PRESERVE_P (decl) = 1;
11759 finish_var_decl (decl, exp);
11763 handle_impent (struct imp_entry *impent)
11767 objc_implementation_context = impent->imp_context;
11768 implementation_template = impent->imp_template;
11770 switch (TREE_CODE (impent->imp_context))
11772 case CLASS_IMPLEMENTATION_TYPE:
11774 const char *const class_name =
11775 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
11777 string = (char *) alloca (strlen (class_name) + 30);
11779 sprintf (string, "%sobjc_class_name_%s",
11780 (flag_next_runtime ? "." : "__"), class_name);
11783 case CATEGORY_IMPLEMENTATION_TYPE:
11785 const char *const class_name =
11786 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
11787 const char *const class_super_name =
11788 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
11790 string = (char *) alloca (strlen (class_name)
11791 + strlen (class_super_name) + 30);
11793 /* Do the same for categories. Even though no references to
11794 these symbols are generated automatically by the compiler,
11795 it gives you a handle to pull them into an archive by
11797 sprintf (string, "*%sobjc_category_name_%s_%s",
11798 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
11805 #ifdef ASM_DECLARE_CLASS_REFERENCE
11806 if (flag_next_runtime)
11808 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
11816 init = integer_zero_node;
11817 decl = build_decl (input_location,
11818 VAR_DECL, get_identifier (string), TREE_TYPE (init));
11819 TREE_PUBLIC (decl) = 1;
11820 TREE_READONLY (decl) = 1;
11821 TREE_USED (decl) = 1;
11822 TREE_CONSTANT (decl) = 1;
11823 DECL_CONTEXT (decl) = NULL_TREE;
11824 DECL_ARTIFICIAL (decl) = 1;
11825 TREE_STATIC (decl) = 1;
11826 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
11827 /* We must force the reference. */
11828 DECL_PRESERVE_P (decl) = 1;
11830 finish_var_decl(decl, init) ;
11834 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
11835 later requires that ObjC translation units participating in F&C be
11836 specially marked. The following routine accomplishes this. */
11838 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
11841 generate_objc_image_info (void)
11845 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
11846 | (flag_objc_gc ? 2 : 0));
11847 VEC(constructor_elt,gc) *v = NULL;
11851 return; /* No need for an image_info entry. */
11853 array_type = build_sized_array_type (integer_type_node, 2);
11855 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
11857 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
11858 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
11859 /* If we need this (determined above) it is because the runtime wants to
11860 refer to it in a manner hidden from the compiler. So we must force the
11862 DECL_PRESERVE_P (decl) = 1;
11863 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
11866 /* Routine is called to issue diagnostic when reference to a private
11867 ivar is made and no other variable with same name is found in
11870 objc_diagnose_private_ivar (tree id)
11873 if (!objc_method_context)
11875 ivar = is_ivar (objc_ivar_chain, id);
11876 if (ivar && is_private (ivar))
11878 error ("instance variable %qs is declared private",
11879 IDENTIFIER_POINTER (id));
11885 /* Look up ID as an instance variable. OTHER contains the result of
11886 the C or C++ lookup, which we may want to use instead. */
11887 /* To use properties inside an instance method, use self.property. */
11889 objc_lookup_ivar (tree other, tree id)
11893 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
11894 if (!objc_method_context)
11897 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
11898 /* We have a message to super. */
11899 return get_super_receiver ();
11901 /* In a class method, look up an instance variable only as a last
11903 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
11904 && other && other != error_mark_node)
11907 /* Look up the ivar, but do not use it if it is not accessible. */
11908 ivar = is_ivar (objc_ivar_chain, id);
11910 if (!ivar || is_private (ivar))
11913 /* In an instance method, a local variable (or parameter) may hide the
11914 instance variable. */
11915 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11916 && other && other != error_mark_node
11918 && CP_DECL_CONTEXT (other) != global_namespace)
11920 && !DECL_FILE_SCOPE_P (other))
11923 warning (0, "local declaration of %qE hides instance variable", id);
11928 /* At this point, we are either in an instance method with no obscuring
11929 local definitions, or in a class method with no alternate definitions
11931 return build_ivar_reference (id);
11934 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
11935 needs to be done if we are calling a function through a cast. */
11938 objc_rewrite_function_call (tree function, tree first_param)
11940 if (TREE_CODE (function) == NOP_EXPR
11941 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
11942 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
11945 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
11946 TREE_OPERAND (function, 0),
11947 first_param, size_zero_node);
11953 /* This is called to "gimplify" a PROPERTY_REF node. It builds the
11954 corresponding 'getter' function call. Note that we assume the
11955 PROPERTY_REF to be valid since we generated it while parsing. */
11957 objc_gimplify_property_ref (tree *expr_p)
11959 tree object_expression = PROPERTY_REF_OBJECT (*expr_p);
11960 tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
11961 tree call_exp, getter;
11963 /* TODO: Implement super.property. */
11965 getter = objc_finish_message_expr (object_expression,
11966 PROPERTY_GETTER_NAME (property_decl),
11970 /* In C++, a getter which returns an aggregate value results in a
11971 target_expr which initializes a temporary to the call
11973 if (TREE_CODE (getter) == TARGET_EXPR)
11975 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
11976 gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
11977 call_exp = TREE_OPERAND (getter, 1);
11980 gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
11982 *expr_p = call_exp;
11985 /* This is called when "gimplifying" the trees. We need to gimplify
11986 the Objective-C/Objective-C++ specific trees, then hand over the
11987 process to C/C++. */
11989 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
11991 enum tree_code code = TREE_CODE (*expr_p);
11994 /* Look for the special case of OBJC_TYPE_REF with the address
11995 of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
11996 or one of its cousins). */
11998 if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
11999 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
12002 enum gimplify_status r0, r1;
12004 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
12005 value of the OBJ_TYPE_REF, so force them to be emitted
12006 during subexpression evaluation rather than after the
12007 OBJ_TYPE_REF. This permits objc_msgSend calls in
12008 Objective C to use direct rather than indirect calls when
12009 the object expression has a postincrement. */
12010 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
12011 is_gimple_val, fb_rvalue);
12012 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
12013 is_gimple_val, fb_rvalue);
12015 return MIN (r0, r1);
12019 objc_gimplify_property_ref (expr_p);
12020 /* Do not return yet; let C/C++ gimplify the resulting expression. */
12027 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
12029 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
12033 /* This routine returns true if TYP is a valid objc object type,
12034 suitable for messaging; false otherwise.
12038 objc_type_valid_for_messaging (tree typ)
12040 if (!POINTER_TYPE_P (typ))
12044 typ = TREE_TYPE (typ); /* Remove indirections. */
12045 while (POINTER_TYPE_P (typ));
12047 if (TREE_CODE (typ) != RECORD_TYPE)
12050 return objc_is_object_id (typ) || TYPE_HAS_OBJC_INFO (typ);
12053 /* Begin code generation for fast enumeration (foreach) ... */
12057 struct __objcFastEnumerationState
12059 unsigned long state;
12061 unsigned long *mutationsPtr;
12062 unsigned long extra[5];
12065 Confusingly enough, NSFastEnumeration is then defined by libraries
12066 to be the same structure.
12070 build_fast_enumeration_state_template (void)
12072 tree decls, *chain = NULL;
12075 objc_fast_enumeration_state_template = objc_start_struct (get_identifier
12076 (TAG_FAST_ENUMERATION_STATE));
12078 /* unsigned long state; */
12079 decls = add_field_decl (long_unsigned_type_node, "state", &chain);
12081 /* id *itemsPtr; */
12082 add_field_decl (build_pointer_type (objc_object_type),
12083 "itemsPtr", &chain);
12085 /* unsigned long *mutationsPtr; */
12086 add_field_decl (build_pointer_type (long_unsigned_type_node),
12087 "mutationsPtr", &chain);
12089 /* unsigned long extra[5]; */
12090 add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
12094 objc_finish_struct (objc_fast_enumeration_state_template, decls);
12098 'objc_finish_foreach_loop()' generates the code for an Objective-C
12099 foreach loop. The 'location' argument is the location of the 'for'
12100 that starts the loop. The 'object_expression' is the expression of
12101 the 'object' that iterates; the 'collection_expression' is the
12102 expression of the collection that we iterate over (we need to make
12103 sure we evaluate this only once); the 'for_body' is the set of
12104 statements to be executed in each iteration; 'break_label' and
12105 'continue_label' are the break and continue labels which we need to
12106 emit since the <statements> may be jumping to 'break_label' (if they
12107 contain 'break') or to 'continue_label' (if they contain
12112 for (<object expression> in <collection expression>)
12115 which is compiled into the following blurb:
12118 id __objc_foreach_collection;
12119 __objc_fast_enumeration_state __objc_foreach_enum_state;
12120 unsigned long __objc_foreach_batchsize;
12121 id __objc_foreach_items[16];
12122 __objc_foreach_collection = <collection expression>;
12123 __objc_foreach_enum_state = { 0 };
12124 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
12126 if (__objc_foreach_batchsize == 0)
12127 <object expression> = nil;
12130 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
12133 unsigned long __objc_foreach_index;
12134 __objc_foreach_index = 0;
12137 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
12138 <object expression> = enumState.itemsPtr[__objc_foreach_index];
12139 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
12142 __objc_foreach_index++;
12143 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
12144 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
12146 if (__objc_foreach_batchsize != 0) goto next_batch;
12147 <object expression> = nil;
12152 'statements' may contain a 'continue' or 'break' instruction, which
12153 the user expects to 'continue' or 'break' the entire foreach loop.
12154 We are provided the labels that 'break' and 'continue' jump to, so
12155 we place them where we want them to jump to when they pick them.
12157 Optimization TODO: we could cache the IMP of
12158 countByEnumeratingWithState:objects:count:.
12161 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
12162 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
12164 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
12165 #include "tree-pretty-print.h"
12169 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
12170 tree break_label, tree continue_label)
12172 /* A tree representing the __objcFastEnumerationState struct type,
12173 or NSFastEnumerationState struct, whatever we are using. */
12174 tree objc_fast_enumeration_state_type;
12176 /* The trees representing the declarations of each of the local variables. */
12177 tree objc_foreach_collection_decl;
12178 tree objc_foreach_enum_state_decl;
12179 tree objc_foreach_items_decl;
12180 tree objc_foreach_batchsize_decl;
12181 tree objc_foreach_mutations_pointer_decl;
12182 tree objc_foreach_index_decl;
12184 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
12185 tree selector_name;
12187 /* A tree representing the local bind. */
12190 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
12193 /* A tree representing the 'else' part of 'first_if' */
12196 /* A tree representing the 'next_batch' label. */
12197 tree next_batch_label_decl;
12199 /* A tree representing the binding after the 'next_batch' label. */
12200 tree next_batch_bind;
12202 /* A tree representing the 'next_object' label. */
12203 tree next_object_label_decl;
12205 /* Temporary variables. */
12209 if (flag_objc1_only)
12210 error_at (location, "fast enumeration is not available in Objective-C 1.0");
12212 if (object_expression == error_mark_node)
12215 if (collection_expression == error_mark_node)
12218 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression)))
12220 error ("iterating variable in fast enumeration is not an object");
12224 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression)))
12226 error ("collection in fast enumeration is not an object");
12230 /* TODO: Check that object_expression is either a variable
12231 declaration, or an lvalue. */
12233 /* This kludge is an idea from apple. We use the
12234 __objcFastEnumerationState struct implicitly defined by the
12235 compiler, unless a NSFastEnumerationState struct has been defined
12236 (by a Foundation library such as GNUstep Base) in which case, we
12239 objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
12241 tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
12243 if (objc_NSFastEnumeration_type)
12245 /* TODO: We really need to check that
12246 objc_NSFastEnumeration_type is the same as ours! */
12247 if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
12249 /* If it's a typedef, use the original type. */
12250 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
12251 objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
12253 objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
12259 /* Done by c-parser.c. */
12262 /* Done by c-parser.c. */
12264 /* id __objc_foreach_collection */
12265 objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
12267 /* __objcFastEnumerationState __objc_foreach_enum_state; */
12268 objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
12269 TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
12271 /* id __objc_foreach_items[16]; */
12272 objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
12273 TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
12275 /* unsigned long __objc_foreach_batchsize; */
12276 objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
12277 TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
12279 /* Generate the local variable binding. */
12280 bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
12281 SET_EXPR_LOCATION (bind, location);
12282 TREE_SIDE_EFFECTS (bind) = 1;
12284 /* __objc_foreach_collection = <collection expression>; */
12285 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
12286 SET_EXPR_LOCATION (t, location);
12287 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12289 /* __objc_foreach_enum_state.state = 0; */
12290 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
12291 get_identifier ("state")),
12292 build_int_cst (long_unsigned_type_node, 0));
12293 SET_EXPR_LOCATION (t, location);
12294 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12296 /* __objc_foreach_enum_state.itemsPtr = NULL; */
12297 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
12298 get_identifier ("itemsPtr")),
12299 null_pointer_node);
12300 SET_EXPR_LOCATION (t, location);
12301 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12303 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
12304 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
12305 get_identifier ("mutationsPtr")),
12306 null_pointer_node);
12307 SET_EXPR_LOCATION (t, location);
12308 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12310 /* __objc_foreach_enum_state.extra[0] = 0; */
12311 /* __objc_foreach_enum_state.extra[1] = 0; */
12312 /* __objc_foreach_enum_state.extra[2] = 0; */
12313 /* __objc_foreach_enum_state.extra[3] = 0; */
12314 /* __objc_foreach_enum_state.extra[4] = 0; */
12315 for (i = 0; i < 5 ; i++)
12317 t = build2 (MODIFY_EXPR, void_type_node,
12318 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
12319 get_identifier ("extra")),
12320 build_int_cst (NULL_TREE, i)),
12321 build_int_cst (long_unsigned_type_node, 0));
12322 SET_EXPR_LOCATION (t, location);
12323 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12326 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
12327 selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
12329 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
12331 tree_cons /* &__objc_foreach_enum_state */
12332 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
12333 tree_cons /* __objc_foreach_items */
12334 (NULL_TREE, objc_foreach_items_decl,
12336 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
12338 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
12340 struct c_expr array;
12341 array.value = objc_foreach_items_decl;
12342 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
12344 tree_cons /* &__objc_foreach_enum_state */
12345 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
12346 tree_cons /* __objc_foreach_items */
12347 (NULL_TREE, default_function_array_conversion (location, array).value,
12349 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
12352 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
12353 convert (long_unsigned_type_node, t));
12354 SET_EXPR_LOCATION (t, location);
12355 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12357 /* if (__objc_foreach_batchsize == 0) */
12358 first_if = build3 (COND_EXPR, void_type_node,
12361 (c_common_truthvalue_conversion
12363 build_binary_op (location,
12365 objc_foreach_batchsize_decl,
12366 build_int_cst (long_unsigned_type_node, 0), 1)),
12368 /* Then block (we fill it in later). */
12370 /* Else block (we fill it in later). */
12372 SET_EXPR_LOCATION (first_if, location);
12373 append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
12375 /* then <object expression> = nil; */
12376 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
12377 SET_EXPR_LOCATION (t, location);
12378 COND_EXPR_THEN (first_if) = t;
12380 /* Now we build the 'else' part of the if; once we finish building
12381 it, we attach it to first_if as the 'else' part. */
12386 /* unsigned long __objc_foreach_mutations_pointer; */
12387 objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
12389 /* Generate the local variable binding. */
12390 first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
12391 SET_EXPR_LOCATION (first_else, location);
12392 TREE_SIDE_EFFECTS (first_else) = 1;
12394 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
12395 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
12396 build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
12397 get_identifier ("mutationsPtr")),
12399 SET_EXPR_LOCATION (t, location);
12400 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12403 next_batch_label_decl = create_artificial_label (location);
12404 t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
12405 SET_EXPR_LOCATION (t, location);
12406 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12410 /* unsigned long __objc_foreach_index; */
12411 objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
12413 /* Generate the local variable binding. */
12414 next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
12415 SET_EXPR_LOCATION (next_batch_bind, location);
12416 TREE_SIDE_EFFECTS (next_batch_bind) = 1;
12417 append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
12419 /* __objc_foreach_index = 0; */
12420 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
12421 build_int_cst (long_unsigned_type_node, 0));
12422 SET_EXPR_LOCATION (t, location);
12423 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12426 next_object_label_decl = create_artificial_label (location);
12427 t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
12428 SET_EXPR_LOCATION (t, location);
12429 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12431 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
12432 t = build3 (COND_EXPR, void_type_node,
12435 (c_common_truthvalue_conversion
12440 objc_foreach_mutations_pointer_decl,
12441 build_indirect_ref (location,
12442 objc_build_component_ref (objc_foreach_enum_state_decl,
12443 get_identifier ("mutationsPtr")),
12444 RO_UNARY_STAR), 1)),
12447 build_function_call (input_location,
12448 objc_enumeration_mutation_decl,
12449 tree_cons (NULL, collection_expression, NULL)),
12452 SET_EXPR_LOCATION (t, location);
12453 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12455 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
12456 t = build2 (MODIFY_EXPR, void_type_node, object_expression,
12457 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
12458 get_identifier ("itemsPtr")),
12459 objc_foreach_index_decl));
12460 SET_EXPR_LOCATION (t, location);
12461 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12463 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
12464 append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
12466 /* continue_label: */
12467 if (continue_label)
12469 t = build1 (LABEL_EXPR, void_type_node, continue_label);
12470 SET_EXPR_LOCATION (t, location);
12471 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12474 /* __objc_foreach_index++; */
12475 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
12476 build_binary_op (location,
12478 objc_foreach_index_decl,
12479 build_int_cst (long_unsigned_type_node, 1), 1));
12480 SET_EXPR_LOCATION (t, location);
12481 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12483 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
12484 t = build3 (COND_EXPR, void_type_node,
12487 (c_common_truthvalue_conversion
12489 build_binary_op (location,
12491 objc_foreach_index_decl,
12492 objc_foreach_batchsize_decl, 1)),
12495 build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
12498 SET_EXPR_LOCATION (t, location);
12499 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12501 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
12503 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
12505 tree_cons /* &__objc_foreach_enum_state */
12506 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
12507 tree_cons /* __objc_foreach_items */
12508 (NULL_TREE, objc_foreach_items_decl,
12510 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
12512 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
12514 struct c_expr array;
12515 array.value = objc_foreach_items_decl;
12516 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
12518 tree_cons /* &__objc_foreach_enum_state */
12519 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
12520 tree_cons /* __objc_foreach_items */
12521 (NULL_TREE, default_function_array_conversion (location, array).value,
12523 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
12526 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
12527 convert (long_unsigned_type_node, t));
12528 SET_EXPR_LOCATION (t, location);
12529 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12533 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
12534 t = build3 (COND_EXPR, void_type_node,
12537 (c_common_truthvalue_conversion
12539 build_binary_op (location,
12541 objc_foreach_batchsize_decl,
12542 build_int_cst (long_unsigned_type_node, 0), 1)),
12545 build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
12548 SET_EXPR_LOCATION (t, location);
12549 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12551 /* <object expression> = nil; */
12552 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
12553 SET_EXPR_LOCATION (t, location);
12554 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12559 t = build1 (LABEL_EXPR, void_type_node, break_label);
12560 SET_EXPR_LOCATION (t, location);
12561 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12565 COND_EXPR_ELSE (first_if) = first_else;
12567 /* Do the whole thing. */
12570 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
12571 /* This will print to stderr the whole blurb generated by the
12572 compiler while compiling (assuming the compiler doesn't crash
12573 before getting here).
12575 debug_generic_stmt (bind);
12579 /* Done by c-parser.c */
12582 #include "gt-objc-objc-act.h"