2010-11-11 Jakub Jelinek <jakub@redhat.com>
[official-gcc.git] / gcc / objc / objc-act.c
blob715623f379f3202198d9e3bb1b1b04b4360143f5
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)
12 any later version.
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/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
29 #ifdef OBJCPLUS
30 #include "cp-tree.h"
31 #else
32 #include "c-tree.h"
33 #include "c-lang.h"
34 #endif
36 #include "c-family/c-common.h"
37 #include "c-family/c-pragma.h"
38 #include "c-family/c-format.h"
39 #include "flags.h"
40 #include "langhooks.h"
41 #include "objc-act.h"
42 #include "input.h"
43 #include "function.h"
44 #include "output.h"
45 #include "toplev.h"
46 #include "ggc.h"
47 #include "debug.h"
48 #include "target.h"
49 #include "diagnostic-core.h"
50 #include "intl.h"
51 #include "cgraph.h"
52 #include "tree-iterator.h"
53 #include "hashtab.h"
54 #include "langhooks-def.h"
56 /* For default_tree_printer (). */
57 #include "tree-pretty-print.h"
59 /* For enum gimplify_status */
60 #include "gimple.h"
62 #define OBJC_VOID_AT_END void_list_node
64 static unsigned int should_call_super_dealloc = 0;
66 /* When building Objective-C++, we need in_late_binary_op. */
67 #ifdef OBJCPLUS
68 bool in_late_binary_op = false;
69 #endif /* OBJCPLUS */
71 /* When building Objective-C++, we are not linking against the C front-end
72 and so need to replicate the C tree-construction functions in some way. */
73 #ifdef OBJCPLUS
74 #define OBJCP_REMAP_FUNCTIONS
75 #include "objcp-decl.h"
76 #endif /* OBJCPLUS */
78 /* This is the default way of generating a method name. */
79 /* This has the problem that "test_method:argument:" and
80 "test:method_argument:" will generate the same name
81 ("_i_Test__test_method_argument_" for an instance method of the
82 class "Test"), so you can't have them both in the same class!
83 Moreover, the demangling (going from
84 "_i_Test__test_method_argument" back to the original name) is
85 undefined because there are two correct ways of demangling the
86 name. */
87 #ifndef OBJC_GEN_METHOD_LABEL
88 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
89 do { \
90 char *temp; \
91 sprintf ((BUF), "_%s_%s_%s_%s", \
92 ((IS_INST) ? "i" : "c"), \
93 (CLASS_NAME), \
94 ((CAT_NAME)? (CAT_NAME) : ""), \
95 (SEL_NAME)); \
96 for (temp = (BUF); *temp; temp++) \
97 if (*temp == ':') *temp = '_'; \
98 } while (0)
99 #endif
101 /* These need specifying. */
102 #ifndef OBJC_FORWARDING_STACK_OFFSET
103 #define OBJC_FORWARDING_STACK_OFFSET 0
104 #endif
106 #ifndef OBJC_FORWARDING_MIN_OFFSET
107 #define OBJC_FORWARDING_MIN_OFFSET 0
108 #endif
110 /* Set up for use of obstacks. */
112 #include "obstack.h"
114 /* This obstack is used to accumulate the encoding of a data type. */
115 static struct obstack util_obstack;
117 /* This points to the beginning of obstack contents, so we can free
118 the whole contents. */
119 char *util_firstobj;
121 /* The version identifies which language generation and runtime
122 the module (file) was compiled for, and is recorded in the
123 module descriptor. */
125 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
126 #define PROTOCOL_VERSION 2
128 /* (Decide if these can ever be validly changed.) */
129 #define OBJC_ENCODE_INLINE_DEFS 0
130 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
132 /*** Private Interface (procedures) ***/
134 /* Used by compile_file. */
136 static void init_objc (void);
137 static void finish_objc (void);
139 /* Code generation. */
141 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
142 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
143 static tree get_proto_encoding (tree);
144 static tree lookup_interface (tree);
145 static tree objc_add_static_instance (tree, tree);
147 static tree start_class (enum tree_code, tree, tree, tree);
148 static tree continue_class (tree);
149 static void finish_class (tree);
150 static void start_method_def (tree);
151 #ifdef OBJCPLUS
152 static void objc_start_function (tree, tree, tree, tree);
153 #else
154 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
155 #endif
156 static tree start_protocol (enum tree_code, tree, tree);
157 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
158 static tree objc_add_method (tree, tree, int, bool);
159 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
160 static tree build_ivar_reference (tree);
161 static tree is_ivar (tree, tree);
163 static void build_objc_exception_stuff (void);
164 static void build_next_objc_exception_stuff (void);
166 /* We only need the following for ObjC; ObjC++ will use C++'s definition
167 of DERIVED_FROM_P. */
168 #ifndef OBJCPLUS
169 static bool objc_derived_from_p (tree, tree);
170 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
171 #endif
173 /* Property. */
174 static void objc_gen_property_data (tree, tree);
175 static void objc_synthesize_getter (tree, tree, tree);
176 static void objc_synthesize_setter (tree, tree, tree);
177 static char *objc_build_property_setter_name (tree);
178 static int match_proto_with_proto (tree, tree, int);
179 static tree lookup_property (tree, tree);
180 static tree lookup_property_in_list (tree, tree);
181 static tree lookup_property_in_protocol_list (tree, tree);
182 static void build_objc_property_accessor_helpers (void);
184 static void objc_xref_basetypes (tree, tree);
186 static void build_class_template (void);
187 static void build_selector_template (void);
188 static void build_category_template (void);
189 static void build_super_template (void);
190 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
191 static tree get_class_ivars (tree, bool);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
195 static void build_fast_enumeration_state_template (void);
197 #ifdef OBJCPLUS
198 static void objc_generate_cxx_cdtors (void);
199 #endif
201 /* objc attribute */
202 static void objc_decl_method_attributes (tree*, tree, int);
203 static tree build_keyword_selector (tree);
204 static const char *synth_id_with_class_suffix (const char *, tree);
206 /* Hash tables to manage the global pool of method prototypes. */
208 hash *nst_method_hash_list = 0;
209 hash *cls_method_hash_list = 0;
211 /* Hash tables to manage the global pool of class names. */
213 hash *cls_name_hash_list = 0;
214 hash *als_name_hash_list = 0;
216 static void hash_class_name_enter (hash *, tree, tree);
217 static hash hash_class_name_lookup (hash *, tree);
219 static hash hash_lookup (hash *, tree);
220 static tree lookup_method (tree, tree);
221 static tree lookup_method_static (tree, tree, int);
223 static tree add_class (tree, tree);
224 static void add_category (tree, tree);
225 static inline tree lookup_category (tree, tree);
227 enum string_section
229 class_names, /* class, category, protocol, module names */
230 meth_var_names, /* method and variable names */
231 meth_var_types /* method and variable type descriptors */
234 static tree add_objc_string (tree, enum string_section);
235 static void build_selector_table_decl (void);
237 /* Protocol additions. */
239 static tree lookup_protocol (tree);
240 static tree lookup_and_install_protocols (tree);
242 /* Type encoding. */
244 static void encode_type_qualifiers (tree);
245 static void encode_type (tree, int, int);
246 static void encode_field_decl (tree, int, int);
248 #ifdef OBJCPLUS
249 static void really_start_method (tree, tree);
250 #else
251 static void really_start_method (tree, struct c_arg_info *);
252 #endif
253 static int comp_proto_with_proto (tree, tree, int);
254 static tree get_arg_type_list (tree, int, int);
255 static tree objc_decay_parm_type (tree);
256 static void objc_push_parm (tree);
257 #ifdef OBJCPLUS
258 static tree objc_get_parm_info (int);
259 #else
260 static struct c_arg_info *objc_get_parm_info (int);
261 #endif
263 /* Utilities for debugging and error diagnostics. */
265 static char *gen_type_name (tree);
266 static char *gen_type_name_0 (tree);
267 static char *gen_method_decl (tree);
268 static char *gen_declaration (tree);
270 /* Everything else. */
272 static tree create_field_decl (tree, const char *);
273 static void add_class_reference (tree);
274 static void build_protocol_template (void);
275 static tree encode_method_prototype (tree);
276 static void generate_classref_translation_entry (tree);
277 static void handle_class_ref (tree);
278 static void generate_struct_by_value_array (void)
279 ATTRIBUTE_NORETURN;
280 static void mark_referenced_methods (void);
281 static void generate_objc_image_info (void);
282 static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
284 /*** Private Interface (data) ***/
286 /* Reserved tag definitions. */
288 #define OBJECT_TYPEDEF_NAME "id"
289 #define CLASS_TYPEDEF_NAME "Class"
291 #define TAG_OBJECT "objc_object"
292 #define TAG_CLASS "objc_class"
293 #define TAG_SUPER "objc_super"
294 #define TAG_SELECTOR "objc_selector"
296 #define UTAG_CLASS "_objc_class"
297 #define UTAG_IVAR "_objc_ivar"
298 #define UTAG_IVAR_LIST "_objc_ivar_list"
299 #define UTAG_METHOD "_objc_method"
300 #define UTAG_METHOD_LIST "_objc_method_list"
301 #define UTAG_CATEGORY "_objc_category"
302 #define UTAG_MODULE "_objc_module"
303 #define UTAG_SYMTAB "_objc_symtab"
304 #define UTAG_SUPER "_objc_super"
305 #define UTAG_SELECTOR "_objc_selector"
307 #define UTAG_PROTOCOL "_objc_protocol"
308 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
309 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
311 /* Note that the string object global name is only needed for the
312 NeXT runtime. */
313 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
315 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
317 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
318 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
320 static const char *TAG_GETCLASS;
321 static const char *TAG_GETMETACLASS;
322 static const char *TAG_MSGSEND;
323 static const char *TAG_MSGSENDSUPER;
324 /* The NeXT Objective-C messenger may have two extra entry points, for use
325 when returning a structure. */
326 static const char *TAG_MSGSEND_STRET;
327 static const char *TAG_MSGSENDSUPER_STRET;
328 static const char *default_constant_string_class_name;
330 /* Runtime metadata flags. */
331 #define CLS_FACTORY 0x0001L
332 #define CLS_META 0x0002L
333 #define CLS_HAS_CXX_STRUCTORS 0x2000L
335 #define OBJC_MODIFIER_STATIC 0x00000001
336 #define OBJC_MODIFIER_FINAL 0x00000002
337 #define OBJC_MODIFIER_PUBLIC 0x00000004
338 #define OBJC_MODIFIER_PRIVATE 0x00000008
339 #define OBJC_MODIFIER_PROTECTED 0x00000010
340 #define OBJC_MODIFIER_NATIVE 0x00000020
341 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
342 #define OBJC_MODIFIER_ABSTRACT 0x00000080
343 #define OBJC_MODIFIER_VOLATILE 0x00000100
344 #define OBJC_MODIFIER_TRANSIENT 0x00000200
345 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
347 /* NeXT-specific tags. */
349 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
350 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
351 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
352 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
353 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
354 #define TAG_EXCEPTIONMATCH "objc_exception_match"
355 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
356 #define TAG_SYNCENTER "objc_sync_enter"
357 #define TAG_SYNCEXIT "objc_sync_exit"
358 #define TAG_SETJMP "_setjmp"
359 #define UTAG_EXCDATA "_objc_exception_data"
361 #define TAG_ASSIGNIVAR "objc_assign_ivar"
362 #define TAG_ASSIGNGLOBAL "objc_assign_global"
363 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
365 /* Branch entry points. All that matters here are the addresses;
366 functions with these names do not really exist in libobjc. */
368 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
369 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
371 #define TAG_CXX_CONSTRUCT ".cxx_construct"
372 #define TAG_CXX_DESTRUCT ".cxx_destruct"
374 /* GNU-specific tags. */
376 #define TAG_EXECCLASS "__objc_exec_class"
377 #define TAG_GNUINIT "__objc_gnu_init"
379 /* Flags for lookup_method_static(). */
381 /* Look for class methods. */
382 #define OBJC_LOOKUP_CLASS 1
383 /* Do not examine superclasses. */
384 #define OBJC_LOOKUP_NO_SUPER 2
385 /* Disable returning an instance method of a root class when a class
386 method can't be found. */
387 #define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4
389 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
390 tree objc_global_trees[OCTI_MAX];
392 static void handle_impent (struct imp_entry *);
394 struct imp_entry *imp_list = 0;
395 int imp_count = 0; /* `@implementation' */
396 int cat_count = 0; /* `@category' */
398 objc_ivar_visibility_kind objc_ivar_visibility;
400 /* Use to generate method labels. */
401 static int method_slot = 0;
403 /* Flag to say whether methods in a protocol are optional or
404 required. */
405 static bool objc_method_optional_flag = false;
407 static int objc_collecting_ivars = 0;
409 #define BUFSIZE 1024
411 static char *errbuf; /* Buffer for error diagnostics */
413 /* Data imported from tree.c. */
415 extern enum debug_info_type write_symbols;
418 static int flag_typed_selectors;
420 /* Store all constructed constant strings in a hash table so that
421 they get uniqued properly. */
423 struct GTY(()) string_descriptor {
424 /* The literal argument . */
425 tree literal;
427 /* The resulting constant string. */
428 tree constructor;
431 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
433 FILE *gen_declaration_file;
435 /* Tells "encode_pointer/encode_aggregate" whether we are generating
436 type descriptors for instance variables (as opposed to methods).
437 Type descriptors for instance variables contain more information
438 than methods (for static typing and embedded structures). */
440 static int generating_instance_variables = 0;
442 /* For building an objc struct. These may not be used when this file
443 is compiled as part of obj-c++. */
445 static bool objc_building_struct;
446 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
448 /* Start building a struct for objc. */
450 static tree
451 objc_start_struct (tree name)
453 gcc_assert (!objc_building_struct);
454 objc_building_struct = true;
455 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
458 /* Finish building a struct for objc. */
460 static tree
461 objc_finish_struct (tree type, tree fieldlist)
463 gcc_assert (objc_building_struct);
464 objc_building_struct = false;
465 return finish_struct (input_location, type, fieldlist, NULL_TREE,
466 objc_struct_info);
469 static tree
470 build_sized_array_type (tree base_type, int size)
472 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
473 return build_array_type (base_type, index_type);
476 static tree
477 add_field_decl (tree type, const char *name, tree **chain)
479 tree field = create_field_decl (type, name);
481 if (*chain != NULL)
482 **chain = field;
483 *chain = &DECL_CHAIN (field);
485 return field;
488 /* Some platforms pass small structures through registers versus
489 through an invisible pointer. Determine at what size structure is
490 the transition point between the two possibilities. */
492 static void
493 generate_struct_by_value_array (void)
495 tree type;
496 tree decls;
497 int i, j;
498 int aggregate_in_mem[32];
499 int found = 0;
501 /* Presumably no platform passes 32 byte structures in a register. */
502 for (i = 1; i < 32; i++)
504 char buffer[5];
505 tree *chain = NULL;
507 /* Create an unnamed struct that has `i' character components */
508 type = objc_start_struct (NULL_TREE);
510 strcpy (buffer, "c1");
511 decls = add_field_decl (char_type_node, buffer, &chain);
513 for (j = 1; j < i; j++)
515 sprintf (buffer, "c%d", j + 1);
516 add_field_decl (char_type_node, buffer, &chain);
518 objc_finish_struct (type, decls);
520 aggregate_in_mem[i] = aggregate_value_p (type, 0);
521 if (!aggregate_in_mem[i])
522 found = 1;
525 /* We found some structures that are returned in registers instead of memory
526 so output the necessary data. */
527 if (found)
529 for (i = 31; i >= 0; i--)
530 if (!aggregate_in_mem[i])
531 break;
532 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
534 /* The first member of the structure is always 0 because we don't handle
535 structures with 0 members */
536 printf ("static int struct_forward_array[] = {\n 0");
538 for (j = 1; j <= i; j++)
539 printf (", %d", aggregate_in_mem[j]);
540 printf ("\n};\n");
543 exit (0);
546 bool
547 objc_init (void)
549 #ifdef OBJCPLUS
550 if (cxx_init () == false)
551 #else
552 if (c_objc_common_init () == false)
553 #endif
554 return false;
556 /* If gen_declaration desired, open the output file. */
557 if (flag_gen_declaration)
559 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
560 gen_declaration_file = fopen (dumpname, "w");
561 if (gen_declaration_file == 0)
562 fatal_error ("can%'t open %s: %m", dumpname);
563 free (dumpname);
566 if (flag_next_runtime)
568 TAG_GETCLASS = "objc_getClass";
569 TAG_GETMETACLASS = "objc_getMetaClass";
570 TAG_MSGSEND = "objc_msgSend";
571 TAG_MSGSENDSUPER = "objc_msgSendSuper";
572 TAG_MSGSEND_STRET = "objc_msgSend_stret";
573 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
574 default_constant_string_class_name = "NSConstantString";
576 else
578 TAG_GETCLASS = "objc_get_class";
579 TAG_GETMETACLASS = "objc_get_meta_class";
580 TAG_MSGSEND = "objc_msg_lookup";
581 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
582 /* GNU runtime does not provide special functions to support
583 structure-returning methods. */
584 default_constant_string_class_name = "NXConstantString";
585 flag_typed_selectors = 1;
586 /* GNU runtime does not need the compiler to change code
587 in order to do GC. */
588 if (flag_objc_gc)
590 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
591 flag_objc_gc=0;
595 init_objc ();
597 if (print_struct_values && !flag_compare_debug)
598 generate_struct_by_value_array ();
600 return true;
603 /* This is called automatically (at the very end of compilation) by
604 c_write_global_declarations and cp_write_global_declarations. */
605 void
606 objc_write_global_declarations (void)
608 mark_referenced_methods ();
610 /* Finalize Objective-C runtime data. */
611 finish_objc ();
613 if (gen_declaration_file)
614 fclose (gen_declaration_file);
617 /* Return the first occurrence of a method declaration corresponding
618 to sel_name in rproto_list. Search rproto_list recursively.
619 If is_class is 0, search for instance methods, otherwise for class
620 methods. */
621 static tree
622 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
623 int is_class)
625 tree rproto, p;
626 tree fnd = 0;
628 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
630 p = TREE_VALUE (rproto);
632 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
634 if ((fnd = lookup_method (is_class
635 ? PROTOCOL_CLS_METHODS (p)
636 : PROTOCOL_NST_METHODS (p), sel_name)))
638 else if (PROTOCOL_LIST (p))
639 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
640 sel_name, is_class);
642 else
644 ; /* An identifier...if we could not find a protocol. */
647 if (fnd)
648 return fnd;
651 return 0;
654 static tree
655 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
657 tree rproto, p;
659 /* Make sure the protocol is supported by the object on the rhs. */
660 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
662 tree fnd = 0;
663 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
665 p = TREE_VALUE (rproto);
667 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
669 if (lproto == p)
670 fnd = lproto;
672 else if (PROTOCOL_LIST (p))
673 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
676 if (fnd)
677 return fnd;
680 else
682 ; /* An identifier...if we could not find a protocol. */
685 return 0;
688 void
689 objc_start_class_interface (tree klass, tree super_class,
690 tree protos, tree attributes)
692 if (attributes)
694 if (flag_objc1_only)
695 error_at (input_location, "class attributes are not available in Objective-C 1.0");
696 else
697 warning_at (input_location, OPT_Wattributes,
698 "class attributes are not available in this version"
699 " of the compiler, (ignored)");
701 objc_interface_context
702 = objc_ivar_context
703 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
704 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
707 void
708 objc_start_category_interface (tree klass, tree categ,
709 tree protos, tree attributes)
711 if (attributes)
713 if (flag_objc1_only)
714 error_at (input_location, "category attributes are not available in Objective-C 1.0");
715 else
716 warning_at (input_location, OPT_Wattributes,
717 "category attributes are not available in this version"
718 " of the compiler, (ignored)");
720 objc_interface_context
721 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
722 objc_ivar_chain
723 = continue_class (objc_interface_context);
726 void
727 objc_start_protocol (tree name, tree protos, tree attributes)
729 if (attributes)
731 if (flag_objc1_only)
732 error_at (input_location, "protocol attributes are not available in Objective-C 1.0");
733 else
734 warning_at (input_location, OPT_Wattributes,
735 "protocol attributes are not available in this version"
736 " of the compiler, (ignored)");
738 objc_interface_context
739 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
740 objc_method_optional_flag = false;
743 void
744 objc_continue_interface (void)
746 objc_ivar_chain
747 = continue_class (objc_interface_context);
750 void
751 objc_finish_interface (void)
753 finish_class (objc_interface_context);
754 objc_interface_context = NULL_TREE;
755 objc_method_optional_flag = false;
758 void
759 objc_start_class_implementation (tree klass, tree super_class)
761 objc_implementation_context
762 = objc_ivar_context
763 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
764 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
767 void
768 objc_start_category_implementation (tree klass, tree categ)
770 objc_implementation_context
771 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
772 objc_ivar_chain
773 = continue_class (objc_implementation_context);
776 void
777 objc_continue_implementation (void)
779 objc_ivar_chain
780 = continue_class (objc_implementation_context);
783 void
784 objc_finish_implementation (void)
786 #ifdef OBJCPLUS
787 if (flag_objc_call_cxx_cdtors)
788 objc_generate_cxx_cdtors ();
789 #endif
791 if (objc_implementation_context)
793 finish_class (objc_implementation_context);
794 objc_ivar_chain = NULL_TREE;
795 objc_implementation_context = NULL_TREE;
797 else
798 warning (0, "%<@end%> must appear in an @implementation context");
801 void
802 objc_set_visibility (objc_ivar_visibility_kind visibility)
804 if (visibility == OBJC_IVAR_VIS_PACKAGE)
806 if (flag_objc1_only)
807 error ("%<@package%> is not available in Objective-C 1.0");
808 else
809 warning (0, "%<@package%> presently has the same effect as %<@public%>");
811 objc_ivar_visibility = visibility;
814 void
815 objc_set_method_opt (bool optional)
817 if (flag_objc1_only)
818 error_at (input_location, "@optional/@required are not available in Objective-C 1.0");
820 objc_method_optional_flag = optional;
821 if (!objc_interface_context
822 || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
824 error ("@optional/@required is allowed in @protocol context only");
825 objc_method_optional_flag = false;
829 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
830 PROTOCOL. */
831 static tree
832 lookup_property_in_list (tree chain, tree property)
834 tree x;
835 for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
836 if (PROPERTY_NAME (x) == property)
837 return x;
838 return NULL_TREE;
841 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
842 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
844 tree rproto, x;
845 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
847 tree p = TREE_VALUE (rproto);
848 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
850 if ((x = lookup_property_in_list (p, property)))
851 return x;
852 if (PROTOCOL_LIST (p))
853 return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
855 else
857 ; /* An identifier...if we could not find a protocol. */
860 return NULL_TREE;
863 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
864 chain of interface hierarchy. */
865 static tree
866 lookup_property (tree interface_type, tree property)
868 tree inter = interface_type;
869 while (inter)
871 tree x, category;
872 if ((x = lookup_property_in_list (inter, property)))
873 return x;
874 /* Failing that, look for the property in each category of the class. */
875 category = inter;
876 while ((category = CLASS_CATEGORY_LIST (category)))
878 if ((x = lookup_property_in_list (category, property)))
879 return x;
881 /* When checking a category, also check the protocols
882 attached with the category itself. */
883 if (CLASS_PROTOCOL_LIST (category)
884 && (x = lookup_property_in_protocol_list
885 (CLASS_PROTOCOL_LIST (category), property)))
886 return x;
889 /* Failing to find in categories, look for property in protocol list. */
890 if (CLASS_PROTOCOL_LIST (inter)
891 && (x = lookup_property_in_protocol_list
892 (CLASS_PROTOCOL_LIST (inter), property)))
893 return x;
895 /* Failing that, climb up the inheritance hierarchy. */
896 inter = lookup_interface (CLASS_SUPER_NAME (inter));
898 return inter;
901 /* This routine is called by the parser when a
902 @property... declaration is found. 'decl' is the declaration of
903 the property (type/identifier), and the other arguments represent
904 property attributes that may have been specified in the Objective-C
905 declaration. 'parsed_property_readonly' is 'true' if the attribute
906 'readonly' was specified, and 'false' if not; similarly for the
907 other bool parameters. 'parsed_property_getter_ident' is NULL_TREE
908 if the attribute 'getter' was not specified, and is the identifier
909 corresponding to the specified getter if it was; similarly for
910 'parsed_property_setter_ident'. */
911 void
912 objc_add_property_declaration (location_t location, tree decl,
913 bool parsed_property_readonly, bool parsed_property_readwrite,
914 bool parsed_property_assign, bool parsed_property_retain,
915 bool parsed_property_copy, bool parsed_property_nonatomic,
916 tree parsed_property_getter_ident, tree parsed_property_setter_ident)
918 tree property_decl;
919 tree x;
920 /* 'property_readonly' and 'property_assign_semantics' are the final
921 attributes of the property after all parsed attributes have been
922 considered (eg, if we parsed no 'readonly' and no 'readwrite', ie
923 parsed_property_readonly = false and parsed_property_readwrite =
924 false, then property_readonly will be false because the default
925 is readwrite). */
926 bool property_readonly = false;
927 objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN;
929 if (flag_objc1_only)
930 error_at (input_location, "%<@property%> is not available in Objective-C 1.0");
932 if (parsed_property_readonly && parsed_property_readwrite)
934 error_at (location, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
935 /* In case of conflicting attributes (here and below), after
936 producing an error, we pick one of the attributes and keep
937 going. */
938 property_readonly = false;
940 else
942 if (parsed_property_readonly)
943 property_readonly = true;
945 if (parsed_property_readwrite)
946 property_readonly = false;
949 if (parsed_property_readonly && parsed_property_setter_ident)
951 /* Maybe this should be an error ? The Apple documentation says it is a warning. */
952 warning_at (location, 0, "%<readonly%> attribute conflicts with %<setter%> attribute");
953 property_readonly = false;
956 if (parsed_property_assign && parsed_property_retain)
958 error_at (location, "%<assign%> attribute conflicts with %<retain%> attribute");
959 property_assign_semantics = OBJC_PROPERTY_RETAIN;
961 else if (parsed_property_assign && parsed_property_copy)
963 error_at (location, "%<assign%> attribute conflicts with %<copy%> attribute");
964 property_assign_semantics = OBJC_PROPERTY_COPY;
966 else if (parsed_property_retain && parsed_property_copy)
968 error_at (location, "%<retain%> attribute conflicts with %<copy%> attribute");
969 property_assign_semantics = OBJC_PROPERTY_COPY;
971 else
973 if (parsed_property_assign)
974 property_assign_semantics = OBJC_PROPERTY_ASSIGN;
976 if (parsed_property_retain)
977 property_assign_semantics = OBJC_PROPERTY_RETAIN;
979 if (parsed_property_copy)
980 property_assign_semantics = OBJC_PROPERTY_COPY;
983 if (!objc_interface_context)
985 error_at (location, "property declaration not in @interface or @protocol context");
986 return;
989 /* At this point we know that we are either in an interface, a
990 category, or a protocol. */
992 /* Check that the property does not have an initial value specified.
993 This should never happen as the parser doesn't allow this, but
994 it's just in case. */
995 if (DECL_INITIAL (decl))
997 error_at (location, "property can not have an initial value");
998 return;
1001 /* TODO: Check that the property type is an Objective-C object or a "POD". */
1003 /* Implement -Wproperty-assign-default (which is enabled by default). */
1004 if (warn_property_assign_default
1005 /* If garbage collection is not being used, then 'assign' is
1006 valid for objects (and typically used for delegates) but it
1007 is wrong in most cases (since most objects need to be
1008 retained or copied in setters). Warn users when 'assign' is
1009 used implicitly. */
1010 && property_assign_semantics == OBJC_PROPERTY_ASSIGN
1011 /* Read-only properties are never assigned, so the assignment
1012 semantics do not matter in that case. */
1013 && !property_readonly
1014 && !flag_objc_gc)
1016 /* Please note that it would make sense to default to 'assign'
1017 for non-{Objective-C objects}, and to 'retain' for
1018 Objective-C objects. But that would break compatibility with
1019 other compilers. */
1020 if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy)
1022 /* Use 'false' so we do not warn for Class objects. */
1023 if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
1025 warning_at (location,
1027 "object property %qD has no %<assign%>, %<retain%> or %<copy%> attribute; assuming %<assign%>",
1028 decl);
1029 inform (location,
1030 "%<assign%> can be unsafe for Objective-C objects; please state explicitly if you need it");
1035 if (property_assign_semantics == OBJC_PROPERTY_RETAIN
1036 && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1037 error_at (location, "%<retain%> attribute is only valid for Objective-C objects");
1039 if (property_assign_semantics == OBJC_PROPERTY_COPY
1040 && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1041 error_at (location, "%<copy%> attribute is only valid for Objective-C objects");
1043 /* Now determine the final property getter and setter names. They
1044 will be stored in the PROPERTY_DECL, from which they'll always be
1045 extracted and used. */
1047 /* Adjust, or fill in, setter and getter names. We overwrite the
1048 parsed_property_setter_ident and parsed_property_getter_ident
1049 with the final setter and getter identifiers that will be
1050 used. */
1051 if (parsed_property_setter_ident)
1053 /* The setter should be terminated by ':', but the parser only
1054 gives us an identifier without ':'. So, we need to add ':'
1055 at the end. */
1056 const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident);
1057 size_t length = strlen (parsed_setter);
1058 char *final_setter = (char *)alloca (length + 2);
1060 sprintf (final_setter, "%s:", parsed_setter);
1061 parsed_property_setter_ident = get_identifier (final_setter);
1063 else
1065 if (!property_readonly)
1066 parsed_property_setter_ident = get_identifier (objc_build_property_setter_name
1067 (DECL_NAME (decl)));
1070 if (!parsed_property_getter_ident)
1071 parsed_property_getter_ident = DECL_NAME (decl);
1073 /* Check for duplicate property declarations. We first check the
1074 immediate context for a property with the same name. Any such
1075 declarations are an error. */
1076 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
1078 if (PROPERTY_NAME (x) == DECL_NAME (decl))
1080 location_t original_location = DECL_SOURCE_LOCATION (x);
1082 error_at (location, "redeclaration of property %qD", decl);
1084 if (original_location != UNKNOWN_LOCATION)
1085 inform (original_location, "originally specified here");
1086 return;
1090 /* We now need to check for existing property declarations (in the
1091 superclass, other categories or protocols) and check that the new
1092 declaration is not in conflict with existing ones. */
1094 /* Search for a previous, existing declaration of a property with
1095 the same name in superclasses, protocols etc. If one is found,
1096 it will be in the 'x' variable. */
1097 x = NULL_TREE;
1099 /* Note that, for simplicity, the following may search again the
1100 local context. That's Ok as nothing will be found (else we'd
1101 have thrown an error above); it's only a little inefficient, but
1102 the code is simpler. */
1103 switch (TREE_CODE (objc_interface_context))
1105 case CLASS_INTERFACE_TYPE:
1106 /* Look up the property in the current @interface (which will
1107 find nothing), then its protocols and categories and
1108 superclasses. */
1109 x = lookup_property (objc_interface_context, DECL_NAME (decl));
1110 break;
1111 case CATEGORY_INTERFACE_TYPE:
1112 /* Look up the property in the main @interface, then protocols
1113 and categories (one of them is ours, and will find nothing)
1114 and superclasses. */
1115 x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
1116 DECL_NAME (decl));
1117 break;
1118 case PROTOCOL_INTERFACE_TYPE:
1119 /* Looks up the property in any protocols attached to the
1120 current protocol. */
1121 if (PROTOCOL_LIST (objc_interface_context))
1123 x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
1124 DECL_NAME (decl));
1126 break;
1127 default:
1128 gcc_unreachable ();
1131 if (x != NULL_TREE)
1133 /* An existing property was found; check that it has the same
1134 types, or it is compatible. */
1135 location_t original_location = DECL_SOURCE_LOCATION (x);
1137 if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic)
1139 error_at (location, "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
1141 if (original_location != UNKNOWN_LOCATION)
1142 inform (original_location, "originally specified here");
1143 return;
1146 if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident)
1148 error_at (location, "'getter' attribute of property %qD conflicts with previous declaration", decl);
1150 if (original_location != UNKNOWN_LOCATION)
1151 inform (original_location, "originally specified here");
1152 return;
1155 /* We can only compare the setter names if both the old and new property have a setter. */
1156 if (!property_readonly && !PROPERTY_READONLY(x))
1158 if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident)
1160 error_at (location, "'setter' attribute of property %qD conflicts with previous declaration", decl);
1162 if (original_location != UNKNOWN_LOCATION)
1163 inform (original_location, "originally specified here");
1164 return;
1168 if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
1170 error_at (location, "assign semantics attributes of property %qD conflict with previous declaration", decl);
1172 if (original_location != UNKNOWN_LOCATION)
1173 inform (original_location, "originally specified here");
1174 return;
1177 /* It's ok to have a readonly property that becomes a readwrite, but not vice versa. */
1178 if (PROPERTY_READONLY (x) == 0 && property_readonly == 1)
1180 error_at (location, "'readonly' attribute of property %qD conflicts with previous declaration", decl);
1182 if (original_location != UNKNOWN_LOCATION)
1183 inform (original_location, "originally specified here");
1184 return;
1187 /* We now check that the new and old property declarations have
1188 the same types (or compatible one). In the Objective-C
1189 tradition of loose type checking, we do type-checking but
1190 only generate warnings (not errors) if they do not match.
1191 For non-readonly properties, the types must match exactly;
1192 for readonly properties, it is allowed to use a "more
1193 specialized" type in the new property declaration. Eg, the
1194 superclass has a getter returning (NSArray *) and the
1195 subclass a getter returning (NSMutableArray *). The object's
1196 getter returns an (NSMutableArray *); but if you cast the
1197 object to the superclass, which is allowed, you'd still
1198 expect the getter to return an (NSArray *), which works since
1199 an (NSMutableArray *) is an (NSArray *) too. So, the set of
1200 objects belonging to the type of the new @property should be
1201 a subset of the set of objects belonging to the type of the
1202 old @property. This is what "specialization" means. And the
1203 reason it only applies to readonly properties is that for a
1204 readwrite property the setter would have the opposite
1205 requirement - ie that the superclass type is more specialized
1206 then the subclass one; hence the only way to satisfy both
1207 constraints is that the types match. */
1209 /* If the types are not the same in the C sense, we warn ... */
1210 if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
1211 /* ... unless the property is readonly, in which case we
1212 allow a new, more specialized, declaration. */
1213 && (!property_readonly
1214 || !objc_compare_types (TREE_TYPE (x),
1215 TREE_TYPE (decl), -5, NULL_TREE)))
1217 warning_at (location, 0,
1218 "type of property %qD conflicts with previous declaration", decl);
1219 if (original_location != UNKNOWN_LOCATION)
1220 inform (original_location, "originally specified here");
1221 return;
1225 /* Create a PROPERTY_DECL node. */
1226 property_decl = make_node (PROPERTY_DECL);
1228 /* Copy the basic information from the original decl. */
1229 TREE_TYPE (property_decl) = TREE_TYPE (decl);
1230 DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
1231 TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
1233 /* Add property-specific information. */
1234 PROPERTY_NAME (property_decl) = DECL_NAME (decl);
1235 PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident;
1236 PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident;
1237 PROPERTY_READONLY (property_decl) = property_readonly;
1238 PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic;
1239 PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
1240 PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1241 PROPERTY_DYNAMIC (property_decl) = 0;
1243 /* Note that PROPERTY_GETTER_NAME is always set for all
1244 PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
1245 PROPERTY_DECLs where PROPERTY_READONLY == 0. Any time we deal
1246 with a getter or setter, we should get the PROPERTY_DECL and use
1247 PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
1248 names. */
1250 /* Add the PROPERTY_DECL to the list of properties for the class. */
1251 TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
1252 CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
1255 /* This is a subroutine of objc_maybe_build_component_ref. Search the
1256 list of methods in the interface (and, failing that, the local list
1257 in the implementation, and failing that, the protocol list)
1258 provided for a 'setter' or 'getter' for 'component' with default
1259 names (ie, if 'component' is "name", then search for "name" and
1260 "setName:"). If any is found, then create an artificial property
1261 that uses them. Return NULL_TREE if 'getter' or 'setter' could not
1262 be found. */
1263 static tree
1264 maybe_make_artificial_property_decl (tree interface, tree implementation,
1265 tree protocol_list, tree component, bool is_class)
1267 tree getter_name = component;
1268 tree setter_name = get_identifier (objc_build_property_setter_name (component));
1269 tree getter = NULL_TREE;
1270 tree setter = NULL_TREE;
1272 /* First, check the @interface and all superclasses. */
1273 if (interface)
1275 int flags = 0;
1277 /* Using instance methods of the root class as accessors is most
1278 likely unwanted and can be extremely confusing (and, most
1279 importantly, other Objective-C 2.0 compilers do not do it).
1280 Turn it off. */
1281 if (is_class)
1282 flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;
1284 getter = lookup_method_static (interface, getter_name, flags);
1285 setter = lookup_method_static (interface, setter_name, flags);
1288 /* Second, check the local @implementation context. */
1289 if (!getter && !setter)
1291 if (implementation)
1293 if (is_class)
1295 getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
1296 setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
1298 else
1300 getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
1301 setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);
1306 /* Try the protocol_list if we didn't find anything in the
1307 @interface and in the @implementation. */
1308 if (!getter && !setter)
1310 getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
1311 setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
1314 /* There needs to be at least a getter or setter for this to be a
1315 valid 'object.component' syntax. */
1316 if (getter || setter)
1318 /* Yes ... determine the type of the expression. */
1319 tree property_decl;
1320 tree type;
1322 if (getter)
1323 type = TREE_VALUE (TREE_TYPE (getter));
1324 else
1325 type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
1327 /* Create an artificial property declaration with the
1328 information we collected on the type and getter/setter
1329 names. */
1330 property_decl = make_node (PROPERTY_DECL);
1332 TREE_TYPE (property_decl) = type;
1333 DECL_SOURCE_LOCATION (property_decl) = input_location;
1334 TREE_DEPRECATED (property_decl) = 0;
1335 DECL_ARTIFICIAL (property_decl) = 1;
1337 /* Add property-specific information. Note that one of
1338 PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
1339 non-existing method; this will generate an error when the
1340 expression is later compiled. At this stage we don't know if
1341 the getter or setter will be used, so we can't generate an
1342 error. */
1343 PROPERTY_NAME (property_decl) = component;
1344 PROPERTY_GETTER_NAME (property_decl) = getter_name;
1345 PROPERTY_SETTER_NAME (property_decl) = setter_name;
1346 PROPERTY_READONLY (property_decl) = 0;
1347 PROPERTY_NONATOMIC (property_decl) = 0;
1348 PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
1349 PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1350 PROPERTY_DYNAMIC (property_decl) = 0;
1352 if (!getter)
1353 PROPERTY_HAS_NO_GETTER (property_decl) = 1;
1355 /* The following is currently unused, but it's nice to have
1356 there. We may use it if we need in the future. */
1357 if (!setter)
1358 PROPERTY_HAS_NO_SETTER (property_decl) = 1;
1360 return property_decl;
1363 return NULL_TREE;
1366 /* This hook routine is invoked by the parser when an expression such
1367 as 'xxx.yyy' is parsed. We get a chance to process these
1368 expressions in a way that is specified to Objective-C (to implement
1369 the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
1370 If the expression is not an Objective-C specified expression, we
1371 should return NULL_TREE; else we return the expression.
1373 At the moment this only implements dot-syntax and properties (not
1374 non-fragile ivars yet), ie 'object.property' or 'object.component'
1375 where 'component' is not a declared property, but a valid getter or
1376 setter for it could be found. */
1377 tree
1378 objc_maybe_build_component_ref (tree object, tree property_ident)
1380 tree x = NULL_TREE;
1381 tree rtype;
1383 /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
1384 not available. */
1385 if (flag_objc1_only)
1386 return NULL_TREE;
1388 /* Try to determine if 'object' is an Objective-C object or not. If
1389 not, return. */
1390 if (object == NULL_TREE || object == error_mark_node
1391 || (rtype = TREE_TYPE (object)) == NULL_TREE)
1392 return NULL_TREE;
1394 if (property_ident == NULL_TREE || property_ident == error_mark_node
1395 || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1396 return NULL_TREE;
1398 /* The following analysis of 'object' is similar to the one used for
1399 the 'receiver' of a method invocation. We need to determine what
1400 'object' is and find the appropriate property (either declared,
1401 or artificial) for it (in the same way as we need to find the
1402 appropriate method prototype for a method invocation). There are
1403 some simplifications here though: "object.property" is invalid if
1404 "object" has a type of "id" or "Class"; it must at least have a
1405 protocol attached to it, and "object" is never a class name as
1406 that is done by objc_build_class_component_ref. Finally, we
1407 don't know if this really is a dot-syntax expression, so we want
1408 to make a quick exit if it is not; for this reason, we try to
1409 postpone checks after determining that 'object' looks like an
1410 Objective-C object. */
1412 if (objc_is_id (rtype))
1414 /* This is the case that the 'object' is of type 'id' or
1415 'Class'. */
1417 /* Check if at least it is of type 'id <Protocol>' or 'Class
1418 <Protocol>'; if so, look the property up in the
1419 protocols. */
1420 if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
1422 tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));
1424 if (rprotos)
1426 /* No point looking up declared @properties if we are
1427 dealing with a class. Classes have no declared
1428 properties. */
1429 if (!IS_CLASS (rtype))
1430 x = lookup_property_in_protocol_list (rprotos, property_ident);
1432 if (x == NULL_TREE)
1434 /* Ok, no property. Maybe it was an
1435 object.component dot-syntax without a declared
1436 property (this is valid for classes too). Look
1437 for getter/setter methods and internally declare
1438 an artifical property based on them if found. */
1439 x = maybe_make_artificial_property_decl (NULL_TREE,
1440 NULL_TREE,
1441 rprotos,
1442 property_ident,
1443 IS_CLASS (rtype));
1447 else if (objc_method_context)
1449 /* Else, if we are inside a method it could be the case of
1450 'super' or 'self'. */
1451 tree interface_type = NULL_TREE;
1452 tree t = object;
1453 while (TREE_CODE (t) == COMPOUND_EXPR
1454 || TREE_CODE (t) == MODIFY_EXPR
1455 || CONVERT_EXPR_P (t)
1456 || TREE_CODE (t) == COMPONENT_REF)
1457 t = TREE_OPERAND (t, 0);
1459 if (t == UOBJC_SUPER_decl)
1461 /* TODO: Check if this is correct also for 'super' in categories. */
1462 interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
1464 else if (t == self_decl)
1465 interface_type = lookup_interface (CLASS_NAME (implementation_template));
1467 if (interface_type)
1469 if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
1470 x = lookup_property (interface_type, property_ident);
1472 if (x == NULL_TREE)
1474 /* Try the dot-syntax without a declared property.
1475 If this is an access to 'self', it is possible
1476 that they may refer to a setter/getter that is
1477 not declared in the interface, but exists locally
1478 in the implementation. In that case, get the
1479 implementation context and use it. */
1480 tree implementation = NULL_TREE;
1482 if (t == self_decl)
1483 implementation = objc_implementation_context;
1485 x = maybe_make_artificial_property_decl
1486 (interface_type, implementation, NULL_TREE,
1487 property_ident,
1488 (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL));
1493 else
1495 /* This is the case where we have more information on 'rtype'. */
1496 tree basetype = TYPE_MAIN_VARIANT (rtype);
1498 /* Skip the pointer - if none, it's not an Objective-C object or
1499 class. */
1500 if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1501 basetype = TREE_TYPE (basetype);
1502 else
1503 return NULL_TREE;
1505 /* Traverse typedefs. */
1506 while (basetype != NULL_TREE
1507 && TREE_CODE (basetype) == RECORD_TYPE
1508 && OBJC_TYPE_NAME (basetype)
1509 && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1510 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1511 basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1513 if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1515 tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1516 tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
1518 if (interface_type
1519 && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
1520 || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
1521 || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
1523 /* Not sure 'rtype' could ever be a class here! Just
1524 for safety we keep the checks. */
1525 if (!IS_CLASS (rtype))
1527 x = lookup_property (interface_type, property_ident);
1529 if (x == NULL_TREE)
1530 x = lookup_property_in_protocol_list (protocol_list,
1531 property_ident);
1534 if (x == NULL_TREE)
1536 /* Try the dot-syntax without a declared property.
1537 If we are inside a method implementation, it is
1538 possible that they may refer to a setter/getter
1539 that is not declared in the interface, but exists
1540 locally in the implementation. In that case, get
1541 the implementation context and use it. */
1542 tree implementation = NULL_TREE;
1544 if (objc_implementation_context
1545 && CLASS_NAME (objc_implementation_context)
1546 == OBJC_TYPE_NAME (interface_type))
1547 implementation = objc_implementation_context;
1549 x = maybe_make_artificial_property_decl (interface_type,
1550 implementation,
1551 protocol_list,
1552 property_ident,
1553 IS_CLASS (rtype));
1559 if (x)
1561 tree expression;
1562 tree getter_call;
1564 /* We have an additional nasty problem here; if this
1565 PROPERTY_REF needs to become a 'getter', then the conversion
1566 from PROPERTY_REF into a getter call happens in gimplify,
1567 after the selector table has already been generated and when
1568 it is too late to add another selector to it. To work around
1569 the problem, we always create the getter call at this stage,
1570 which puts the selector in the table. Note that if the
1571 PROPERTY_REF becomes a 'setter' instead of a 'getter', then
1572 we have added a selector too many to the selector table.
1573 This is a little inefficient.
1575 Also note that method calls to 'self' and 'super' require the
1576 context (self_decl, UOBJS_SUPER_decl,
1577 objc_implementation_context etc) to be built correctly; this
1578 is yet another reason why building the call at the gimplify
1579 stage (when this context has been lost) is not very
1580 practical. If we build it at this stage, we know it will
1581 always be built correctly.
1583 If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
1584 property decl created to deal with a dotsyntax not really
1585 referring to an existing property) then do not try to build a
1586 call to the getter as there is no getter. */
1587 if (PROPERTY_HAS_NO_GETTER (x))
1588 getter_call = NULL_TREE;
1589 else
1590 getter_call = objc_finish_message_expr (object,
1591 PROPERTY_GETTER_NAME (x),
1592 NULL_TREE);
1594 if (TREE_DEPRECATED (x))
1595 warn_deprecated_use (x, NULL_TREE);
1597 expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1598 SET_EXPR_LOCATION (expression, input_location);
1599 TREE_SIDE_EFFECTS (expression) = 1;
1601 return expression;
1604 return NULL_TREE;
1607 /* This hook routine is invoked by the parser when an expression such
1608 as 'xxx.yyy' is parsed, and 'xxx' is a class name. This is the
1609 Objective-C 2.0 dot-syntax applied to classes, so we need to
1610 convert it into a setter/getter call on the class. */
1611 tree
1612 objc_build_class_component_ref (tree class_name, tree property_ident)
1614 tree x = NULL_TREE;
1615 tree object, rtype;
1617 if (flag_objc1_only)
1618 error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
1620 if (class_name == NULL_TREE || class_name == error_mark_node
1621 || TREE_CODE (class_name) != IDENTIFIER_NODE)
1622 return error_mark_node;
1624 if (property_ident == NULL_TREE || property_ident == error_mark_node
1625 || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1626 return NULL_TREE;
1628 object = objc_get_class_reference (class_name);
1629 if (!object)
1631 /* We know that 'class_name' is an Objective-C class name as the
1632 parser won't call this function if it is not. This is only a
1633 double-check for safety. */
1634 error_at (input_location, "could not find class %qE", class_name);
1635 return error_mark_node;
1638 rtype = lookup_interface (class_name);
1639 if (!rtype)
1641 /* Again, this should never happen, but we do check. */
1642 error_at (input_location, "could not find interface for class %qE", class_name);
1643 return error_mark_node;
1646 x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
1647 property_ident,
1648 true);
1650 if (x)
1652 tree expression;
1653 tree getter_call;
1655 if (PROPERTY_HAS_NO_GETTER (x))
1656 getter_call = NULL_TREE;
1657 else
1658 getter_call = objc_finish_message_expr (object,
1659 PROPERTY_GETTER_NAME (x),
1660 NULL_TREE);
1661 if (TREE_DEPRECATED (x))
1662 warn_deprecated_use (x, NULL_TREE);
1664 expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1665 SET_EXPR_LOCATION (expression, input_location);
1666 TREE_SIDE_EFFECTS (expression) = 1;
1668 return expression;
1670 else
1672 error_at (input_location, "could not find setter/getter for %qE in class %qE",
1673 property_ident, class_name);
1674 return error_mark_node;
1677 return NULL_TREE;
1682 /* This is used because we don't want to expose PROPERTY_REF to the
1683 C/C++ frontends. Maybe we should! */
1684 bool
1685 objc_is_property_ref (tree node)
1687 if (node && TREE_CODE (node) == PROPERTY_REF)
1688 return true;
1689 else
1690 return false;
1693 /* This hook routine is called when a MODIFY_EXPR is being built. We
1694 check what is being modified; if it is a PROPERTY_REF, we need to
1695 generate a 'setter' function call for the property. If this is not
1696 a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
1697 on creating their MODIFY_EXPR.
1699 This is used for example if you write
1701 object.count = 1;
1703 where 'count' is a property. The left-hand side creates a
1704 PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
1705 to assign something to it. We intercept that here, and generate a
1706 call to the 'setter' method instead. */
1707 tree
1708 objc_maybe_build_modify_expr (tree lhs, tree rhs)
1710 if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
1712 tree object_expr = PROPERTY_REF_OBJECT (lhs);
1713 tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
1715 if (PROPERTY_READONLY (property_decl))
1717 error ("readonly property can not be set");
1718 return error_mark_node;
1720 else
1722 tree setter_argument = build_tree_list (NULL_TREE, rhs);
1723 tree setter;
1725 /* TODO: Check that the setter return type is 'void'. */
1727 /* TODO: Decay argument in C. */
1728 setter = objc_finish_message_expr (object_expr,
1729 PROPERTY_SETTER_NAME (property_decl),
1730 setter_argument);
1731 return setter;
1734 else
1735 return NULL_TREE;
1738 tree
1739 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1740 tree optparms, bool ellipsis)
1742 if (is_class_method)
1743 return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
1744 optparms, ellipsis);
1745 else
1746 return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
1747 optparms, ellipsis);
1750 void
1751 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
1753 if (!objc_interface_context)
1755 /* PS: At the moment, due to how the parser works, it should be
1756 impossible to get here. But it's good to have the check in
1757 case the parser changes.
1759 fatal_error ("method declaration not in @interface context");
1762 if (flag_objc1_only && attributes)
1763 error_at (input_location, "method attributes are not available in Objective-C 1.0");
1765 objc_decl_method_attributes (&decl, attributes, 0);
1766 objc_add_method (objc_interface_context,
1767 decl,
1768 is_class_method,
1769 objc_method_optional_flag);
1772 /* Return 'true' if the method definition could be started, and
1773 'false' if not (because we are outside an @implementation context).
1775 bool
1776 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
1778 if (!objc_implementation_context)
1780 error ("method definition not in @implementation context");
1781 return false;
1784 if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node)
1785 return false;
1787 #ifndef OBJCPLUS
1788 /* Indicate no valid break/continue context by setting these variables
1789 to some non-null, non-label value. We'll notice and emit the proper
1790 error message in c_finish_bc_stmt. */
1791 c_break_label = c_cont_label = size_zero_node;
1792 #endif
1794 if (attributes)
1795 warning_at (input_location, 0, "method attributes can not be specified in @implementation context");
1796 else
1797 objc_decl_method_attributes (&decl, attributes, 0);
1799 objc_add_method (objc_implementation_context,
1800 decl,
1801 is_class_method,
1802 /* is optional */ false);
1803 start_method_def (decl);
1804 return true;
1807 void
1808 objc_add_instance_variable (tree decl)
1810 (void) add_instance_variable (objc_ivar_context,
1811 objc_ivar_visibility,
1812 decl);
1815 /* Return true if TYPE is 'id'. */
1817 static bool
1818 objc_is_object_id (tree type)
1820 return OBJC_TYPE_NAME (type) == objc_object_id;
1823 static bool
1824 objc_is_class_id (tree type)
1826 return OBJC_TYPE_NAME (type) == objc_class_id;
1829 /* Construct a C struct with same name as KLASS, a base struct with tag
1830 SUPER_NAME (if any), and FIELDS indicated. */
1832 static tree
1833 objc_build_struct (tree klass, tree fields, tree super_name)
1835 tree name = CLASS_NAME (klass);
1836 tree s = objc_start_struct (name);
1837 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
1838 tree t;
1839 VEC(tree,heap) *objc_info = NULL;
1840 int i;
1842 if (super)
1844 /* Prepend a packed variant of the base class into the layout. This
1845 is necessary to preserve ObjC ABI compatibility. */
1846 tree base = build_decl (input_location,
1847 FIELD_DECL, NULL_TREE, super);
1848 tree field = TYPE_FIELDS (super);
1850 while (field && DECL_CHAIN (field)
1851 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
1852 field = DECL_CHAIN (field);
1854 /* For ObjC ABI purposes, the "packed" size of a base class is
1855 the sum of the offset and the size (in bits) of the last field
1856 in the class. */
1857 DECL_SIZE (base)
1858 = (field && TREE_CODE (field) == FIELD_DECL
1859 ? size_binop (PLUS_EXPR,
1860 size_binop (PLUS_EXPR,
1861 size_binop
1862 (MULT_EXPR,
1863 convert (bitsizetype,
1864 DECL_FIELD_OFFSET (field)),
1865 bitsize_int (BITS_PER_UNIT)),
1866 DECL_FIELD_BIT_OFFSET (field)),
1867 DECL_SIZE (field))
1868 : bitsize_zero_node);
1869 DECL_SIZE_UNIT (base)
1870 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
1871 size_int (BITS_PER_UNIT));
1872 DECL_ARTIFICIAL (base) = 1;
1873 DECL_ALIGN (base) = 1;
1874 DECL_FIELD_CONTEXT (base) = s;
1875 #ifdef OBJCPLUS
1876 DECL_FIELD_IS_BASE (base) = 1;
1878 if (fields)
1879 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
1880 #endif /* are following the ObjC ABI here. */
1881 DECL_CHAIN (base) = fields;
1882 fields = base;
1885 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1886 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1887 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1888 Hence, we must squirrel away the ObjC-specific information before calling
1889 finish_struct(), and then reinstate it afterwards. */
1891 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
1893 if (!TYPE_HAS_OBJC_INFO (t))
1895 INIT_TYPE_OBJC_INFO (t);
1896 TYPE_OBJC_INTERFACE (t) = klass;
1898 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
1901 /* Point the struct at its related Objective-C class. */
1902 INIT_TYPE_OBJC_INFO (s);
1903 TYPE_OBJC_INTERFACE (s) = klass;
1905 s = objc_finish_struct (s, fields);
1907 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
1909 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
1910 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1911 TYPE_OBJC_INTERFACE (t) = klass;
1913 VEC_free (tree, heap, objc_info);
1915 /* Use TYPE_BINFO structures to point at the super class, if any. */
1916 objc_xref_basetypes (s, super);
1918 /* Mark this struct as a class template. */
1919 CLASS_STATIC_TEMPLATE (klass) = s;
1921 return s;
1924 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1925 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1926 process. */
1927 static tree
1928 objc_build_volatilized_type (tree type)
1930 tree t;
1932 /* Check if we have not constructed the desired variant already. */
1933 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1935 /* The type qualifiers must (obviously) match up. */
1936 if (!TYPE_VOLATILE (t)
1937 || (TYPE_READONLY (t) != TYPE_READONLY (type))
1938 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
1939 continue;
1941 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1942 info, if any) must match up. */
1943 if (POINTER_TYPE_P (t)
1944 && (TREE_TYPE (t) != TREE_TYPE (type)))
1945 continue;
1947 /* Only match up the types which were previously volatilized in similar fashion and not
1948 because they were declared as such. */
1949 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
1950 continue;
1952 /* Everything matches up! */
1953 return t;
1956 /* Ok, we could not re-use any of the pre-existing variants. Create
1957 a new one. */
1958 t = build_variant_type_copy (type);
1959 TYPE_VOLATILE (t) = 1;
1961 TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
1962 tree_cons (get_identifier ("objc_volatilized"),
1963 NULL_TREE,
1964 NULL_TREE));
1965 if (TREE_CODE (t) == ARRAY_TYPE)
1966 TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
1968 /* Set up the canonical type information. */
1969 if (TYPE_STRUCTURAL_EQUALITY_P (type))
1970 SET_TYPE_STRUCTURAL_EQUALITY (t);
1971 else if (TYPE_CANONICAL (type) != type)
1972 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
1973 else
1974 TYPE_CANONICAL (t) = t;
1976 return t;
1979 /* Mark DECL as being 'volatile' for purposes of Darwin
1980 _setjmp()/_longjmp() exception handling. Called from
1981 objc_mark_locals_volatile(). */
1982 void
1983 objc_volatilize_decl (tree decl)
1985 /* Do not mess with variables that are 'static' or (already)
1986 'volatile'. */
1987 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
1988 && (TREE_CODE (decl) == VAR_DECL
1989 || TREE_CODE (decl) == PARM_DECL))
1991 tree t = TREE_TYPE (decl);
1993 t = objc_build_volatilized_type (t);
1995 TREE_TYPE (decl) = t;
1996 TREE_THIS_VOLATILE (decl) = 1;
1997 TREE_SIDE_EFFECTS (decl) = 1;
1998 DECL_REGISTER (decl) = 0;
1999 #ifndef OBJCPLUS
2000 C_DECL_REGISTER (decl) = 0;
2001 #endif
2005 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
2006 (including its categories and superclasses) or by object type TYP.
2007 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
2009 static bool
2010 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
2012 bool class_type = (cls != NULL_TREE);
2014 while (cls)
2016 tree c;
2018 /* Check protocols adopted by the class and its categories. */
2019 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
2021 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
2022 return true;
2025 /* Repeat for superclasses. */
2026 cls = lookup_interface (CLASS_SUPER_NAME (cls));
2029 /* Check for any protocols attached directly to the object type. */
2030 if (TYPE_HAS_OBJC_INFO (typ))
2032 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
2033 return true;
2036 if (warn)
2038 *errbuf = 0;
2039 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
2040 /* NB: Types 'id' and 'Class' cannot reasonably be described as
2041 "implementing" a given protocol, since they do not have an
2042 implementation. */
2043 if (class_type)
2044 warning (0, "class %qs does not implement the %qE protocol",
2045 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2046 else
2047 warning (0, "type %qs does not conform to the %qE protocol",
2048 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2051 return false;
2054 /* Check if class RCLS and instance struct type RTYP conform to at least the
2055 same protocols that LCLS and LTYP conform to. */
2057 static bool
2058 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
2060 tree p;
2061 bool have_lproto = false;
2063 while (lcls)
2065 /* NB: We do _not_ look at categories defined for LCLS; these may or
2066 may not get loaded in, and therefore it is unreasonable to require
2067 that RCLS/RTYP must implement any of their protocols. */
2068 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
2070 have_lproto = true;
2072 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2073 return warn;
2076 /* Repeat for superclasses. */
2077 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
2080 /* Check for any protocols attached directly to the object type. */
2081 if (TYPE_HAS_OBJC_INFO (ltyp))
2083 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
2085 have_lproto = true;
2087 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2088 return warn;
2092 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
2093 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
2094 away with simply checking for 'id' or 'Class' (!RCLS), since this
2095 routine will not get called in other cases. */
2096 return have_lproto || (rcls != NULL_TREE);
2099 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
2100 Both TYPE1 and TYPE2 must be pointers, and already determined to be
2101 compatible by objc_compare_types() below. */
2103 tree
2104 objc_common_type (tree type1, tree type2)
2106 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
2108 while (POINTER_TYPE_P (inner1))
2110 inner1 = TREE_TYPE (inner1);
2111 inner2 = TREE_TYPE (inner2);
2114 /* If one type is derived from another, return the base type. */
2115 if (DERIVED_FROM_P (inner1, inner2))
2116 return type1;
2117 else if (DERIVED_FROM_P (inner2, inner1))
2118 return type2;
2120 /* If both types are 'Class', return 'Class'. */
2121 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
2122 return objc_class_type;
2124 /* Otherwise, return 'id'. */
2125 return objc_object_type;
2128 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
2129 an instance of RTYP to an instance of LTYP or to compare the two
2130 (if ARGNO is equal to -3), per ObjC type system rules. Before
2131 returning 'true', this routine may issue warnings related to, e.g.,
2132 protocol conformance. When returning 'false', the routine must
2133 produce absolutely no warnings; the C or C++ front-end will do so
2134 instead, if needed. If either LTYP or RTYP is not an Objective-C
2135 type, the routine must return 'false'.
2137 The ARGNO parameter is encoded as follows:
2138 >= 1 Parameter number (CALLEE contains function being called);
2139 0 Return value;
2140 -1 Assignment;
2141 -2 Initialization;
2142 -3 Comparison (LTYP and RTYP may match in either direction);
2143 -4 Silent comparison (for C++ overload resolution);
2144 -5 Silent "specialization" comparison for RTYP to be a "specialization"
2145 of LTYP (a specialization means that RTYP is LTYP plus some constraints,
2146 so that each object of type RTYP is also of type LTYP). This is used
2147 when comparing property types. */
2149 bool
2150 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
2152 tree lcls, rcls, lproto, rproto;
2153 bool pointers_compatible;
2155 /* We must be dealing with pointer types */
2156 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
2157 return false;
2161 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
2162 rtyp = TREE_TYPE (rtyp);
2164 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2166 /* We must also handle function pointers, since ObjC is a bit more
2167 lenient than C or C++ on this. */
2168 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
2170 /* Return types must be covariant. */
2171 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
2172 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
2173 argno, callee))
2174 return false;
2176 /* Argument types must be contravariant. */
2177 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
2178 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
2180 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
2181 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
2182 argno, callee))
2183 return false;
2186 return (ltyp == rtyp);
2189 /* Past this point, we are only interested in ObjC class instances,
2190 or 'id' or 'Class'. */
2191 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
2192 return false;
2194 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
2195 && !TYPE_HAS_OBJC_INFO (ltyp))
2196 return false;
2198 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
2199 && !TYPE_HAS_OBJC_INFO (rtyp))
2200 return false;
2202 /* Past this point, we are committed to returning 'true' to the caller
2203 (unless performing a silent comparison; see below). However, we can
2204 still warn about type and/or protocol mismatches. */
2206 if (TYPE_HAS_OBJC_INFO (ltyp))
2208 lcls = TYPE_OBJC_INTERFACE (ltyp);
2209 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
2211 else
2212 lcls = lproto = NULL_TREE;
2214 if (TYPE_HAS_OBJC_INFO (rtyp))
2216 rcls = TYPE_OBJC_INTERFACE (rtyp);
2217 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
2219 else
2220 rcls = rproto = NULL_TREE;
2222 /* If we could not find an @interface declaration, we must have
2223 only seen a @class declaration; for purposes of type comparison,
2224 treat it as a stand-alone (root) class. */
2226 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
2227 lcls = NULL_TREE;
2229 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
2230 rcls = NULL_TREE;
2232 /* If either type is an unqualified 'id', we're done. This is because
2233 an 'id' can be assigned to or from any type with no warnings. */
2234 if (argno != -5)
2236 if ((!lproto && objc_is_object_id (ltyp))
2237 || (!rproto && objc_is_object_id (rtyp)))
2238 return true;
2240 else
2242 /* For property checks, though, an 'id' is considered the most
2243 general type of object, hence if you try to specialize an
2244 'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
2245 to warn. */
2246 if (!lproto && objc_is_object_id (ltyp))
2247 return true;
2250 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
2252 /* If the underlying types are the same, and at most one of them has
2253 a protocol list, we do not need to issue any diagnostics. */
2254 if (pointers_compatible && (!lproto || !rproto))
2255 return true;
2257 /* If exactly one of the types is 'Class', issue a diagnostic; any
2258 exceptions of this rule have already been handled. */
2259 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
2260 pointers_compatible = false;
2261 /* Otherwise, check for inheritance relations. */
2262 else
2264 if (!pointers_compatible)
2266 /* Again, if any of the two is an 'id', we're satisfied,
2267 unless we're comparing properties, in which case only an
2268 'id' on the left-hand side (old property) is good
2269 enough. */
2270 if (argno != -5)
2271 pointers_compatible
2272 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
2273 else
2274 pointers_compatible = objc_is_object_id (ltyp);
2277 if (!pointers_compatible)
2278 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
2280 if (!pointers_compatible && (argno == -3 || argno == -4))
2281 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
2284 /* If the pointers match modulo protocols, check for protocol conformance
2285 mismatches. */
2286 if (pointers_compatible)
2288 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
2289 argno != -3);
2291 if (!pointers_compatible && argno == -3)
2292 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
2293 argno != -3);
2296 if (!pointers_compatible)
2298 /* The two pointers are not exactly compatible. Issue a warning, unless
2299 we are performing a silent comparison, in which case return 'false'
2300 instead. */
2301 /* NB: For the time being, we shall make our warnings look like their
2302 C counterparts. In the future, we may wish to make them more
2303 ObjC-specific. */
2304 switch (argno)
2306 case -5:
2307 case -4:
2308 return false;
2310 case -3:
2311 warning (0, "comparison of distinct Objective-C types lacks a cast");
2312 break;
2314 case -2:
2315 warning (0, "initialization from distinct Objective-C type");
2316 break;
2318 case -1:
2319 warning (0, "assignment from distinct Objective-C type");
2320 break;
2322 case 0:
2323 warning (0, "distinct Objective-C type in return");
2324 break;
2326 default:
2327 warning (0, "passing argument %d of %qE from distinct "
2328 "Objective-C type", argno, callee);
2329 break;
2333 return true;
2336 /* This routine is similar to objc_compare_types except that function-pointers are
2337 excluded. This is because, caller assumes that common types are of (id, Object*)
2338 variety and calls objc_common_type to obtain a common type. There is no commonolty
2339 between two function-pointers in this regard. */
2341 bool
2342 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
2344 if (objc_compare_types (ltyp, rtyp, argno, callee))
2346 /* exclude function-pointer types. */
2349 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
2350 rtyp = TREE_TYPE (rtyp);
2352 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2353 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
2355 return false;
2358 /* Check if LTYP and RTYP have the same type qualifiers. If either type
2359 lives in the volatilized hash table, ignore the 'volatile' bit when
2360 making the comparison. */
2362 bool
2363 objc_type_quals_match (tree ltyp, tree rtyp)
2365 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
2367 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
2368 lquals &= ~TYPE_QUAL_VOLATILE;
2370 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
2371 rquals &= ~TYPE_QUAL_VOLATILE;
2373 return (lquals == rquals);
2376 #ifndef OBJCPLUS
2377 /* Determine if CHILD is derived from PARENT. The routine assumes that
2378 both parameters are RECORD_TYPEs, and is non-reflexive. */
2380 static bool
2381 objc_derived_from_p (tree parent, tree child)
2383 parent = TYPE_MAIN_VARIANT (parent);
2385 for (child = TYPE_MAIN_VARIANT (child);
2386 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
2388 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
2389 (TYPE_BINFO (child),
2390 0)));
2392 if (child == parent)
2393 return true;
2396 return false;
2398 #endif
2400 static tree
2401 objc_build_component_ref (tree datum, tree component)
2403 /* If COMPONENT is NULL, the caller is referring to the anonymous
2404 base class field. */
2405 if (!component)
2407 tree base = TYPE_FIELDS (TREE_TYPE (datum));
2409 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
2412 /* The 'build_component_ref' routine has been removed from the C++
2413 front-end, but 'finish_class_member_access_expr' seems to be
2414 a worthy substitute. */
2415 #ifdef OBJCPLUS
2416 return finish_class_member_access_expr (datum, component, false,
2417 tf_warning_or_error);
2418 #else
2419 return build_component_ref (input_location, datum, component);
2420 #endif
2423 /* Recursively copy inheritance information rooted at BINFO. To do this,
2424 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
2426 static tree
2427 objc_copy_binfo (tree binfo)
2429 tree btype = BINFO_TYPE (binfo);
2430 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
2431 tree base_binfo;
2432 int ix;
2434 BINFO_TYPE (binfo2) = btype;
2435 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
2436 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
2438 /* Recursively copy base binfos of BINFO. */
2439 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
2441 tree base_binfo2 = objc_copy_binfo (base_binfo);
2443 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
2444 BINFO_BASE_APPEND (binfo2, base_binfo2);
2447 return binfo2;
2450 /* Record superclass information provided in BASETYPE for ObjC class REF.
2451 This is loosely based on cp/decl.c:xref_basetypes(). */
2453 static void
2454 objc_xref_basetypes (tree ref, tree basetype)
2456 tree binfo = make_tree_binfo (basetype ? 1 : 0);
2458 TYPE_BINFO (ref) = binfo;
2459 BINFO_OFFSET (binfo) = size_zero_node;
2460 BINFO_TYPE (binfo) = ref;
2462 if (basetype)
2464 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
2466 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
2467 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
2468 BINFO_BASE_APPEND (binfo, base_binfo);
2469 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
2473 /* Called from finish_decl. */
2475 void
2476 objc_check_decl (tree decl)
2478 tree type = TREE_TYPE (decl);
2480 if (TREE_CODE (type) != RECORD_TYPE)
2481 return;
2482 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
2483 error ("statically allocated instance of Objective-C class %qE",
2484 type);
2487 void
2488 objc_check_global_decl (tree decl)
2490 tree id = DECL_NAME (decl);
2491 if (objc_is_class_name (id) && global_bindings_p())
2492 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2495 /* Return a non-volatalized version of TYPE. */
2497 tree
2498 objc_non_volatilized_type (tree type)
2500 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
2501 type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
2502 return type;
2505 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2506 either name an Objective-C class, or refer to the special 'id' or 'Class'
2507 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2509 tree
2510 objc_get_protocol_qualified_type (tree interface, tree protocols)
2512 /* If INTERFACE is not provided, default to 'id'. */
2513 tree type = (interface ? objc_is_id (interface) : objc_object_type);
2514 bool is_ptr = (type != NULL_TREE);
2516 if (!is_ptr)
2518 type = objc_is_class_name (interface);
2520 if (type)
2522 /* If looking at a typedef, retrieve the precise type it
2523 describes. */
2524 if (TREE_CODE (interface) == IDENTIFIER_NODE)
2525 interface = identifier_global_value (interface);
2527 type = ((interface && TREE_CODE (interface) == TYPE_DECL
2528 && DECL_ORIGINAL_TYPE (interface))
2529 ? DECL_ORIGINAL_TYPE (interface)
2530 : xref_tag (RECORD_TYPE, type));
2532 else
2533 return interface;
2536 if (protocols)
2538 type = build_variant_type_copy (type);
2540 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2541 to the pointee. */
2542 if (is_ptr)
2544 tree orig_pointee_type = TREE_TYPE (type);
2545 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2547 /* Set up the canonical type information. */
2548 TYPE_CANONICAL (type)
2549 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2551 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2552 type = TREE_TYPE (type);
2555 /* Look up protocols and install in lang specific list. */
2556 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2557 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2559 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2560 return the pointer to the new pointee variant. */
2561 if (is_ptr)
2562 type = TYPE_POINTER_TO (type);
2563 else
2564 TYPE_OBJC_INTERFACE (type)
2565 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2568 return type;
2571 /* Check for circular dependencies in protocols. The arguments are
2572 PROTO, the protocol to check, and LIST, a list of protocol it
2573 conforms to. */
2575 static void
2576 check_protocol_recursively (tree proto, tree list)
2578 tree p;
2580 for (p = list; p; p = TREE_CHAIN (p))
2582 tree pp = TREE_VALUE (p);
2584 if (TREE_CODE (pp) == IDENTIFIER_NODE)
2585 pp = lookup_protocol (pp);
2587 if (pp == proto)
2588 fatal_error ("protocol %qE has circular dependency",
2589 PROTOCOL_NAME (pp));
2590 if (pp)
2591 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2595 /* Look up PROTOCOLS, and return a list of those that are found.
2596 If none are found, return NULL. */
2598 static tree
2599 lookup_and_install_protocols (tree protocols)
2601 tree proto;
2602 tree return_value = NULL_TREE;
2604 if (protocols == error_mark_node)
2605 return NULL;
2607 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2609 tree ident = TREE_VALUE (proto);
2610 tree p = lookup_protocol (ident);
2612 if (p)
2613 return_value = chainon (return_value,
2614 build_tree_list (NULL_TREE, p));
2615 else if (ident != error_mark_node)
2616 error ("cannot find protocol declaration for %qE",
2617 ident);
2620 return return_value;
2623 /* Create a declaration for field NAME of a given TYPE. */
2625 static tree
2626 create_field_decl (tree type, const char *name)
2628 return build_decl (input_location,
2629 FIELD_DECL, get_identifier (name), type);
2632 /* Create a global, static declaration for variable NAME of a given TYPE. The
2633 finish_var_decl() routine will need to be called on it afterwards. */
2635 static tree
2636 start_var_decl (tree type, const char *name)
2638 tree var = build_decl (input_location,
2639 VAR_DECL, get_identifier (name), type);
2641 TREE_STATIC (var) = 1;
2642 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
2643 DECL_IGNORED_P (var) = 1;
2644 DECL_ARTIFICIAL (var) = 1;
2645 DECL_CONTEXT (var) = NULL_TREE;
2646 #ifdef OBJCPLUS
2647 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2648 #endif
2650 return var;
2653 /* Finish off the variable declaration created by start_var_decl(). */
2655 static void
2656 finish_var_decl (tree var, tree initializer)
2658 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2661 /* Find the decl for the constant string class reference. This is only
2662 used for the NeXT runtime. */
2664 static tree
2665 setup_string_decl (void)
2667 char *name;
2668 size_t length;
2670 /* %s in format will provide room for terminating null */
2671 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2672 + strlen (constant_string_class_name);
2673 name = XNEWVEC (char, length);
2674 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2675 constant_string_class_name);
2676 constant_string_global_id = get_identifier (name);
2677 string_class_decl = lookup_name (constant_string_global_id);
2679 return string_class_decl;
2682 /* Purpose: "play" parser, creating/installing representations
2683 of the declarations that are required by Objective-C.
2685 Model:
2687 type_spec--------->sc_spec
2688 (tree_list) (tree_list)
2691 identifier_node identifier_node */
2693 static void
2694 synth_module_prologue (void)
2696 tree type;
2697 enum debug_info_type save_write_symbols = write_symbols;
2698 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2700 /* Suppress outputting debug symbols, because
2701 dbxout_init hasn't been called yet. */
2702 write_symbols = NO_DEBUG;
2703 debug_hooks = &do_nothing_debug_hooks;
2705 #ifdef OBJCPLUS
2706 push_lang_context (lang_name_c); /* extern "C" */
2707 #endif
2709 /* The following are also defined in <objc/objc.h> and friends. */
2711 objc_object_id = get_identifier (TAG_OBJECT);
2712 objc_class_id = get_identifier (TAG_CLASS);
2714 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2715 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2717 objc_object_type = build_pointer_type (objc_object_reference);
2718 objc_class_type = build_pointer_type (objc_class_reference);
2720 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2721 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2723 /* Declare the 'id' and 'Class' typedefs. */
2725 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2726 TYPE_DECL,
2727 objc_object_name,
2728 objc_object_type));
2729 TREE_NO_WARNING (type) = 1;
2730 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2731 TYPE_DECL,
2732 objc_class_name,
2733 objc_class_type));
2734 TREE_NO_WARNING (type) = 1;
2736 /* Forward-declare '@interface Protocol'. */
2738 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
2739 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
2740 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
2741 type));
2743 /* Declare type of selector-objects that represent an operation name. */
2745 if (flag_next_runtime)
2746 /* `struct objc_selector *' */
2747 objc_selector_type
2748 = build_pointer_type (xref_tag (RECORD_TYPE,
2749 get_identifier (TAG_SELECTOR)));
2750 else
2751 /* `const struct objc_selector *' */
2752 objc_selector_type
2753 = build_pointer_type
2754 (build_qualified_type (xref_tag (RECORD_TYPE,
2755 get_identifier (TAG_SELECTOR)),
2756 TYPE_QUAL_CONST));
2758 /* Declare receiver type used for dispatching messages to 'super'. */
2760 /* `struct objc_super *' */
2761 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
2762 get_identifier (TAG_SUPER)));
2764 /* Declare pointers to method and ivar lists. */
2765 objc_method_list_ptr = build_pointer_type
2766 (xref_tag (RECORD_TYPE,
2767 get_identifier (UTAG_METHOD_LIST)));
2768 objc_method_proto_list_ptr
2769 = build_pointer_type (xref_tag (RECORD_TYPE,
2770 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2771 objc_ivar_list_ptr = build_pointer_type
2772 (xref_tag (RECORD_TYPE,
2773 get_identifier (UTAG_IVAR_LIST)));
2775 /* TREE_NOTHROW is cleared for the message-sending functions,
2776 because the function that gets called can throw in Obj-C++, or
2777 could itself call something that can throw even in Obj-C. */
2779 if (flag_next_runtime)
2781 /* NB: In order to call one of the ..._stret (struct-returning)
2782 functions, the function *MUST* first be cast to a signature that
2783 corresponds to the actual ObjC method being invoked. This is
2784 what is done by the build_objc_method_call() routine below. */
2786 /* id objc_msgSend (id, SEL, ...); */
2787 /* id objc_msgSendNonNil (id, SEL, ...); */
2788 /* id objc_msgSend_stret (id, SEL, ...); */
2789 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2790 type
2791 = build_varargs_function_type_list (objc_object_type,
2792 objc_object_type,
2793 objc_selector_type,
2794 NULL_TREE);
2795 umsg_decl = add_builtin_function (TAG_MSGSEND,
2796 type, 0, NOT_BUILT_IN,
2797 NULL, NULL_TREE);
2798 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
2799 type, 0, NOT_BUILT_IN,
2800 NULL, NULL_TREE);
2801 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
2802 type, 0, NOT_BUILT_IN,
2803 NULL, NULL_TREE);
2804 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
2805 type, 0, NOT_BUILT_IN,
2806 NULL, NULL_TREE);
2808 /* These can throw, because the function that gets called can throw
2809 in Obj-C++, or could itself call something that can throw even
2810 in Obj-C. */
2811 TREE_NOTHROW (umsg_decl) = 0;
2812 TREE_NOTHROW (umsg_nonnil_decl) = 0;
2813 TREE_NOTHROW (umsg_stret_decl) = 0;
2814 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
2816 /* id objc_msgSend_Fast (id, SEL, ...)
2817 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2818 #ifdef OFFS_MSGSEND_FAST
2819 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
2820 type, 0, NOT_BUILT_IN,
2821 NULL, NULL_TREE);
2822 TREE_NOTHROW (umsg_fast_decl) = 0;
2823 DECL_ATTRIBUTES (umsg_fast_decl)
2824 = tree_cons (get_identifier ("hard_coded_address"),
2825 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
2826 NULL_TREE);
2827 #else
2828 /* No direct dispatch available. */
2829 umsg_fast_decl = umsg_decl;
2830 #endif
2832 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2833 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2834 type
2835 = build_varargs_function_type_list (objc_object_type,
2836 objc_super_type,
2837 objc_selector_type,
2838 NULL_TREE);
2839 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2840 type, 0, NOT_BUILT_IN,
2841 NULL, NULL_TREE);
2842 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
2843 type, 0, NOT_BUILT_IN, 0,
2844 NULL_TREE);
2845 TREE_NOTHROW (umsg_super_decl) = 0;
2846 TREE_NOTHROW (umsg_super_stret_decl) = 0;
2848 else
2850 /* GNU runtime messenger entry points. */
2852 /* typedef id (*IMP)(id, SEL, ...); */
2853 tree ftype =
2854 build_varargs_function_type_list (objc_object_type,
2855 objc_object_type,
2856 objc_selector_type,
2857 NULL_TREE);
2858 tree IMP_type = build_pointer_type (ftype);
2860 /* IMP objc_msg_lookup (id, SEL); */
2861 type = build_function_type_list (IMP_type,
2862 objc_object_type,
2863 objc_selector_type,
2864 NULL_TREE);
2865 umsg_decl = add_builtin_function (TAG_MSGSEND,
2866 type, 0, NOT_BUILT_IN,
2867 NULL, NULL_TREE);
2868 TREE_NOTHROW (umsg_decl) = 0;
2870 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2871 type
2872 = build_function_type_list (IMP_type,
2873 objc_super_type,
2874 objc_selector_type,
2875 NULL_TREE);
2876 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2877 type, 0, NOT_BUILT_IN,
2878 NULL, NULL_TREE);
2879 TREE_NOTHROW (umsg_super_decl) = 0;
2881 /* The following GNU runtime entry point is called to initialize
2882 each module:
2884 __objc_exec_class (void *); */
2885 type
2886 = build_function_type_list (void_type_node,
2887 ptr_type_node,
2888 NULL_TREE);
2889 execclass_decl = add_builtin_function (TAG_EXECCLASS,
2890 type, 0, NOT_BUILT_IN,
2891 NULL, NULL_TREE);
2894 /* id objc_getClass (const char *); */
2896 type = build_function_type_list (objc_object_type,
2897 const_string_type_node,
2898 NULL_TREE);
2900 objc_get_class_decl
2901 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
2902 NULL, NULL_TREE);
2904 /* id objc_getMetaClass (const char *); */
2906 objc_get_meta_class_decl
2907 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
2909 build_class_template ();
2910 build_super_template ();
2911 build_protocol_template ();
2912 build_category_template ();
2913 build_objc_exception_stuff ();
2915 /* Declare objc_getProperty, object_setProperty and other property
2916 accessor helpers. */
2917 build_objc_property_accessor_helpers ();
2919 if (flag_next_runtime)
2920 build_next_objc_exception_stuff ();
2922 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2924 if (! flag_next_runtime)
2925 build_selector_table_decl ();
2927 /* Forward declare constant_string_id and constant_string_type. */
2928 if (!constant_string_class_name)
2929 constant_string_class_name = default_constant_string_class_name;
2931 constant_string_id = get_identifier (constant_string_class_name);
2932 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
2934 /* Pre-build the following entities - for speed/convenience. */
2935 self_id = get_identifier ("self");
2936 ucmd_id = get_identifier ("_cmd");
2938 /* Declare struct _objc_fast_enumeration_state { ... }; */
2939 build_fast_enumeration_state_template ();
2941 /* void objc_enumeration_mutation (id) */
2942 type = build_function_type (void_type_node,
2943 tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
2944 objc_enumeration_mutation_decl
2945 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
2946 NULL, NULL_TREE);
2947 TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
2949 #ifdef OBJCPLUS
2950 pop_lang_context ();
2951 #endif
2953 write_symbols = save_write_symbols;
2954 debug_hooks = save_hooks;
2957 /* Ensure that the ivar list for NSConstantString/NXConstantString
2958 (or whatever was specified via `-fconstant-string-class')
2959 contains fields at least as large as the following three, so that
2960 the runtime can stomp on them with confidence:
2962 struct STRING_OBJECT_CLASS_NAME
2964 Object isa;
2965 char *cString;
2966 unsigned int length;
2967 }; */
2969 static int
2970 check_string_class_template (void)
2972 tree field_decl = objc_get_class_ivars (constant_string_id);
2974 #define AT_LEAST_AS_LARGE_AS(F, T) \
2975 (F && TREE_CODE (F) == FIELD_DECL \
2976 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2977 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2979 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2980 return 0;
2982 field_decl = DECL_CHAIN (field_decl);
2983 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2984 return 0;
2986 field_decl = DECL_CHAIN (field_decl);
2987 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
2989 #undef AT_LEAST_AS_LARGE_AS
2992 /* Avoid calling `check_string_class_template ()' more than once. */
2993 static GTY(()) int string_layout_checked;
2995 /* Construct an internal string layout to be used as a template for
2996 creating NSConstantString/NXConstantString instances. */
2998 static tree
2999 objc_build_internal_const_str_type (void)
3001 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
3002 tree fields = build_decl (input_location,
3003 FIELD_DECL, NULL_TREE, ptr_type_node);
3004 tree field = build_decl (input_location,
3005 FIELD_DECL, NULL_TREE, ptr_type_node);
3007 DECL_CHAIN (field) = fields; fields = field;
3008 field = build_decl (input_location,
3009 FIELD_DECL, NULL_TREE, unsigned_type_node);
3010 DECL_CHAIN (field) = fields; fields = field;
3011 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
3012 reverse order! */
3013 finish_builtin_struct (type, "__builtin_ObjCString",
3014 fields, NULL_TREE);
3016 return type;
3019 /* Custom build_string which sets TREE_TYPE! */
3021 static tree
3022 my_build_string (int len, const char *str)
3024 return fix_string_type (build_string (len, str));
3027 /* Build a string with contents STR and length LEN and convert it to a
3028 pointer. */
3030 static tree
3031 my_build_string_pointer (int len, const char *str)
3033 tree string = my_build_string (len, str);
3034 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
3035 return build1 (ADDR_EXPR, ptrtype, string);
3038 static hashval_t
3039 string_hash (const void *ptr)
3041 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
3042 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
3043 int i, len = TREE_STRING_LENGTH (str);
3044 hashval_t h = len;
3046 for (i = 0; i < len; i++)
3047 h = ((h * 613) + p[i]);
3049 return h;
3052 static int
3053 string_eq (const void *ptr1, const void *ptr2)
3055 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
3056 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
3057 int len1 = TREE_STRING_LENGTH (str1);
3059 return (len1 == TREE_STRING_LENGTH (str2)
3060 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
3061 len1));
3064 /* Given a chain of STRING_CST's, build a static instance of
3065 NXConstantString which points at the concatenation of those
3066 strings. We place the string object in the __string_objects
3067 section of the __OBJC segment. The Objective-C runtime will
3068 initialize the isa pointers of the string objects to point at the
3069 NXConstantString class object. */
3071 tree
3072 objc_build_string_object (tree string)
3074 tree constant_string_class;
3075 int length;
3076 tree fields, addr;
3077 struct string_descriptor *desc, key;
3078 void **loc;
3080 /* Prep the string argument. */
3081 string = fix_string_type (string);
3082 TREE_SET_CODE (string, STRING_CST);
3083 length = TREE_STRING_LENGTH (string) - 1;
3085 /* The target may have different ideas on how to construct an ObjC string
3086 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
3087 constant CFString reference instead.
3088 At present, this is only supported for the NeXT runtime. */
3089 if (flag_next_runtime && targetcm.objc_construct_string_object)
3091 tree constructor = (*targetcm.objc_construct_string_object) (string);
3092 if (constructor)
3093 return build1 (NOP_EXPR, objc_object_type, constructor);
3096 /* Check whether the string class being used actually exists and has the
3097 correct ivar layout. */
3098 if (!string_layout_checked)
3100 string_layout_checked = -1;
3101 constant_string_class = lookup_interface (constant_string_id);
3102 internal_const_str_type = objc_build_internal_const_str_type ();
3104 if (!constant_string_class
3105 || !(constant_string_type
3106 = CLASS_STATIC_TEMPLATE (constant_string_class)))
3107 error ("cannot find interface declaration for %qE",
3108 constant_string_id);
3109 /* The NSConstantString/NXConstantString ivar layout is now known. */
3110 else if (!check_string_class_template ())
3111 error ("interface %qE does not have valid constant string layout",
3112 constant_string_id);
3113 /* For the NeXT runtime, we can generate a literal reference
3114 to the string class, don't need to run a constructor. */
3115 else if (flag_next_runtime && !setup_string_decl ())
3116 error ("cannot find reference tag for class %qE",
3117 constant_string_id);
3118 else
3120 string_layout_checked = 1; /* Success! */
3121 add_class_reference (constant_string_id);
3125 if (string_layout_checked == -1)
3126 return error_mark_node;
3128 /* Perhaps we already constructed a constant string just like this one? */
3129 key.literal = string;
3130 loc = htab_find_slot (string_htab, &key, INSERT);
3131 desc = (struct string_descriptor *) *loc;
3133 if (!desc)
3135 tree var, constructor;
3136 VEC(constructor_elt,gc) *v = NULL;
3137 *loc = desc = ggc_alloc_string_descriptor ();
3138 desc->literal = string;
3140 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
3141 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
3142 fields = TYPE_FIELDS (internal_const_str_type);
3143 CONSTRUCTOR_APPEND_ELT (v, fields,
3144 flag_next_runtime
3145 ? build_unary_op (input_location,
3146 ADDR_EXPR, string_class_decl, 0)
3147 : build_int_cst (NULL_TREE, 0));
3148 fields = DECL_CHAIN (fields);
3149 CONSTRUCTOR_APPEND_ELT (v, fields,
3150 build_unary_op (input_location,
3151 ADDR_EXPR, string, 1));
3152 fields = DECL_CHAIN (fields);
3153 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
3154 constructor = objc_build_constructor (internal_const_str_type, v);
3156 if (!flag_next_runtime)
3157 constructor
3158 = objc_add_static_instance (constructor, constant_string_type);
3159 else
3161 var = build_decl (input_location,
3162 CONST_DECL, NULL, TREE_TYPE (constructor));
3163 DECL_INITIAL (var) = constructor;
3164 TREE_STATIC (var) = 1;
3165 pushdecl_top_level (var);
3166 constructor = var;
3168 desc->constructor = constructor;
3171 addr = convert (build_pointer_type (constant_string_type),
3172 build_unary_op (input_location,
3173 ADDR_EXPR, desc->constructor, 1));
3175 return addr;
3178 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
3180 static GTY(()) int num_static_inst;
3182 static tree
3183 objc_add_static_instance (tree constructor, tree class_decl)
3185 tree *chain, decl;
3186 char buf[256];
3188 /* Find the list of static instances for the CLASS_DECL. Create one if
3189 not found. */
3190 for (chain = &objc_static_instances;
3191 *chain && TREE_VALUE (*chain) != class_decl;
3192 chain = &TREE_CHAIN (*chain));
3193 if (!*chain)
3195 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
3196 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
3199 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
3200 decl = build_decl (input_location,
3201 VAR_DECL, get_identifier (buf), class_decl);
3202 TREE_STATIC (decl) = 1;
3203 DECL_ARTIFICIAL (decl) = 1;
3204 TREE_USED (decl) = 1;
3205 DECL_INITIAL (decl) = constructor;
3207 /* We may be writing something else just now.
3208 Postpone till end of input. */
3209 DECL_DEFER_OUTPUT (decl) = 1;
3210 pushdecl_top_level (decl);
3211 rest_of_decl_compilation (decl, 1, 0);
3213 /* Add the DECL to the head of this CLASS' list. */
3214 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
3216 return decl;
3219 /* Build a static constant CONSTRUCTOR
3220 with type TYPE and elements ELTS. */
3222 static tree
3223 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
3225 tree constructor = build_constructor (type, elts);
3227 TREE_CONSTANT (constructor) = 1;
3228 TREE_STATIC (constructor) = 1;
3229 TREE_READONLY (constructor) = 1;
3231 #ifdef OBJCPLUS
3232 /* Adjust for impedance mismatch. We should figure out how to build
3233 CONSTRUCTORs that consistently please both the C and C++ gods. */
3234 if (!VEC_index (constructor_elt, elts, 0)->index)
3235 TREE_TYPE (constructor) = init_list_type_node;
3236 #endif
3238 return constructor;
3241 /* Take care of defining and initializing _OBJC_SYMBOLS. */
3243 /* Predefine the following data type:
3245 struct _objc_symtab
3247 long sel_ref_cnt;
3248 SEL *refs;
3249 short cls_def_cnt;
3250 short cat_def_cnt;
3251 void *defs[cls_def_cnt + cat_def_cnt];
3252 }; */
3254 static void
3255 build_objc_symtab_template (void)
3257 tree fields, *chain = NULL;
3259 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
3261 /* long sel_ref_cnt; */
3262 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
3264 /* SEL *refs; */
3265 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
3267 /* short cls_def_cnt; */
3268 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
3270 /* short cat_def_cnt; */
3271 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
3273 if (imp_count || cat_count || !flag_next_runtime)
3275 /* void *defs[imp_count + cat_count (+ 1)]; */
3276 /* NB: The index is one less than the size of the array. */
3277 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
3278 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
3279 add_field_decl (array_type, "defs", &chain);
3282 objc_finish_struct (objc_symtab_template, fields);
3285 /* Create the initial value for the `defs' field of _objc_symtab.
3286 This is a CONSTRUCTOR. */
3288 static tree
3289 init_def_list (tree type)
3291 tree expr;
3292 struct imp_entry *impent;
3293 VEC(constructor_elt,gc) *v = NULL;
3295 if (imp_count)
3296 for (impent = imp_list; impent; impent = impent->next)
3298 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
3300 expr = build_unary_op (input_location,
3301 ADDR_EXPR, impent->class_decl, 0);
3302 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3306 if (cat_count)
3307 for (impent = imp_list; impent; impent = impent->next)
3309 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3311 expr = build_unary_op (input_location,
3312 ADDR_EXPR, impent->class_decl, 0);
3313 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3317 if (!flag_next_runtime)
3319 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
3320 if (static_instances_decl)
3321 expr = build_unary_op (input_location,
3322 ADDR_EXPR, static_instances_decl, 0);
3323 else
3324 expr = integer_zero_node;
3326 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3329 return objc_build_constructor (type, v);
3332 /* Construct the initial value for all of _objc_symtab. */
3334 static tree
3335 init_objc_symtab (tree type)
3337 VEC(constructor_elt,gc) *v = NULL;
3339 /* sel_ref_cnt = { ..., 5, ... } */
3341 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3342 build_int_cst (long_integer_type_node, 0));
3344 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
3346 if (flag_next_runtime || ! sel_ref_chain)
3347 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
3348 build_pointer_type (objc_selector_type),
3349 integer_zero_node));
3350 else
3352 tree expr = build_unary_op (input_location, ADDR_EXPR,
3353 UOBJC_SELECTOR_TABLE_decl, 1);
3355 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3356 convert (build_pointer_type (objc_selector_type),
3357 expr));
3360 /* cls_def_cnt = { ..., 5, ... } */
3362 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3363 build_int_cst (short_integer_type_node, imp_count));
3365 /* cat_def_cnt = { ..., 5, ... } */
3367 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3368 build_int_cst (short_integer_type_node, cat_count));
3370 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
3372 if (imp_count || cat_count || !flag_next_runtime)
3375 tree field = TYPE_FIELDS (type);
3376 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
3378 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
3381 return objc_build_constructor (type, v);
3384 /* Generate forward declarations for metadata such as
3385 'OBJC_CLASS_...'. */
3387 static tree
3388 build_metadata_decl (const char *name, tree type)
3390 tree decl;
3392 /* struct TYPE NAME_<name>; */
3393 decl = start_var_decl (type, synth_id_with_class_suffix
3394 (name,
3395 objc_implementation_context));
3397 return decl;
3400 /* Push forward-declarations of all the categories so that
3401 init_def_list can use them in a CONSTRUCTOR. */
3403 static void
3404 forward_declare_categories (void)
3406 struct imp_entry *impent;
3407 tree sav = objc_implementation_context;
3409 for (impent = imp_list; impent; impent = impent->next)
3411 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3413 /* Set an invisible arg to synth_id_with_class_suffix. */
3414 objc_implementation_context = impent->imp_context;
3415 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
3416 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
3417 objc_category_template);
3420 objc_implementation_context = sav;
3423 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
3424 and initialized appropriately. */
3426 static void
3427 generate_objc_symtab_decl (void)
3430 build_objc_symtab_template ();
3431 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
3432 finish_var_decl (UOBJC_SYMBOLS_decl,
3433 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
3436 static tree
3437 init_module_descriptor (tree type)
3439 tree expr;
3440 VEC(constructor_elt,gc) *v = NULL;
3442 /* version = { 1, ... } */
3444 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
3445 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3447 /* size = { ..., sizeof (struct _objc_module), ... } */
3449 expr = convert (long_integer_type_node,
3450 size_in_bytes (objc_module_template));
3451 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3453 /* Don't provide any file name for security reasons. */
3454 /* name = { ..., "", ... } */
3456 expr = add_objc_string (get_identifier (""), class_names);
3457 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3459 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3461 if (UOBJC_SYMBOLS_decl)
3462 expr = build_unary_op (input_location,
3463 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
3464 else
3465 expr = null_pointer_node;
3466 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3468 return objc_build_constructor (type, v);
3471 /* Write out the data structures to describe Objective C classes defined.
3473 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
3475 static void
3476 build_module_descriptor (void)
3478 tree decls, *chain = NULL;
3480 #ifdef OBJCPLUS
3481 push_lang_context (lang_name_c); /* extern "C" */
3482 #endif
3484 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
3486 /* long version; */
3487 decls = add_field_decl (long_integer_type_node, "version", &chain);
3489 /* long size; */
3490 add_field_decl (long_integer_type_node, "size", &chain);
3492 /* char *name; */
3493 add_field_decl (string_type_node, "name", &chain);
3495 /* struct _objc_symtab *symtab; */
3496 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3497 get_identifier (UTAG_SYMTAB))),
3498 "symtab", &chain);
3500 objc_finish_struct (objc_module_template, decls);
3502 /* Create an instance of "_objc_module". */
3503 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3504 /* This is the root of the metadata for defined classes and categories, it
3505 is referenced by the runtime and, therefore, needed. */
3506 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3507 finish_var_decl (UOBJC_MODULES_decl,
3508 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3510 #ifdef OBJCPLUS
3511 pop_lang_context ();
3512 #endif
3515 /* The GNU runtime requires us to provide a static initializer function
3516 for each module:
3518 static void __objc_gnu_init (void) {
3519 __objc_exec_class (&L_OBJC_MODULES);
3520 } */
3522 static void
3523 build_module_initializer_routine (void)
3525 tree body;
3527 #ifdef OBJCPLUS
3528 push_lang_context (lang_name_c); /* extern "C" */
3529 #endif
3531 objc_push_parm (build_decl (input_location,
3532 PARM_DECL, NULL_TREE, void_type_node));
3533 #ifdef OBJCPLUS
3534 objc_start_function (get_identifier (TAG_GNUINIT),
3535 build_function_type_list (void_type_node, NULL_TREE),
3536 NULL_TREE, NULL_TREE);
3537 #else
3538 objc_start_function (get_identifier (TAG_GNUINIT),
3539 build_function_type_list (void_type_node, NULL_TREE),
3540 NULL_TREE, objc_get_parm_info (0));
3541 #endif
3542 body = c_begin_compound_stmt (true);
3543 add_stmt (build_function_call
3544 (input_location,
3545 execclass_decl,
3546 build_tree_list
3547 (NULL_TREE,
3548 build_unary_op (input_location, ADDR_EXPR,
3549 UOBJC_MODULES_decl, 0))));
3550 add_stmt (c_end_compound_stmt (input_location, body, true));
3552 TREE_PUBLIC (current_function_decl) = 0;
3554 #ifndef OBJCPLUS
3555 /* For Objective-C++, we will need to call __objc_gnu_init
3556 from objc_generate_static_init_call() below. */
3557 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3558 #endif
3560 GNU_INIT_decl = current_function_decl;
3561 finish_function ();
3563 #ifdef OBJCPLUS
3564 pop_lang_context ();
3565 #endif
3568 #ifdef OBJCPLUS
3569 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3570 to be called by the module initializer routine. */
3573 objc_static_init_needed_p (void)
3575 return (GNU_INIT_decl != NULL_TREE);
3578 /* Generate a call to the __objc_gnu_init initializer function. */
3580 tree
3581 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3583 add_stmt (build_stmt (input_location, EXPR_STMT,
3584 build_function_call (input_location,
3585 GNU_INIT_decl, NULL_TREE)));
3587 return ctors;
3589 #endif /* OBJCPLUS */
3591 /* Return the DECL of the string IDENT in the SECTION. */
3593 static tree
3594 get_objc_string_decl (tree ident, enum string_section section)
3596 tree chain;
3598 switch (section)
3600 case class_names:
3601 chain = class_names_chain;
3602 break;
3603 case meth_var_names:
3604 chain = meth_var_names_chain;
3605 break;
3606 case meth_var_types:
3607 chain = meth_var_types_chain;
3608 break;
3609 default:
3610 gcc_unreachable ();
3613 for (; chain != 0; chain = TREE_CHAIN (chain))
3614 if (TREE_VALUE (chain) == ident)
3615 return (TREE_PURPOSE (chain));
3617 gcc_unreachable ();
3618 return NULL_TREE;
3621 /* Output references to all statically allocated objects. Return the DECL
3622 for the array built. */
3624 static void
3625 generate_static_references (void)
3627 tree expr = NULL_TREE;
3628 tree class_name, klass, decl;
3629 tree cl_chain, in_chain, type
3630 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3631 int num_inst, num_class;
3632 char buf[256];
3633 VEC(constructor_elt,gc) *decls = NULL;
3635 if (flag_next_runtime)
3636 gcc_unreachable ();
3638 for (cl_chain = objc_static_instances, num_class = 0;
3639 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3641 VEC(constructor_elt,gc) *v = NULL;
3643 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3644 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3646 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3647 decl = start_var_decl (type, buf);
3649 /* Output {class_name, ...}. */
3650 klass = TREE_VALUE (cl_chain);
3651 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3652 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3653 build_unary_op (input_location,
3654 ADDR_EXPR, class_name, 1));
3656 /* Output {..., instance, ...}. */
3657 for (in_chain = TREE_PURPOSE (cl_chain);
3658 in_chain; in_chain = TREE_CHAIN (in_chain))
3660 expr = build_unary_op (input_location,
3661 ADDR_EXPR, TREE_VALUE (in_chain), 1);
3662 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3665 /* Output {..., NULL}. */
3666 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3668 expr = objc_build_constructor (TREE_TYPE (decl), v);
3669 finish_var_decl (decl, expr);
3670 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3671 build_unary_op (input_location,
3672 ADDR_EXPR, decl, 1));
3675 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3676 expr = objc_build_constructor (type, decls);
3677 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3678 finish_var_decl (static_instances_decl, expr);
3681 static GTY(()) int selector_reference_idx;
3683 static tree
3684 build_selector_reference_decl (void)
3686 tree decl;
3687 char buf[256];
3689 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3690 decl = start_var_decl (objc_selector_type, buf);
3692 return decl;
3695 static void
3696 build_selector_table_decl (void)
3698 tree temp;
3700 if (flag_typed_selectors)
3702 build_selector_template ();
3703 temp = build_array_type (objc_selector_template, NULL_TREE);
3705 else
3706 temp = build_array_type (objc_selector_type, NULL_TREE);
3708 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3711 /* Just a handy wrapper for add_objc_string. */
3713 static tree
3714 build_selector (tree ident)
3716 return convert (objc_selector_type,
3717 add_objc_string (ident, meth_var_names));
3720 /* Used only by build_*_selector_translation_table (). */
3721 static void
3722 diagnose_missing_method (tree meth, location_t here)
3724 tree method_chain;
3725 bool found = false;
3726 for (method_chain = meth_var_names_chain;
3727 method_chain;
3728 method_chain = TREE_CHAIN (method_chain))
3730 if (TREE_VALUE (method_chain) == meth)
3732 found = true;
3733 break;
3737 if (!found)
3738 warning_at (here, 0, "creating selector for nonexistent method %qE",
3739 meth);
3742 static void
3743 build_next_selector_translation_table (void)
3745 tree chain;
3746 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3748 tree expr;
3749 tree decl = TREE_PURPOSE (chain);
3750 if (warn_selector && objc_implementation_context)
3752 location_t loc;
3753 if (decl)
3754 loc = DECL_SOURCE_LOCATION (decl);
3755 else
3756 loc = input_location;
3757 diagnose_missing_method (TREE_VALUE (chain), loc);
3760 expr = build_selector (TREE_VALUE (chain));
3762 if (decl)
3764 /* Entries of this form are used for references to methods.
3765 The runtime re-writes these on start-up, but the compiler can't see
3766 that and optimizes it away unless we force it. */
3767 DECL_PRESERVE_P (decl) = 1;
3768 finish_var_decl (decl, expr);
3773 static void
3774 build_gnu_selector_translation_table (void)
3776 tree chain;
3777 /* int offset = 0;
3778 tree decl = NULL_TREE;*/
3779 VEC(constructor_elt,gc) *inits = NULL;
3781 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3783 tree expr;
3785 if (warn_selector && objc_implementation_context)
3786 diagnose_missing_method (TREE_VALUE (chain), input_location);
3788 expr = build_selector (TREE_VALUE (chain));
3789 /* add one for the '\0' character
3790 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3793 if (flag_typed_selectors)
3795 VEC(constructor_elt,gc) *v = NULL;
3796 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
3797 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3798 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
3799 expr = objc_build_constructor (objc_selector_template, v);
3802 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3804 } /* each element in the chain */
3807 /* Cause the selector table (previously forward-declared)
3808 to be actually output. */
3809 tree expr;
3811 if (flag_typed_selectors)
3813 VEC(constructor_elt,gc) *v = NULL;
3814 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3815 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3816 expr = objc_build_constructor (objc_selector_template, v);
3818 else
3819 expr = integer_zero_node;
3821 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3822 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
3823 inits);
3824 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
3828 static tree
3829 get_proto_encoding (tree proto)
3831 tree encoding;
3832 if (proto)
3834 if (! METHOD_ENCODING (proto))
3836 encoding = encode_method_prototype (proto);
3837 METHOD_ENCODING (proto) = encoding;
3839 else
3840 encoding = METHOD_ENCODING (proto);
3842 return add_objc_string (encoding, meth_var_types);
3844 else
3845 return build_int_cst (NULL_TREE, 0);
3848 /* sel_ref_chain is a list whose "value" fields will be instances of
3849 identifier_node that represent the selector. LOC is the location of
3850 the @selector. */
3852 static tree
3853 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
3855 tree *chain = &sel_ref_chain;
3856 tree expr;
3857 int index = 0;
3859 while (*chain)
3861 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
3862 goto return_at_index;
3864 index++;
3865 chain = &TREE_CHAIN (*chain);
3868 *chain = tree_cons (prototype, ident, NULL_TREE);
3870 return_at_index:
3871 expr = build_unary_op (loc, ADDR_EXPR,
3872 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3873 build_int_cst (NULL_TREE, index)),
3875 return convert (objc_selector_type, expr);
3878 static tree
3879 build_selector_reference (location_t loc, tree ident)
3881 tree *chain = &sel_ref_chain;
3882 tree expr;
3883 int index = 0;
3885 while (*chain)
3887 if (TREE_VALUE (*chain) == ident)
3888 return (flag_next_runtime
3889 ? TREE_PURPOSE (*chain)
3890 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3891 build_int_cst (NULL_TREE, index)));
3893 index++;
3894 chain = &TREE_CHAIN (*chain);
3897 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
3899 *chain = tree_cons (expr, ident, NULL_TREE);
3901 return (flag_next_runtime
3902 ? expr
3903 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3904 build_int_cst (NULL_TREE, index)));
3907 static GTY(()) int class_reference_idx;
3909 static tree
3910 build_class_reference_decl (void)
3912 tree decl;
3913 char buf[256];
3915 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
3916 decl = start_var_decl (objc_class_type, buf);
3918 return decl;
3921 /* Create a class reference, but don't create a variable to reference
3922 it. */
3924 static void
3925 add_class_reference (tree ident)
3927 tree chain;
3929 if ((chain = cls_ref_chain))
3931 tree tail;
3934 if (ident == TREE_VALUE (chain))
3935 return;
3937 tail = chain;
3938 chain = TREE_CHAIN (chain);
3940 while (chain);
3942 /* Append to the end of the list */
3943 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
3945 else
3946 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
3949 /* Get a class reference, creating it if necessary. Also create the
3950 reference variable. */
3952 tree
3953 objc_get_class_reference (tree ident)
3955 tree orig_ident = (DECL_P (ident)
3956 ? DECL_NAME (ident)
3957 : TYPE_P (ident)
3958 ? OBJC_TYPE_NAME (ident)
3959 : ident);
3960 bool local_scope = false;
3962 #ifdef OBJCPLUS
3963 if (processing_template_decl)
3964 /* Must wait until template instantiation time. */
3965 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
3966 #endif
3968 if (TREE_CODE (ident) == TYPE_DECL)
3969 ident = (DECL_ORIGINAL_TYPE (ident)
3970 ? DECL_ORIGINAL_TYPE (ident)
3971 : TREE_TYPE (ident));
3973 #ifdef OBJCPLUS
3974 if (TYPE_P (ident)
3975 && CP_TYPE_CONTEXT (ident) != global_namespace)
3976 local_scope = true;
3977 #endif
3979 if (local_scope || !(ident = objc_is_class_name (ident)))
3981 error ("%qE is not an Objective-C class name or alias",
3982 orig_ident);
3983 return error_mark_node;
3986 if (flag_next_runtime && !flag_zero_link)
3988 tree *chain;
3989 tree decl;
3991 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
3992 if (TREE_VALUE (*chain) == ident)
3994 if (! TREE_PURPOSE (*chain))
3995 TREE_PURPOSE (*chain) = build_class_reference_decl ();
3997 return TREE_PURPOSE (*chain);
4000 decl = build_class_reference_decl ();
4001 *chain = tree_cons (decl, ident, NULL_TREE);
4002 return decl;
4004 else
4006 tree params;
4008 add_class_reference (ident);
4010 params = build_tree_list (NULL_TREE,
4011 my_build_string_pointer
4012 (IDENTIFIER_LENGTH (ident) + 1,
4013 IDENTIFIER_POINTER (ident)));
4015 assemble_external (objc_get_class_decl);
4016 return build_function_call (input_location, objc_get_class_decl, params);
4020 /* For each string section we have a chain which maps identifier nodes
4021 to decls for the strings. */
4023 static GTY(()) int class_names_idx;
4024 static GTY(()) int meth_var_names_idx;
4025 static GTY(()) int meth_var_types_idx;
4027 static tree
4028 add_objc_string (tree ident, enum string_section section)
4030 tree *chain, decl, type, string_expr;
4031 char buf[256];
4033 buf[0] = 0;
4034 switch (section)
4036 case class_names:
4037 chain = &class_names_chain;
4038 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
4039 break;
4040 case meth_var_names:
4041 chain = &meth_var_names_chain;
4042 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
4043 break;
4044 case meth_var_types:
4045 chain = &meth_var_types_chain;
4046 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
4047 break;
4048 default:
4049 gcc_unreachable ();
4052 while (*chain)
4054 if (TREE_VALUE (*chain) == ident)
4055 return convert (string_type_node,
4056 build_unary_op (input_location,
4057 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
4059 chain = &TREE_CHAIN (*chain);
4062 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
4063 decl = start_var_decl (type, buf);
4064 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
4065 IDENTIFIER_POINTER (ident));
4066 TREE_CONSTANT (decl) = 1;
4067 finish_var_decl (decl, string_expr);
4069 *chain = tree_cons (decl, ident, NULL_TREE);
4071 return convert (string_type_node, build_unary_op (input_location,
4072 ADDR_EXPR, decl, 1));
4075 void
4076 objc_declare_alias (tree alias_ident, tree class_ident)
4078 tree underlying_class;
4080 #ifdef OBJCPLUS
4081 if (current_namespace != global_namespace) {
4082 error ("Objective-C declarations may only appear in global scope");
4084 #endif /* OBJCPLUS */
4086 if (!(underlying_class = objc_is_class_name (class_ident)))
4087 warning (0, "cannot find class %qE", class_ident);
4088 else if (objc_is_class_name (alias_ident))
4089 warning (0, "class %qE already exists", alias_ident);
4090 else
4092 /* Implement @compatibility_alias as a typedef. */
4093 #ifdef OBJCPLUS
4094 push_lang_context (lang_name_c); /* extern "C" */
4095 #endif
4096 lang_hooks.decls.pushdecl (build_decl
4097 (input_location,
4098 TYPE_DECL,
4099 alias_ident,
4100 xref_tag (RECORD_TYPE, underlying_class)));
4101 #ifdef OBJCPLUS
4102 pop_lang_context ();
4103 #endif
4104 hash_class_name_enter (als_name_hash_list, alias_ident,
4105 underlying_class);
4109 void
4110 objc_declare_class (tree ident_list)
4112 tree list;
4113 #ifdef OBJCPLUS
4114 if (current_namespace != global_namespace) {
4115 error ("Objective-C declarations may only appear in global scope");
4117 #endif /* OBJCPLUS */
4119 for (list = ident_list; list; list = TREE_CHAIN (list))
4121 tree ident = TREE_VALUE (list);
4123 if (! objc_is_class_name (ident))
4125 tree record = lookup_name (ident), type = record;
4127 if (record)
4129 if (TREE_CODE (record) == TYPE_DECL)
4130 type = DECL_ORIGINAL_TYPE (record) ?
4131 DECL_ORIGINAL_TYPE (record) :
4132 TREE_TYPE (record);
4134 if (!TYPE_HAS_OBJC_INFO (type)
4135 || !TYPE_OBJC_INTERFACE (type))
4137 error ("%qE redeclared as different kind of symbol",
4138 ident);
4139 error ("previous declaration of %q+D",
4140 record);
4144 record = xref_tag (RECORD_TYPE, ident);
4145 INIT_TYPE_OBJC_INFO (record);
4146 TYPE_OBJC_INTERFACE (record) = ident;
4147 hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
4152 tree
4153 objc_is_class_name (tree ident)
4155 hash target;
4157 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
4158 && identifier_global_value (ident))
4159 ident = identifier_global_value (ident);
4160 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
4161 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
4163 if (ident && TREE_CODE (ident) == RECORD_TYPE)
4164 ident = OBJC_TYPE_NAME (ident);
4165 #ifdef OBJCPLUS
4166 if (ident && TREE_CODE (ident) == TYPE_DECL)
4168 tree type = TREE_TYPE (ident);
4169 if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
4170 return NULL_TREE;
4171 ident = DECL_NAME (ident);
4173 #endif
4174 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
4175 return NULL_TREE;
4177 if (lookup_interface (ident))
4178 return ident;
4180 target = hash_class_name_lookup (cls_name_hash_list, ident);
4181 if (target)
4182 return target->key;
4184 target = hash_class_name_lookup (als_name_hash_list, ident);
4185 if (target)
4187 gcc_assert (target->list && target->list->value);
4188 return target->list->value;
4191 return 0;
4194 /* Check whether TYPE is either 'id' or 'Class'. */
4196 tree
4197 objc_is_id (tree type)
4199 if (type && TREE_CODE (type) == IDENTIFIER_NODE
4200 && identifier_global_value (type))
4201 type = identifier_global_value (type);
4203 if (type && TREE_CODE (type) == TYPE_DECL)
4204 type = TREE_TYPE (type);
4206 /* NB: This function may be called before the ObjC front-end has
4207 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
4208 return (objc_object_type && type
4209 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
4210 ? type
4211 : NULL_TREE);
4214 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
4215 class instance. This is needed by other parts of the compiler to
4216 handle ObjC types gracefully. */
4218 tree
4219 objc_is_object_ptr (tree type)
4221 tree ret;
4223 type = TYPE_MAIN_VARIANT (type);
4224 if (!POINTER_TYPE_P (type))
4225 return 0;
4227 ret = objc_is_id (type);
4228 if (!ret)
4229 ret = objc_is_class_name (TREE_TYPE (type));
4231 return ret;
4234 static int
4235 objc_is_gcable_type (tree type, int or_strong_p)
4237 tree name;
4239 if (!TYPE_P (type))
4240 return 0;
4241 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
4242 return 1;
4243 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
4244 return 1;
4245 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
4246 return 0;
4247 type = TREE_TYPE (type);
4248 if (TREE_CODE (type) != RECORD_TYPE)
4249 return 0;
4250 name = TYPE_NAME (type);
4251 return (objc_is_class_name (name) != NULL_TREE);
4254 static tree
4255 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
4257 if (expr == oldexpr)
4258 return newexpr;
4260 switch (TREE_CODE (expr))
4262 case COMPONENT_REF:
4263 return objc_build_component_ref
4264 (objc_substitute_decl (TREE_OPERAND (expr, 0),
4265 oldexpr,
4266 newexpr),
4267 DECL_NAME (TREE_OPERAND (expr, 1)));
4268 case ARRAY_REF:
4269 return build_array_ref (input_location,
4270 objc_substitute_decl (TREE_OPERAND (expr, 0),
4271 oldexpr,
4272 newexpr),
4273 TREE_OPERAND (expr, 1));
4274 case INDIRECT_REF:
4275 return build_indirect_ref (input_location,
4276 objc_substitute_decl (TREE_OPERAND (expr, 0),
4277 oldexpr,
4278 newexpr), RO_ARROW);
4279 default:
4280 return expr;
4284 static tree
4285 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
4287 tree func_params;
4288 /* The LHS parameter contains the expression 'outervar->memberspec';
4289 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
4290 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
4292 tree offs
4293 = objc_substitute_decl
4294 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
4295 tree func
4296 = (flag_objc_direct_dispatch
4297 ? objc_assign_ivar_fast_decl
4298 : objc_assign_ivar_decl);
4300 offs = convert (integer_type_node, build_unary_op (input_location,
4301 ADDR_EXPR, offs, 0));
4302 offs = fold (offs);
4303 func_params = tree_cons (NULL_TREE,
4304 convert (objc_object_type, rhs),
4305 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
4306 tree_cons (NULL_TREE, offs,
4307 NULL_TREE)));
4309 assemble_external (func);
4310 return build_function_call (input_location, func, func_params);
4313 static tree
4314 objc_build_global_assignment (tree lhs, tree rhs)
4316 tree func_params = tree_cons (NULL_TREE,
4317 convert (objc_object_type, rhs),
4318 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4319 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4320 NULL_TREE));
4322 assemble_external (objc_assign_global_decl);
4323 return build_function_call (input_location,
4324 objc_assign_global_decl, func_params);
4327 static tree
4328 objc_build_strong_cast_assignment (tree lhs, tree rhs)
4330 tree func_params = tree_cons (NULL_TREE,
4331 convert (objc_object_type, rhs),
4332 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4333 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4334 NULL_TREE));
4336 assemble_external (objc_assign_strong_cast_decl);
4337 return build_function_call (input_location,
4338 objc_assign_strong_cast_decl, func_params);
4341 static int
4342 objc_is_gcable_p (tree expr)
4344 return (TREE_CODE (expr) == COMPONENT_REF
4345 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
4346 : TREE_CODE (expr) == ARRAY_REF
4347 ? (objc_is_gcable_p (TREE_TYPE (expr))
4348 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
4349 : TREE_CODE (expr) == ARRAY_TYPE
4350 ? objc_is_gcable_p (TREE_TYPE (expr))
4351 : TYPE_P (expr)
4352 ? objc_is_gcable_type (expr, 1)
4353 : (objc_is_gcable_p (TREE_TYPE (expr))
4354 || (DECL_P (expr)
4355 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
4358 static int
4359 objc_is_ivar_reference_p (tree expr)
4361 return (TREE_CODE (expr) == ARRAY_REF
4362 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
4363 : TREE_CODE (expr) == COMPONENT_REF
4364 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
4365 : 0);
4368 static int
4369 objc_is_global_reference_p (tree expr)
4371 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
4372 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
4373 : DECL_P (expr)
4374 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
4375 : 0);
4378 tree
4379 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
4381 tree result = NULL_TREE, outer;
4382 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
4384 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
4385 will have been transformed to the form '*(type *)&expr'. */
4386 if (TREE_CODE (lhs) == INDIRECT_REF)
4388 outer = TREE_OPERAND (lhs, 0);
4390 while (!strong_cast_p
4391 && (CONVERT_EXPR_P (outer)
4392 || TREE_CODE (outer) == NON_LVALUE_EXPR))
4394 tree lhstype = TREE_TYPE (outer);
4396 /* Descend down the cast chain, and record the first objc_gc
4397 attribute found. */
4398 if (POINTER_TYPE_P (lhstype))
4400 tree attr
4401 = lookup_attribute ("objc_gc",
4402 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
4404 if (attr)
4405 strong_cast_p = 1;
4408 outer = TREE_OPERAND (outer, 0);
4412 /* If we have a __strong cast, it trumps all else. */
4413 if (strong_cast_p)
4415 if (modifycode != NOP_EXPR)
4416 goto invalid_pointer_arithmetic;
4418 if (warn_assign_intercept)
4419 warning (0, "strong-cast assignment has been intercepted");
4421 result = objc_build_strong_cast_assignment (lhs, rhs);
4423 goto exit_point;
4426 /* the lhs must be of a suitable type, regardless of its underlying
4427 structure. */
4428 if (!objc_is_gcable_p (lhs))
4429 goto exit_point;
4431 outer = lhs;
4433 while (outer
4434 && (TREE_CODE (outer) == COMPONENT_REF
4435 || TREE_CODE (outer) == ARRAY_REF))
4436 outer = TREE_OPERAND (outer, 0);
4438 if (TREE_CODE (outer) == INDIRECT_REF)
4440 outer = TREE_OPERAND (outer, 0);
4441 indirect_p = 1;
4444 outer_gc_p = objc_is_gcable_p (outer);
4446 /* Handle ivar assignments. */
4447 if (objc_is_ivar_reference_p (lhs))
4449 /* if the struct to the left of the ivar is not an Objective-C object (__strong
4450 doesn't cut it here), the best we can do here is suggest a cast. */
4451 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
4453 /* We may still be able to use the global write barrier... */
4454 if (!indirect_p && objc_is_global_reference_p (outer))
4455 goto global_reference;
4457 suggest_cast:
4458 if (modifycode == NOP_EXPR)
4460 if (warn_assign_intercept)
4461 warning (0, "strong-cast may possibly be needed");
4464 goto exit_point;
4467 if (modifycode != NOP_EXPR)
4468 goto invalid_pointer_arithmetic;
4470 if (warn_assign_intercept)
4471 warning (0, "instance variable assignment has been intercepted");
4473 result = objc_build_ivar_assignment (outer, lhs, rhs);
4475 goto exit_point;
4478 /* Likewise, intercept assignment to global/static variables if their type is
4479 GC-marked. */
4480 if (objc_is_global_reference_p (outer))
4482 if (indirect_p)
4483 goto suggest_cast;
4485 global_reference:
4486 if (modifycode != NOP_EXPR)
4488 invalid_pointer_arithmetic:
4489 if (outer_gc_p)
4490 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4492 goto exit_point;
4495 if (warn_assign_intercept)
4496 warning (0, "global/static variable assignment has been intercepted");
4498 result = objc_build_global_assignment (lhs, rhs);
4501 /* In all other cases, fall back to the normal mechanism. */
4502 exit_point:
4503 return result;
4506 struct GTY(()) interface_tuple {
4507 tree id;
4508 tree class_name;
4511 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4513 static hashval_t
4514 hash_interface (const void *p)
4516 const struct interface_tuple *d = (const struct interface_tuple *) p;
4517 return IDENTIFIER_HASH_VALUE (d->id);
4520 static int
4521 eq_interface (const void *p1, const void *p2)
4523 const struct interface_tuple *d = (const struct interface_tuple *) p1;
4524 return d->id == p2;
4527 static tree
4528 lookup_interface (tree ident)
4530 #ifdef OBJCPLUS
4531 if (ident && TREE_CODE (ident) == TYPE_DECL)
4532 ident = DECL_NAME (ident);
4533 #endif
4535 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4536 return NULL_TREE;
4539 struct interface_tuple **slot;
4540 tree i = NULL_TREE;
4542 if (interface_htab)
4544 slot = (struct interface_tuple **)
4545 htab_find_slot_with_hash (interface_htab, ident,
4546 IDENTIFIER_HASH_VALUE (ident),
4547 NO_INSERT);
4548 if (slot && *slot)
4549 i = (*slot)->class_name;
4551 return i;
4555 /* Implement @defs (<classname>) within struct bodies. */
4557 tree
4558 objc_get_class_ivars (tree class_name)
4560 tree interface = lookup_interface (class_name);
4562 if (interface)
4563 return get_class_ivars (interface, true);
4565 error ("cannot find interface declaration for %qE",
4566 class_name);
4568 return error_mark_node;
4571 /* Called when checking the variables in a struct. If we are not
4572 doing the ivars list inside an @interface context, then returns
4573 fieldlist unchanged. Else, returns the list of class ivars.
4575 tree
4576 objc_get_interface_ivars (tree fieldlist)
4578 if (!objc_collecting_ivars || !objc_interface_context
4579 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4580 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4581 return fieldlist;
4583 return get_class_ivars (objc_interface_context, true);
4586 /* Used by: build_private_template, continue_class,
4587 and for @defs constructs. */
4589 static tree
4590 get_class_ivars (tree interface, bool inherited)
4592 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4594 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4595 by the current class (i.e., they do not include super-class ivars).
4596 However, the CLASS_IVARS list will be side-effected by a call to
4597 finish_struct(), which will fill in field offsets. */
4598 if (!CLASS_IVARS (interface))
4599 CLASS_IVARS (interface) = ivar_chain;
4601 if (!inherited)
4602 return ivar_chain;
4604 while (CLASS_SUPER_NAME (interface))
4606 /* Prepend super-class ivars. */
4607 interface = lookup_interface (CLASS_SUPER_NAME (interface));
4608 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4609 ivar_chain);
4612 return ivar_chain;
4615 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4616 the specified name, else use no name. Returns the declaration of
4617 the type. The 'name' is mostly useful for debugging.
4619 static tree
4620 objc_create_temporary_var (tree type, const char *name)
4622 tree decl;
4624 if (name != NULL)
4626 decl = build_decl (input_location,
4627 VAR_DECL, get_identifier (name), type);
4629 else
4631 decl = build_decl (input_location,
4632 VAR_DECL, NULL_TREE, type);
4634 TREE_USED (decl) = 1;
4635 DECL_ARTIFICIAL (decl) = 1;
4636 DECL_IGNORED_P (decl) = 1;
4637 DECL_CONTEXT (decl) = current_function_decl;
4639 return decl;
4642 /* Exception handling constructs. We begin by having the parser do most
4643 of the work and passing us blocks. What we do next depends on whether
4644 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4645 We abstract all of this in a handful of appropriately named routines. */
4647 /* Stack of open try blocks. */
4649 struct objc_try_context
4651 struct objc_try_context *outer;
4653 /* Statements (or statement lists) as processed by the parser. */
4654 tree try_body;
4655 tree finally_body;
4657 /* Some file position locations. */
4658 location_t try_locus;
4659 location_t end_try_locus;
4660 location_t end_catch_locus;
4661 location_t finally_locus;
4662 location_t end_finally_locus;
4664 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4665 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4666 tree catch_list;
4668 /* The CATCH_EXPR of an open @catch clause. */
4669 tree current_catch;
4671 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4672 tree caught_decl;
4673 tree stack_decl;
4674 tree rethrow_decl;
4677 static struct objc_try_context *cur_try_context;
4679 static GTY(()) tree objc_eh_personality_decl;
4681 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4682 that represents TYPE. For Objective-C, this is just the class name. */
4683 /* ??? Isn't there a class object or some such? Is it easy to get? */
4685 #ifndef OBJCPLUS
4686 tree
4687 objc_eh_runtime_type (tree type)
4689 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4692 tree
4693 objc_eh_personality (void)
4695 if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4696 objc_eh_personality_decl = build_personality_function ("gnu_objc");
4697 return objc_eh_personality_decl;
4699 #endif
4701 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4702 of Darwin, we'll arrange for it to be initialized (and associated
4703 with a binding) later. */
4705 static tree
4706 objc_build_exc_ptr (void)
4708 if (flag_objc_sjlj_exceptions)
4710 tree var = cur_try_context->caught_decl;
4711 if (!var)
4713 var = objc_create_temporary_var (objc_object_type, NULL);
4714 cur_try_context->caught_decl = var;
4716 return var;
4718 else
4720 tree t;
4721 t = built_in_decls[BUILT_IN_EH_POINTER];
4722 t = build_call_expr (t, 1, integer_zero_node);
4723 return fold_convert (objc_object_type, t);
4727 /* Build "objc_exception_try_exit(&_stack)". */
4729 static tree
4730 next_sjlj_build_try_exit (void)
4732 tree t;
4733 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4734 t = tree_cons (NULL, t, NULL);
4735 t = build_function_call (input_location,
4736 objc_exception_try_exit_decl, t);
4737 return t;
4740 /* Build
4741 objc_exception_try_enter (&_stack);
4742 if (_setjmp(&_stack.buf))
4744 else
4746 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4747 empty, ready for the caller to fill them in. */
4749 static tree
4750 next_sjlj_build_enter_and_setjmp (void)
4752 tree t, enter, sj, cond;
4754 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4755 t = tree_cons (NULL, t, NULL);
4756 enter = build_function_call (input_location,
4757 objc_exception_try_enter_decl, t);
4759 t = objc_build_component_ref (cur_try_context->stack_decl,
4760 get_identifier ("buf"));
4761 t = build_fold_addr_expr_loc (input_location, t);
4762 #ifdef OBJCPLUS
4763 /* Convert _setjmp argument to type that is expected. */
4764 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
4765 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
4766 else
4767 t = convert (ptr_type_node, t);
4768 #else
4769 t = convert (ptr_type_node, t);
4770 #endif
4771 t = tree_cons (NULL, t, NULL);
4772 sj = build_function_call (input_location,
4773 objc_setjmp_decl, t);
4775 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
4776 cond = c_common_truthvalue_conversion (input_location, cond);
4778 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
4781 /* Build:
4783 DECL = objc_exception_extract(&_stack); */
4785 static tree
4786 next_sjlj_build_exc_extract (tree decl)
4788 tree t;
4790 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4791 t = tree_cons (NULL, t, NULL);
4792 t = build_function_call (input_location,
4793 objc_exception_extract_decl, t);
4794 t = convert (TREE_TYPE (decl), t);
4795 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4797 return t;
4800 /* Build
4801 if (objc_exception_match(obj_get_class(TYPE), _caught)
4802 BODY
4803 else if (...)
4805 else
4807 _rethrow = _caught;
4808 objc_exception_try_exit(&_stack);
4810 from the sequence of CATCH_EXPRs in the current try context. */
4812 static tree
4813 next_sjlj_build_catch_list (void)
4815 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4816 tree catch_seq, t;
4817 tree *last = &catch_seq;
4818 bool saw_id = false;
4820 for (; !tsi_end_p (i); tsi_next (&i))
4822 tree stmt = tsi_stmt (i);
4823 tree type = CATCH_TYPES (stmt);
4824 tree body = CATCH_BODY (stmt);
4826 if (type == NULL)
4828 *last = body;
4829 saw_id = true;
4830 break;
4832 else
4834 tree args, cond;
4836 if (type == error_mark_node)
4837 cond = error_mark_node;
4838 else
4840 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
4841 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
4842 args = tree_cons (NULL, t, args);
4843 t = build_function_call (input_location,
4844 objc_exception_match_decl, args);
4845 cond = c_common_truthvalue_conversion (input_location, t);
4847 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
4848 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
4850 *last = t;
4851 last = &COND_EXPR_ELSE (t);
4855 if (!saw_id)
4857 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
4858 cur_try_context->caught_decl);
4859 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4860 append_to_statement_list (t, last);
4862 t = next_sjlj_build_try_exit ();
4863 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4864 append_to_statement_list (t, last);
4867 return catch_seq;
4870 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4871 exception handling. We aim to build:
4874 struct _objc_exception_data _stack;
4875 id _rethrow = 0;
4878 objc_exception_try_enter (&_stack);
4879 if (_setjmp(&_stack.buf))
4881 id _caught = objc_exception_extract(&_stack);
4882 objc_exception_try_enter (&_stack);
4883 if (_setjmp(&_stack.buf))
4884 _rethrow = objc_exception_extract(&_stack);
4885 else
4886 CATCH-LIST
4888 else
4889 TRY-BLOCK
4891 finally
4893 if (!_rethrow)
4894 objc_exception_try_exit(&_stack);
4895 FINALLY-BLOCK
4896 if (_rethrow)
4897 objc_exception_throw(_rethrow);
4901 If CATCH-LIST is empty, we can omit all of the block containing
4902 "_caught" except for the setting of _rethrow. Note the use of
4903 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4904 but handles goto and other exits from the block. */
4906 static tree
4907 next_sjlj_build_try_catch_finally (void)
4909 tree rethrow_decl, stack_decl, t;
4910 tree catch_seq, try_fin, bind;
4912 /* Create the declarations involved. */
4913 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
4914 stack_decl = objc_create_temporary_var (t, NULL);
4915 cur_try_context->stack_decl = stack_decl;
4917 rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
4918 cur_try_context->rethrow_decl = rethrow_decl;
4919 TREE_CHAIN (rethrow_decl) = stack_decl;
4921 /* Build the outermost variable binding level. */
4922 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
4923 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
4924 TREE_SIDE_EFFECTS (bind) = 1;
4926 /* Initialize rethrow_decl. */
4927 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
4928 convert (objc_object_type, null_pointer_node));
4929 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4930 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4932 /* Build the outermost TRY_FINALLY_EXPR. */
4933 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
4934 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
4935 TREE_SIDE_EFFECTS (try_fin) = 1;
4936 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
4938 /* Create the complete catch sequence. */
4939 if (cur_try_context->catch_list)
4941 tree caught_decl = objc_build_exc_ptr ();
4942 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
4943 TREE_SIDE_EFFECTS (catch_seq) = 1;
4945 t = next_sjlj_build_exc_extract (caught_decl);
4946 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4948 t = next_sjlj_build_enter_and_setjmp ();
4949 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
4950 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
4951 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4953 else
4954 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
4955 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
4957 /* Build the main register-and-try if statement. */
4958 t = next_sjlj_build_enter_and_setjmp ();
4959 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4960 COND_EXPR_THEN (t) = catch_seq;
4961 COND_EXPR_ELSE (t) = cur_try_context->try_body;
4962 TREE_OPERAND (try_fin, 0) = t;
4964 /* Build the complete FINALLY statement list. */
4965 t = next_sjlj_build_try_exit ();
4966 t = build_stmt (input_location, COND_EXPR,
4967 c_common_truthvalue_conversion
4968 (input_location, rethrow_decl),
4969 NULL, t);
4970 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
4971 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4973 append_to_statement_list (cur_try_context->finally_body,
4974 &TREE_OPERAND (try_fin, 1));
4976 t = tree_cons (NULL, rethrow_decl, NULL);
4977 t = build_function_call (input_location,
4978 objc_exception_throw_decl, t);
4979 t = build_stmt (input_location, COND_EXPR,
4980 c_common_truthvalue_conversion (input_location,
4981 rethrow_decl),
4982 t, NULL);
4983 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
4984 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4986 return bind;
4989 /* Called just after parsing the @try and its associated BODY. We now
4990 must prepare for the tricky bits -- handling the catches and finally. */
4992 void
4993 objc_begin_try_stmt (location_t try_locus, tree body)
4995 struct objc_try_context *c = XCNEW (struct objc_try_context);
4996 c->outer = cur_try_context;
4997 c->try_body = body;
4998 c->try_locus = try_locus;
4999 c->end_try_locus = input_location;
5000 cur_try_context = c;
5002 /* -fobjc-exceptions is required to enable Objective-C exceptions.
5003 For example, on Darwin, ObjC exceptions require a sufficiently
5004 recent version of the runtime, so the user must ask for them
5005 explicitly. On other platforms, at the moment -fobjc-exceptions
5006 triggers -fexceptions which again is required for exceptions to
5007 work.
5009 if (!flag_objc_exceptions)
5011 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5014 if (flag_objc_sjlj_exceptions)
5015 objc_mark_locals_volatile (NULL);
5018 /* Called just after parsing "@catch (parm)". Open a binding level,
5019 enter DECL into the binding level, and initialize it. Leave the
5020 binding level open while the body of the compound statement is parsed. */
5022 void
5023 objc_begin_catch_clause (tree decl)
5025 tree compound, type, t;
5027 /* Begin a new scope that the entire catch clause will live in. */
5028 compound = c_begin_compound_stmt (true);
5030 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
5031 decl = build_decl (input_location,
5032 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
5033 lang_hooks.decls.pushdecl (decl);
5035 /* Since a decl is required here by syntax, don't warn if its unused. */
5036 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
5037 be what the previous objc implementation did. */
5038 TREE_USED (decl) = 1;
5039 DECL_READ_P (decl) = 1;
5041 /* Verify that the type of the catch is valid. It must be a pointer
5042 to an Objective-C class, or "id" (which is catch-all). */
5043 type = TREE_TYPE (decl);
5045 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
5046 type = NULL;
5047 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
5049 error ("@catch parameter is not a known Objective-C class type");
5050 type = error_mark_node;
5052 else if (cur_try_context->catch_list)
5054 /* Examine previous @catch clauses and see if we've already
5055 caught the type in question. */
5056 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
5057 for (; !tsi_end_p (i); tsi_next (&i))
5059 tree stmt = tsi_stmt (i);
5060 t = CATCH_TYPES (stmt);
5061 if (t == error_mark_node)
5062 continue;
5063 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
5065 warning (0, "exception of type %<%T%> will be caught",
5066 TREE_TYPE (type));
5067 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
5068 TREE_TYPE (t ? t : objc_object_type));
5069 break;
5074 /* Record the data for the catch in the try context so that we can
5075 finalize it later. */
5076 t = build_stmt (input_location, CATCH_EXPR, type, compound);
5077 cur_try_context->current_catch = t;
5079 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
5080 t = objc_build_exc_ptr ();
5081 t = convert (TREE_TYPE (decl), t);
5082 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
5083 add_stmt (t);
5086 /* Called just after parsing the closing brace of a @catch clause. Close
5087 the open binding level, and record a CATCH_EXPR for it. */
5089 void
5090 objc_finish_catch_clause (void)
5092 tree c = cur_try_context->current_catch;
5093 cur_try_context->current_catch = NULL;
5094 cur_try_context->end_catch_locus = input_location;
5096 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
5097 append_to_statement_list (c, &cur_try_context->catch_list);
5100 /* Called after parsing a @finally clause and its associated BODY.
5101 Record the body for later placement. */
5103 void
5104 objc_build_finally_clause (location_t finally_locus, tree body)
5106 cur_try_context->finally_body = body;
5107 cur_try_context->finally_locus = finally_locus;
5108 cur_try_context->end_finally_locus = input_location;
5111 /* Called to finalize a @try construct. */
5113 tree
5114 objc_finish_try_stmt (void)
5116 struct objc_try_context *c = cur_try_context;
5117 tree stmt;
5119 if (c->catch_list == NULL && c->finally_body == NULL)
5120 error ("%<@try%> without %<@catch%> or %<@finally%>");
5122 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
5123 if (flag_objc_sjlj_exceptions)
5125 bool save = in_late_binary_op;
5126 in_late_binary_op = true;
5127 if (!cur_try_context->finally_body)
5129 cur_try_context->finally_locus = input_location;
5130 cur_try_context->end_finally_locus = input_location;
5132 stmt = next_sjlj_build_try_catch_finally ();
5133 in_late_binary_op = save;
5135 else
5137 /* Otherwise, nest the CATCH inside a FINALLY. */
5138 stmt = c->try_body;
5139 if (c->catch_list)
5141 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
5142 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5144 if (c->finally_body)
5146 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
5147 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5150 add_stmt (stmt);
5152 cur_try_context = c->outer;
5153 free (c);
5154 return stmt;
5157 tree
5158 objc_build_throw_stmt (location_t loc, tree throw_expr)
5160 tree args;
5162 if (!flag_objc_exceptions)
5164 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5167 if (throw_expr == NULL)
5169 /* If we're not inside a @catch block, there is no "current
5170 exception" to be rethrown. */
5171 if (cur_try_context == NULL
5172 || cur_try_context->current_catch == NULL)
5174 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
5175 return NULL_TREE;
5178 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
5179 value that we get from the runtime. */
5180 throw_expr = objc_build_exc_ptr ();
5183 /* A throw is just a call to the runtime throw function with the
5184 object as a parameter. */
5185 args = tree_cons (NULL, throw_expr, NULL);
5186 return add_stmt (build_function_call (loc,
5187 objc_exception_throw_decl, args));
5190 tree
5191 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
5193 tree args, call;
5195 /* First lock the mutex. */
5196 mutex = save_expr (mutex);
5197 args = tree_cons (NULL, mutex, NULL);
5198 call = build_function_call (input_location,
5199 objc_sync_enter_decl, args);
5200 SET_EXPR_LOCATION (call, start_locus);
5201 add_stmt (call);
5203 /* Build the mutex unlock. */
5204 args = tree_cons (NULL, mutex, NULL);
5205 call = build_function_call (input_location,
5206 objc_sync_exit_decl, args);
5207 SET_EXPR_LOCATION (call, input_location);
5209 /* Put the that and the body in a TRY_FINALLY. */
5210 objc_begin_try_stmt (start_locus, body);
5211 objc_build_finally_clause (input_location, call);
5212 return objc_finish_try_stmt ();
5216 /* Predefine the following data type:
5218 struct _objc_exception_data
5220 int buf[OBJC_JBLEN];
5221 void *pointers[4];
5222 }; */
5224 /* The following yuckiness should prevent users from having to #include
5225 <setjmp.h> in their code... */
5227 /* Define to a harmless positive value so the below code doesn't die. */
5228 #ifndef OBJC_JBLEN
5229 #define OBJC_JBLEN 18
5230 #endif
5232 static void
5233 build_next_objc_exception_stuff (void)
5235 tree decls, temp_type, *chain = NULL;
5237 objc_exception_data_template
5238 = objc_start_struct (get_identifier (UTAG_EXCDATA));
5240 /* int buf[OBJC_JBLEN]; */
5242 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
5243 decls = add_field_decl (temp_type, "buf", &chain);
5245 /* void *pointers[4]; */
5247 temp_type = build_sized_array_type (ptr_type_node, 4);
5248 add_field_decl (temp_type, "pointers", &chain);
5250 objc_finish_struct (objc_exception_data_template, decls);
5252 /* int _setjmp(...); */
5253 /* If the user includes <setjmp.h>, this shall be superseded by
5254 'int _setjmp(jmp_buf);' */
5255 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
5256 objc_setjmp_decl
5257 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
5259 /* id objc_exception_extract(struct _objc_exception_data *); */
5260 temp_type
5261 = build_function_type_list (objc_object_type,
5262 build_pointer_type (objc_exception_data_template),
5263 NULL_TREE);
5264 objc_exception_extract_decl
5265 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
5266 NULL_TREE);
5267 /* void objc_exception_try_enter(struct _objc_exception_data *); */
5268 /* void objc_exception_try_exit(struct _objc_exception_data *); */
5269 temp_type
5270 = build_function_type_list (void_type_node,
5271 build_pointer_type (objc_exception_data_template),
5272 NULL_TREE);
5273 objc_exception_try_enter_decl
5274 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
5275 NULL_TREE);
5276 objc_exception_try_exit_decl
5277 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
5278 NULL_TREE);
5280 /* int objc_exception_match(id, id); */
5281 temp_type
5282 = build_function_type_list (integer_type_node,
5283 objc_object_type, objc_object_type, NULL_TREE);
5284 objc_exception_match_decl
5285 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
5286 NULL_TREE);
5288 /* id objc_assign_ivar (id, id, unsigned int); */
5289 /* id objc_assign_ivar_Fast (id, id, unsigned int)
5290 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
5291 temp_type
5292 = build_function_type_list (objc_object_type,
5293 objc_object_type,
5294 objc_object_type,
5295 unsigned_type_node,
5296 NULL_TREE);
5297 objc_assign_ivar_decl
5298 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
5299 NULL, NULL_TREE);
5300 #ifdef OFFS_ASSIGNIVAR_FAST
5301 objc_assign_ivar_fast_decl
5302 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
5303 NOT_BUILT_IN, NULL, NULL_TREE);
5304 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
5305 = tree_cons (get_identifier ("hard_coded_address"),
5306 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
5307 NULL_TREE);
5308 #else
5309 /* Default to slower ivar method. */
5310 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
5311 #endif
5313 /* id objc_assign_global (id, id *); */
5314 /* id objc_assign_strongCast (id, id *); */
5315 temp_type = build_function_type_list (objc_object_type,
5316 objc_object_type,
5317 build_pointer_type (objc_object_type),
5318 NULL_TREE);
5319 objc_assign_global_decl
5320 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
5321 NULL_TREE);
5322 objc_assign_strong_cast_decl
5323 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
5324 NULL_TREE);
5327 static void
5328 build_objc_exception_stuff (void)
5330 tree noreturn_list, nothrow_list, temp_type;
5332 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
5333 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
5335 /* void objc_exception_throw(id) __attribute__((noreturn)); */
5336 /* void objc_sync_enter(id); */
5337 /* void objc_sync_exit(id); */
5338 temp_type = build_function_type_list (void_type_node,
5339 objc_object_type,
5340 NULL_TREE);
5341 objc_exception_throw_decl
5342 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
5343 noreturn_list);
5344 objc_sync_enter_decl
5345 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
5346 NULL, nothrow_list);
5347 objc_sync_exit_decl
5348 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
5349 NULL, nothrow_list);
5352 /* Construct a C struct corresponding to ObjC class CLASS, with the same
5353 name as the class:
5355 struct <classname> {
5356 struct _objc_class *isa;
5358 }; */
5360 static void
5361 build_private_template (tree klass)
5363 if (!CLASS_STATIC_TEMPLATE (klass))
5365 tree record = objc_build_struct (klass,
5366 get_class_ivars (klass, false),
5367 CLASS_SUPER_NAME (klass));
5369 /* Set the TREE_USED bit for this struct, so that stab generator
5370 can emit stabs for this struct type. */
5371 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
5372 TREE_USED (TYPE_STUB_DECL (record)) = 1;
5376 /* Begin code generation for protocols... */
5378 /* struct _objc_protocol {
5379 struct _objc_class *isa;
5380 char *protocol_name;
5381 struct _objc_protocol **protocol_list;
5382 struct _objc__method_prototype_list *instance_methods;
5383 struct _objc__method_prototype_list *class_methods;
5384 }; */
5386 static void
5387 build_protocol_template (void)
5389 tree ptype, decls, *chain = NULL;
5391 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
5393 /* struct _objc_class *isa; */
5394 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5395 get_identifier (UTAG_CLASS)));
5396 decls = add_field_decl (ptype, "isa", &chain);
5398 /* char *protocol_name; */
5399 add_field_decl (string_type_node, "protocol_name", &chain);
5401 /* struct _objc_protocol **protocol_list; */
5402 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5403 add_field_decl (ptype, "protocol_list", &chain);
5405 /* struct _objc__method_prototype_list *instance_methods; */
5406 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
5408 /* struct _objc__method_prototype_list *class_methods; */
5409 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
5411 objc_finish_struct (objc_protocol_template, decls);
5414 static tree
5415 build_descriptor_table_initializer (tree type, tree entries)
5417 VEC(constructor_elt,gc) *inits = NULL;
5421 VEC(constructor_elt,gc) *elts = NULL;
5423 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5424 build_selector (METHOD_SEL_NAME (entries)));
5425 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5426 add_objc_string (METHOD_ENCODING (entries),
5427 meth_var_types));
5429 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5430 objc_build_constructor (type, elts));
5432 entries = DECL_CHAIN (entries);
5434 while (entries);
5436 return objc_build_constructor (build_array_type (type, 0), inits);
5439 /* struct objc_method_prototype_list {
5440 int count;
5441 struct objc_method_prototype {
5442 SEL name;
5443 char *types;
5444 } list[1];
5445 }; */
5447 static tree
5448 build_method_prototype_list_template (tree list_type, int size)
5450 tree objc_ivar_list_record;
5451 tree array_type, decls, *chain = NULL;
5453 /* Generate an unnamed struct definition. */
5455 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5457 /* int method_count; */
5458 decls = add_field_decl (integer_type_node, "method_count", &chain);
5460 /* struct objc_method method_list[]; */
5461 array_type = build_sized_array_type (list_type, size);
5462 add_field_decl (array_type, "method_list", &chain);
5464 objc_finish_struct (objc_ivar_list_record, decls);
5466 return objc_ivar_list_record;
5469 static tree
5470 build_method_prototype_template (void)
5472 tree proto_record;
5473 tree decls, *chain = NULL;
5475 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
5477 /* SEL _cmd; */
5478 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5480 /* char *method_types; */
5481 add_field_decl (string_type_node, "method_types", &chain);
5483 objc_finish_struct (proto_record, decls);
5485 return proto_record;
5488 static tree
5489 objc_method_parm_type (tree type)
5491 type = TREE_VALUE (TREE_TYPE (type));
5492 if (TREE_CODE (type) == TYPE_DECL)
5493 type = TREE_TYPE (type);
5494 return type;
5497 static int
5498 objc_encoded_type_size (tree type)
5500 int sz = int_size_in_bytes (type);
5502 /* Make all integer and enum types at least as large
5503 as an int. */
5504 if (sz > 0 && INTEGRAL_TYPE_P (type))
5505 sz = MAX (sz, int_size_in_bytes (integer_type_node));
5506 /* Treat arrays as pointers, since that's how they're
5507 passed in. */
5508 else if (TREE_CODE (type) == ARRAY_TYPE)
5509 sz = int_size_in_bytes (ptr_type_node);
5510 return sz;
5513 /* Encode a method prototype.
5515 The format is described in gcc/doc/objc.texi, section 'Method
5516 signatures'.
5518 static tree
5519 encode_method_prototype (tree method_decl)
5521 tree parms;
5522 int parm_offset, i;
5523 char buf[40];
5524 tree result;
5526 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5527 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5529 /* Encode return type. */
5530 encode_type (objc_method_parm_type (method_decl),
5531 obstack_object_size (&util_obstack),
5532 OBJC_ENCODE_INLINE_DEFS);
5534 /* Stack size. */
5535 /* The first two arguments (self and _cmd) are pointers; account for
5536 their size. */
5537 i = int_size_in_bytes (ptr_type_node);
5538 parm_offset = 2 * i;
5539 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5540 parms = DECL_CHAIN (parms))
5542 tree type = objc_method_parm_type (parms);
5543 int sz = objc_encoded_type_size (type);
5545 /* If a type size is not known, bail out. */
5546 if (sz < 0)
5548 error ("type %q+D does not have a known size",
5549 type);
5550 /* Pretend that the encoding succeeded; the compilation will
5551 fail nevertheless. */
5552 goto finish_encoding;
5554 parm_offset += sz;
5557 sprintf (buf, "%d@0:%d", parm_offset, i);
5558 obstack_grow (&util_obstack, buf, strlen (buf));
5560 /* Argument types. */
5561 parm_offset = 2 * i;
5562 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5563 parms = DECL_CHAIN (parms))
5565 tree type = objc_method_parm_type (parms);
5567 /* Process argument qualifiers for user supplied arguments. */
5568 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5570 /* Type. */
5571 encode_type (type, obstack_object_size (&util_obstack),
5572 OBJC_ENCODE_INLINE_DEFS);
5574 /* Compute offset. */
5575 sprintf (buf, "%d", parm_offset);
5576 parm_offset += objc_encoded_type_size (type);
5578 obstack_grow (&util_obstack, buf, strlen (buf));
5581 finish_encoding:
5582 obstack_1grow (&util_obstack, '\0');
5583 result = get_identifier (XOBFINISH (&util_obstack, char *));
5584 obstack_free (&util_obstack, util_firstobj);
5585 return result;
5588 static tree
5589 generate_descriptor_table (tree type, const char *name, int size, tree list,
5590 tree proto)
5592 tree decl;
5593 VEC(constructor_elt,gc) *v = NULL;
5595 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5597 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5598 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5600 finish_var_decl (decl, objc_build_constructor (type, v));
5602 return decl;
5605 static void
5606 generate_method_descriptors (tree protocol)
5608 tree initlist, chain, method_list_template;
5609 int size;
5611 if (!objc_method_prototype_template)
5612 objc_method_prototype_template = build_method_prototype_template ();
5614 chain = PROTOCOL_CLS_METHODS (protocol);
5615 if (chain)
5617 size = list_length (chain);
5619 method_list_template
5620 = build_method_prototype_list_template (objc_method_prototype_template,
5621 size);
5623 initlist
5624 = build_descriptor_table_initializer (objc_method_prototype_template,
5625 chain);
5627 UOBJC_CLASS_METHODS_decl
5628 = generate_descriptor_table (method_list_template,
5629 "_OBJC_PROTOCOL_CLASS_METHODS",
5630 size, initlist, protocol);
5632 else
5633 UOBJC_CLASS_METHODS_decl = 0;
5635 chain = PROTOCOL_NST_METHODS (protocol);
5636 if (chain)
5638 size = list_length (chain);
5640 method_list_template
5641 = build_method_prototype_list_template (objc_method_prototype_template,
5642 size);
5643 initlist
5644 = build_descriptor_table_initializer (objc_method_prototype_template,
5645 chain);
5647 UOBJC_INSTANCE_METHODS_decl
5648 = generate_descriptor_table (method_list_template,
5649 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5650 size, initlist, protocol);
5652 else
5653 UOBJC_INSTANCE_METHODS_decl = 0;
5656 static void
5657 generate_protocol_references (tree plist)
5659 tree lproto;
5661 /* Forward declare protocols referenced. */
5662 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5664 tree proto = TREE_VALUE (lproto);
5666 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5667 && PROTOCOL_NAME (proto))
5669 if (! PROTOCOL_FORWARD_DECL (proto))
5670 build_protocol_reference (proto);
5672 if (PROTOCOL_LIST (proto))
5673 generate_protocol_references (PROTOCOL_LIST (proto));
5678 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5679 current class. */
5680 #ifdef OBJCPLUS
5681 static void
5682 objc_generate_cxx_ctor_or_dtor (bool dtor)
5684 tree fn, body, compound_stmt, ivar;
5686 /* - (id) .cxx_construct { ... return self; } */
5687 /* - (void) .cxx_construct { ... } */
5689 objc_start_method_definition
5690 (false /* is_class_method */,
5691 objc_build_method_signature (false /* is_class_method */,
5692 build_tree_list (NULL_TREE,
5693 dtor
5694 ? void_type_node
5695 : objc_object_type),
5696 get_identifier (dtor
5697 ? TAG_CXX_DESTRUCT
5698 : TAG_CXX_CONSTRUCT),
5699 make_node (TREE_LIST),
5700 false), NULL);
5701 body = begin_function_body ();
5702 compound_stmt = begin_compound_stmt (0);
5704 ivar = CLASS_IVARS (implementation_template);
5705 /* Destroy ivars in reverse order. */
5706 if (dtor)
5707 ivar = nreverse (copy_list (ivar));
5709 for (; ivar; ivar = TREE_CHAIN (ivar))
5711 if (TREE_CODE (ivar) == FIELD_DECL)
5713 tree type = TREE_TYPE (ivar);
5715 /* Call the ivar's default constructor or destructor. Do not
5716 call the destructor unless a corresponding constructor call
5717 has also been made (or is not needed). */
5718 if (MAYBE_CLASS_TYPE_P (type)
5719 && (dtor
5720 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5721 && (!TYPE_NEEDS_CONSTRUCTING (type)
5722 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5723 : (TYPE_NEEDS_CONSTRUCTING (type)
5724 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5725 finish_expr_stmt
5726 (build_special_member_call
5727 (build_ivar_reference (DECL_NAME (ivar)),
5728 dtor ? complete_dtor_identifier : complete_ctor_identifier,
5729 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5733 /* The constructor returns 'self'. */
5734 if (!dtor)
5735 finish_return_stmt (self_decl);
5737 finish_compound_stmt (compound_stmt);
5738 finish_function_body (body);
5739 fn = current_function_decl;
5740 finish_function ();
5741 objc_finish_method_definition (fn);
5744 /* The following routine will examine the current @interface for any
5745 non-POD C++ ivars requiring non-trivial construction and/or
5746 destruction, and then synthesize special '- .cxx_construct' and/or
5747 '- .cxx_destruct' methods which will run the appropriate
5748 construction or destruction code. Note that ivars inherited from
5749 super-classes are _not_ considered. */
5750 static void
5751 objc_generate_cxx_cdtors (void)
5753 bool need_ctor = false, need_dtor = false;
5754 tree ivar;
5756 /* Error case, due to possibly an extra @end. */
5757 if (!objc_implementation_context)
5758 return;
5760 /* We do not want to do this for categories, since they do not have
5761 their own ivars. */
5763 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
5764 return;
5766 /* First, determine if we even need a constructor and/or destructor. */
5768 for (ivar = CLASS_IVARS (implementation_template); ivar;
5769 ivar = TREE_CHAIN (ivar))
5771 if (TREE_CODE (ivar) == FIELD_DECL)
5773 tree type = TREE_TYPE (ivar);
5775 if (MAYBE_CLASS_TYPE_P (type))
5777 if (TYPE_NEEDS_CONSTRUCTING (type)
5778 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
5779 /* NB: If a default constructor is not available, we will not
5780 be able to initialize this ivar; the add_instance_variable()
5781 routine will already have warned about this. */
5782 need_ctor = true;
5784 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5785 && (!TYPE_NEEDS_CONSTRUCTING (type)
5786 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5787 /* NB: If a default constructor is not available, we will not
5788 call the destructor either, for symmetry. */
5789 need_dtor = true;
5794 /* Generate '- .cxx_construct' if needed. */
5796 if (need_ctor)
5797 objc_generate_cxx_ctor_or_dtor (false);
5799 /* Generate '- .cxx_destruct' if needed. */
5801 if (need_dtor)
5802 objc_generate_cxx_ctor_or_dtor (true);
5804 /* The 'imp_list' variable points at an imp_entry record for the current
5805 @implementation. Record the existence of '- .cxx_construct' and/or
5806 '- .cxx_destruct' methods therein; it will be included in the
5807 metadata for the class. */
5808 if (flag_next_runtime)
5809 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
5811 #endif
5813 /* For each protocol which was referenced either from a @protocol()
5814 expression, or because a class/category implements it (then a
5815 pointer to the protocol is stored in the struct describing the
5816 class/category), we create a statically allocated instance of the
5817 Protocol class. The code is written in such a way as to generate
5818 as few Protocol objects as possible; we generate a unique Protocol
5819 instance for each protocol, and we don't generate a Protocol
5820 instance if the protocol is never referenced (either from a
5821 @protocol() or from a class/category implementation). These
5822 statically allocated objects can be referred to via the static
5823 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5825 The statically allocated Protocol objects that we generate here
5826 need to be fixed up at runtime in order to be used: the 'isa'
5827 pointer of the objects need to be set up to point to the 'Protocol'
5828 class, as known at runtime.
5830 The NeXT runtime fixes up all protocols at program startup time,
5831 before main() is entered. It uses a low-level trick to look up all
5832 those symbols, then loops on them and fixes them up.
5834 The GNU runtime as well fixes up all protocols before user code
5835 from the module is executed; it requires pointers to those symbols
5836 to be put in the objc_symtab (which is then passed as argument to
5837 the function __objc_exec_class() which the compiler sets up to be
5838 executed automatically when the module is loaded); setup of those
5839 Protocol objects happen in two ways in the GNU runtime: all
5840 Protocol objects referred to by a class or category implementation
5841 are fixed up when the class/category is loaded; all Protocol
5842 objects referred to by a @protocol() expression are added by the
5843 compiler to the list of statically allocated instances to fixup
5844 (the same list holding the statically allocated constant string
5845 objects). Because, as explained above, the compiler generates as
5846 few Protocol objects as possible, some Protocol object might end up
5847 being referenced multiple times when compiled with the GNU runtime,
5848 and end up being fixed up multiple times at runtime initialization.
5849 But that doesn't hurt, it's just a little inefficient. */
5851 static void
5852 generate_protocols (void)
5854 tree p, encoding;
5855 tree decl;
5856 tree initlist, protocol_name_expr, refs_decl, refs_expr;
5858 /* If a protocol was directly referenced, pull in indirect references. */
5859 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5860 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
5861 generate_protocol_references (PROTOCOL_LIST (p));
5863 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5865 tree nst_methods = PROTOCOL_NST_METHODS (p);
5866 tree cls_methods = PROTOCOL_CLS_METHODS (p);
5868 /* If protocol wasn't referenced, don't generate any code. */
5869 decl = PROTOCOL_FORWARD_DECL (p);
5871 if (!decl)
5872 continue;
5874 /* Make sure we link in the Protocol class. */
5875 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5877 while (nst_methods)
5879 if (! METHOD_ENCODING (nst_methods))
5881 encoding = encode_method_prototype (nst_methods);
5882 METHOD_ENCODING (nst_methods) = encoding;
5884 nst_methods = DECL_CHAIN (nst_methods);
5887 while (cls_methods)
5889 if (! METHOD_ENCODING (cls_methods))
5891 encoding = encode_method_prototype (cls_methods);
5892 METHOD_ENCODING (cls_methods) = encoding;
5895 cls_methods = DECL_CHAIN (cls_methods);
5897 generate_method_descriptors (p);
5899 if (PROTOCOL_LIST (p))
5900 refs_decl = generate_protocol_list (p);
5901 else
5902 refs_decl = 0;
5904 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5905 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
5907 if (refs_decl)
5908 refs_expr = convert (build_pointer_type (build_pointer_type
5909 (objc_protocol_template)),
5910 build_unary_op (input_location,
5911 ADDR_EXPR, refs_decl, 0));
5912 else
5913 refs_expr = build_int_cst (NULL_TREE, 0);
5915 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5916 by generate_method_descriptors, which is called above. */
5917 initlist = build_protocol_initializer (TREE_TYPE (decl),
5918 protocol_name_expr, refs_expr,
5919 UOBJC_INSTANCE_METHODS_decl,
5920 UOBJC_CLASS_METHODS_decl);
5921 finish_var_decl (decl, initlist);
5925 static tree
5926 build_protocol_initializer (tree type, tree protocol_name,
5927 tree protocol_list, tree instance_methods,
5928 tree class_methods)
5930 tree expr;
5931 tree cast_type = build_pointer_type
5932 (xref_tag (RECORD_TYPE,
5933 get_identifier (UTAG_CLASS)));
5934 VEC(constructor_elt,gc) *inits = NULL;
5936 /* Filling the "isa" in with one allows the runtime system to
5937 detect that the version change...should remove before final release. */
5939 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
5940 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5941 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
5942 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
5944 if (!instance_methods)
5945 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5946 else
5948 expr = convert (objc_method_proto_list_ptr,
5949 build_unary_op (input_location,
5950 ADDR_EXPR, instance_methods, 0));
5951 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5954 if (!class_methods)
5955 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5956 else
5958 expr = convert (objc_method_proto_list_ptr,
5959 build_unary_op (input_location,
5960 ADDR_EXPR, class_methods, 0));
5961 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5964 return objc_build_constructor (type, inits);
5967 /* struct _objc_category {
5968 char *category_name;
5969 char *class_name;
5970 struct _objc_method_list *instance_methods;
5971 struct _objc_method_list *class_methods;
5972 struct _objc_protocol_list *protocols;
5973 }; */
5975 static void
5976 build_category_template (void)
5978 tree ptype, decls, *chain = NULL;
5980 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
5982 /* char *category_name; */
5983 decls = add_field_decl (string_type_node, "category_name", &chain);
5985 /* char *class_name; */
5986 add_field_decl (string_type_node, "class_name", &chain);
5988 /* struct _objc_method_list *instance_methods; */
5989 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
5991 /* struct _objc_method_list *class_methods; */
5992 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
5994 /* struct _objc_protocol **protocol_list; */
5995 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5996 add_field_decl (ptype, "protocol_list", &chain);
5998 objc_finish_struct (objc_category_template, decls);
6001 /* struct _objc_selector {
6002 SEL sel_id;
6003 char *sel_type;
6004 }; */
6006 static void
6007 build_selector_template (void)
6009 tree decls, *chain = NULL;
6011 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
6013 /* SEL sel_id; */
6014 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
6016 /* char *sel_type; */
6017 add_field_decl (string_type_node, "sel_type", &chain);
6019 objc_finish_struct (objc_selector_template, decls);
6022 /* struct _objc_class {
6023 struct _objc_class *isa;
6024 struct _objc_class *super_class;
6025 char *name;
6026 long version;
6027 long info;
6028 long instance_size;
6029 struct _objc_ivar_list *ivars;
6030 struct _objc_method_list *methods;
6031 #ifdef __NEXT_RUNTIME__
6032 struct objc_cache *cache;
6033 #else
6034 struct sarray *dtable;
6035 struct _objc_class *subclass_list;
6036 struct _objc_class *sibling_class;
6037 #endif
6038 struct _objc_protocol_list *protocols;
6039 #ifdef __NEXT_RUNTIME__
6040 void *sel_id;
6041 #endif
6042 void *gc_object_type;
6043 }; */
6045 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
6046 the NeXT/Apple runtime; still, the compiler must generate them to
6047 maintain backward binary compatibility (and to allow for future
6048 expansion). */
6050 static void
6051 build_class_template (void)
6053 tree ptype, decls, *chain = NULL;
6055 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
6057 /* struct _objc_class *isa; */
6058 decls = add_field_decl (build_pointer_type (objc_class_template),
6059 "isa", &chain);
6061 /* struct _objc_class *super_class; */
6062 add_field_decl (build_pointer_type (objc_class_template),
6063 "super_class", &chain);
6065 /* char *name; */
6066 add_field_decl (string_type_node, "name", &chain);
6068 /* long version; */
6069 add_field_decl (long_integer_type_node, "version", &chain);
6071 /* long info; */
6072 add_field_decl (long_integer_type_node, "info", &chain);
6074 /* long instance_size; */
6075 add_field_decl (long_integer_type_node, "instance_size", &chain);
6077 /* struct _objc_ivar_list *ivars; */
6078 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
6080 /* struct _objc_method_list *methods; */
6081 add_field_decl (objc_method_list_ptr, "methods", &chain);
6083 if (flag_next_runtime)
6085 /* struct objc_cache *cache; */
6086 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
6087 get_identifier ("objc_cache")));
6088 add_field_decl (ptype, "cache", &chain);
6090 else
6092 /* struct sarray *dtable; */
6093 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
6094 get_identifier ("sarray")));
6095 add_field_decl (ptype, "dtable", &chain);
6097 /* struct objc_class *subclass_list; */
6098 ptype = build_pointer_type (objc_class_template);
6099 add_field_decl (ptype, "subclass_list", &chain);
6101 /* struct objc_class *sibling_class; */
6102 ptype = build_pointer_type (objc_class_template);
6103 add_field_decl (ptype, "sibling_class", &chain);
6106 /* struct _objc_protocol **protocol_list; */
6107 ptype = build_pointer_type (build_pointer_type
6108 (xref_tag (RECORD_TYPE,
6109 get_identifier (UTAG_PROTOCOL))));
6110 add_field_decl (ptype, "protocol_list", &chain);
6112 if (flag_next_runtime)
6114 /* void *sel_id; */
6115 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
6118 /* void *gc_object_type; */
6119 add_field_decl (build_pointer_type (void_type_node),
6120 "gc_object_type", &chain);
6122 objc_finish_struct (objc_class_template, decls);
6125 /* Generate appropriate forward declarations for an implementation. */
6127 static void
6128 synth_forward_declarations (void)
6130 tree an_id;
6132 /* static struct objc_class _OBJC_CLASS_<my_name>; */
6133 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
6134 objc_class_template);
6136 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
6137 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
6138 objc_class_template);
6140 /* Pre-build the following entities - for speed/convenience. */
6142 an_id = get_identifier ("super_class");
6143 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
6144 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
6147 static void
6148 error_with_ivar (const char *message, tree decl)
6150 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
6151 message, identifier_to_locale (gen_declaration (decl)));
6155 static void
6156 check_ivars (tree inter, tree imp)
6158 tree intdecls = CLASS_RAW_IVARS (inter);
6159 tree impdecls = CLASS_RAW_IVARS (imp);
6161 while (1)
6163 tree t1, t2;
6165 #ifdef OBJCPLUS
6166 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
6167 intdecls = TREE_CHAIN (intdecls);
6168 #endif
6169 if (intdecls == 0 && impdecls == 0)
6170 break;
6171 if (intdecls == 0 || impdecls == 0)
6173 error ("inconsistent instance variable specification");
6174 break;
6177 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
6179 if (!comptypes (t1, t2)
6180 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
6181 DECL_INITIAL (impdecls)))
6183 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
6185 error_with_ivar ("conflicting instance variable type",
6186 impdecls);
6187 error_with_ivar ("previous declaration of",
6188 intdecls);
6190 else /* both the type and the name don't match */
6192 error ("inconsistent instance variable specification");
6193 break;
6197 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
6199 error_with_ivar ("conflicting instance variable name",
6200 impdecls);
6201 error_with_ivar ("previous declaration of",
6202 intdecls);
6205 intdecls = DECL_CHAIN (intdecls);
6206 impdecls = DECL_CHAIN (impdecls);
6210 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
6211 This needs to be done just once per compilation. */
6213 /* struct _objc_super {
6214 struct _objc_object *self;
6215 struct _objc_class *super_class;
6216 }; */
6218 static void
6219 build_super_template (void)
6221 tree decls, *chain = NULL;
6223 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
6225 /* struct _objc_object *self; */
6226 decls = add_field_decl (objc_object_type, "self", &chain);
6228 /* struct _objc_class *super_class; */
6229 add_field_decl (build_pointer_type (objc_class_template),
6230 "super_class", &chain);
6232 objc_finish_struct (objc_super_template, decls);
6235 /* struct _objc_ivar {
6236 char *ivar_name;
6237 char *ivar_type;
6238 int ivar_offset;
6239 }; */
6241 static tree
6242 build_ivar_template (void)
6244 tree objc_ivar_id, objc_ivar_record;
6245 tree decls, *chain = NULL;
6247 objc_ivar_id = get_identifier (UTAG_IVAR);
6248 objc_ivar_record = objc_start_struct (objc_ivar_id);
6250 /* char *ivar_name; */
6251 decls = add_field_decl (string_type_node, "ivar_name", &chain);
6253 /* char *ivar_type; */
6254 add_field_decl (string_type_node, "ivar_type", &chain);
6256 /* int ivar_offset; */
6257 add_field_decl (integer_type_node, "ivar_offset", &chain);
6259 objc_finish_struct (objc_ivar_record, decls);
6261 return objc_ivar_record;
6264 /* struct {
6265 int ivar_count;
6266 struct objc_ivar ivar_list[ivar_count];
6267 }; */
6269 static tree
6270 build_ivar_list_template (tree list_type, int size)
6272 tree objc_ivar_list_record;
6273 tree array_type, decls, *chain = NULL;
6275 objc_ivar_list_record = objc_start_struct (NULL_TREE);
6277 /* int ivar_count; */
6278 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
6280 /* struct objc_ivar ivar_list[]; */
6281 array_type = build_sized_array_type (list_type, size);
6282 add_field_decl (array_type, "ivar_list", &chain);
6284 objc_finish_struct (objc_ivar_list_record, decls);
6286 return objc_ivar_list_record;
6289 /* struct {
6290 struct _objc__method_prototype_list *method_next;
6291 int method_count;
6292 struct objc_method method_list[method_count];
6293 }; */
6295 static tree
6296 build_method_list_template (tree list_type, int size)
6298 tree objc_ivar_list_record;
6299 tree array_type, decls, *chain = NULL;
6301 objc_ivar_list_record = objc_start_struct (NULL_TREE);
6303 /* struct _objc__method_prototype_list *method_next; */
6304 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
6306 /* int method_count; */
6307 add_field_decl (integer_type_node, "method_count", &chain);
6309 /* struct objc_method method_list[]; */
6310 array_type = build_sized_array_type (list_type, size);
6311 add_field_decl (array_type, "method_list", &chain);
6313 objc_finish_struct (objc_ivar_list_record, decls);
6315 return objc_ivar_list_record;
6318 static tree
6319 build_ivar_list_initializer (tree type, tree field_decl)
6321 VEC(constructor_elt,gc) *inits = NULL;
6325 VEC(constructor_elt,gc) *ivar = NULL;
6326 tree id;
6328 /* Set name. */
6329 if (DECL_NAME (field_decl))
6330 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
6331 add_objc_string (DECL_NAME (field_decl),
6332 meth_var_names));
6333 else
6334 /* Unnamed bit-field ivar (yuck). */
6335 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
6337 /* Set type. */
6338 encode_field_decl (field_decl,
6339 obstack_object_size (&util_obstack),
6340 OBJC_ENCODE_DONT_INLINE_DEFS);
6342 /* Null terminate string. */
6343 obstack_1grow (&util_obstack, 0);
6344 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
6345 meth_var_types);
6346 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
6347 obstack_free (&util_obstack, util_firstobj);
6349 /* Set offset. */
6350 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
6351 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6352 objc_build_constructor (type, ivar));
6354 field_decl = DECL_CHAIN (field_decl);
6355 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
6357 while (field_decl);
6359 return objc_build_constructor (build_array_type (type, 0), inits);
6362 static tree
6363 generate_ivars_list (tree type, const char *name, int size, tree list)
6365 tree decl;
6366 VEC(constructor_elt,gc) *inits = NULL;
6368 decl = start_var_decl (type, synth_id_with_class_suffix
6369 (name, objc_implementation_context));
6371 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
6372 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
6374 finish_var_decl (decl,
6375 objc_build_constructor (TREE_TYPE (decl), inits));
6377 return decl;
6380 /* Count only the fields occurring in T. */
6382 static int
6383 ivar_list_length (tree t)
6385 int count = 0;
6387 for (; t; t = DECL_CHAIN (t))
6388 if (TREE_CODE (t) == FIELD_DECL)
6389 ++count;
6391 return count;
6394 static void
6395 generate_ivar_lists (void)
6397 tree initlist, ivar_list_template, chain;
6398 int size;
6400 generating_instance_variables = 1;
6402 if (!objc_ivar_template)
6403 objc_ivar_template = build_ivar_template ();
6405 /* Only generate class variables for the root of the inheritance
6406 hierarchy since these will be the same for every class. */
6408 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
6409 && (chain = TYPE_FIELDS (objc_class_template)))
6411 size = ivar_list_length (chain);
6413 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6414 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6416 UOBJC_CLASS_VARIABLES_decl
6417 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
6418 size, initlist);
6420 else
6421 UOBJC_CLASS_VARIABLES_decl = 0;
6423 chain = CLASS_IVARS (implementation_template);
6424 if (chain)
6426 size = ivar_list_length (chain);
6427 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6428 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6430 UOBJC_INSTANCE_VARIABLES_decl
6431 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
6432 size, initlist);
6434 else
6435 UOBJC_INSTANCE_VARIABLES_decl = 0;
6437 generating_instance_variables = 0;
6440 static tree
6441 build_dispatch_table_initializer (tree type, tree entries)
6443 VEC(constructor_elt,gc) *inits = NULL;
6447 VEC(constructor_elt,gc) *elems = NULL;
6448 tree expr;
6450 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6451 build_selector (METHOD_SEL_NAME (entries)));
6453 /* Generate the method encoding if we don't have one already. */
6454 if (! METHOD_ENCODING (entries))
6455 METHOD_ENCODING (entries) =
6456 encode_method_prototype (entries);
6458 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6459 add_objc_string (METHOD_ENCODING (entries),
6460 meth_var_types));
6462 expr = convert (ptr_type_node,
6463 build_unary_op (input_location, ADDR_EXPR,
6464 METHOD_DEFINITION (entries), 1));
6465 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
6467 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6468 objc_build_constructor (type, elems));
6470 entries = DECL_CHAIN (entries);
6472 while (entries);
6474 return objc_build_constructor (build_array_type (type, 0), inits);
6477 /* To accomplish method prototyping without generating all kinds of
6478 inane warnings, the definition of the dispatch table entries were
6479 changed from:
6481 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
6483 struct objc_method { SEL _cmd; ...; void *_imp; }; */
6485 static tree
6486 build_method_template (void)
6488 tree _SLT_record;
6489 tree decls, *chain = NULL;
6491 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
6493 /* SEL _cmd; */
6494 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6496 /* char *method_types; */
6497 add_field_decl (string_type_node, "method_types", &chain);
6499 /* void *_imp; */
6500 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6502 objc_finish_struct (_SLT_record, decls);
6504 return _SLT_record;
6508 static tree
6509 generate_dispatch_table (tree type, const char *name, int size, tree list)
6511 tree decl;
6512 VEC(constructor_elt,gc) *v = NULL;
6514 decl = start_var_decl (type, synth_id_with_class_suffix
6515 (name, objc_implementation_context));
6517 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6518 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6519 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6521 finish_var_decl (decl,
6522 objc_build_constructor (TREE_TYPE (decl), v));
6524 return decl;
6527 static void
6528 mark_referenced_methods (void)
6530 struct imp_entry *impent;
6531 tree chain;
6533 for (impent = imp_list; impent; impent = impent->next)
6535 chain = CLASS_CLS_METHODS (impent->imp_context);
6536 while (chain)
6538 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6539 chain = DECL_CHAIN (chain);
6542 chain = CLASS_NST_METHODS (impent->imp_context);
6543 while (chain)
6545 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6546 chain = DECL_CHAIN (chain);
6551 static void
6552 generate_dispatch_tables (void)
6554 tree initlist, chain, method_list_template;
6555 int size;
6557 if (!objc_method_template)
6558 objc_method_template = build_method_template ();
6560 chain = CLASS_CLS_METHODS (objc_implementation_context);
6561 if (chain)
6563 size = list_length (chain);
6565 method_list_template
6566 = build_method_list_template (objc_method_template, size);
6567 initlist
6568 = build_dispatch_table_initializer (objc_method_template, chain);
6570 UOBJC_CLASS_METHODS_decl
6571 = generate_dispatch_table (method_list_template,
6572 ((TREE_CODE (objc_implementation_context)
6573 == CLASS_IMPLEMENTATION_TYPE)
6574 ? "_OBJC_CLASS_METHODS"
6575 : "_OBJC_CATEGORY_CLASS_METHODS"),
6576 size, initlist);
6578 else
6579 UOBJC_CLASS_METHODS_decl = 0;
6581 chain = CLASS_NST_METHODS (objc_implementation_context);
6582 if (chain)
6584 size = list_length (chain);
6586 method_list_template
6587 = build_method_list_template (objc_method_template, size);
6588 initlist
6589 = build_dispatch_table_initializer (objc_method_template, chain);
6591 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6592 UOBJC_INSTANCE_METHODS_decl
6593 = generate_dispatch_table (method_list_template,
6594 "_OBJC_INSTANCE_METHODS",
6595 size, initlist);
6596 else
6597 /* We have a category. */
6598 UOBJC_INSTANCE_METHODS_decl
6599 = generate_dispatch_table (method_list_template,
6600 "_OBJC_CATEGORY_INSTANCE_METHODS",
6601 size, initlist);
6603 else
6604 UOBJC_INSTANCE_METHODS_decl = 0;
6607 static tree
6608 generate_protocol_list (tree i_or_p)
6610 tree array_type, ptype, refs_decl, lproto, e, plist;
6611 int size = 0;
6612 const char *ref_name;
6613 VEC(constructor_elt,gc) *v = NULL;
6615 switch (TREE_CODE (i_or_p))
6617 case CLASS_INTERFACE_TYPE:
6618 case CATEGORY_INTERFACE_TYPE:
6619 plist = CLASS_PROTOCOL_LIST (i_or_p);
6620 break;
6621 case PROTOCOL_INTERFACE_TYPE:
6622 plist = PROTOCOL_LIST (i_or_p);
6623 break;
6624 default:
6625 gcc_unreachable ();
6628 /* Compute size. */
6629 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6630 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6631 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6632 size++;
6634 /* Build initializer. */
6635 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6636 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6637 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6639 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6641 tree pval = TREE_VALUE (lproto);
6643 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6644 && PROTOCOL_FORWARD_DECL (pval))
6646 e = build_unary_op (input_location, ADDR_EXPR,
6647 PROTOCOL_FORWARD_DECL (pval), 0);
6648 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6652 /* static struct objc_protocol *refs[n]; */
6654 switch (TREE_CODE (i_or_p))
6656 case PROTOCOL_INTERFACE_TYPE:
6657 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6658 break;
6659 case CLASS_INTERFACE_TYPE:
6660 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6661 break;
6662 case CATEGORY_INTERFACE_TYPE:
6663 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6664 break;
6665 default:
6666 gcc_unreachable ();
6669 ptype = build_pointer_type (objc_protocol_template);
6670 array_type = build_sized_array_type (ptype, size + 3);
6671 refs_decl = start_var_decl (array_type, ref_name);
6673 finish_var_decl (refs_decl,
6674 objc_build_constructor (TREE_TYPE (refs_decl), v));
6676 return refs_decl;
6679 static tree
6680 build_category_initializer (tree type, tree cat_name, tree class_name,
6681 tree instance_methods, tree class_methods,
6682 tree protocol_list)
6684 tree expr;
6685 VEC(constructor_elt,gc) *v = NULL;
6687 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6688 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6690 if (!instance_methods)
6691 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6692 else
6694 expr = convert (objc_method_list_ptr,
6695 build_unary_op (input_location, ADDR_EXPR,
6696 instance_methods, 0));
6697 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6699 if (!class_methods)
6700 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6701 else
6703 expr = convert (objc_method_list_ptr,
6704 build_unary_op (input_location, ADDR_EXPR,
6705 class_methods, 0));
6706 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6709 /* protocol_list = */
6710 if (!protocol_list)
6711 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6712 else
6714 expr = convert (build_pointer_type
6715 (build_pointer_type
6716 (objc_protocol_template)),
6717 build_unary_op (input_location, ADDR_EXPR,
6718 protocol_list, 0));
6719 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6722 return objc_build_constructor (type, v);
6725 /* struct _objc_class {
6726 struct objc_class *isa;
6727 struct objc_class *super_class;
6728 char *name;
6729 long version;
6730 long info;
6731 long instance_size;
6732 struct objc_ivar_list *ivars;
6733 struct objc_method_list *methods;
6734 if (flag_next_runtime)
6735 struct objc_cache *cache;
6736 else {
6737 struct sarray *dtable;
6738 struct objc_class *subclass_list;
6739 struct objc_class *sibling_class;
6741 struct objc_protocol_list *protocols;
6742 if (flag_next_runtime)
6743 void *sel_id;
6744 void *gc_object_type;
6745 }; */
6747 static tree
6748 build_shared_structure_initializer (tree type, tree isa, tree super,
6749 tree name, tree size, int status,
6750 tree dispatch_table, tree ivar_list,
6751 tree protocol_list)
6753 tree expr;
6754 VEC(constructor_elt,gc) *v = NULL;
6756 /* isa = */
6757 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
6759 /* super_class = */
6760 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
6762 /* name = */
6763 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
6765 /* version = */
6766 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6767 build_int_cst (long_integer_type_node, 0));
6769 /* info = */
6770 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6771 build_int_cst (long_integer_type_node, status));
6773 /* instance_size = */
6774 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6775 convert (long_integer_type_node, size));
6777 /* objc_ivar_list = */
6778 if (!ivar_list)
6779 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6780 else
6782 expr = convert (objc_ivar_list_ptr,
6783 build_unary_op (input_location, ADDR_EXPR,
6784 ivar_list, 0));
6785 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6788 /* objc_method_list = */
6789 if (!dispatch_table)
6790 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6791 else
6793 expr = convert (objc_method_list_ptr,
6794 build_unary_op (input_location, ADDR_EXPR,
6795 dispatch_table, 0));
6796 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6799 if (flag_next_runtime)
6800 /* method_cache = */
6801 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6802 else
6804 /* dtable = */
6805 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6807 /* subclass_list = */
6808 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6810 /* sibling_class = */
6811 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6814 /* protocol_list = */
6815 if (! protocol_list)
6816 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6817 else
6819 expr = convert (build_pointer_type
6820 (build_pointer_type
6821 (objc_protocol_template)),
6822 build_unary_op (input_location, ADDR_EXPR,
6823 protocol_list, 0));
6824 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6827 if (flag_next_runtime)
6828 /* sel_id = NULL */
6829 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6831 /* gc_object_type = NULL */
6832 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6834 return objc_build_constructor (type, v);
6837 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6839 static inline tree
6840 lookup_category (tree klass, tree cat_name)
6842 tree category = CLASS_CATEGORY_LIST (klass);
6844 while (category && CLASS_SUPER_NAME (category) != cat_name)
6845 category = CLASS_CATEGORY_LIST (category);
6846 return category;
6849 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6851 static void
6852 generate_category (struct imp_entry *impent)
6854 tree initlist, cat_name_expr, class_name_expr;
6855 tree protocol_decl, category;
6856 tree cat = impent->imp_context;
6858 implementation_template = impent->imp_template;
6859 UOBJC_CLASS_decl = impent->class_decl;
6860 UOBJC_METACLASS_decl = impent->meta_decl;
6862 add_class_reference (CLASS_NAME (cat));
6863 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
6865 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
6867 category = lookup_category (implementation_template,
6868 CLASS_SUPER_NAME (cat));
6870 if (category && CLASS_PROTOCOL_LIST (category))
6872 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
6873 protocol_decl = generate_protocol_list (category);
6875 else
6876 protocol_decl = 0;
6878 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
6879 cat_name_expr, class_name_expr,
6880 UOBJC_INSTANCE_METHODS_decl,
6881 UOBJC_CLASS_METHODS_decl,
6882 protocol_decl);
6883 /* Finish and initialize the forward decl. */
6884 finish_var_decl (UOBJC_CLASS_decl, initlist);
6887 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6888 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6890 static void
6891 generate_shared_structures (struct imp_entry *impent)
6893 tree name_expr, super_expr, root_expr;
6894 tree my_root_id, my_super_id;
6895 tree cast_type, initlist, protocol_decl;
6896 int cls_flags;
6898 objc_implementation_context = impent->imp_context;
6899 implementation_template = impent->imp_template;
6900 UOBJC_CLASS_decl = impent->class_decl;
6901 UOBJC_METACLASS_decl = impent->meta_decl;
6902 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
6904 my_super_id = CLASS_SUPER_NAME (implementation_template);
6905 if (my_super_id)
6907 add_class_reference (my_super_id);
6909 /* Compute "my_root_id" - this is required for code generation.
6910 the "isa" for all meta class structures points to the root of
6911 the inheritance hierarchy (e.g. "__Object")... */
6912 my_root_id = my_super_id;
6915 tree my_root_int = lookup_interface (my_root_id);
6917 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
6918 my_root_id = CLASS_SUPER_NAME (my_root_int);
6919 else
6920 break;
6922 while (1);
6924 else
6925 /* No super class. */
6926 my_root_id = CLASS_NAME (implementation_template);
6928 cast_type = build_pointer_type (objc_class_template);
6929 name_expr = add_objc_string (CLASS_NAME (implementation_template),
6930 class_names);
6932 /* Install class `isa' and `super' pointers at runtime. */
6933 if (my_super_id)
6934 super_expr = add_objc_string (my_super_id, class_names);
6935 else
6936 super_expr = integer_zero_node;
6938 super_expr = build_c_cast (input_location,
6939 cast_type, super_expr); /* cast! */
6941 root_expr = add_objc_string (my_root_id, class_names);
6942 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
6944 if (CLASS_PROTOCOL_LIST (implementation_template))
6946 generate_protocol_references
6947 (CLASS_PROTOCOL_LIST (implementation_template));
6948 protocol_decl = generate_protocol_list (implementation_template);
6950 else
6951 protocol_decl = 0;
6953 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6955 initlist
6956 = build_shared_structure_initializer
6957 (TREE_TYPE (UOBJC_METACLASS_decl),
6958 root_expr, super_expr, name_expr,
6959 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
6960 2 /*CLS_META*/,
6961 UOBJC_CLASS_METHODS_decl,
6962 UOBJC_CLASS_VARIABLES_decl,
6963 protocol_decl);
6965 finish_var_decl (UOBJC_METACLASS_decl, initlist);
6967 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6969 initlist
6970 = build_shared_structure_initializer
6971 (TREE_TYPE (UOBJC_CLASS_decl),
6972 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
6973 super_expr, name_expr,
6974 convert (integer_type_node,
6975 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6976 (implementation_template))),
6977 1 /*CLS_FACTORY*/ | cls_flags,
6978 UOBJC_INSTANCE_METHODS_decl,
6979 UOBJC_INSTANCE_VARIABLES_decl,
6980 protocol_decl);
6982 finish_var_decl (UOBJC_CLASS_decl, initlist);
6986 static const char *
6987 synth_id_with_class_suffix (const char *preamble, tree ctxt)
6989 static char string[BUFSIZE];
6991 switch (TREE_CODE (ctxt))
6993 case CLASS_IMPLEMENTATION_TYPE:
6994 case CLASS_INTERFACE_TYPE:
6995 sprintf (string, "%s_%s", preamble,
6996 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
6997 break;
6998 case CATEGORY_IMPLEMENTATION_TYPE:
6999 case CATEGORY_INTERFACE_TYPE:
7001 /* We have a category. */
7002 const char *const class_name
7003 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7004 const char *const class_super_name
7005 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
7006 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
7007 break;
7009 case PROTOCOL_INTERFACE_TYPE:
7011 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
7012 sprintf (string, "%s_%s", preamble, protocol_name);
7013 break;
7015 default:
7016 gcc_unreachable ();
7019 return string;
7022 /* If type is empty or only type qualifiers are present, add default
7023 type of id (otherwise grokdeclarator will default to int). */
7024 static inline tree
7025 adjust_type_for_id_default (tree type)
7027 if (!type)
7028 type = make_node (TREE_LIST);
7030 if (!TREE_VALUE (type))
7031 TREE_VALUE (type) = objc_object_type;
7032 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
7033 && TYPED_OBJECT (TREE_VALUE (type)))
7034 error ("can not use an object as parameter to a method");
7036 return type;
7039 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
7040 arg_name and attributes. (TODO: Rename KEYWORD_DECL to
7041 OBJC_METHOD_PARM_DECL ?)
7043 A KEYWORD_DECL is a tree representing the declaration of a
7044 parameter of an Objective-C method. It is produced when parsing a
7045 fragment of Objective-C method declaration of the form
7047 keyworddecl:
7048 selector ':' '(' typename ')' identifier
7050 For example, take the Objective-C method
7052 -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
7054 the two fragments "pathForResource:(NSString *)resource" and
7055 "ofType:(NSString *)type" will generate a KEYWORD_DECL each. The
7056 KEYWORD_DECL stores the 'key_name' (eg, identifier for
7057 "pathForResource"), the 'arg_type' (eg, tree representing a
7058 NSString *), the 'arg_name' (eg identifier for "resource") and
7059 potentially some attributes (for example, a tree representing
7060 __attribute__ ((unused)) if such an attribute was attached to a
7061 certain parameter). You can access this information using the
7062 TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
7063 KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
7065 'key_name' is an identifier node (and is optional as you can omit
7066 it in Objective-C methods).
7067 'arg_type' is a tree list (and is optional too if no parameter type
7068 was specified).
7069 'arg_name' is an identifier node and is required.
7070 'attributes' is an optional tree containing parameter attributes. */
7071 tree
7072 objc_build_keyword_decl (tree key_name, tree arg_type,
7073 tree arg_name, tree attributes)
7075 tree keyword_decl;
7077 if (flag_objc1_only && attributes)
7078 error_at (input_location, "method argument attributes are not available in Objective-C 1.0");
7080 /* If no type is specified, default to "id". */
7081 arg_type = adjust_type_for_id_default (arg_type);
7083 keyword_decl = make_node (KEYWORD_DECL);
7085 TREE_TYPE (keyword_decl) = arg_type;
7086 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
7087 KEYWORD_KEY_NAME (keyword_decl) = key_name;
7088 DECL_ATTRIBUTES (keyword_decl) = attributes;
7090 return keyword_decl;
7093 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
7094 static tree
7095 build_keyword_selector (tree selector)
7097 int len = 0;
7098 tree key_chain, key_name;
7099 char *buf;
7101 /* Scan the selector to see how much space we'll need. */
7102 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7104 switch (TREE_CODE (selector))
7106 case KEYWORD_DECL:
7107 key_name = KEYWORD_KEY_NAME (key_chain);
7108 break;
7109 case TREE_LIST:
7110 key_name = TREE_PURPOSE (key_chain);
7111 break;
7112 default:
7113 gcc_unreachable ();
7116 if (key_name)
7117 len += IDENTIFIER_LENGTH (key_name) + 1;
7118 else
7119 /* Just a ':' arg. */
7120 len++;
7123 buf = (char *) alloca (len + 1);
7124 /* Start the buffer out as an empty string. */
7125 buf[0] = '\0';
7127 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7129 switch (TREE_CODE (selector))
7131 case KEYWORD_DECL:
7132 key_name = KEYWORD_KEY_NAME (key_chain);
7133 break;
7134 case TREE_LIST:
7135 key_name = TREE_PURPOSE (key_chain);
7136 /* The keyword decl chain will later be used as a function
7137 argument chain. Unhook the selector itself so as to not
7138 confuse other parts of the compiler. */
7139 TREE_PURPOSE (key_chain) = NULL_TREE;
7140 break;
7141 default:
7142 gcc_unreachable ();
7145 if (key_name)
7146 strcat (buf, IDENTIFIER_POINTER (key_name));
7147 strcat (buf, ":");
7150 return get_identifier (buf);
7153 /* Used for declarations and definitions. */
7155 static tree
7156 build_method_decl (enum tree_code code, tree ret_type, tree selector,
7157 tree add_args, bool ellipsis)
7159 tree method_decl;
7161 /* If no type is specified, default to "id". */
7162 ret_type = adjust_type_for_id_default (ret_type);
7164 /* Note how a method_decl has a TREE_TYPE which is not the function
7165 type of the function implementing the method, but only the return
7166 type of the method. We may want to change this, and store the
7167 entire function type in there (eg, it may be used to simplify
7168 dealing with attributes below). */
7169 method_decl = make_node (code);
7170 TREE_TYPE (method_decl) = ret_type;
7172 /* If we have a keyword selector, create an identifier_node that
7173 represents the full selector name (`:' included)... */
7174 if (TREE_CODE (selector) == KEYWORD_DECL)
7176 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
7177 METHOD_SEL_ARGS (method_decl) = selector;
7178 METHOD_ADD_ARGS (method_decl) = add_args;
7179 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
7181 else
7183 METHOD_SEL_NAME (method_decl) = selector;
7184 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
7185 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
7188 return method_decl;
7191 #define METHOD_DEF 0
7192 #define METHOD_REF 1
7194 /* This routine processes objective-c method attributes. */
7196 static void
7197 objc_decl_method_attributes (tree *node, tree attributes, int flags)
7199 /* TODO: Replace the hackery below. An idea would be to store the
7200 full function type in the method declaration (for example in
7201 TREE_TYPE) and then expose ObjC method declarations to c-family
7202 and they could deal with them by simply treating them as
7203 functions. */
7205 /* Because of the dangers in the hackery below, we filter out any
7206 attribute that we do not know about. For the ones we know about,
7207 we know that they work with the hackery. For the other ones,
7208 there is no guarantee, so we have to filter them out. */
7209 tree filtered_attributes = NULL_TREE;
7211 if (attributes)
7213 tree attribute;
7214 for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
7216 tree name = TREE_PURPOSE (attribute);
7218 if (is_attribute_p ("deprecated", name)
7219 || is_attribute_p ("sentinel", name)
7220 || is_attribute_p ("noreturn", name))
7222 /* An attribute that we support; add it to the filtered
7223 attributes. */
7224 filtered_attributes = chainon (filtered_attributes,
7225 copy_node (attribute));
7227 else if (is_attribute_p ("format", name))
7229 /* "format" is special because before adding it to the
7230 filtered attributes we need to adjust the specified
7231 format by adding the hidden function parameters for
7232 an Objective-C method (self, _cmd). */
7233 tree new_attribute = copy_node (attribute);
7235 /* Check the arguments specified with the attribute, and
7236 modify them adding 2 for the two hidden arguments.
7237 Note how this differs from C++; according to the
7238 specs, C++ does not do it so you have to add the +1
7239 yourself. For Objective-C, instead, the compiler
7240 adds the +2 for you. */
7242 /* The attribute arguments have not been checked yet, so
7243 we need to be careful as they could be missing or
7244 invalid. If anything looks wrong, we skip the
7245 process and the compiler will complain about it later
7246 when it validates the attribute. */
7247 /* Check that we have at least three arguments. */
7248 if (TREE_VALUE (new_attribute)
7249 && TREE_CHAIN (TREE_VALUE (new_attribute))
7250 && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
7252 tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
7253 tree third_argument = TREE_CHAIN (second_argument);
7254 tree number;
7256 /* This is the second argument, the "string-index",
7257 which specifies the index of the format string
7258 argument. Add 2. */
7259 number = TREE_VALUE (second_argument);
7260 if (number
7261 && TREE_CODE (number) == INTEGER_CST
7262 && TREE_INT_CST_HIGH (number) == 0)
7264 TREE_VALUE (second_argument)
7265 = build_int_cst (integer_type_node,
7266 TREE_INT_CST_LOW (number) + 2);
7269 /* This is the third argument, the "first-to-check",
7270 which specifies the index of the first argument to
7271 check. This could be 0, meaning it is not available,
7272 in which case we don't need to add 2. Add 2 if not
7273 0. */
7274 number = TREE_VALUE (third_argument);
7275 if (number
7276 && TREE_CODE (number) == INTEGER_CST
7277 && TREE_INT_CST_HIGH (number) == 0
7278 && TREE_INT_CST_LOW (number) != 0)
7280 TREE_VALUE (third_argument)
7281 = build_int_cst (integer_type_node,
7282 TREE_INT_CST_LOW (number) + 2);
7285 filtered_attributes = chainon (filtered_attributes,
7286 new_attribute);
7288 else
7289 warning (OPT_Wattributes, "%qE attribute directive ignored", name);
7293 if (filtered_attributes)
7295 /* This hackery changes the TREE_TYPE of the ObjC method
7296 declaration to be a function type, so that decl_attributes
7297 will treat the ObjC method as if it was a function. Some
7298 attributes (sentinel, format) will be applied to the function
7299 type, changing it in place; so after calling decl_attributes,
7300 we extract the function type attributes and store them in
7301 METHOD_TYPE_ATTRIBUTES. Some other attributes (noreturn,
7302 deprecated) are applied directly to the method declaration
7303 (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
7304 is nothing to do. */
7305 tree saved_type = TREE_TYPE (*node);
7306 TREE_TYPE (*node) = build_function_type
7307 (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
7308 decl_attributes (node, filtered_attributes, flags);
7309 METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
7310 TREE_TYPE (*node) = saved_type;
7314 bool
7315 objc_method_decl (enum tree_code opcode)
7317 return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
7320 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
7321 an argument list for method METH. CONTEXT is either METHOD_DEF or
7322 METHOD_REF, saying whether we are trying to define a method or call
7323 one. SUPERFLAG says this is for a send to super; this makes a
7324 difference for the NeXT calling sequence in which the lookup and
7325 the method call are done together. If METH is null, user-defined
7326 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
7328 static tree
7329 get_arg_type_list (tree meth, int context, int superflag)
7331 tree arglist, akey;
7333 /* Receiver type. */
7334 if (flag_next_runtime && superflag)
7335 arglist = build_tree_list (NULL_TREE, objc_super_type);
7336 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
7337 arglist = build_tree_list (NULL_TREE, objc_instance_type);
7338 else
7339 arglist = build_tree_list (NULL_TREE, objc_object_type);
7341 /* Selector type - will eventually change to `int'. */
7342 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
7344 /* No actual method prototype given -- assume that remaining arguments
7345 are `...'. */
7346 if (!meth)
7347 return arglist;
7349 /* Build a list of argument types. */
7350 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
7352 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
7354 /* Decay argument types for the underlying C function as appropriate. */
7355 arg_type = objc_decay_parm_type (arg_type);
7357 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7360 if (METHOD_ADD_ARGS (meth))
7362 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
7363 akey; akey = TREE_CHAIN (akey))
7365 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
7367 arg_type = objc_decay_parm_type (arg_type);
7369 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7372 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
7373 goto lack_of_ellipsis;
7375 else
7377 lack_of_ellipsis:
7378 chainon (arglist, OBJC_VOID_AT_END);
7381 return arglist;
7384 static tree
7385 check_duplicates (hash hsh, int methods, int is_class)
7387 tree meth = NULL_TREE;
7389 if (hsh)
7391 meth = hsh->key;
7393 if (hsh->list)
7395 /* We have two or more methods with the same name but
7396 different types. */
7397 attr loop;
7399 /* But just how different are those types? If
7400 -Wno-strict-selector-match is specified, we shall not
7401 complain if the differences are solely among types with
7402 identical size and alignment. */
7403 if (!warn_strict_selector_match)
7405 for (loop = hsh->list; loop; loop = loop->next)
7406 if (!comp_proto_with_proto (meth, loop->value, 0))
7407 goto issue_warning;
7409 return meth;
7412 issue_warning:
7413 if (methods)
7415 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7417 warning_at (input_location, 0,
7418 "multiple methods named %<%c%E%> found",
7419 (is_class ? '+' : '-'),
7420 METHOD_SEL_NAME (meth));
7421 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
7422 (type ? '-' : '+'),
7423 identifier_to_locale (gen_method_decl (meth)));
7425 else
7427 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7429 warning_at (input_location, 0,
7430 "multiple selectors named %<%c%E%> found",
7431 (is_class ? '+' : '-'),
7432 METHOD_SEL_NAME (meth));
7433 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
7434 (type ? '-' : '+'),
7435 identifier_to_locale (gen_method_decl (meth)));
7438 for (loop = hsh->list; loop; loop = loop->next)
7440 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
7442 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
7443 (type ? '-' : '+'),
7444 identifier_to_locale (gen_method_decl (loop->value)));
7448 return meth;
7451 /* If RECEIVER is a class reference, return the identifier node for
7452 the referenced class. RECEIVER is created by objc_get_class_reference,
7453 so we check the exact form created depending on which runtimes are
7454 used. */
7456 static tree
7457 receiver_is_class_object (tree receiver, int self, int super)
7459 tree chain, exp, arg;
7461 /* The receiver is 'self' or 'super' in the context of a class method. */
7462 if (objc_method_context
7463 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
7464 && (self || super))
7465 return (super
7466 ? CLASS_SUPER_NAME (implementation_template)
7467 : CLASS_NAME (implementation_template));
7469 if (flag_next_runtime)
7471 /* The receiver is a variable created by
7472 build_class_reference_decl. */
7473 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
7474 /* Look up the identifier. */
7475 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7476 if (TREE_PURPOSE (chain) == receiver)
7477 return TREE_VALUE (chain);
7480 /* The receiver is a function call that returns an id. Check if
7481 it is a call to objc_getClass, if so, pick up the class name. */
7482 if (TREE_CODE (receiver) == CALL_EXPR
7483 && (exp = CALL_EXPR_FN (receiver))
7484 && TREE_CODE (exp) == ADDR_EXPR
7485 && (exp = TREE_OPERAND (exp, 0))
7486 && TREE_CODE (exp) == FUNCTION_DECL
7487 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
7488 prototypes for objc_get_class(). Thankfully, they seem to share the
7489 same function type. */
7490 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
7491 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
7492 /* We have a call to objc_get_class/objc_getClass! */
7493 && (arg = CALL_EXPR_ARG (receiver, 0)))
7495 STRIP_NOPS (arg);
7496 if (TREE_CODE (arg) == ADDR_EXPR
7497 && (arg = TREE_OPERAND (arg, 0))
7498 && TREE_CODE (arg) == STRING_CST)
7499 /* Finally, we have the class name. */
7500 return get_identifier (TREE_STRING_POINTER (arg));
7502 return 0;
7505 /* If we are currently building a message expr, this holds
7506 the identifier of the selector of the message. This is
7507 used when printing warnings about argument mismatches. */
7509 static tree current_objc_message_selector = 0;
7511 tree
7512 objc_message_selector (void)
7514 return current_objc_message_selector;
7517 /* Construct an expression for sending a message.
7518 MESS has the object to send to in TREE_PURPOSE
7519 and the argument list (including selector) in TREE_VALUE.
7521 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
7522 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
7524 tree
7525 objc_build_message_expr (tree mess)
7527 tree receiver = TREE_PURPOSE (mess);
7528 tree sel_name;
7529 #ifdef OBJCPLUS
7530 tree args = TREE_PURPOSE (TREE_VALUE (mess));
7531 #else
7532 tree args = TREE_VALUE (mess);
7533 #endif
7534 tree method_params = NULL_TREE;
7536 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
7537 return error_mark_node;
7539 /* Obtain the full selector name. */
7540 switch (TREE_CODE (args))
7542 case IDENTIFIER_NODE:
7543 /* A unary selector. */
7544 sel_name = args;
7545 break;
7546 case TREE_LIST:
7547 sel_name = build_keyword_selector (args);
7548 break;
7549 default:
7550 gcc_unreachable ();
7553 /* Build the parameter list to give to the method. */
7554 if (TREE_CODE (args) == TREE_LIST)
7555 #ifdef OBJCPLUS
7556 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
7557 #else
7559 tree chain = args, prev = NULL_TREE;
7561 /* We have a keyword selector--check for comma expressions. */
7562 while (chain)
7564 tree element = TREE_VALUE (chain);
7566 /* We have a comma expression, must collapse... */
7567 if (TREE_CODE (element) == TREE_LIST)
7569 if (prev)
7570 TREE_CHAIN (prev) = element;
7571 else
7572 args = element;
7574 prev = chain;
7575 chain = TREE_CHAIN (chain);
7577 method_params = args;
7579 #endif
7581 #ifdef OBJCPLUS
7582 if (processing_template_decl)
7583 /* Must wait until template instantiation time. */
7584 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
7585 method_params);
7586 #endif
7588 return objc_finish_message_expr (receiver, sel_name, method_params);
7591 /* Look up method SEL_NAME that would be suitable for receiver
7592 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
7593 nonzero), and report on any duplicates. */
7595 static tree
7596 lookup_method_in_hash_lists (tree sel_name, int is_class)
7598 hash method_prototype = NULL;
7600 if (!is_class)
7601 method_prototype = hash_lookup (nst_method_hash_list,
7602 sel_name);
7604 if (!method_prototype)
7606 method_prototype = hash_lookup (cls_method_hash_list,
7607 sel_name);
7608 is_class = 1;
7611 return check_duplicates (method_prototype, 1, is_class);
7614 /* The 'objc_finish_message_expr' routine is called from within
7615 'objc_build_message_expr' for non-template functions. In the case of
7616 C++ template functions, it is called from 'build_expr_from_tree'
7617 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
7619 tree
7620 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7622 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7623 tree selector, retval, class_tree;
7624 int self, super, have_cast;
7626 /* We have used the receiver, so mark it as read. */
7627 mark_exp_read (receiver);
7629 /* Extract the receiver of the message, as well as its type
7630 (where the latter may take the form of a cast or be inferred
7631 from the implementation context). */
7632 rtype = receiver;
7633 while (TREE_CODE (rtype) == COMPOUND_EXPR
7634 || TREE_CODE (rtype) == MODIFY_EXPR
7635 || CONVERT_EXPR_P (rtype)
7636 || TREE_CODE (rtype) == COMPONENT_REF)
7637 rtype = TREE_OPERAND (rtype, 0);
7639 self = (rtype == self_decl);
7640 super = (rtype == UOBJC_SUPER_decl);
7641 rtype = TREE_TYPE (receiver);
7643 have_cast = (TREE_CODE (receiver) == NOP_EXPR
7644 || (TREE_CODE (receiver) == COMPOUND_EXPR
7645 && !IS_SUPER (rtype)));
7647 /* If we are calling [super dealloc], reset our warning flag. */
7648 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7649 should_call_super_dealloc = 0;
7651 /* If the receiver is a class object, retrieve the corresponding
7652 @interface, if one exists. */
7653 class_tree = receiver_is_class_object (receiver, self, super);
7655 /* Now determine the receiver type (if an explicit cast has not been
7656 provided). */
7657 if (!have_cast)
7659 if (class_tree)
7660 rtype = lookup_interface (class_tree);
7661 /* Handle `self' and `super'. */
7662 else if (super)
7664 if (!CLASS_SUPER_NAME (implementation_template))
7666 error ("no super class declared in @interface for %qE",
7667 CLASS_NAME (implementation_template));
7668 return error_mark_node;
7670 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7672 else if (self)
7673 rtype = lookup_interface (CLASS_NAME (implementation_template));
7676 /* If receiver is of type `id' or `Class' (or if the @interface for a
7677 class is not visible), we shall be satisfied with the existence of
7678 any instance or class method. */
7679 if (objc_is_id (rtype))
7681 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7682 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7683 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7684 : NULL_TREE);
7685 rtype = NULL_TREE;
7687 if (rprotos)
7689 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7690 in protocols themselves for the method prototype. */
7691 method_prototype
7692 = lookup_method_in_protocol_list (rprotos, sel_name,
7693 class_tree != NULL_TREE);
7695 /* If messaging 'Class <Proto>' but did not find a class method
7696 prototype, search for an instance method instead, and warn
7697 about having done so. */
7698 if (!method_prototype && !rtype && class_tree != NULL_TREE)
7700 method_prototype
7701 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7703 if (method_prototype)
7704 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7705 sel_name, sel_name);
7709 else if (rtype)
7711 tree orig_rtype = rtype;
7713 if (TREE_CODE (rtype) == POINTER_TYPE)
7714 rtype = TREE_TYPE (rtype);
7715 /* Traverse typedef aliases */
7716 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7717 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7718 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7719 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7720 if (TYPED_OBJECT (rtype))
7722 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7723 rtype = TYPE_OBJC_INTERFACE (rtype);
7725 /* If we could not find an @interface declaration, we must have
7726 only seen a @class declaration; so, we cannot say anything
7727 more intelligent about which methods the receiver will
7728 understand. */
7729 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7731 rtype = NULL_TREE;
7732 /* We could not find an @interface declaration, yet Message maybe in a
7733 @class's protocol. */
7734 if (!method_prototype && rprotos)
7735 method_prototype
7736 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7738 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7739 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7741 /* We have a valid ObjC class name. Look up the method name
7742 in the published @interface for the class (and its
7743 superclasses). */
7744 method_prototype
7745 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7747 /* If the method was not found in the @interface, it may still
7748 exist locally as part of the @implementation. */
7749 if (!method_prototype && objc_implementation_context
7750 && CLASS_NAME (objc_implementation_context)
7751 == OBJC_TYPE_NAME (rtype))
7752 method_prototype
7753 = lookup_method
7754 ((class_tree
7755 ? CLASS_CLS_METHODS (objc_implementation_context)
7756 : CLASS_NST_METHODS (objc_implementation_context)),
7757 sel_name);
7759 /* If we haven't found a candidate method by now, try looking for
7760 it in the protocol list. */
7761 if (!method_prototype && rprotos)
7762 method_prototype
7763 = lookup_method_in_protocol_list (rprotos, sel_name,
7764 class_tree != NULL_TREE);
7766 else
7768 warning (0, "invalid receiver type %qs",
7769 identifier_to_locale (gen_type_name (orig_rtype)));
7770 /* After issuing the "invalid receiver" warning, perform method
7771 lookup as if we were messaging 'id'. */
7772 rtype = rprotos = NULL_TREE;
7777 /* For 'id' or 'Class' receivers, search in the global hash table
7778 as a last resort. For all receivers, warn if protocol searches
7779 have failed. */
7780 if (!method_prototype)
7782 if (rprotos)
7783 warning (0, "%<%c%E%> not found in protocol(s)",
7784 (class_tree ? '+' : '-'),
7785 sel_name);
7787 if (!rtype)
7788 method_prototype
7789 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
7792 if (!method_prototype)
7794 static bool warn_missing_methods = false;
7796 if (rtype)
7797 warning (0, "%qE may not respond to %<%c%E%>",
7798 OBJC_TYPE_NAME (rtype),
7799 (class_tree ? '+' : '-'),
7800 sel_name);
7801 /* If we are messaging an 'id' or 'Class' object and made it here,
7802 then we have failed to find _any_ instance or class method,
7803 respectively. */
7804 else
7805 warning (0, "no %<%c%E%> method found",
7806 (class_tree ? '+' : '-'),
7807 sel_name);
7809 if (!warn_missing_methods)
7811 warning_at (input_location,
7812 0, "(Messages without a matching method signature");
7813 warning_at (input_location,
7814 0, "will be assumed to return %<id%> and accept");
7815 warning_at (input_location,
7816 0, "%<...%> as arguments.)");
7817 warn_missing_methods = true;
7820 else
7822 /* Warn if the method is deprecated, but not if the receiver is
7823 a generic 'id'. 'id' is used to cast an object to a generic
7824 object of an unspecified class; in that case, we'll use
7825 whatever method prototype we can find to get the method
7826 argument and return types, but it is not appropriate to
7827 produce deprecation warnings since we don't know the class
7828 that the object will be of at runtime. The @interface(s) for
7829 that class may not even be available to the compiler right
7830 now, and it is perfectly possible that the method is marked
7831 as non-deprecated in such @interface(s).
7833 In practice this makes sense since casting an object to 'id'
7834 is often used precisely to turn off warnings associated with
7835 the object being of a particular class. */
7836 if (TREE_DEPRECATED (method_prototype) && rtype != NULL_TREE)
7837 warn_deprecated_use (method_prototype, NULL_TREE);
7841 /* Save the selector name for printing error messages. */
7842 current_objc_message_selector = sel_name;
7844 /* Build the parameters list for looking up the method.
7845 These are the object itself and the selector. */
7847 if (flag_typed_selectors)
7848 selector = build_typed_selector_reference (input_location,
7849 sel_name, method_prototype);
7850 else
7851 selector = build_selector_reference (input_location, sel_name);
7853 retval = build_objc_method_call (input_location, super, method_prototype,
7854 receiver,
7855 selector, method_params);
7857 current_objc_message_selector = 0;
7859 return retval;
7862 /* Build a tree expression to send OBJECT the operation SELECTOR,
7863 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7864 assuming the method has prototype METHOD_PROTOTYPE.
7865 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7866 LOC is the location of the expression to build.
7867 Use METHOD_PARAMS as list of args to pass to the method.
7868 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7870 static tree
7871 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
7872 tree lookup_object, tree selector,
7873 tree method_params)
7875 tree sender = (super_flag ? umsg_super_decl :
7876 (!flag_next_runtime || flag_nil_receivers
7877 ? (flag_objc_direct_dispatch
7878 ? umsg_fast_decl
7879 : umsg_decl)
7880 : umsg_nonnil_decl));
7881 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
7882 VEC(tree, gc) *parms = NULL;
7883 unsigned nparm = (method_params ? list_length (method_params) : 0);
7885 /* If a prototype for the method to be called exists, then cast
7886 the sender's return type and arguments to match that of the method.
7887 Otherwise, leave sender as is. */
7888 tree ret_type
7889 = (method_prototype
7890 ? TREE_VALUE (TREE_TYPE (method_prototype))
7891 : objc_object_type);
7893 tree method_param_types =
7894 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
7895 tree ftype = build_function_type (ret_type, method_param_types);
7896 tree sender_cast;
7897 tree method, t;
7899 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
7900 ftype = build_type_attribute_variant (ftype,
7901 METHOD_TYPE_ATTRIBUTES
7902 (method_prototype));
7904 sender_cast = build_pointer_type (ftype);
7906 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
7908 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7909 lookup_object = save_expr (lookup_object);
7911 /* Param list + 2 slots for object and selector. */
7912 parms = VEC_alloc (tree, gc, nparm + 2);
7914 if (flag_next_runtime)
7916 /* If we are returning a struct in memory, and the address
7917 of that memory location is passed as a hidden first
7918 argument, then change which messenger entry point this
7919 expr will call. NB: Note that sender_cast remains
7920 unchanged (it already has a struct return type). */
7921 if (!targetm.calls.struct_value_rtx (0, 0)
7922 && (TREE_CODE (ret_type) == RECORD_TYPE
7923 || TREE_CODE (ret_type) == UNION_TYPE)
7924 && targetm.calls.return_in_memory (ret_type, 0))
7925 sender = (super_flag ? umsg_super_stret_decl :
7926 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
7928 method = build_fold_addr_expr_loc (input_location, sender);
7929 /* Pass the object to the method. */
7930 VEC_quick_push (tree, parms, lookup_object);
7932 else
7934 /* This is the portable (GNU) way. */
7935 /* First, call the lookup function to get a pointer to the method,
7936 then cast the pointer, then call it with the method arguments. */
7937 VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
7938 VEC_quick_push (tree, tv, lookup_object);
7939 VEC_quick_push (tree, tv, selector);
7940 method = build_function_call_vec (loc, sender, tv, NULL);
7941 VEC_free (tree, gc, tv);
7943 /* Pass the appropriate object to the method. */
7944 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
7947 /* Pass the selector to the method. */
7948 VEC_quick_push (tree, parms, selector);
7949 /* Now append the remainder of the parms. */
7950 if (nparm)
7951 for (; method_params; method_params = TREE_CHAIN (method_params))
7952 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
7954 /* Build an obj_type_ref, with the correct cast for the method call. */
7955 t = build3 (OBJ_TYPE_REF, sender_cast, method,
7956 lookup_object, size_zero_node);
7957 t = build_function_call_vec (loc, t, parms, NULL);\
7958 VEC_free (tree, gc, parms);
7959 return t;
7962 static void
7963 build_protocol_reference (tree p)
7965 tree decl;
7966 const char *proto_name;
7968 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7970 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
7971 decl = start_var_decl (objc_protocol_template, proto_name);
7973 PROTOCOL_FORWARD_DECL (p) = decl;
7976 /* This function is called by the parser when (and only when) a
7977 @protocol() expression is found, in order to compile it. */
7978 tree
7979 objc_build_protocol_expr (tree protoname)
7981 tree expr;
7982 tree p = lookup_protocol (protoname);
7984 if (!p)
7986 error ("cannot find protocol declaration for %qE",
7987 protoname);
7988 return error_mark_node;
7991 if (!PROTOCOL_FORWARD_DECL (p))
7992 build_protocol_reference (p);
7994 expr = build_unary_op (input_location,
7995 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
7997 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7998 if we have it, rather than converting it here. */
7999 expr = convert (objc_protocol_type, expr);
8001 /* The @protocol() expression is being compiled into a pointer to a
8002 statically allocated instance of the Protocol class. To become
8003 usable at runtime, the 'isa' pointer of the instance need to be
8004 fixed up at runtime by the runtime library, to point to the
8005 actual 'Protocol' class. */
8007 /* For the GNU runtime, put the static Protocol instance in the list
8008 of statically allocated instances, so that we make sure that its
8009 'isa' pointer is fixed up at runtime by the GNU runtime library
8010 to point to the Protocol class (at runtime, when loading the
8011 module, the GNU runtime library loops on the statically allocated
8012 instances (as found in the defs field in objc_symtab) and fixups
8013 all the 'isa' pointers of those objects). */
8014 if (! flag_next_runtime)
8016 /* This type is a struct containing the fields of a Protocol
8017 object. (Cfr. objc_protocol_type instead is the type of a pointer
8018 to such a struct). */
8019 tree protocol_struct_type = xref_tag
8020 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
8021 tree *chain;
8023 /* Look for the list of Protocol statically allocated instances
8024 to fixup at runtime. Create a new list to hold Protocol
8025 statically allocated instances, if the list is not found. At
8026 present there is only another list, holding NSConstantString
8027 static instances to be fixed up at runtime. */
8028 for (chain = &objc_static_instances;
8029 *chain && TREE_VALUE (*chain) != protocol_struct_type;
8030 chain = &TREE_CHAIN (*chain));
8031 if (!*chain)
8033 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
8034 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
8035 class_names);
8038 /* Add this statically allocated instance to the Protocol list. */
8039 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
8040 PROTOCOL_FORWARD_DECL (p),
8041 TREE_PURPOSE (*chain));
8045 return expr;
8048 /* This function is called by the parser when a @selector() expression
8049 is found, in order to compile it. It is only called by the parser
8050 and only to compile a @selector(). LOC is the location of the
8051 @selector. */
8052 tree
8053 objc_build_selector_expr (location_t loc, tree selnamelist)
8055 tree selname;
8057 /* Obtain the full selector name. */
8058 switch (TREE_CODE (selnamelist))
8060 case IDENTIFIER_NODE:
8061 /* A unary selector. */
8062 selname = selnamelist;
8063 break;
8064 case TREE_LIST:
8065 selname = build_keyword_selector (selnamelist);
8066 break;
8067 default:
8068 gcc_unreachable ();
8071 /* If we are required to check @selector() expressions as they
8072 are found, check that the selector has been declared. */
8073 if (warn_undeclared_selector)
8075 /* Look the selector up in the list of all known class and
8076 instance methods (up to this line) to check that the selector
8077 exists. */
8078 hash hsh;
8080 /* First try with instance methods. */
8081 hsh = hash_lookup (nst_method_hash_list, selname);
8083 /* If not found, try with class methods. */
8084 if (!hsh)
8086 hsh = hash_lookup (cls_method_hash_list, selname);
8089 /* If still not found, print out a warning. */
8090 if (!hsh)
8092 warning (0, "undeclared selector %qE", selname);
8097 if (flag_typed_selectors)
8098 return build_typed_selector_reference (loc, selname, 0);
8099 else
8100 return build_selector_reference (loc, selname);
8103 /* This is used to implement @encode(). See gcc/doc/objc.texi,
8104 section '@encode'. */
8105 tree
8106 objc_build_encode_expr (tree type)
8108 tree result;
8109 const char *string;
8111 encode_type (type, obstack_object_size (&util_obstack),
8112 OBJC_ENCODE_INLINE_DEFS);
8113 obstack_1grow (&util_obstack, 0); /* null terminate string */
8114 string = XOBFINISH (&util_obstack, const char *);
8116 /* Synthesize a string that represents the encoded struct/union. */
8117 result = my_build_string (strlen (string) + 1, string);
8118 obstack_free (&util_obstack, util_firstobj);
8119 return result;
8122 static tree
8123 build_ivar_reference (tree id)
8125 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8127 /* Historically, a class method that produced objects (factory
8128 method) would assign `self' to the instance that it
8129 allocated. This would effectively turn the class method into
8130 an instance method. Following this assignment, the instance
8131 variables could be accessed. That practice, while safe,
8132 violates the simple rule that a class method should not refer
8133 to an instance variable. It's better to catch the cases
8134 where this is done unknowingly than to support the above
8135 paradigm. */
8136 warning (0, "instance variable %qE accessed in class method",
8137 id);
8138 self_decl = convert (objc_instance_type, self_decl); /* cast */
8141 return objc_build_component_ref (build_indirect_ref (input_location,
8142 self_decl, RO_ARROW),
8143 id);
8146 /* Compute a hash value for a given method SEL_NAME. */
8148 static size_t
8149 hash_func (tree sel_name)
8151 const unsigned char *s
8152 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
8153 size_t h = 0;
8155 while (*s)
8156 h = h * 67 + *s++ - 113;
8157 return h;
8160 static void
8161 hash_init (void)
8163 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8164 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8166 cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8167 als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8169 /* Initialize the hash table used to hold the constant string objects. */
8170 string_htab = htab_create_ggc (31, string_hash,
8171 string_eq, NULL);
8174 /* This routine adds sel_name to the hash list. sel_name is a class or alias
8175 name for the class. If alias name, then value is its underlying class.
8176 If class, the value is NULL_TREE. */
8178 static void
8179 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
8181 hash obj;
8182 int slot = hash_func (sel_name) % SIZEHASHTABLE;
8184 obj = ggc_alloc_hashed_entry ();
8185 if (value != NULL_TREE)
8187 /* Save the underlying class for the 'alias' in the hash table */
8188 attr obj_attr = ggc_alloc_hashed_attribute ();
8189 obj_attr->value = value;
8190 obj->list = obj_attr;
8192 else
8193 obj->list = 0;
8194 obj->next = hashlist[slot];
8195 obj->key = sel_name;
8197 hashlist[slot] = obj; /* append to front */
8202 Searches in the hash table looking for a match for class or alias name.
8205 static hash
8206 hash_class_name_lookup (hash *hashlist, tree sel_name)
8208 hash target;
8210 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8212 while (target)
8214 if (sel_name == target->key)
8215 return target;
8217 target = target->next;
8219 return 0;
8222 /* WARNING!!!! hash_enter is called with a method, and will peek
8223 inside to find its selector! But hash_lookup is given a selector
8224 directly, and looks for the selector that's inside the found
8225 entry's key (method) for comparison. */
8227 static void
8228 hash_enter (hash *hashlist, tree method)
8230 hash obj;
8231 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
8233 obj = ggc_alloc_hashed_entry ();
8234 obj->list = 0;
8235 obj->next = hashlist[slot];
8236 obj->key = method;
8238 hashlist[slot] = obj; /* append to front */
8241 static hash
8242 hash_lookup (hash *hashlist, tree sel_name)
8244 hash target;
8246 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8248 while (target)
8250 if (sel_name == METHOD_SEL_NAME (target->key))
8251 return target;
8253 target = target->next;
8255 return 0;
8258 static void
8259 hash_add_attr (hash entry, tree value)
8261 attr obj;
8263 obj = ggc_alloc_hashed_attribute ();
8264 obj->next = entry->list;
8265 obj->value = value;
8267 entry->list = obj; /* append to front */
8270 static tree
8271 lookup_method (tree mchain, tree method)
8273 tree key;
8275 if (TREE_CODE (method) == IDENTIFIER_NODE)
8276 key = method;
8277 else
8278 key = METHOD_SEL_NAME (method);
8280 while (mchain)
8282 if (METHOD_SEL_NAME (mchain) == key)
8283 return mchain;
8285 mchain = DECL_CHAIN (mchain);
8287 return NULL_TREE;
8290 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance
8291 method in INTERFACE, along with any categories and protocols
8292 attached thereto. If method is not found, and the
8293 OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, recursively examine the
8294 INTERFACE's superclass. If OBJC_LOOKUP_CLASS is set,
8295 OBJC_LOOKUP_NO_SUPER is clear, and no suitable class method could
8296 be found in INTERFACE or any of its superclasses, look for an
8297 _instance_ method of the same name in the root class as a last
8298 resort. This behaviour can be turned off by using
8299 OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS.
8301 If a suitable method cannot be found, return NULL_TREE. */
8303 static tree
8304 lookup_method_static (tree interface, tree ident, int flags)
8306 tree meth = NULL_TREE, root_inter = NULL_TREE;
8307 tree inter = interface;
8308 int is_class = (flags & OBJC_LOOKUP_CLASS);
8309 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
8310 int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS);
8312 while (inter)
8314 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
8315 tree category = inter;
8317 /* First, look up the method in the class itself. */
8318 if ((meth = lookup_method (chain, ident)))
8319 return meth;
8321 /* Failing that, look for the method in each category of the class. */
8322 while ((category = CLASS_CATEGORY_LIST (category)))
8324 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
8326 /* Check directly in each category. */
8327 if ((meth = lookup_method (chain, ident)))
8328 return meth;
8330 /* Failing that, check in each category's protocols. */
8331 if (CLASS_PROTOCOL_LIST (category))
8333 if ((meth = (lookup_method_in_protocol_list
8334 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
8335 return meth;
8339 /* If not found in categories, check in protocols of the main class. */
8340 if (CLASS_PROTOCOL_LIST (inter))
8342 if ((meth = (lookup_method_in_protocol_list
8343 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
8344 return meth;
8347 /* If we were instructed not to look in superclasses, don't. */
8348 if (no_superclasses)
8349 return NULL_TREE;
8351 /* Failing that, climb up the inheritance hierarchy. */
8352 root_inter = inter;
8353 inter = lookup_interface (CLASS_SUPER_NAME (inter));
8355 while (inter);
8357 if (is_class && !no_instance_methods_of_root_class)
8359 /* If no class (factory) method was found, check if an _instance_
8360 method of the same name exists in the root class. This is what
8361 the Objective-C runtime will do. */
8362 return lookup_method_static (root_inter, ident, 0);
8364 else
8366 /* If an instance method was not found, return 0. */
8367 return NULL_TREE;
8371 /* Add the method to the hash list if it doesn't contain an identical
8372 method already. */
8374 static void
8375 add_method_to_hash_list (hash *hash_list, tree method)
8377 hash hsh;
8379 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
8381 /* Install on a global chain. */
8382 hash_enter (hash_list, method);
8384 else
8386 /* Check types against those; if different, add to a list. */
8387 attr loop;
8388 int already_there = comp_proto_with_proto (method, hsh->key, 1);
8389 for (loop = hsh->list; !already_there && loop; loop = loop->next)
8390 already_there |= comp_proto_with_proto (method, loop->value, 1);
8391 if (!already_there)
8392 hash_add_attr (hsh, method);
8396 static tree
8397 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
8399 tree mth;
8401 /* @optional methods are added to protocol's OPTIONAL list */
8402 if (is_optional)
8404 gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
8405 if (!(mth = lookup_method (is_class
8406 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
8407 : PROTOCOL_OPTIONAL_NST_METHODS (klass),
8408 method)))
8410 if (is_class)
8412 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
8413 PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
8415 else
8417 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
8418 PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
8422 else if (!(mth = lookup_method (is_class
8423 ? CLASS_CLS_METHODS (klass)
8424 : CLASS_NST_METHODS (klass), method)))
8426 /* put method on list in reverse order */
8427 if (is_class)
8429 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
8430 CLASS_CLS_METHODS (klass) = method;
8432 else
8434 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
8435 CLASS_NST_METHODS (klass) = method;
8438 else
8440 /* When processing an @interface for a class or category, give hard
8441 errors on methods with identical selectors but differing argument
8442 and/or return types. We do not do this for @implementations, because
8443 C/C++ will do it for us (i.e., there will be duplicate function
8444 definition errors). */
8445 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
8446 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
8447 && !comp_proto_with_proto (method, mth, 1))
8448 error ("duplicate declaration of method %<%c%E%>",
8449 is_class ? '+' : '-',
8450 METHOD_SEL_NAME (mth));
8453 if (is_class)
8454 add_method_to_hash_list (cls_method_hash_list, method);
8455 else
8457 add_method_to_hash_list (nst_method_hash_list, method);
8459 /* Instance methods in root classes (and categories thereof)
8460 may act as class methods as a last resort. We also add
8461 instance methods listed in @protocol declarations to
8462 the class hash table, on the assumption that @protocols
8463 may be adopted by root classes or categories. */
8464 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
8465 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
8466 klass = lookup_interface (CLASS_NAME (klass));
8468 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
8469 || !CLASS_SUPER_NAME (klass))
8470 add_method_to_hash_list (cls_method_hash_list, method);
8473 return method;
8476 static tree
8477 add_class (tree class_name, tree name)
8479 struct interface_tuple **slot;
8481 /* Put interfaces on list in reverse order. */
8482 TREE_CHAIN (class_name) = interface_chain;
8483 interface_chain = class_name;
8485 if (interface_htab == NULL)
8486 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
8487 slot = (struct interface_tuple **)
8488 htab_find_slot_with_hash (interface_htab, name,
8489 IDENTIFIER_HASH_VALUE (name),
8490 INSERT);
8491 if (!*slot)
8493 *slot = ggc_alloc_cleared_interface_tuple ();
8494 (*slot)->id = name;
8496 (*slot)->class_name = class_name;
8498 return interface_chain;
8501 static void
8502 add_category (tree klass, tree category)
8504 /* Put categories on list in reverse order. */
8505 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
8507 if (cat)
8509 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
8510 CLASS_NAME (klass),
8511 CLASS_SUPER_NAME (category));
8513 else
8515 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
8516 CLASS_CATEGORY_LIST (klass) = category;
8520 /* Called after parsing each instance variable declaration. Necessary to
8521 preserve typedefs and implement public/private...
8523 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
8525 static tree
8526 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
8527 tree field_decl)
8529 tree field_type = TREE_TYPE (field_decl);
8530 const char *ivar_name = DECL_NAME (field_decl)
8531 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
8532 : _("<unnamed>");
8534 #ifdef OBJCPLUS
8535 if (TREE_CODE (field_type) == REFERENCE_TYPE)
8537 error ("illegal reference type specified for instance variable %qs",
8538 ivar_name);
8539 /* Return class as is without adding this ivar. */
8540 return klass;
8542 #endif
8544 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
8545 || TYPE_SIZE (field_type) == error_mark_node)
8546 /* 'type[0]' is allowed, but 'type[]' is not! */
8548 error ("instance variable %qs has unknown size", ivar_name);
8549 /* Return class as is without adding this ivar. */
8550 return klass;
8553 #ifdef OBJCPLUS
8554 /* Check if the ivar being added has a non-POD C++ type. If so, we will
8555 need to either (1) warn the user about it or (2) generate suitable
8556 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
8557 methods (if '-fobjc-call-cxx-cdtors' was specified). */
8558 if (MAYBE_CLASS_TYPE_P (field_type)
8559 && (TYPE_NEEDS_CONSTRUCTING (field_type)
8560 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
8561 || TYPE_POLYMORPHIC_P (field_type)))
8563 tree type_name = OBJC_TYPE_NAME (field_type);
8565 if (flag_objc_call_cxx_cdtors)
8567 /* Since the ObjC runtime will be calling the constructors and
8568 destructors for us, the only thing we can't handle is the lack
8569 of a default constructor. */
8570 if (TYPE_NEEDS_CONSTRUCTING (field_type)
8571 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
8573 warning (0, "type %qE has no default constructor to call",
8574 type_name);
8576 /* If we cannot call a constructor, we should also avoid
8577 calling the destructor, for symmetry. */
8578 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8579 warning (0, "destructor for %qE shall not be run either",
8580 type_name);
8583 else
8585 static bool warn_cxx_ivars = false;
8587 if (TYPE_POLYMORPHIC_P (field_type))
8589 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
8590 initialize them. */
8591 error ("type %qE has virtual member functions", type_name);
8592 error ("illegal aggregate type %qE specified "
8593 "for instance variable %qs",
8594 type_name, ivar_name);
8595 /* Return class as is without adding this ivar. */
8596 return klass;
8599 /* User-defined constructors and destructors are not known to Obj-C
8600 and hence will not be called. This may or may not be a problem. */
8601 if (TYPE_NEEDS_CONSTRUCTING (field_type))
8602 warning (0, "type %qE has a user-defined constructor", type_name);
8603 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8604 warning (0, "type %qE has a user-defined destructor", type_name);
8606 if (!warn_cxx_ivars)
8608 warning (0, "C++ constructors and destructors will not "
8609 "be invoked for Objective-C fields");
8610 warn_cxx_ivars = true;
8614 #endif
8616 /* Overload the public attribute, it is not used for FIELD_DECLs. */
8617 switch (visibility)
8619 case OBJC_IVAR_VIS_PROTECTED:
8620 TREE_PUBLIC (field_decl) = 0;
8621 TREE_PRIVATE (field_decl) = 0;
8622 TREE_PROTECTED (field_decl) = 1;
8623 break;
8625 case OBJC_IVAR_VIS_PACKAGE:
8626 /* TODO: Implement the package variant. */
8627 case OBJC_IVAR_VIS_PUBLIC:
8628 TREE_PUBLIC (field_decl) = 1;
8629 TREE_PRIVATE (field_decl) = 0;
8630 TREE_PROTECTED (field_decl) = 0;
8631 break;
8633 case OBJC_IVAR_VIS_PRIVATE:
8634 TREE_PUBLIC (field_decl) = 0;
8635 TREE_PRIVATE (field_decl) = 1;
8636 TREE_PROTECTED (field_decl) = 0;
8637 break;
8641 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
8643 return klass;
8647 static tree
8648 is_ivar (tree decl_chain, tree ident)
8650 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8651 if (DECL_NAME (decl_chain) == ident)
8652 return decl_chain;
8653 return NULL_TREE;
8656 /* True if the ivar is private and we are not in its implementation. */
8658 static int
8659 is_private (tree decl)
8661 return (TREE_PRIVATE (decl)
8662 && ! is_ivar (CLASS_IVARS (implementation_template),
8663 DECL_NAME (decl)));
8666 /* We have an instance variable reference;, check to see if it is public. */
8669 objc_is_public (tree expr, tree identifier)
8671 tree basetype, decl;
8673 #ifdef OBJCPLUS
8674 if (processing_template_decl)
8675 return 1;
8676 #endif
8678 if (TREE_TYPE (expr) == error_mark_node)
8679 return 1;
8681 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8683 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8685 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8687 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8689 if (!klass)
8691 error ("cannot find interface declaration for %qE",
8692 OBJC_TYPE_NAME (basetype));
8693 return 0;
8696 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8698 if (TREE_PUBLIC (decl))
8699 return 1;
8701 /* Important difference between the Stepstone translator:
8702 all instance variables should be public within the context
8703 of the implementation. */
8704 if (objc_implementation_context
8705 && ((TREE_CODE (objc_implementation_context)
8706 == CLASS_IMPLEMENTATION_TYPE)
8707 || (TREE_CODE (objc_implementation_context)
8708 == CATEGORY_IMPLEMENTATION_TYPE)))
8710 tree curtype = TYPE_MAIN_VARIANT
8711 (CLASS_STATIC_TEMPLATE
8712 (implementation_template));
8714 if (basetype == curtype
8715 || DERIVED_FROM_P (basetype, curtype))
8717 int priv = is_private (decl);
8719 if (priv)
8720 error ("instance variable %qE is declared private",
8721 DECL_NAME (decl));
8723 return !priv;
8727 /* The 2.95.2 compiler sometimes allowed C functions to access
8728 non-@public ivars. We will let this slide for now... */
8729 if (!objc_method_context)
8731 warning (0, "instance variable %qE is %s; "
8732 "this will be a hard error in the future",
8733 identifier,
8734 TREE_PRIVATE (decl) ? "@private" : "@protected");
8735 return 1;
8738 error ("instance variable %qE is declared %s",
8739 identifier,
8740 TREE_PRIVATE (decl) ? "private" : "protected");
8741 return 0;
8746 return 1;
8749 /* Make sure all methods in CHAIN (a list of method declarations from
8750 an @interface or a @protocol) are in IMPLEMENTATION (the
8751 implementation context). This is used to check for example that
8752 all methods declared in an @interface were implemented in an
8753 @implementation.
8755 Some special methods (property setters/getters) are special and if
8756 they are not found in IMPLEMENTATION, we look them up in its
8757 superclasses. */
8759 static int
8760 check_methods (tree chain, tree implementation, int mtype)
8762 int first = 1;
8763 tree list;
8765 if (mtype == (int)'+')
8766 list = CLASS_CLS_METHODS (implementation);
8767 else
8768 list = CLASS_NST_METHODS (implementation);
8770 while (chain)
8772 /* If the method is associated with a dynamic property, then it
8773 is Ok not to have the method implementation, as it will be
8774 generated dynamically at runtime. To decide if the method is
8775 associated with a @dynamic property, we search the list of
8776 @synthesize and @dynamic for this implementation, and look
8777 for any @dynamic property with the same setter or getter name
8778 as this method. */
8779 tree x;
8780 for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
8781 if (PROPERTY_DYNAMIC (x)
8782 && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
8783 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
8784 break;
8786 if (x != NULL_TREE)
8788 chain = TREE_CHAIN (chain); /* next method... */
8789 continue;
8792 if (!lookup_method (list, chain))
8794 /* If the method is a property setter/getter, we'll still
8795 allow it to be missing if it is implemented by
8796 'interface' or any of its superclasses. */
8797 tree property = METHOD_PROPERTY_CONTEXT (chain);
8798 if (property)
8800 /* Note that since this is a property getter/setter, it
8801 is obviously an instance method. */
8802 tree interface = NULL_TREE;
8804 /* For a category, first check the main class
8805 @interface. */
8806 if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
8808 interface = lookup_interface (CLASS_NAME (implementation));
8810 /* If the method is found in the main class, it's Ok. */
8811 if (lookup_method (CLASS_NST_METHODS (interface), chain))
8813 chain = DECL_CHAIN (chain);
8814 continue;
8817 /* Else, get the superclass. */
8818 if (CLASS_SUPER_NAME (interface))
8819 interface = lookup_interface (CLASS_SUPER_NAME (interface));
8820 else
8821 interface = NULL_TREE;
8824 /* Get the superclass for classes. */
8825 if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
8827 if (CLASS_SUPER_NAME (implementation))
8828 interface = lookup_interface (CLASS_SUPER_NAME (implementation));
8829 else
8830 interface = NULL_TREE;
8833 /* Now, interface is the superclass, if any; go check it. */
8834 if (interface)
8836 if (lookup_method_static (interface, chain, 0))
8838 chain = DECL_CHAIN (chain);
8839 continue;
8842 /* Else, fall through - warn. */
8844 if (first)
8846 switch (TREE_CODE (implementation))
8848 case CLASS_IMPLEMENTATION_TYPE:
8849 warning (0, "incomplete implementation of class %qE",
8850 CLASS_NAME (implementation));
8851 break;
8852 case CATEGORY_IMPLEMENTATION_TYPE:
8853 warning (0, "incomplete implementation of category %qE",
8854 CLASS_SUPER_NAME (implementation));
8855 break;
8856 default:
8857 gcc_unreachable ();
8859 first = 0;
8862 warning (0, "method definition for %<%c%E%> not found",
8863 mtype, METHOD_SEL_NAME (chain));
8866 chain = DECL_CHAIN (chain);
8869 return first;
8872 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8874 static int
8875 conforms_to_protocol (tree klass, tree protocol)
8877 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
8879 tree p = CLASS_PROTOCOL_LIST (klass);
8880 while (p && TREE_VALUE (p) != protocol)
8881 p = TREE_CHAIN (p);
8883 if (!p)
8885 tree super = (CLASS_SUPER_NAME (klass)
8886 ? lookup_interface (CLASS_SUPER_NAME (klass))
8887 : NULL_TREE);
8888 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
8889 if (!tmp)
8890 return 0;
8894 return 1;
8897 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8898 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8900 static int
8901 check_methods_accessible (tree chain, tree context, int mtype)
8903 int first = 1;
8904 tree list;
8905 tree base_context = context;
8907 while (chain)
8909 /* If the method is associated with a dynamic property, then it
8910 is Ok not to have the method implementation, as it will be
8911 generated dynamically at runtime. Search for any @dynamic
8912 property with the same setter or getter name as this
8913 method. TODO: Use a hashtable lookup. */
8914 tree x;
8915 for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
8916 if (PROPERTY_DYNAMIC (x)
8917 && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
8918 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
8919 break;
8921 if (x != NULL_TREE)
8923 chain = TREE_CHAIN (chain); /* next method... */
8924 continue;
8927 context = base_context;
8928 while (context)
8930 if (mtype == '+')
8931 list = CLASS_CLS_METHODS (context);
8932 else
8933 list = CLASS_NST_METHODS (context);
8935 if (lookup_method (list, chain))
8936 break;
8938 switch (TREE_CODE (context))
8940 case CLASS_IMPLEMENTATION_TYPE:
8941 case CLASS_INTERFACE_TYPE:
8942 context = (CLASS_SUPER_NAME (context)
8943 ? lookup_interface (CLASS_SUPER_NAME (context))
8944 : NULL_TREE);
8945 break;
8946 case CATEGORY_IMPLEMENTATION_TYPE:
8947 case CATEGORY_INTERFACE_TYPE:
8948 context = (CLASS_NAME (context)
8949 ? lookup_interface (CLASS_NAME (context))
8950 : NULL_TREE);
8951 break;
8952 default:
8953 gcc_unreachable ();
8957 if (context == NULL_TREE)
8959 if (first)
8961 switch (TREE_CODE (objc_implementation_context))
8963 case CLASS_IMPLEMENTATION_TYPE:
8964 warning (0, "incomplete implementation of class %qE",
8965 CLASS_NAME (objc_implementation_context));
8966 break;
8967 case CATEGORY_IMPLEMENTATION_TYPE:
8968 warning (0, "incomplete implementation of category %qE",
8969 CLASS_SUPER_NAME (objc_implementation_context));
8970 break;
8971 default:
8972 gcc_unreachable ();
8974 first = 0;
8976 warning (0, "method definition for %<%c%E%> not found",
8977 mtype, METHOD_SEL_NAME (chain));
8980 chain = TREE_CHAIN (chain); /* next method... */
8982 return first;
8985 /* Check whether the current interface (accessible via
8986 'objc_implementation_context') actually implements protocol P, along
8987 with any protocols that P inherits. */
8989 static void
8990 check_protocol (tree p, const char *type, tree name)
8992 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
8994 int f1, f2;
8996 /* Ensure that all protocols have bodies! */
8997 if (warn_protocol)
8999 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
9000 objc_implementation_context,
9001 '+');
9002 f2 = check_methods (PROTOCOL_NST_METHODS (p),
9003 objc_implementation_context,
9004 '-');
9006 else
9008 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
9009 objc_implementation_context,
9010 '+');
9011 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
9012 objc_implementation_context,
9013 '-');
9016 if (!f1 || !f2)
9017 warning (0, "%s %qE does not fully implement the %qE protocol",
9018 type, name, PROTOCOL_NAME (p));
9021 /* Check protocols recursively. */
9022 if (PROTOCOL_LIST (p))
9024 tree subs = PROTOCOL_LIST (p);
9025 tree super_class =
9026 lookup_interface (CLASS_SUPER_NAME (implementation_template));
9028 while (subs)
9030 tree sub = TREE_VALUE (subs);
9032 /* If the superclass does not conform to the protocols
9033 inherited by P, then we must! */
9034 if (!super_class || !conforms_to_protocol (super_class, sub))
9035 check_protocol (sub, type, name);
9036 subs = TREE_CHAIN (subs);
9041 /* Check whether the current interface (accessible via
9042 'objc_implementation_context') actually implements the protocols listed
9043 in PROTO_LIST. */
9045 static void
9046 check_protocols (tree proto_list, const char *type, tree name)
9048 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
9050 tree p = TREE_VALUE (proto_list);
9052 check_protocol (p, type, name);
9056 /* Make sure that the class CLASS_NAME is defined
9057 CODE says which kind of thing CLASS_NAME ought to be.
9058 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
9059 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
9061 static tree
9062 start_class (enum tree_code code, tree class_name, tree super_name,
9063 tree protocol_list)
9065 tree klass, decl;
9067 #ifdef OBJCPLUS
9068 if (current_namespace != global_namespace) {
9069 error ("Objective-C declarations may only appear in global scope");
9071 #endif /* OBJCPLUS */
9073 if (objc_implementation_context)
9075 warning (0, "%<@end%> missing in implementation context");
9076 finish_class (objc_implementation_context);
9077 objc_ivar_chain = NULL_TREE;
9078 objc_implementation_context = NULL_TREE;
9081 klass = make_node (code);
9082 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
9084 /* Check for existence of the super class, if one was specified. Note
9085 that we must have seen an @interface, not just a @class. If we
9086 are looking at a @compatibility_alias, traverse it first. */
9087 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
9088 && super_name)
9090 tree super = objc_is_class_name (super_name);
9092 if (!super || !lookup_interface (super))
9094 error ("cannot find interface declaration for %qE, superclass of %qE",
9095 super ? super : super_name,
9096 class_name);
9097 super_name = NULL_TREE;
9099 else
9100 super_name = super;
9103 CLASS_NAME (klass) = class_name;
9104 CLASS_SUPER_NAME (klass) = super_name;
9105 CLASS_CLS_METHODS (klass) = NULL_TREE;
9107 if (! objc_is_class_name (class_name)
9108 && (decl = lookup_name (class_name)))
9110 error ("%qE redeclared as different kind of symbol",
9111 class_name);
9112 error ("previous declaration of %q+D",
9113 decl);
9116 switch (code)
9118 case CLASS_IMPLEMENTATION_TYPE:
9120 tree chain;
9122 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
9123 if (TREE_VALUE (chain) == class_name)
9125 error ("reimplementation of class %qE",
9126 class_name);
9127 return error_mark_node;
9129 implemented_classes = tree_cons (NULL_TREE, class_name,
9130 implemented_classes);
9133 /* Reset for multiple classes per file. */
9134 method_slot = 0;
9136 objc_implementation_context = klass;
9138 /* Lookup the interface for this implementation. */
9140 if (!(implementation_template = lookup_interface (class_name)))
9142 warning (0, "cannot find interface declaration for %qE",
9143 class_name);
9144 add_class (implementation_template = objc_implementation_context,
9145 class_name);
9148 /* If a super class has been specified in the implementation,
9149 insure it conforms to the one specified in the interface. */
9151 if (super_name
9152 && (super_name != CLASS_SUPER_NAME (implementation_template)))
9154 tree previous_name = CLASS_SUPER_NAME (implementation_template);
9155 error ("conflicting super class name %qE",
9156 super_name);
9157 if (previous_name)
9158 error ("previous declaration of %qE", previous_name);
9159 else
9160 error ("previous declaration");
9163 else if (! super_name)
9165 CLASS_SUPER_NAME (objc_implementation_context)
9166 = CLASS_SUPER_NAME (implementation_template);
9168 break;
9170 case CLASS_INTERFACE_TYPE:
9171 if (lookup_interface (class_name))
9172 #ifdef OBJCPLUS
9173 error ("duplicate interface declaration for class %qE", class_name);
9174 #else
9175 warning (0, "duplicate interface declaration for class %qE", class_name);
9176 #endif
9177 else
9178 add_class (klass, class_name);
9180 if (protocol_list)
9181 CLASS_PROTOCOL_LIST (klass)
9182 = lookup_and_install_protocols (protocol_list);
9183 break;
9185 case CATEGORY_INTERFACE_TYPE:
9187 tree class_category_is_assoc_with;
9189 /* For a category, class_name is really the name of the class that
9190 the following set of methods will be associated with. We must
9191 find the interface so that can derive the objects template. */
9192 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
9194 error ("cannot find interface declaration for %qE",
9195 class_name);
9196 exit (FATAL_EXIT_CODE);
9198 else
9199 add_category (class_category_is_assoc_with, klass);
9201 if (protocol_list)
9202 CLASS_PROTOCOL_LIST (klass)
9203 = lookup_and_install_protocols (protocol_list);
9205 break;
9207 case CATEGORY_IMPLEMENTATION_TYPE:
9208 /* Reset for multiple classes per file. */
9209 method_slot = 0;
9211 objc_implementation_context = klass;
9213 /* For a category, class_name is really the name of the class that
9214 the following set of methods will be associated with. We must
9215 find the interface so that can derive the objects template. */
9217 if (!(implementation_template = lookup_interface (class_name)))
9219 error ("cannot find interface declaration for %qE",
9220 class_name);
9221 exit (FATAL_EXIT_CODE);
9223 break;
9224 default:
9225 gcc_unreachable ();
9227 return klass;
9230 static tree
9231 continue_class (tree klass)
9233 switch (TREE_CODE (klass))
9235 case CLASS_IMPLEMENTATION_TYPE:
9236 case CATEGORY_IMPLEMENTATION_TYPE:
9238 struct imp_entry *imp_entry;
9240 /* Check consistency of the instance variables. */
9242 if (CLASS_RAW_IVARS (klass))
9243 check_ivars (implementation_template, klass);
9245 /* code generation */
9246 #ifdef OBJCPLUS
9247 push_lang_context (lang_name_c);
9248 #endif
9249 build_private_template (implementation_template);
9250 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
9251 objc_instance_type = build_pointer_type (uprivate_record);
9253 imp_entry = ggc_alloc_imp_entry ();
9255 imp_entry->next = imp_list;
9256 imp_entry->imp_context = klass;
9257 imp_entry->imp_template = implementation_template;
9259 synth_forward_declarations ();
9260 imp_entry->class_decl = UOBJC_CLASS_decl;
9261 imp_entry->meta_decl = UOBJC_METACLASS_decl;
9262 imp_entry->has_cxx_cdtors = 0;
9264 /* Append to front and increment count. */
9265 imp_list = imp_entry;
9266 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
9267 imp_count++;
9268 else
9269 cat_count++;
9270 #ifdef OBJCPLUS
9271 pop_lang_context ();
9272 #endif /* OBJCPLUS */
9274 return get_class_ivars (implementation_template, true);
9275 break;
9277 case CLASS_INTERFACE_TYPE:
9279 #ifdef OBJCPLUS
9280 push_lang_context (lang_name_c);
9281 #endif /* OBJCPLUS */
9282 objc_collecting_ivars = 1;
9283 build_private_template (klass);
9284 objc_collecting_ivars = 0;
9285 #ifdef OBJCPLUS
9286 pop_lang_context ();
9287 #endif /* OBJCPLUS */
9288 return NULL_TREE;
9289 break;
9291 default:
9292 return error_mark_node;
9296 /* This routine builds name of the setter synthesized function. */
9297 static char *
9298 objc_build_property_setter_name (tree ident)
9300 /* TODO: Use alloca to allocate buffer of appropriate size. */
9301 static char string[BUFSIZE];
9302 sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
9303 string[3] = TOUPPER (string[3]);
9304 return string;
9307 /* This routine prepares the declarations of the property accessor
9308 helper functions (objc_getProperty(), etc) that are used when
9309 @synthesize is used. */
9310 static void
9311 build_objc_property_accessor_helpers (void)
9313 tree type;
9315 /* Declare the following function:
9317 objc_getProperty (id self, SEL _cmd,
9318 ptrdiff_t offset, BOOL is_atomic); */
9319 type = build_function_type_list (objc_object_type,
9320 objc_object_type,
9321 objc_selector_type,
9322 ptrdiff_type_node,
9323 boolean_type_node,
9324 NULL_TREE);
9325 objc_getProperty_decl = add_builtin_function ("objc_getProperty",
9326 type, 0, NOT_BUILT_IN,
9327 NULL, NULL_TREE);
9328 TREE_NOTHROW (objc_getProperty_decl) = 0;
9330 /* Declare the following function:
9331 void
9332 objc_setProperty (id self, SEL _cmd,
9333 ptrdiff_t offset, id new_value,
9334 BOOL is_atomic, BOOL should_copy); */
9335 type = build_function_type_list (void_type_node,
9336 objc_object_type,
9337 objc_selector_type,
9338 ptrdiff_type_node,
9339 objc_object_type,
9340 boolean_type_node,
9341 boolean_type_node,
9342 NULL_TREE);
9343 objc_setProperty_decl = add_builtin_function ("objc_setProperty",
9344 type, 0, NOT_BUILT_IN,
9345 NULL, NULL_TREE);
9346 TREE_NOTHROW (objc_setProperty_decl) = 0;
9348 /* This is the type of all of the following functions
9349 (objc_copyStruct(), objc_getPropertyStruct() and
9350 objc_setPropertyStruct()). */
9351 type = build_function_type_list (void_type_node,
9352 ptr_type_node,
9353 const_ptr_type_node,
9354 ptrdiff_type_node,
9355 boolean_type_node,
9356 boolean_type_node,
9357 NULL_TREE);
9359 if (flag_next_runtime)
9361 /* Declare the following function:
9362 void
9363 objc_copyStruct (void *destination, const void *source,
9364 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
9365 objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
9366 type, 0, NOT_BUILT_IN,
9367 NULL, NULL_TREE);
9368 TREE_NOTHROW (objc_copyStruct_decl) = 0;
9369 objc_getPropertyStruct_decl = NULL_TREE;
9370 objc_setPropertyStruct_decl = NULL_TREE;
9372 else
9374 objc_copyStruct_decl = NULL_TREE;
9376 /* Declare the following function:
9377 void
9378 objc_getPropertyStruct (void *destination, const void *source,
9379 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
9380 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
9381 type, 0, NOT_BUILT_IN,
9382 NULL, NULL_TREE);
9383 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
9384 /* Declare the following function:
9385 void
9386 objc_setPropertyStruct (void *destination, const void *source,
9387 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
9388 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
9389 type, 0, NOT_BUILT_IN,
9390 NULL, NULL_TREE);
9391 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
9395 /* This looks up an ivar in a class (including superclasses). */
9396 static tree
9397 lookup_ivar (tree interface, tree instance_variable_name)
9399 while (interface)
9401 tree decl_chain;
9403 for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
9404 if (DECL_NAME (decl_chain) == instance_variable_name)
9405 return decl_chain;
9407 /* Not found. Search superclass if any. */
9408 if (CLASS_SUPER_NAME (interface))
9409 interface = lookup_interface (CLASS_SUPER_NAME (interface));
9412 return NULL_TREE;
9415 /* This routine synthesizes a 'getter' method. This is only called
9416 for @synthesize properties. */
9417 static void
9418 objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9420 location_t location = DECL_SOURCE_LOCATION (property);
9421 tree fn, decl;
9422 tree body;
9423 tree ret_val;
9425 /* If user has implemented a getter with same name then do nothing. */
9426 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9427 PROPERTY_GETTER_NAME (property)))
9428 return;
9430 /* Find declaration of the property getter in the interface (or
9431 superclass, or protocol). There must be one. */
9432 decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);
9434 /* If one not declared in the interface, this condition has already
9435 been reported as user error (because property was not declared in
9436 the interface). */
9437 if (!decl)
9438 return;
9440 /* Adapt the 'decl'. Use the source location of the @synthesize
9441 statement for error messages. */
9442 decl = copy_node (decl);
9443 DECL_SOURCE_LOCATION (decl) = location;
9445 objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9446 body = c_begin_compound_stmt (true);
9448 /* Now we need to decide how we build the getter. There are three
9449 cases:
9451 for 'copy' or 'retain' properties we need to use the
9452 objc_getProperty() accessor helper which knows about retain and
9453 copy. It supports both 'nonatomic' and 'atomic' access.
9455 for 'nonatomic, assign' properties we can access the instance
9456 variable directly. 'nonatomic' means we don't have to use locks,
9457 and 'assign' means we don't have to worry about retain or copy.
9458 If you combine the two, it means we can just access the instance
9459 variable directly.
9461 for 'atomic, assign' properties we use objc_copyStruct() (for the
9462 next runtime) or objc_getPropertyStruct() (for the GNU runtime). */
9463 switch (PROPERTY_ASSIGN_SEMANTICS (property))
9465 case OBJC_PROPERTY_RETAIN:
9466 case OBJC_PROPERTY_COPY:
9468 /* We build "return objc_getProperty (self, _cmd, offset, is_atomic);" */
9469 tree cmd, ivar, offset, is_atomic;
9470 cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9472 /* Find the ivar to compute the offset. */
9473 ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9474 if (!ivar || is_private (ivar))
9476 /* This should never happen. */
9477 error_at (location,
9478 "can not find instance variable associated with property");
9479 ret_val = error_mark_node;
9480 break;
9482 offset = byte_position (ivar);
9484 if (PROPERTY_NONATOMIC (property))
9485 is_atomic = boolean_false_node;
9486 else
9487 is_atomic = boolean_true_node;
9489 ret_val = build_function_call
9490 (location,
9491 /* Function prototype. */
9492 objc_getProperty_decl,
9493 /* Parameters. */
9494 tree_cons /* self */
9495 (NULL_TREE, self_decl,
9496 tree_cons /* _cmd */
9497 (NULL_TREE, cmd,
9498 tree_cons /* offset */
9499 (NULL_TREE, offset,
9500 tree_cons /* is_atomic */
9501 (NULL_TREE, is_atomic, NULL_TREE)))));
9503 break;
9504 case OBJC_PROPERTY_ASSIGN:
9505 if (PROPERTY_NONATOMIC (property))
9507 /* We build "return self->PROPERTY_IVAR_NAME;" */
9508 ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
9509 break;
9511 else
9513 /* We build
9514 <property type> __objc_property_temp;
9515 objc_getPropertyStruct (&__objc_property_temp,
9516 &(self->PROPERTY_IVAR_NAME),
9517 sizeof (type of self->PROPERTY_IVAR_NAME),
9518 is_atomic,
9519 false)
9520 return __objc_property_temp;
9522 For the NeXT runtime, we need to use objc_copyStruct
9523 instead of objc_getPropertyStruct. */
9524 tree objc_property_temp_decl, function_decl, function_call;
9525 tree size_of, is_atomic;
9527 objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
9528 DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
9529 objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
9531 /* sizeof (ivar type). Since the ivar and the property have
9532 the same type, there is no need to lookup the ivar. */
9533 size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9534 true /* is_sizeof */,
9535 false /* complain */);
9537 if (PROPERTY_NONATOMIC (property))
9538 is_atomic = boolean_false_node;
9539 else
9540 is_atomic = boolean_true_node;
9542 if (flag_next_runtime)
9543 function_decl = objc_copyStruct_decl;
9544 else
9545 function_decl = objc_getPropertyStruct_decl;
9547 function_call = build_function_call
9548 (location,
9549 /* Function prototype. */
9550 function_decl,
9551 /* Parameters. */
9552 tree_cons /* &__objc_property_temp_decl */
9553 /* Warning: note that using build_fold_addr_expr_loc()
9554 here causes invalid code to be generated. */
9555 (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
9556 tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9557 (NULL_TREE, build_fold_addr_expr_loc (location,
9558 objc_lookup_ivar
9559 (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9560 tree_cons /* sizeof (PROPERTY_IVAR) */
9561 (NULL_TREE, size_of,
9562 tree_cons /* is_atomic */
9563 (NULL_TREE, is_atomic,
9564 /* TODO: This is currently ignored by the GNU
9565 runtime, but what about the next one ? */
9566 tree_cons /* has_strong */
9567 (NULL_TREE, boolean_true_node, NULL_TREE))))));
9569 add_stmt (function_call);
9571 ret_val = objc_property_temp_decl;
9573 break;
9574 default:
9575 gcc_unreachable ();
9578 gcc_assert (ret_val);
9580 #ifdef OBJCPLUS
9581 finish_return_stmt (ret_val);
9582 #else
9583 c_finish_return (location, ret_val, NULL_TREE);
9584 #endif
9586 add_stmt (c_end_compound_stmt (location, body, true));
9587 fn = current_function_decl;
9588 #ifdef OBJCPLUS
9589 finish_function ();
9590 #endif
9591 objc_finish_method_definition (fn);
9594 /* This routine synthesizes a 'setter' method. */
9596 static void
9597 objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9599 location_t location = DECL_SOURCE_LOCATION (property);
9600 tree fn, decl;
9601 tree body;
9602 tree new_value, statement;
9604 /* If user has implemented a setter with same name then do nothing. */
9605 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9606 PROPERTY_SETTER_NAME (property)))
9607 return;
9609 /* Find declaration of the property setter in the interface (or
9610 superclass, or protocol). There must be one. */
9611 decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);
9613 /* If one not declared in the interface, this condition has already
9614 been reported as user error (because property was not declared in
9615 the interface). */
9616 if (!decl)
9617 return;
9619 /* Adapt the 'decl'. Use the source location of the @synthesize
9620 statement for error messages. */
9621 decl = copy_node (decl);
9622 DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
9624 objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9626 body = c_begin_compound_stmt (true);
9628 /* The 'new_value' is the only argument to the method, which is the
9629 3rd argument of the function, after self and _cmd. We use twice
9630 TREE_CHAIN to move forward two arguments. */
9631 new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
9633 /* This would presumably happen if the user has specified a
9634 prototype for the setter that does not have an argument! */
9635 if (new_value == NULL_TREE)
9637 /* TODO: This should be caught much earlier than this. */
9638 error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
9639 /* Try to recover somehow. */
9640 new_value = error_mark_node;
9643 /* Now we need to decide how we build the setter. There are three
9644 cases:
9646 for 'copy' or 'retain' properties we need to use the
9647 objc_setProperty() accessor helper which knows about retain and
9648 copy. It supports both 'nonatomic' and 'atomic' access.
9650 for 'nonatomic, assign' properties we can access the instance
9651 variable directly. 'nonatomic' means we don't have to use locks,
9652 and 'assign' means we don't have to worry about retain or copy.
9653 If you combine the two, it means we can just access the instance
9654 variable directly.
9656 for 'atomic, assign' properties we use objc_copyStruct() (for the
9657 next runtime) or objc_setPropertyStruct() (for the GNU runtime). */
9658 switch (PROPERTY_ASSIGN_SEMANTICS (property))
9660 case OBJC_PROPERTY_RETAIN:
9661 case OBJC_PROPERTY_COPY:
9663 /* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);" */
9664 tree cmd, ivar, offset, is_atomic, should_copy;
9665 cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9667 /* Find the ivar to compute the offset. */
9668 ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9669 if (!ivar || is_private (ivar))
9671 error_at (location,
9672 "can not find instance variable associated with property");
9673 statement = error_mark_node;
9674 break;
9676 offset = byte_position (ivar);
9678 if (PROPERTY_NONATOMIC (property))
9679 is_atomic = boolean_false_node;
9680 else
9681 is_atomic = boolean_true_node;
9683 if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
9684 should_copy = boolean_true_node;
9685 else
9686 should_copy = boolean_false_node;
9688 statement = build_function_call
9689 (location,
9690 /* Function prototype. */
9691 objc_setProperty_decl,
9692 /* Parameters. */
9693 tree_cons /* self */
9694 (NULL_TREE, self_decl,
9695 tree_cons /* _cmd */
9696 (NULL_TREE, cmd,
9697 tree_cons /* offset */
9698 (NULL_TREE, offset,
9699 tree_cons /* new_value */
9700 (NULL_TREE, new_value,
9701 tree_cons /* is_atomic */
9702 (NULL_TREE, is_atomic,
9703 tree_cons /* should_copy */
9704 (NULL_TREE, should_copy, NULL_TREE)))))));
9706 break;
9707 case OBJC_PROPERTY_ASSIGN:
9708 if (PROPERTY_NONATOMIC (property))
9710 /* We build "self->PROPERTY_IVAR_NAME = new_value;" */
9711 statement = build_modify_expr
9712 (location,
9713 objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
9714 NULL_TREE, NOP_EXPR,
9715 location, new_value, NULL_TREE);
9716 break;
9718 else
9720 /* We build
9721 objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
9722 &new_value,
9723 sizeof (type of self->PROPERTY_IVAR_NAME),
9724 is_atomic,
9725 false)
9727 For the NeXT runtime, we need to use objc_copyStruct
9728 instead of objc_getPropertyStruct. */
9729 tree function_decl, size_of, is_atomic;
9731 /* sizeof (ivar type). Since the ivar and the property have
9732 the same type, there is no need to lookup the ivar. */
9733 size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
9734 true /* is_sizeof */,
9735 false /* complain */);
9737 if (PROPERTY_NONATOMIC (property))
9738 is_atomic = boolean_false_node;
9739 else
9740 is_atomic = boolean_true_node;
9742 if (flag_next_runtime)
9743 function_decl = objc_copyStruct_decl;
9744 else
9745 function_decl = objc_setPropertyStruct_decl;
9747 statement = build_function_call
9748 (location,
9749 /* Function prototype. */
9750 function_decl,
9751 /* Parameters. */
9752 tree_cons /* &(self->PROPERTY_IVAR_NAME); */
9753 (NULL_TREE, build_fold_addr_expr_loc (location,
9754 objc_lookup_ivar
9755 (NULL_TREE, PROPERTY_IVAR_NAME (property))),
9756 tree_cons /* &new_value */
9757 (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
9758 tree_cons /* sizeof (PROPERTY_IVAR) */
9759 (NULL_TREE, size_of,
9760 tree_cons /* is_atomic */
9761 (NULL_TREE, is_atomic,
9762 /* TODO: This is currently ignored by the GNU
9763 runtime, but what about the next one ? */
9764 tree_cons /* has_strong */
9765 (NULL_TREE, boolean_true_node, NULL_TREE))))));
9767 break;
9768 default:
9769 gcc_unreachable ();
9771 gcc_assert (statement);
9773 add_stmt (statement);
9774 add_stmt (c_end_compound_stmt (location, body, true));
9775 fn = current_function_decl;
9776 #ifdef OBJCPLUS
9777 finish_function ();
9778 #endif
9779 objc_finish_method_definition (fn);
9782 /* This function is a sub-routine of objc_add_synthesize_declaration.
9783 It is called for each property to synthesize once we have
9784 determined that the context is Ok. */
9785 static void
9786 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
9787 tree property_name, tree ivar_name)
9789 /* Find the @property declaration. */
9790 tree property;
9791 tree x;
9793 /* Check that synthesize or dynamic has not already been used for
9794 the same property. */
9795 for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
9796 if (PROPERTY_NAME (property) == property_name)
9798 location_t original_location = DECL_SOURCE_LOCATION (property);
9800 if (PROPERTY_DYNAMIC (property))
9801 error_at (location, "property %qs already specified in %<@dynamic%>",
9802 IDENTIFIER_POINTER (property_name));
9803 else
9804 error_at (location, "property %qs already specified in %<@synthesize%>",
9805 IDENTIFIER_POINTER (property_name));
9807 if (original_location != UNKNOWN_LOCATION)
9808 inform (original_location, "originally specified here");
9809 return;
9812 /* Check that the property is declared in the interface. It could
9813 also be declared in a superclass or protocol. */
9814 property = lookup_property (interface, property_name);
9816 if (!property)
9818 error_at (location, "no declaration of property %qs found in the interface",
9819 IDENTIFIER_POINTER (property_name));
9820 return;
9822 else
9824 /* We have to copy the property, because we want to chain it to
9825 the implementation context, and we want to store the source
9826 location of the @synthesize, not of the original
9827 @property. */
9828 property = copy_node (property);
9829 DECL_SOURCE_LOCATION (property) = location;
9832 /* Determine PROPERTY_IVAR_NAME. */
9833 if (ivar_name == NULL_TREE)
9834 ivar_name = property_name;
9836 /* Check that the instance variable exists. You can only use an
9837 instance variable from the same class, not one from the
9838 superclass (this makes sense as it allows us to check that an
9839 instance variable is only used in one synthesized property). */
9841 tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
9842 if (!ivar)
9844 error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar",
9845 IDENTIFIER_POINTER (property_name));
9846 return;
9849 /* If the instance variable has a different C type, we warn. */
9850 if (!comptypes (TREE_TYPE (property), TREE_TYPE (ivar)))
9852 location_t original_location = DECL_SOURCE_LOCATION (ivar);
9854 error_at (location, "property %qs is using instance variable %qs of incompatible type",
9855 IDENTIFIER_POINTER (property_name),
9856 IDENTIFIER_POINTER (ivar_name));
9858 if (original_location != UNKNOWN_LOCATION)
9859 inform (original_location, "originally specified here");
9863 /* Check that no other property is using the same instance
9864 variable. */
9865 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
9866 if (PROPERTY_IVAR_NAME (x) == ivar_name)
9868 location_t original_location = DECL_SOURCE_LOCATION (x);
9870 error_at (location, "property %qs is using the same instance variable as property %qs",
9871 IDENTIFIER_POINTER (property_name),
9872 IDENTIFIER_POINTER (PROPERTY_NAME (x)));
9874 if (original_location != UNKNOWN_LOCATION)
9875 inform (original_location, "originally specified here");
9877 /* We keep going on. This won't cause the compiler to fail;
9878 the failure would most likely be at runtime. */
9881 /* Note that a @synthesize (and only a @synthesize) always sets
9882 PROPERTY_IVAR_NAME to a non-NULL_TREE. You can recognize a
9883 @synthesize by that. */
9884 PROPERTY_IVAR_NAME (property) = ivar_name;
9886 /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
9887 original declaration; they are always set (with the exception of
9888 PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1). */
9890 /* Add the property to the list of properties for current implementation. */
9891 TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
9892 IMPL_PROPERTY_DECL (objc_implementation_context) = property;
9894 /* Note how we don't actually synthesize the getter/setter here; it
9895 would be very natural, but we may miss the fact that the user has
9896 implemented his own getter/setter later on in the @implementation
9897 (in which case we shouldn't generate getter/setter). We wait
9898 until we have parsed it all before generating the code. */
9901 /* This function is called by the parser after a @synthesize
9902 expression is parsed. 'location' is the location of the
9903 @synthesize expression, and 'property_and_ivar_list' is a chained
9904 list of the property and ivar names. */
9905 void
9906 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
9908 tree interface, chain;
9910 if (flag_objc1_only)
9911 error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
9913 if (property_and_ivar_list == error_mark_node)
9914 return;
9916 if (!objc_implementation_context)
9918 /* We can get here only in Objective-C; the Objective-C++ parser
9919 detects the problem while parsing, outputs the error
9920 "misplaced '@synthesize' Objective-C++ construct" and skips
9921 the declaration. */
9922 error_at (location, "%<@synthesize%> not in @implementation context");
9923 return;
9926 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
9928 error_at (location, "%<@synthesize%> can not be used in categories");
9929 return;
9932 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
9933 if (!interface)
9935 /* I can't see how this could happen, but it is good as a safety check. */
9936 error_at (location,
9937 "%<@synthesize%> requires the @interface of the class to be available");
9938 return;
9941 /* Now, iterate over the properties and do each of them. */
9942 for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
9944 objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain),
9945 TREE_PURPOSE (chain));
9949 /* This function is a sub-routine of objc_add_dynamic_declaration. It
9950 is called for each property to mark as dynamic once we have
9951 determined that the context is Ok. */
9952 static void
9953 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
9954 tree property_name)
9956 /* Find the @property declaration. */
9957 tree property;
9959 /* Check that synthesize or dynamic has not already been used for
9960 the same property. */
9961 for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
9962 if (PROPERTY_NAME (property) == property_name)
9964 location_t original_location = DECL_SOURCE_LOCATION (property);
9966 if (PROPERTY_DYNAMIC (property))
9967 error_at (location, "property %qs already specified in %<@dynamic%>",
9968 IDENTIFIER_POINTER (property_name));
9969 else
9970 error_at (location, "property %qs already specified in %<@synthesize%>",
9971 IDENTIFIER_POINTER (property_name));
9973 if (original_location != UNKNOWN_LOCATION)
9974 inform (original_location, "originally specified here");
9975 return;
9978 /* Check that the property is declared in the interface. It could
9979 also be declared in a superclass or protocol. */
9980 property = lookup_property (interface, property_name);
9982 if (!property)
9984 error_at (location, "no declaration of property %qs found in the interface",
9985 IDENTIFIER_POINTER (property_name));
9986 return;
9988 else
9990 /* We have to copy the property, because we want to chain it to
9991 the implementation context, and we want to store the source
9992 location of the @synthesize, not of the original
9993 @property. */
9994 property = copy_node (property);
9995 DECL_SOURCE_LOCATION (property) = location;
9998 /* Note that a @dynamic (and only a @dynamic) always sets
9999 PROPERTY_DYNAMIC to 1. You can recognize a @dynamic by that.
10000 (actually, as explained above, PROPERTY_DECL generated by
10001 @property and associated with a @dynamic property are also marked
10002 as PROPERTY_DYNAMIC). */
10003 PROPERTY_DYNAMIC (property) = 1;
10005 /* Add the property to the list of properties for current implementation. */
10006 TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10007 IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10010 /* This function is called by the parser after a @dynamic expression
10011 is parsed. 'location' is the location of the @dynamic expression,
10012 and 'property_list' is a chained list of all the property
10013 names. */
10014 void
10015 objc_add_dynamic_declaration (location_t location, tree property_list)
10017 tree interface, chain;
10019 if (flag_objc1_only)
10020 error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
10022 if (property_list == error_mark_node)
10023 return;
10025 if (!objc_implementation_context)
10027 /* We can get here only in Objective-C; the Objective-C++ parser
10028 detects the problem while parsing, outputs the error
10029 "misplaced '@dynamic' Objective-C++ construct" and skips the
10030 declaration. */
10031 error_at (location, "%<@dynamic%> not in @implementation context");
10032 return;
10035 /* @dynamic is allowed in categories. */
10036 switch (TREE_CODE (objc_implementation_context))
10038 case CLASS_IMPLEMENTATION_TYPE:
10039 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10040 break;
10041 case CATEGORY_IMPLEMENTATION_TYPE:
10042 interface = lookup_category (implementation_template,
10043 CLASS_SUPER_NAME (objc_implementation_context));
10044 break;
10045 default:
10046 gcc_unreachable ();
10049 if (!interface)
10051 /* I can't see how this could happen, but it is good as a safety check. */
10052 error_at (location,
10053 "%<@dynamic%> requires the @interface of the class to be available");
10054 return;
10057 /* Now, iterate over the properties and do each of them. */
10058 for (chain = property_list; chain; chain = TREE_CHAIN (chain))
10060 objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
10064 /* Main routine to generate code/data for all the property information for
10065 current implementation (class or category). CLASS is the interface where
10066 ivars are declared. CLASS_METHODS is where methods are found which
10067 could be a class or a category depending on whether we are implementing
10068 property of a class or a category. */
10070 static void
10071 objc_gen_property_data (tree klass, tree class_methods)
10073 tree x;
10075 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10077 /* @dynamic property - nothing to check or synthesize. */
10078 if (PROPERTY_DYNAMIC (x))
10079 continue;
10081 /* @synthesize property - need to synthesize the accessors. */
10082 if (PROPERTY_IVAR_NAME (x))
10084 objc_synthesize_getter (klass, class_methods, x);
10086 if (PROPERTY_READONLY (x) == 0)
10087 objc_synthesize_setter (klass, class_methods, x);
10089 continue;
10092 gcc_unreachable ();
10096 /* This is called once we see the "@end" in an interface/implementation. */
10098 static void
10099 finish_class (tree klass)
10101 switch (TREE_CODE (klass))
10103 case CLASS_IMPLEMENTATION_TYPE:
10105 /* All code generation is done in finish_objc. */
10107 /* Generate what needed for property; setters, getters, etc. */
10108 objc_gen_property_data (implementation_template, implementation_template);
10110 if (implementation_template != objc_implementation_context)
10112 /* Ensure that all method listed in the interface contain bodies. */
10113 check_methods (CLASS_CLS_METHODS (implementation_template),
10114 objc_implementation_context, '+');
10115 check_methods (CLASS_NST_METHODS (implementation_template),
10116 objc_implementation_context, '-');
10118 if (CLASS_PROTOCOL_LIST (implementation_template))
10119 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
10120 "class",
10121 CLASS_NAME (objc_implementation_context));
10123 break;
10125 case CATEGORY_IMPLEMENTATION_TYPE:
10127 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
10129 if (category)
10131 /* Generate what needed for property; setters, getters, etc. */
10132 objc_gen_property_data (implementation_template, category);
10134 /* Ensure all method listed in the interface contain bodies. */
10135 check_methods (CLASS_CLS_METHODS (category),
10136 objc_implementation_context, '+');
10137 check_methods (CLASS_NST_METHODS (category),
10138 objc_implementation_context, '-');
10140 if (CLASS_PROTOCOL_LIST (category))
10141 check_protocols (CLASS_PROTOCOL_LIST (category),
10142 "category",
10143 CLASS_SUPER_NAME (objc_implementation_context));
10145 break;
10147 case CLASS_INTERFACE_TYPE:
10148 case CATEGORY_INTERFACE_TYPE:
10149 case PROTOCOL_INTERFACE_TYPE:
10151 /* Process properties of the class. */
10152 tree x;
10153 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
10155 /* Now we check that the appropriate getter is declared,
10156 and if not, we declare one ourselves. */
10157 tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
10158 PROPERTY_GETTER_NAME (x));
10160 if (getter_decl)
10162 /* TODO: Check that the declaration is consistent with the property. */
10165 else
10167 /* Generate an instance method declaration for the
10168 getter; for example "- (id) name;". In general it
10169 will be of the form
10170 -(type)property_getter_name; */
10171 tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
10172 getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
10173 rettype, PROPERTY_GETTER_NAME (x),
10174 NULL_TREE, false);
10175 objc_add_method (objc_interface_context, getter_decl, false, false);
10176 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
10179 if (PROPERTY_READONLY (x) == 0)
10181 /* Now we check that the appropriate setter is declared,
10182 and if not, we declare on ourselves. */
10183 tree setter_decl = lookup_method (CLASS_NST_METHODS (klass),
10184 PROPERTY_SETTER_NAME (x));
10186 if (setter_decl)
10188 /* TODO: Check that the declaration is consistent with the property. */
10191 else
10193 /* The setter name is something like 'setName:'.
10194 We need the substring 'setName' to build the
10195 method declaration due to how the declaration
10196 works. TODO: build_method_decl() will then
10197 generate back 'setName:' from 'setName'; it
10198 would be more efficient to hook into there. */
10199 const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
10200 size_t length = strlen (full_setter_name);
10201 char *setter_name = (char *) alloca (length);
10202 tree ret_type, selector, arg_type, arg_name;
10204 strcpy (setter_name, full_setter_name);
10205 setter_name[length - 1] = '\0';
10206 ret_type = build_tree_list (NULL_TREE, void_type_node);
10207 arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
10208 arg_name = get_identifier ("_value");
10209 selector = objc_build_keyword_decl (get_identifier (setter_name),
10210 arg_type, arg_name, NULL);
10211 setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
10212 ret_type, selector,
10213 build_tree_list (NULL_TREE, NULL_TREE),
10214 false);
10215 objc_add_method (objc_interface_context, setter_decl, false, false);
10216 METHOD_PROPERTY_CONTEXT (setter_decl) = x;
10220 break;
10222 default:
10223 gcc_unreachable ();
10224 break;
10228 static tree
10229 add_protocol (tree protocol)
10231 /* Put protocol on list in reverse order. */
10232 TREE_CHAIN (protocol) = protocol_chain;
10233 protocol_chain = protocol;
10234 return protocol_chain;
10237 static tree
10238 lookup_protocol (tree ident)
10240 tree chain;
10242 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
10243 if (ident == PROTOCOL_NAME (chain))
10244 return chain;
10246 return NULL_TREE;
10249 /* This function forward declares the protocols named by NAMES. If
10250 they are already declared or defined, the function has no effect. */
10252 void
10253 objc_declare_protocols (tree names)
10255 tree list;
10257 #ifdef OBJCPLUS
10258 if (current_namespace != global_namespace) {
10259 error ("Objective-C declarations may only appear in global scope");
10261 #endif /* OBJCPLUS */
10263 for (list = names; list; list = TREE_CHAIN (list))
10265 tree name = TREE_VALUE (list);
10267 if (lookup_protocol (name) == NULL_TREE)
10269 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
10271 TYPE_LANG_SLOT_1 (protocol)
10272 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10273 PROTOCOL_NAME (protocol) = name;
10274 PROTOCOL_LIST (protocol) = NULL_TREE;
10275 add_protocol (protocol);
10276 PROTOCOL_DEFINED (protocol) = 0;
10277 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10282 static tree
10283 start_protocol (enum tree_code code, tree name, tree list)
10285 tree protocol;
10287 #ifdef OBJCPLUS
10288 if (current_namespace != global_namespace) {
10289 error ("Objective-C declarations may only appear in global scope");
10291 #endif /* OBJCPLUS */
10293 protocol = lookup_protocol (name);
10295 if (!protocol)
10297 protocol = make_node (code);
10298 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10300 PROTOCOL_NAME (protocol) = name;
10301 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10302 add_protocol (protocol);
10303 PROTOCOL_DEFINED (protocol) = 1;
10304 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10306 check_protocol_recursively (protocol, list);
10308 else if (! PROTOCOL_DEFINED (protocol))
10310 PROTOCOL_DEFINED (protocol) = 1;
10311 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10313 check_protocol_recursively (protocol, list);
10315 else
10317 warning (0, "duplicate declaration for protocol %qE",
10318 name);
10320 return protocol;
10324 /* "Encode" a data type into a string, which grows in util_obstack.
10326 The format is described in gcc/doc/objc.texi, section 'Type
10327 encoding'.
10329 Most of the encode_xxx functions have a 'type' argument, which is
10330 the type to encode, and an integer 'curtype' argument, which is the
10331 index in the encoding string of the beginning of the encoding of
10332 the current type, and allows you to find what characters have
10333 already been written for the current type (they are the ones in the
10334 current encoding string starting from 'curtype').
10336 For example, if we are encoding a method which returns 'int' and
10337 takes a 'char **' argument, then when we get to the point of
10338 encoding the 'char **' argument, the encoded string already
10339 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
10340 'curtype' will be set to 7 when starting to encode 'char **'.
10341 During the whole of the encoding of 'char **', 'curtype' will be
10342 fixed at 7, so the routine encoding the second pointer can find out
10343 that it's actually encoding a pointer to a pointer by looking
10344 backwards at what has already been encoded for the current type,
10345 and seeing there is a "^" (meaning a pointer) in there.
10349 /* Encode type qualifiers encodes one of the "PQ" Objective-C
10350 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
10351 'const', instead, is encoded directly as part of the type.
10354 static void
10355 encode_type_qualifiers (tree declspecs)
10357 tree spec;
10359 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
10361 /* FIXME: Shouldn't we use token->keyword here ? */
10362 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
10363 obstack_1grow (&util_obstack, 'n');
10364 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
10365 obstack_1grow (&util_obstack, 'N');
10366 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
10367 obstack_1grow (&util_obstack, 'o');
10368 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
10369 obstack_1grow (&util_obstack, 'O');
10370 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
10371 obstack_1grow (&util_obstack, 'R');
10372 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
10373 obstack_1grow (&util_obstack, 'V');
10374 else
10375 gcc_unreachable ();
10379 /* Determine if a pointee is marked read-only. Only used by the NeXT
10380 runtime to be compatible with gcc-3.3. */
10382 static bool
10383 pointee_is_readonly (tree pointee)
10385 while (POINTER_TYPE_P (pointee))
10386 pointee = TREE_TYPE (pointee);
10388 return TYPE_READONLY (pointee);
10391 /* Encode a pointer type. */
10393 static void
10394 encode_pointer (tree type, int curtype, int format)
10396 tree pointer_to = TREE_TYPE (type);
10398 if (flag_next_runtime)
10400 /* This code is used to be compatible with gcc-3.3. */
10401 /* For historical/compatibility reasons, the read-only qualifier
10402 of the pointee gets emitted _before_ the '^'. The read-only
10403 qualifier of the pointer itself gets ignored, _unless_ we are
10404 looking at a typedef! Also, do not emit the 'r' for anything
10405 but the outermost type! */
10406 if (!generating_instance_variables
10407 && (obstack_object_size (&util_obstack) - curtype <= 1)
10408 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
10409 ? TYPE_READONLY (type)
10410 : pointee_is_readonly (pointer_to)))
10411 obstack_1grow (&util_obstack, 'r');
10414 if (TREE_CODE (pointer_to) == RECORD_TYPE)
10416 if (OBJC_TYPE_NAME (pointer_to)
10417 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
10419 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
10421 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
10423 obstack_1grow (&util_obstack, '@');
10424 return;
10426 else if (TYPE_HAS_OBJC_INFO (pointer_to)
10427 && TYPE_OBJC_INTERFACE (pointer_to))
10429 if (generating_instance_variables)
10431 obstack_1grow (&util_obstack, '@');
10432 obstack_1grow (&util_obstack, '"');
10433 obstack_grow (&util_obstack, name, strlen (name));
10434 obstack_1grow (&util_obstack, '"');
10435 return;
10437 else
10439 obstack_1grow (&util_obstack, '@');
10440 return;
10443 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
10445 obstack_1grow (&util_obstack, '#');
10446 return;
10448 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
10450 obstack_1grow (&util_obstack, ':');
10451 return;
10455 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
10456 && TYPE_MODE (pointer_to) == QImode)
10458 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
10459 ? OBJC_TYPE_NAME (pointer_to)
10460 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
10462 /* (BOOL *) are an exception and are encoded as ^c, while all
10463 other pointers to char are encoded as *. */
10464 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
10466 if (!flag_next_runtime)
10468 /* The NeXT runtime adds the 'r' before getting here. */
10470 /* It appears that "r*" means "const char *" rather than
10471 "char *const". "char *const" is encoded as "*",
10472 which is identical to "char *", so the "const" is
10473 unfortunately lost. */
10474 if (TYPE_READONLY (pointer_to))
10475 obstack_1grow (&util_obstack, 'r');
10478 obstack_1grow (&util_obstack, '*');
10479 return;
10483 /* We have a normal pointer type that does not get special treatment. */
10484 obstack_1grow (&util_obstack, '^');
10485 encode_type (pointer_to, curtype, format);
10488 static void
10489 encode_array (tree type, int curtype, int format)
10491 tree an_int_cst = TYPE_SIZE (type);
10492 tree array_of = TREE_TYPE (type);
10493 char buffer[40];
10495 if (an_int_cst == NULL)
10497 /* We are trying to encode an incomplete array. An incomplete
10498 array is forbidden as part of an instance variable. */
10499 if (generating_instance_variables)
10501 /* TODO: Detect this error earlier. */
10502 error ("instance variable has unknown size");
10503 return;
10506 /* So the only case in which an incomplete array could occur is
10507 if we are encoding the arguments or return value of a method.
10508 In that case, an incomplete array argument or return value
10509 (eg, -(void)display: (char[])string) is treated like a
10510 pointer because that is how the compiler does the function
10511 call. A special, more complicated case, is when the
10512 incomplete array is the last member of a struct (eg, if we
10513 are encoding "struct { unsigned long int a;double b[];}"),
10514 which is again part of a method argument/return value. In
10515 that case, we really need to communicate to the runtime that
10516 there is an incomplete array (not a pointer!) there. So, we
10517 detect that special case and encode it as a zero-length
10518 array.
10520 Try to detect that we are part of a struct. We do this by
10521 searching for '=' in the type encoding for the current type.
10522 NB: This hack assumes that you can't use '=' as part of a C
10523 identifier.
10526 char *enc = obstack_base (&util_obstack) + curtype;
10527 if (memchr (enc, '=',
10528 obstack_object_size (&util_obstack) - curtype) == NULL)
10530 /* We are not inside a struct. Encode the array as a
10531 pointer. */
10532 encode_pointer (type, curtype, format);
10533 return;
10537 /* Else, we are in a struct, and we encode it as a zero-length
10538 array. */
10539 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10541 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
10542 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
10543 else
10544 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
10545 TREE_INT_CST_LOW (an_int_cst)
10546 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
10548 obstack_grow (&util_obstack, buffer, strlen (buffer));
10549 encode_type (array_of, curtype, format);
10550 obstack_1grow (&util_obstack, ']');
10551 return;
10554 /* Encode a vector. The vector type is a GCC extension to C. */
10555 static void
10556 encode_vector (tree type, int curtype, int format)
10558 tree vector_of = TREE_TYPE (type);
10559 char buffer[40];
10561 /* Vectors are like simple fixed-size arrays. */
10563 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
10564 alignment of the vector, and <code> is the base type. Eg, int
10565 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
10566 assuming that the alignment is 32 bytes. We include size and
10567 alignment in bytes so that the runtime does not have to have any
10568 knowledge of the actual types.
10570 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
10571 /* We want to compute the equivalent of sizeof (<vector>).
10572 Code inspired by c_sizeof_or_alignof_type. */
10573 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
10574 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
10575 /* We want to compute the equivalent of __alignof__
10576 (<vector>). Code inspired by
10577 c_sizeof_or_alignof_type. */
10578 TYPE_ALIGN_UNIT (type));
10579 obstack_grow (&util_obstack, buffer, strlen (buffer));
10580 encode_type (vector_of, curtype, format);
10581 obstack_1grow (&util_obstack, ']');
10582 return;
10585 static void
10586 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
10588 tree field = TYPE_FIELDS (type);
10590 for (; field; field = DECL_CHAIN (field))
10592 #ifdef OBJCPLUS
10593 /* C++ static members, and things that are not field at all,
10594 should not appear in the encoding. */
10595 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
10596 continue;
10597 #endif
10599 /* Recursively encode fields of embedded base classes. */
10600 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
10601 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
10603 encode_aggregate_fields (TREE_TYPE (field),
10604 pointed_to, curtype, format);
10605 continue;
10608 if (generating_instance_variables && !pointed_to)
10610 tree fname = DECL_NAME (field);
10612 obstack_1grow (&util_obstack, '"');
10614 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
10615 obstack_grow (&util_obstack,
10616 IDENTIFIER_POINTER (fname),
10617 strlen (IDENTIFIER_POINTER (fname)));
10619 obstack_1grow (&util_obstack, '"');
10622 encode_field_decl (field, curtype, format);
10626 static void
10627 encode_aggregate_within (tree type, int curtype, int format, int left,
10628 int right)
10630 tree name;
10631 /* NB: aggregates that are pointed to have slightly different encoding
10632 rules in that you never encode the names of instance variables. */
10633 int ob_size = obstack_object_size (&util_obstack);
10634 bool inline_contents = false;
10635 bool pointed_to = false;
10637 if (flag_next_runtime)
10639 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
10640 pointed_to = true;
10642 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10643 && (!pointed_to || ob_size - curtype == 1
10644 || (ob_size - curtype == 2
10645 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
10646 inline_contents = true;
10648 else
10650 /* c0 and c1 are the last two characters in the encoding of the
10651 current type; if the last two characters were '^' or '^r',
10652 then we are encoding an aggregate that is "pointed to". The
10653 comment above applies: in that case we should avoid encoding
10654 the names of instance variables.
10656 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
10657 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
10659 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
10660 pointed_to = true;
10662 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
10664 if (!pointed_to)
10665 inline_contents = true;
10666 else
10668 /* Note that the check (ob_size - curtype < 2) prevents
10669 infinite recursion when encoding a structure which is
10670 a linked list (eg, struct node { struct node *next;
10671 }). Each time we follow a pointer, we add one
10672 character to ob_size, and curtype is fixed, so after
10673 at most two pointers we stop inlining contents and
10674 break the loop.
10676 The other case where we don't inline is "^r", which
10677 is a pointer to a constant struct.
10679 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
10680 inline_contents = true;
10685 /* Traverse struct aliases; it is important to get the
10686 original struct and its tag name (if any). */
10687 type = TYPE_MAIN_VARIANT (type);
10688 name = OBJC_TYPE_NAME (type);
10689 /* Open parenth/bracket. */
10690 obstack_1grow (&util_obstack, left);
10692 /* Encode the struct/union tag name, or '?' if a tag was
10693 not provided. Typedef aliases do not qualify. */
10694 #ifdef OBJCPLUS
10695 /* For compatibility with the NeXT runtime, ObjC++ encodes template
10696 args as a composite struct tag name. */
10697 if (name && TREE_CODE (name) == IDENTIFIER_NODE
10698 /* Did this struct have a tag? */
10699 && !TYPE_WAS_ANONYMOUS (type))
10700 obstack_grow (&util_obstack,
10701 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
10702 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
10703 #else
10704 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
10705 obstack_grow (&util_obstack,
10706 IDENTIFIER_POINTER (name),
10707 strlen (IDENTIFIER_POINTER (name)));
10708 #endif
10709 else
10710 obstack_1grow (&util_obstack, '?');
10712 /* Encode the types (and possibly names) of the inner fields,
10713 if required. */
10714 if (inline_contents)
10716 obstack_1grow (&util_obstack, '=');
10717 encode_aggregate_fields (type, pointed_to, curtype, format);
10719 /* Close parenth/bracket. */
10720 obstack_1grow (&util_obstack, right);
10723 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
10724 field type. */
10726 static void
10727 encode_next_bitfield (int width)
10729 char buffer[40];
10730 sprintf (buffer, "b%d", width);
10731 obstack_grow (&util_obstack, buffer, strlen (buffer));
10735 /* Encodes 'type', ignoring type qualifiers (which you should encode
10736 beforehand if needed) with the exception of 'const', which is
10737 encoded by encode_type. See above for the explanation of
10738 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
10739 OBJC_ENCODE_DONT_INLINE_DEFS.
10741 static void
10742 encode_type (tree type, int curtype, int format)
10744 enum tree_code code = TREE_CODE (type);
10746 /* Ignore type qualifiers other than 'const' when encoding a
10747 type. */
10749 if (type == error_mark_node)
10750 return;
10752 if (!flag_next_runtime)
10754 if (TYPE_READONLY (type))
10755 obstack_1grow (&util_obstack, 'r');
10758 switch (code)
10760 case ENUMERAL_TYPE:
10761 if (flag_next_runtime)
10763 /* Kludge for backwards-compatibility with gcc-3.3: enums
10764 are always encoded as 'i' no matter what type they
10765 actually are (!). */
10766 obstack_1grow (&util_obstack, 'i');
10767 break;
10769 /* Else, they are encoded exactly like the integer type that is
10770 used by the compiler to store them. */
10771 case INTEGER_TYPE:
10773 char c;
10774 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10776 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
10777 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
10778 case 32:
10780 tree int_type = type;
10781 if (flag_next_runtime)
10783 /* Another legacy kludge for compatiblity with
10784 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
10785 but not always. For typedefs, we need to use 'i'
10786 or 'I' instead if encoding a struct field, or a
10787 pointer! */
10788 int_type = ((!generating_instance_variables
10789 && (obstack_object_size (&util_obstack)
10790 == (unsigned) curtype))
10791 ? TYPE_MAIN_VARIANT (type)
10792 : type);
10794 if (int_type == long_unsigned_type_node
10795 || int_type == long_integer_type_node)
10796 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
10797 else
10798 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
10800 break;
10801 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
10802 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
10803 default: gcc_unreachable ();
10805 obstack_1grow (&util_obstack, c);
10806 break;
10808 case REAL_TYPE:
10810 char c;
10811 /* Floating point types. */
10812 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
10814 case 32: c = 'f'; break;
10815 case 64: c = 'd'; break;
10816 case 96:
10817 case 128: c = 'D'; break;
10818 default: gcc_unreachable ();
10820 obstack_1grow (&util_obstack, c);
10821 break;
10823 case VOID_TYPE:
10824 obstack_1grow (&util_obstack, 'v');
10825 break;
10827 case BOOLEAN_TYPE:
10828 obstack_1grow (&util_obstack, 'B');
10829 break;
10831 case ARRAY_TYPE:
10832 encode_array (type, curtype, format);
10833 break;
10835 case POINTER_TYPE:
10836 #ifdef OBJCPLUS
10837 case REFERENCE_TYPE:
10838 #endif
10839 encode_pointer (type, curtype, format);
10840 break;
10842 case RECORD_TYPE:
10843 encode_aggregate_within (type, curtype, format, '{', '}');
10844 break;
10846 case UNION_TYPE:
10847 encode_aggregate_within (type, curtype, format, '(', ')');
10848 break;
10850 case FUNCTION_TYPE: /* '?' means an unknown type. */
10851 obstack_1grow (&util_obstack, '?');
10852 break;
10854 case COMPLEX_TYPE:
10855 /* A complex is encoded as 'j' followed by the inner type (eg,
10856 "_Complex int" is encoded as 'ji'). */
10857 obstack_1grow (&util_obstack, 'j');
10858 encode_type (TREE_TYPE (type), curtype, format);
10859 break;
10861 case VECTOR_TYPE:
10862 encode_vector (type, curtype, format);
10863 break;
10865 default:
10866 warning (0, "unknown type %s found during Objective-C encoding",
10867 gen_type_name (type));
10868 obstack_1grow (&util_obstack, '?');
10869 break;
10872 if (flag_next_runtime)
10874 /* Super-kludge. Some ObjC qualifier and type combinations need
10875 to be rearranged for compatibility with gcc-3.3. */
10876 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
10878 char *enc = obstack_base (&util_obstack) + curtype;
10880 /* Rewrite "in const" from "nr" to "rn". */
10881 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
10882 strncpy (enc - 1, "rn", 2);
10887 static void
10888 encode_gnu_bitfield (int position, tree type, int size)
10890 enum tree_code code = TREE_CODE (type);
10891 char buffer[40];
10892 char charType = '?';
10894 /* This code is only executed for the GNU runtime, so we can ignore
10895 the NeXT runtime kludge of always encoding enums as 'i' no matter
10896 what integers they actually are. */
10897 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
10899 if (integer_zerop (TYPE_MIN_VALUE (type)))
10900 /* Unsigned integer types. */
10902 switch (TYPE_MODE (type))
10904 case QImode:
10905 charType = 'C'; break;
10906 case HImode:
10907 charType = 'S'; break;
10908 case SImode:
10910 if (type == long_unsigned_type_node)
10911 charType = 'L';
10912 else
10913 charType = 'I';
10914 break;
10916 case DImode:
10917 charType = 'Q'; break;
10918 default:
10919 gcc_unreachable ();
10922 else
10923 /* Signed integer types. */
10925 switch (TYPE_MODE (type))
10927 case QImode:
10928 charType = 'c'; break;
10929 case HImode:
10930 charType = 's'; break;
10931 case SImode:
10933 if (type == long_integer_type_node)
10934 charType = 'l';
10935 else
10936 charType = 'i';
10937 break;
10939 case DImode:
10940 charType = 'q'; break;
10941 default:
10942 gcc_unreachable ();
10946 else
10948 /* Do not do any encoding, produce an error and keep going. */
10949 error ("trying to encode non-integer type as a bitfield");
10950 return;
10953 sprintf (buffer, "b%d%c%d", position, charType, size);
10954 obstack_grow (&util_obstack, buffer, strlen (buffer));
10957 static void
10958 encode_field_decl (tree field_decl, int curtype, int format)
10960 #ifdef OBJCPLUS
10961 /* C++ static members, and things that are not fields at all,
10962 should not appear in the encoding. */
10963 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
10964 return;
10965 #endif
10967 /* Generate the bitfield typing information, if needed. Note the difference
10968 between GNU and NeXT runtimes. */
10969 if (DECL_BIT_FIELD_TYPE (field_decl))
10971 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
10973 if (flag_next_runtime)
10974 encode_next_bitfield (size);
10975 else
10976 encode_gnu_bitfield (int_bit_position (field_decl),
10977 DECL_BIT_FIELD_TYPE (field_decl), size);
10979 else
10980 encode_type (TREE_TYPE (field_decl), curtype, format);
10983 /* Decay array and function parameters into pointers. */
10985 static tree
10986 objc_decay_parm_type (tree type)
10988 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
10989 type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
10990 ? TREE_TYPE (type)
10991 : type);
10993 return type;
10996 static GTY(()) tree objc_parmlist = NULL_TREE;
10998 /* Append PARM to a list of formal parameters of a method, making a necessary
10999 array-to-pointer adjustment along the way. */
11001 static void
11002 objc_push_parm (tree parm)
11004 tree type;
11006 if (TREE_TYPE (parm) == error_mark_node)
11008 objc_parmlist = chainon (objc_parmlist, parm);
11009 return;
11012 /* Decay arrays and functions into pointers. */
11013 type = objc_decay_parm_type (TREE_TYPE (parm));
11015 /* If the parameter type has been decayed, a new PARM_DECL needs to be
11016 built as well. */
11017 if (type != TREE_TYPE (parm))
11018 parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
11020 DECL_ARG_TYPE (parm)
11021 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
11023 /* Record constancy and volatility. */
11024 c_apply_type_quals_to_decl
11025 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
11026 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
11027 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
11029 objc_parmlist = chainon (objc_parmlist, parm);
11032 /* Retrieve the formal parameter list constructed via preceding calls to
11033 objc_push_parm(). */
11035 #ifdef OBJCPLUS
11036 static tree
11037 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
11038 #else
11039 static struct c_arg_info *
11040 objc_get_parm_info (int have_ellipsis)
11041 #endif
11043 #ifdef OBJCPLUS
11044 tree parm_info = objc_parmlist;
11045 objc_parmlist = NULL_TREE;
11047 return parm_info;
11048 #else
11049 tree parm_info = objc_parmlist;
11050 struct c_arg_info *arg_info;
11051 /* The C front-end requires an elaborate song and dance at
11052 this point. */
11053 push_scope ();
11054 declare_parm_level ();
11055 while (parm_info)
11057 tree next = DECL_CHAIN (parm_info);
11059 DECL_CHAIN (parm_info) = NULL_TREE;
11060 parm_info = pushdecl (parm_info);
11061 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
11062 parm_info = next;
11064 arg_info = get_parm_info (have_ellipsis);
11065 pop_scope ();
11066 objc_parmlist = NULL_TREE;
11067 return arg_info;
11068 #endif
11071 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
11072 method definitions. In the case of instance methods, we can be more
11073 specific as to the type of 'self'. */
11075 static void
11076 synth_self_and_ucmd_args (void)
11078 tree self_type;
11080 if (objc_method_context
11081 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
11082 self_type = objc_instance_type;
11083 else
11084 /* Really a `struct objc_class *'. However, we allow people to
11085 assign to self, which changes its type midstream. */
11086 self_type = objc_object_type;
11088 /* id self; */
11089 objc_push_parm (build_decl (input_location,
11090 PARM_DECL, self_id, self_type));
11092 /* SEL _cmd; */
11093 objc_push_parm (build_decl (input_location,
11094 PARM_DECL, ucmd_id, objc_selector_type));
11097 /* Transform an Objective-C method definition into a static C function
11098 definition, synthesizing the first two arguments, "self" and "_cmd",
11099 in the process. */
11101 static void
11102 start_method_def (tree method)
11104 tree parmlist;
11105 #ifdef OBJCPLUS
11106 tree parm_info;
11107 #else
11108 struct c_arg_info *parm_info;
11109 #endif
11110 int have_ellipsis = 0;
11112 /* If we are defining a "dealloc" method in a non-root class, we
11113 will need to check if a [super dealloc] is missing, and warn if
11114 it is. */
11115 if(CLASS_SUPER_NAME (objc_implementation_context)
11116 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
11117 should_call_super_dealloc = 1;
11118 else
11119 should_call_super_dealloc = 0;
11121 /* Required to implement _msgSuper. */
11122 objc_method_context = method;
11123 UOBJC_SUPER_decl = NULL_TREE;
11125 /* Generate prototype declarations for arguments..."new-style". */
11126 synth_self_and_ucmd_args ();
11128 /* Generate argument declarations if a keyword_decl. */
11129 parmlist = METHOD_SEL_ARGS (method);
11130 while (parmlist)
11132 /* parmlist is a KEYWORD_DECL. */
11133 tree type = TREE_VALUE (TREE_TYPE (parmlist));
11134 tree parm;
11136 parm = build_decl (input_location,
11137 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
11138 decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
11139 objc_push_parm (parm);
11140 parmlist = DECL_CHAIN (parmlist);
11143 if (METHOD_ADD_ARGS (method))
11145 tree akey;
11147 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
11148 akey; akey = TREE_CHAIN (akey))
11150 objc_push_parm (TREE_VALUE (akey));
11153 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11154 have_ellipsis = 1;
11157 parm_info = objc_get_parm_info (have_ellipsis);
11159 really_start_method (objc_method_context, parm_info);
11162 /* Return 1 if TYPE1 is equivalent to TYPE2
11163 for purposes of method overloading. */
11165 static int
11166 objc_types_are_equivalent (tree type1, tree type2)
11168 if (type1 == type2)
11169 return 1;
11171 /* Strip away indirections. */
11172 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
11173 && (TREE_CODE (type1) == TREE_CODE (type2)))
11174 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
11175 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
11176 return 0;
11178 type1 = (TYPE_HAS_OBJC_INFO (type1)
11179 ? TYPE_OBJC_PROTOCOL_LIST (type1)
11180 : NULL_TREE);
11181 type2 = (TYPE_HAS_OBJC_INFO (type2)
11182 ? TYPE_OBJC_PROTOCOL_LIST (type2)
11183 : NULL_TREE);
11185 if (list_length (type1) == list_length (type2))
11187 for (; type2; type2 = TREE_CHAIN (type2))
11188 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
11189 return 0;
11190 return 1;
11192 return 0;
11195 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
11197 static int
11198 objc_types_share_size_and_alignment (tree type1, tree type2)
11200 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
11201 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
11204 /* Return 1 if PROTO1 is equivalent to PROTO2
11205 for purposes of method overloading. Ordinarily, the type signatures
11206 should match up exactly, unless STRICT is zero, in which case we
11207 shall allow differences in which the size and alignment of a type
11208 is the same. */
11210 static int
11211 comp_proto_with_proto (tree proto1, tree proto2, int strict)
11213 /* The following test is needed in case there are hashing
11214 collisions. */
11215 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
11216 return 0;
11218 return match_proto_with_proto (proto1, proto2, strict);
11221 static int
11222 match_proto_with_proto (tree proto1, tree proto2, int strict)
11224 tree type1, type2;
11226 /* Compare return types. */
11227 type1 = TREE_VALUE (TREE_TYPE (proto1));
11228 type2 = TREE_VALUE (TREE_TYPE (proto2));
11230 if (!objc_types_are_equivalent (type1, type2)
11231 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
11232 return 0;
11234 /* Compare argument types. */
11235 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
11236 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
11237 type1 && type2;
11238 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
11240 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
11241 && (strict
11242 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
11243 TREE_VALUE (type2))))
11244 return 0;
11247 return (!type1 && !type2);
11250 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
11251 this occurs. ObjC method dispatches are _not_ like C++ virtual
11252 member function dispatches, and we account for the difference here. */
11253 tree
11254 #ifdef OBJCPLUS
11255 objc_fold_obj_type_ref (tree ref, tree known_type)
11256 #else
11257 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
11258 tree known_type ATTRIBUTE_UNUSED)
11259 #endif
11261 #ifdef OBJCPLUS
11262 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
11264 /* If the receiver does not have virtual member functions, there
11265 is nothing we can (or need to) do here. */
11266 if (!v)
11267 return NULL_TREE;
11269 /* Let C++ handle C++ virtual functions. */
11270 return cp_fold_obj_type_ref (ref, known_type);
11271 #else
11272 /* For plain ObjC, we currently do not need to do anything. */
11273 return NULL_TREE;
11274 #endif
11277 static void
11278 objc_start_function (tree name, tree type, tree attrs,
11279 #ifdef OBJCPLUS
11280 tree params
11281 #else
11282 struct c_arg_info *params
11283 #endif
11286 tree fndecl = build_decl (input_location,
11287 FUNCTION_DECL, name, type);
11289 #ifdef OBJCPLUS
11290 DECL_ARGUMENTS (fndecl) = params;
11291 DECL_INITIAL (fndecl) = error_mark_node;
11292 DECL_EXTERNAL (fndecl) = 0;
11293 TREE_STATIC (fndecl) = 1;
11294 retrofit_lang_decl (fndecl);
11295 cplus_decl_attributes (&fndecl, attrs, 0);
11296 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
11297 #else
11298 current_function_returns_value = 0; /* Assume, until we see it does. */
11299 current_function_returns_null = 0;
11300 decl_attributes (&fndecl, attrs, 0);
11301 announce_function (fndecl);
11302 DECL_INITIAL (fndecl) = error_mark_node;
11303 DECL_EXTERNAL (fndecl) = 0;
11304 TREE_STATIC (fndecl) = 1;
11305 current_function_decl = pushdecl (fndecl);
11306 push_scope ();
11307 declare_parm_level ();
11308 DECL_RESULT (current_function_decl)
11309 = build_decl (input_location,
11310 RESULT_DECL, NULL_TREE,
11311 TREE_TYPE (TREE_TYPE (current_function_decl)));
11312 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
11313 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
11314 start_fname_decls ();
11315 store_parm_decls_from (params);
11316 #endif
11318 TREE_USED (current_function_decl) = 1;
11321 /* - Generate an identifier for the function. the format is "_n_cls",
11322 where 1 <= n <= nMethods, and cls is the name the implementation we
11323 are processing.
11324 - Install the return type from the method declaration.
11325 - If we have a prototype, check for type consistency. */
11327 static void
11328 really_start_method (tree method,
11329 #ifdef OBJCPLUS
11330 tree parmlist
11331 #else
11332 struct c_arg_info *parmlist
11333 #endif
11336 tree ret_type, meth_type;
11337 tree method_id;
11338 const char *sel_name, *class_name, *cat_name;
11339 char *buf;
11341 /* Synth the storage class & assemble the return type. */
11342 ret_type = TREE_VALUE (TREE_TYPE (method));
11344 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
11345 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
11346 cat_name = ((TREE_CODE (objc_implementation_context)
11347 == CLASS_IMPLEMENTATION_TYPE)
11348 ? NULL
11349 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
11350 method_slot++;
11352 /* Make sure this is big enough for any plausible method label. */
11353 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
11354 + (cat_name ? strlen (cat_name) : 0));
11356 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
11357 class_name, cat_name, sel_name, method_slot);
11359 method_id = get_identifier (buf);
11361 #ifdef OBJCPLUS
11362 /* Objective-C methods cannot be overloaded, so we don't need
11363 the type encoding appended. It looks bad anyway... */
11364 push_lang_context (lang_name_c);
11365 #endif
11367 meth_type
11368 = build_function_type (ret_type,
11369 get_arg_type_list (method, METHOD_DEF, 0));
11370 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
11372 /* Set self_decl from the first argument. */
11373 self_decl = DECL_ARGUMENTS (current_function_decl);
11375 /* Suppress unused warnings. */
11376 TREE_USED (self_decl) = 1;
11377 DECL_READ_P (self_decl) = 1;
11378 TREE_USED (DECL_CHAIN (self_decl)) = 1;
11379 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
11380 #ifdef OBJCPLUS
11381 pop_lang_context ();
11382 #endif
11384 METHOD_DEFINITION (method) = current_function_decl;
11386 /* Check consistency...start_function, pushdecl, duplicate_decls. */
11388 if (implementation_template != objc_implementation_context)
11390 tree proto
11391 = lookup_method_static (implementation_template,
11392 METHOD_SEL_NAME (method),
11393 ((TREE_CODE (method) == CLASS_METHOD_DECL)
11394 | OBJC_LOOKUP_NO_SUPER));
11396 if (proto)
11398 if (!comp_proto_with_proto (method, proto, 1))
11400 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
11402 warning_at (DECL_SOURCE_LOCATION (method), 0,
11403 "conflicting types for %<%c%s%>",
11404 (type ? '-' : '+'),
11405 identifier_to_locale (gen_method_decl (method)));
11406 inform (DECL_SOURCE_LOCATION (proto),
11407 "previous declaration of %<%c%s%>",
11408 (type ? '-' : '+'),
11409 identifier_to_locale (gen_method_decl (proto)));
11411 else
11413 /* If the method in the @interface was deprecated, mark
11414 the implemented method as deprecated too. It should
11415 never be used for messaging (when the deprecation
11416 warnings are produced), but just in case. */
11417 if (TREE_DEPRECATED (proto))
11418 TREE_DEPRECATED (method) = 1;
11420 /* If the method in the @interface was marked as
11421 'noreturn', mark the function implementing the method
11422 as 'noreturn' too. */
11423 TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
11426 else
11428 /* We have a method @implementation even though we did not
11429 see a corresponding @interface declaration (which is allowed
11430 by Objective-C rules). Go ahead and place the method in
11431 the @interface anyway, so that message dispatch lookups
11432 will see it. */
11433 tree interface = implementation_template;
11435 if (TREE_CODE (objc_implementation_context)
11436 == CATEGORY_IMPLEMENTATION_TYPE)
11437 interface = lookup_category
11438 (interface,
11439 CLASS_SUPER_NAME (objc_implementation_context));
11441 if (interface)
11442 objc_add_method (interface, copy_node (method),
11443 TREE_CODE (method) == CLASS_METHOD_DECL,
11444 /* is_optional= */ false);
11449 static void *UOBJC_SUPER_scope = 0;
11451 /* _n_Method (id self, SEL sel, ...)
11453 struct objc_super _S;
11454 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
11455 } */
11457 static tree
11458 get_super_receiver (void)
11460 if (objc_method_context)
11462 tree super_expr, super_expr_list;
11464 if (!UOBJC_SUPER_decl)
11466 UOBJC_SUPER_decl = build_decl (input_location,
11467 VAR_DECL, get_identifier (TAG_SUPER),
11468 objc_super_template);
11469 /* This prevents `unused variable' warnings when compiling with -Wall. */
11470 TREE_USED (UOBJC_SUPER_decl) = 1;
11471 DECL_READ_P (UOBJC_SUPER_decl) = 1;
11472 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
11473 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
11474 NULL_TREE);
11475 UOBJC_SUPER_scope = objc_get_current_scope ();
11478 /* Set receiver to self. */
11479 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
11480 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
11481 NOP_EXPR, input_location, self_decl,
11482 NULL_TREE);
11483 super_expr_list = super_expr;
11485 /* Set class to begin searching. */
11486 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
11487 get_identifier ("super_class"));
11489 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
11491 /* [_cls, __cls]Super are "pre-built" in
11492 synth_forward_declarations. */
11494 super_expr = build_modify_expr (input_location, super_expr,
11495 NULL_TREE, NOP_EXPR,
11496 input_location,
11497 ((TREE_CODE (objc_method_context)
11498 == INSTANCE_METHOD_DECL)
11499 ? ucls_super_ref
11500 : uucls_super_ref),
11501 NULL_TREE);
11504 else
11505 /* We have a category. */
11507 tree super_name = CLASS_SUPER_NAME (implementation_template);
11508 tree super_class;
11510 /* Barf if super used in a category of Object. */
11511 if (!super_name)
11513 error ("no super class declared in interface for %qE",
11514 CLASS_NAME (implementation_template));
11515 return error_mark_node;
11518 if (flag_next_runtime && !flag_zero_link)
11520 super_class = objc_get_class_reference (super_name);
11521 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
11522 /* If we are in a class method, we must retrieve the
11523 _metaclass_ for the current class, pointed at by
11524 the class's "isa" pointer. The following assumes that
11525 "isa" is the first ivar in a class (which it must be). */
11526 super_class
11527 = build_indirect_ref
11528 (input_location,
11529 build_c_cast (input_location,
11530 build_pointer_type (objc_class_type),
11531 super_class), RO_UNARY_STAR);
11533 else
11535 add_class_reference (super_name);
11536 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11537 ? objc_get_class_decl : objc_get_meta_class_decl);
11538 assemble_external (super_class);
11539 super_class
11540 = build_function_call
11541 (input_location,
11542 super_class,
11543 build_tree_list
11544 (NULL_TREE,
11545 my_build_string_pointer
11546 (IDENTIFIER_LENGTH (super_name) + 1,
11547 IDENTIFIER_POINTER (super_name))));
11550 super_expr
11551 = build_modify_expr (input_location, super_expr, NULL_TREE,
11552 NOP_EXPR,
11553 input_location,
11554 build_c_cast (input_location,
11555 TREE_TYPE (super_expr),
11556 super_class),
11557 NULL_TREE);
11560 super_expr_list = build_compound_expr (input_location,
11561 super_expr_list, super_expr);
11563 super_expr = build_unary_op (input_location,
11564 ADDR_EXPR, UOBJC_SUPER_decl, 0);
11565 super_expr_list = build_compound_expr (input_location,
11566 super_expr_list, super_expr);
11568 return super_expr_list;
11570 else
11572 error ("[super ...] must appear in a method context");
11573 return error_mark_node;
11577 /* When exiting a scope, sever links to a 'super' declaration (if any)
11578 therein contained. */
11580 void
11581 objc_clear_super_receiver (void)
11583 if (objc_method_context
11584 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
11585 UOBJC_SUPER_decl = 0;
11586 UOBJC_SUPER_scope = 0;
11590 void
11591 objc_finish_method_definition (tree fndecl)
11593 /* We cannot validly inline ObjC methods, at least not without a language
11594 extension to declare that a method need not be dynamically
11595 dispatched, so suppress all thoughts of doing so. */
11596 DECL_UNINLINABLE (fndecl) = 1;
11598 #ifndef OBJCPLUS
11599 /* The C++ front-end will have called finish_function() for us. */
11600 finish_function ();
11601 #endif
11603 METHOD_ENCODING (objc_method_context)
11604 = encode_method_prototype (objc_method_context);
11606 /* Required to implement _msgSuper. This must be done AFTER finish_function,
11607 since the optimizer may find "may be used before set" errors. */
11608 objc_method_context = NULL_TREE;
11610 if (should_call_super_dealloc)
11611 warning (0, "method possibly missing a [super dealloc] call");
11614 /* Given a tree DECL node, produce a printable description of it in the given
11615 buffer, overwriting the buffer. */
11617 static char *
11618 gen_declaration (tree decl)
11620 errbuf[0] = '\0';
11622 if (DECL_P (decl))
11624 gen_type_name_0 (TREE_TYPE (decl));
11626 if (DECL_NAME (decl))
11628 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
11629 strcat (errbuf, " ");
11631 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
11634 if (DECL_INITIAL (decl)
11635 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
11636 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
11637 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
11640 return errbuf;
11643 /* Given a tree TYPE node, produce a printable description of it in the given
11644 buffer, overwriting the buffer. */
11646 static char *
11647 gen_type_name_0 (tree type)
11649 tree orig = type, proto;
11651 if (TYPE_P (type) && TYPE_NAME (type))
11652 type = TYPE_NAME (type);
11653 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
11655 tree inner = TREE_TYPE (type);
11657 while (TREE_CODE (inner) == ARRAY_TYPE)
11658 inner = TREE_TYPE (inner);
11660 gen_type_name_0 (inner);
11662 if (!POINTER_TYPE_P (inner))
11663 strcat (errbuf, " ");
11665 if (POINTER_TYPE_P (type))
11666 strcat (errbuf, "*");
11667 else
11668 while (type != inner)
11670 strcat (errbuf, "[");
11672 if (TYPE_DOMAIN (type))
11674 char sz[20];
11676 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
11677 (TREE_INT_CST_LOW
11678 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
11679 strcat (errbuf, sz);
11682 strcat (errbuf, "]");
11683 type = TREE_TYPE (type);
11686 goto exit_function;
11689 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
11690 type = DECL_NAME (type);
11692 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
11693 ? IDENTIFIER_POINTER (type)
11694 : "");
11696 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
11697 if (objc_is_id (orig))
11698 orig = TREE_TYPE (orig);
11700 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
11702 if (proto)
11704 strcat (errbuf, " <");
11706 while (proto) {
11707 strcat (errbuf,
11708 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
11709 proto = TREE_CHAIN (proto);
11710 strcat (errbuf, proto ? ", " : ">");
11714 exit_function:
11715 return errbuf;
11718 static char *
11719 gen_type_name (tree type)
11721 errbuf[0] = '\0';
11723 return gen_type_name_0 (type);
11726 /* Given a method tree, put a printable description into the given
11727 buffer (overwriting) and return a pointer to the buffer. */
11729 static char *
11730 gen_method_decl (tree method)
11732 tree chain;
11734 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
11735 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
11736 strcat (errbuf, ")");
11737 chain = METHOD_SEL_ARGS (method);
11739 if (chain)
11741 /* We have a chain of keyword_decls. */
11744 if (KEYWORD_KEY_NAME (chain))
11745 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
11747 strcat (errbuf, ":(");
11748 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
11749 strcat (errbuf, ")");
11751 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
11752 if ((chain = DECL_CHAIN (chain)))
11753 strcat (errbuf, " ");
11755 while (chain);
11757 if (METHOD_ADD_ARGS (method))
11759 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
11761 /* Know we have a chain of parm_decls. */
11762 while (chain)
11764 strcat (errbuf, ", ");
11765 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
11766 chain = TREE_CHAIN (chain);
11769 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11770 strcat (errbuf, ", ...");
11774 else
11775 /* We have a unary selector. */
11776 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
11778 return errbuf;
11781 /* Debug info. */
11784 /* Dump an @interface declaration of the supplied class CHAIN to the
11785 supplied file FP. Used to implement the -gen-decls option (which
11786 prints out an @interface declaration of all classes compiled in
11787 this run); potentially useful for debugging the compiler too. */
11788 static void
11789 dump_interface (FILE *fp, tree chain)
11791 /* FIXME: A heap overflow here whenever a method (or ivar)
11792 declaration is so long that it doesn't fit in the buffer. The
11793 code and all the related functions should be rewritten to avoid
11794 using fixed size buffers. */
11795 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
11796 tree ivar_decls = CLASS_RAW_IVARS (chain);
11797 tree nst_methods = CLASS_NST_METHODS (chain);
11798 tree cls_methods = CLASS_CLS_METHODS (chain);
11800 fprintf (fp, "\n@interface %s", my_name);
11802 /* CLASS_SUPER_NAME is used to store the superclass name for
11803 classes, and the category name for categories. */
11804 if (CLASS_SUPER_NAME (chain))
11806 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
11808 switch (TREE_CODE (chain))
11810 case CATEGORY_IMPLEMENTATION_TYPE:
11811 case CATEGORY_INTERFACE_TYPE:
11812 fprintf (fp, " (%s)\n", name);
11813 break;
11814 default:
11815 fprintf (fp, " : %s\n", name);
11816 break;
11819 else
11820 fprintf (fp, "\n");
11822 /* FIXME - the following doesn't seem to work at the moment. */
11823 if (ivar_decls)
11825 fprintf (fp, "{\n");
11828 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
11829 ivar_decls = TREE_CHAIN (ivar_decls);
11831 while (ivar_decls);
11832 fprintf (fp, "}\n");
11835 while (nst_methods)
11837 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
11838 nst_methods = TREE_CHAIN (nst_methods);
11841 while (cls_methods)
11843 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
11844 cls_methods = TREE_CHAIN (cls_methods);
11847 fprintf (fp, "@end\n");
11850 #if 0
11851 /* Produce the pretty printing for an Objective-C method. This is
11852 currently unused, but could be handy while reorganizing the pretty
11853 printing to be more robust. */
11854 static const char *
11855 objc_pretty_print_method (bool is_class_method,
11856 const char *class_name,
11857 const char *category_name,
11858 const char *selector)
11860 if (category_name)
11862 char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
11863 + strlen (selector) + 7);
11865 if (is_class_method)
11866 sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
11867 else
11868 sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
11870 return result;
11872 else
11874 char *result = XNEWVEC (char, strlen (class_name)
11875 + strlen (selector) + 5);
11877 if (is_class_method)
11878 sprintf (result, "+[%s %s]", class_name, selector);
11879 else
11880 sprintf (result, "-[%s %s]", class_name, selector);
11882 return result;
11885 #endif
11887 /* Demangle function for Objective-C. Attempt to demangle the
11888 function name associated with a method (eg, going from
11889 "_i_NSObject__class" to "-[NSObject class]"); usually for the
11890 purpose of pretty printing or error messages. Return the demangled
11891 name, or NULL if the string is not an Objective-C mangled method
11892 name.
11894 Because of how the mangling is done, any method that has a '_' in
11895 its original name is at risk of being demangled incorrectly. In
11896 some cases there are multiple valid ways to demangle a method name
11897 and there is no way we can decide.
11899 TODO: objc_demangle() can't always get it right; the right way to
11900 get this correct for all method names would be to store the
11901 Objective-C method name somewhere in the function decl. Then,
11902 there is no demangling to do; we'd just pull the method name out of
11903 the decl. As an additional bonus, when printing error messages we
11904 could check for such a method name, and if we find it, we know the
11905 function is actually an Objective-C method and we could print error
11906 messages saying "In method '+[NSObject class]" instead of "In
11907 function '+[NSObject class]" as we do now. */
11908 static const char *
11909 objc_demangle (const char *mangled)
11911 char *demangled, *cp;
11913 if (mangled[0] == '_' &&
11914 (mangled[1] == 'i' || mangled[1] == 'c') &&
11915 mangled[2] == '_')
11917 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
11918 if (mangled[1] == 'i')
11919 *cp++ = '-'; /* for instance method */
11920 else
11921 *cp++ = '+'; /* for class method */
11922 *cp++ = '['; /* opening left brace */
11923 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
11924 while (*cp && *cp == '_')
11925 cp++; /* skip any initial underbars in class name */
11926 cp = strchr(cp, '_'); /* find first non-initial underbar */
11927 if (cp == NULL)
11929 free(demangled); /* not mangled name */
11930 return NULL;
11932 if (cp[1] == '_') /* easy case: no category name */
11934 *cp++ = ' '; /* replace two '_' with one ' ' */
11935 strcpy(cp, mangled + (cp - demangled) + 2);
11937 else
11939 *cp++ = '('; /* less easy case: category name */
11940 cp = strchr(cp, '_');
11941 if (cp == 0)
11943 free(demangled); /* not mangled name */
11944 return NULL;
11946 *cp++ = ')';
11947 *cp++ = ' '; /* overwriting 1st char of method name... */
11948 strcpy(cp, mangled + (cp - demangled)); /* get it back */
11950 /* Now we have the method name. We need to generally replace
11951 '_' with ':' but trying to preserve '_' if it could only have
11952 been in the mangled string because it was already in the
11953 original name. In cases where it's ambiguous, we assume that
11954 any '_' originated from a ':'. */
11956 /* Initial '_'s in method name can't have been generating by
11957 converting ':'s. Skip them. */
11958 while (*cp && *cp == '_')
11959 cp++;
11961 /* If the method name does not end with '_', then it has no
11962 arguments and there was no replacement of ':'s with '_'s
11963 during mangling. Check for that case, and skip any
11964 replacement if so. This at least guarantees that methods
11965 with no arguments are always demangled correctly (unless the
11966 original name ends with '_'). */
11967 if (*(mangled + strlen (mangled) - 1) != '_')
11969 /* Skip to the end. */
11970 for (; *cp; cp++)
11973 else
11975 /* Replace remaining '_' with ':'. This may get it wrong if
11976 there were '_'s in the original name. In most cases it
11977 is impossible to disambiguate. */
11978 for (; *cp; cp++)
11979 if (*cp == '_')
11980 *cp = ':';
11982 *cp++ = ']'; /* closing right brace */
11983 *cp++ = 0; /* string terminator */
11984 return demangled;
11986 else
11987 return NULL; /* not an objc mangled name */
11990 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
11991 specific decl, return the printable name for it. If not, return
11992 NULL. */
11993 const char *
11994 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
11996 switch (TREE_CODE (decl))
11998 case FUNCTION_DECL:
11999 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
12000 break;
12002 /* The following happens when we are printing a deprecation
12003 warning for a method. The warn_deprecation() will end up
12004 trying to print the decl for INSTANCE_METHOD_DECL or
12005 CLASS_METHOD_DECL. It would be nice to be able to print
12006 "-[NSObject autorelease] is deprecated", but to do that, we'd
12007 need to store the class and method name in the method decl,
12008 which we currently don't do. For now, just return the name
12009 of the method. We don't return NULL, because that may
12010 trigger further attempts to pretty-print the decl in C/C++,
12011 but they wouldn't know how to pretty-print it. */
12012 case INSTANCE_METHOD_DECL:
12013 case CLASS_METHOD_DECL:
12014 return IDENTIFIER_POINTER (DECL_NAME (decl));
12015 break;
12016 /* This happens when printing a deprecation warning for a
12017 property. We may want to consider some sort of pretty
12018 printing (eg, include the class name where it was declared
12019 ?). */
12020 case PROPERTY_DECL:
12021 return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
12022 break;
12023 default:
12024 return NULL;
12025 break;
12029 /* Return a printable name for 'decl'. This first tries
12030 objc_maybe_printable_name(), and if that fails, it returns the name
12031 in the decl. This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
12032 Objective-C; in Objective-C++, setting the hook is not enough
12033 because lots of C++ Front-End code calls cxx_printable_name,
12034 dump_decl and other C++ functions directly. So instead we have
12035 modified dump_decl to call objc_maybe_printable_name directly. */
12036 const char *
12037 objc_printable_name (tree decl, int v)
12039 const char *demangled_name = objc_maybe_printable_name (decl, v);
12041 if (demangled_name != NULL)
12042 return demangled_name;
12043 else
12044 return IDENTIFIER_POINTER (DECL_NAME (decl));
12047 static void
12048 init_objc (void)
12050 gcc_obstack_init (&util_obstack);
12051 util_firstobj = (char *) obstack_finish (&util_obstack);
12053 errbuf = XNEWVEC (char, 1024 * 10);
12054 hash_init ();
12055 synth_module_prologue ();
12058 static void
12059 finish_objc (void)
12061 struct imp_entry *impent;
12062 tree chain;
12063 /* The internally generated initializers appear to have missing braces.
12064 Don't warn about this. */
12065 int save_warn_missing_braces = warn_missing_braces;
12066 warn_missing_braces = 0;
12068 /* A missing @end may not be detected by the parser. */
12069 if (objc_implementation_context)
12071 warning (0, "%<@end%> missing in implementation context");
12072 finish_class (objc_implementation_context);
12073 objc_ivar_chain = NULL_TREE;
12074 objc_implementation_context = NULL_TREE;
12077 /* Process the static instances here because initialization of objc_symtab
12078 depends on them. */
12079 if (objc_static_instances)
12080 generate_static_references ();
12082 /* forward declare categories */
12083 if (cat_count)
12084 forward_declare_categories ();
12086 for (impent = imp_list; impent; impent = impent->next)
12088 objc_implementation_context = impent->imp_context;
12089 implementation_template = impent->imp_template;
12091 /* FIXME: This needs reworking to be more obvious. */
12093 UOBJC_CLASS_decl = impent->class_decl;
12094 UOBJC_METACLASS_decl = impent->meta_decl;
12096 /* Dump the @interface of each class as we compile it, if the
12097 -gen-decls option is in use. TODO: Dump the classes in the
12098 order they were found, rather than in reverse order as we
12099 are doing now. */
12100 if (flag_gen_declaration)
12102 dump_interface (gen_declaration_file, objc_implementation_context);
12105 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
12107 /* all of the following reference the string pool... */
12108 generate_ivar_lists ();
12109 generate_dispatch_tables ();
12110 generate_shared_structures (impent);
12112 else
12114 generate_dispatch_tables ();
12115 generate_category (impent);
12118 impent->class_decl = UOBJC_CLASS_decl;
12119 impent->meta_decl = UOBJC_METACLASS_decl;
12122 /* If we are using an array of selectors, we must always
12123 finish up the array decl even if no selectors were used. */
12124 if (flag_next_runtime)
12125 build_next_selector_translation_table ();
12126 else
12127 build_gnu_selector_translation_table ();
12129 if (protocol_chain)
12130 generate_protocols ();
12132 if (flag_next_runtime)
12133 generate_objc_image_info ();
12135 if (imp_list || class_names_chain
12136 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12137 generate_objc_symtab_decl ();
12139 /* Arrange for ObjC data structures to be initialized at run time. */
12140 if (objc_implementation_context || class_names_chain || objc_static_instances
12141 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12143 build_module_descriptor ();
12145 if (!flag_next_runtime)
12146 build_module_initializer_routine ();
12149 /* Dump the class references. This forces the appropriate classes
12150 to be linked into the executable image, preserving unix archive
12151 semantics. This can be removed when we move to a more dynamically
12152 linked environment. */
12154 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
12156 handle_class_ref (chain);
12157 if (TREE_PURPOSE (chain))
12158 generate_classref_translation_entry (chain);
12161 for (impent = imp_list; impent; impent = impent->next)
12162 handle_impent (impent);
12164 if (warn_selector)
12166 int slot;
12167 hash hsh;
12169 /* Run through the selector hash tables and print a warning for any
12170 selector which has multiple methods. */
12172 for (slot = 0; slot < SIZEHASHTABLE; slot++)
12174 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
12175 check_duplicates (hsh, 0, 1);
12176 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
12177 check_duplicates (hsh, 0, 1);
12181 warn_missing_braces = save_warn_missing_braces;
12184 /* Subroutines of finish_objc. */
12186 static void
12187 generate_classref_translation_entry (tree chain)
12189 tree expr, decl, type;
12191 decl = TREE_PURPOSE (chain);
12192 type = TREE_TYPE (decl);
12194 expr = add_objc_string (TREE_VALUE (chain), class_names);
12195 expr = convert (type, expr); /* cast! */
12197 /* This is a class reference. It is re-written by the runtime,
12198 but will be optimized away unless we force it. */
12199 DECL_PRESERVE_P (decl) = 1;
12200 finish_var_decl (decl, expr);
12201 return;
12204 static void
12205 handle_class_ref (tree chain)
12207 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
12208 char *string = (char *) alloca (strlen (name) + 30);
12209 tree decl;
12210 tree exp;
12212 sprintf (string, "%sobjc_class_name_%s",
12213 (flag_next_runtime ? "." : "__"), name);
12215 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
12216 if (flag_next_runtime)
12218 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
12219 return;
12221 #endif
12223 /* Make a decl for this name, so we can use its address in a tree. */
12224 decl = build_decl (input_location,
12225 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
12226 DECL_EXTERNAL (decl) = 1;
12227 TREE_PUBLIC (decl) = 1;
12228 pushdecl (decl);
12229 finish_var_decl (decl, 0);
12231 /* Make a decl for the address. */
12232 sprintf (string, "%sobjc_class_ref_%s",
12233 (flag_next_runtime ? "." : "__"), name);
12234 exp = build1 (ADDR_EXPR, string_type_node, decl);
12235 decl = build_decl (input_location,
12236 VAR_DECL, get_identifier (string), string_type_node);
12237 TREE_STATIC (decl) = 1;
12238 TREE_USED (decl) = 1;
12239 DECL_READ_P (decl) = 1;
12240 DECL_ARTIFICIAL (decl) = 1;
12241 DECL_INITIAL (decl) = error_mark_node;
12243 /* We must force the reference. */
12244 DECL_PRESERVE_P (decl) = 1;
12246 pushdecl (decl);
12247 finish_var_decl (decl, exp);
12250 static void
12251 handle_impent (struct imp_entry *impent)
12253 char *string;
12255 objc_implementation_context = impent->imp_context;
12256 implementation_template = impent->imp_template;
12258 switch (TREE_CODE (impent->imp_context))
12260 case CLASS_IMPLEMENTATION_TYPE:
12262 const char *const class_name =
12263 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12265 string = (char *) alloca (strlen (class_name) + 30);
12267 sprintf (string, "%sobjc_class_name_%s",
12268 (flag_next_runtime ? "." : "__"), class_name);
12269 break;
12271 case CATEGORY_IMPLEMENTATION_TYPE:
12273 const char *const class_name =
12274 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12275 const char *const class_super_name =
12276 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
12278 string = (char *) alloca (strlen (class_name)
12279 + strlen (class_super_name) + 30);
12281 /* Do the same for categories. Even though no references to
12282 these symbols are generated automatically by the compiler,
12283 it gives you a handle to pull them into an archive by
12284 hand. */
12285 sprintf (string, "*%sobjc_category_name_%s_%s",
12286 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
12287 break;
12289 default:
12290 return;
12293 #ifdef ASM_DECLARE_CLASS_REFERENCE
12294 if (flag_next_runtime)
12296 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
12297 return;
12299 else
12300 #endif
12302 tree decl, init;
12304 init = integer_zero_node;
12305 decl = build_decl (input_location,
12306 VAR_DECL, get_identifier (string), TREE_TYPE (init));
12307 TREE_PUBLIC (decl) = 1;
12308 TREE_READONLY (decl) = 1;
12309 TREE_USED (decl) = 1;
12310 TREE_CONSTANT (decl) = 1;
12311 DECL_CONTEXT (decl) = NULL_TREE;
12312 DECL_ARTIFICIAL (decl) = 1;
12313 TREE_STATIC (decl) = 1;
12314 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
12315 /* We must force the reference. */
12316 DECL_PRESERVE_P (decl) = 1;
12318 finish_var_decl(decl, init) ;
12322 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
12323 later requires that ObjC translation units participating in F&C be
12324 specially marked. The following routine accomplishes this. */
12326 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
12328 static void
12329 generate_objc_image_info (void)
12331 tree decl;
12332 int flags
12333 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
12334 | (flag_objc_gc ? 2 : 0));
12335 VEC(constructor_elt,gc) *v = NULL;
12336 tree array_type;
12338 if (!flags)
12339 return; /* No need for an image_info entry. */
12341 array_type = build_sized_array_type (integer_type_node, 2);
12343 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
12345 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
12346 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
12347 /* If we need this (determined above) it is because the runtime wants to
12348 refer to it in a manner hidden from the compiler. So we must force the
12349 output. */
12350 DECL_PRESERVE_P (decl) = 1;
12351 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
12354 /* Routine is called to issue diagnostic when reference to a private
12355 ivar is made and no other variable with same name is found in
12356 current scope. */
12357 bool
12358 objc_diagnose_private_ivar (tree id)
12360 tree ivar;
12361 if (!objc_method_context)
12362 return false;
12363 ivar = is_ivar (objc_ivar_chain, id);
12364 if (ivar && is_private (ivar))
12366 error ("instance variable %qs is declared private",
12367 IDENTIFIER_POINTER (id));
12368 return true;
12370 return false;
12373 /* Look up ID as an instance variable. OTHER contains the result of
12374 the C or C++ lookup, which we may want to use instead. */
12375 /* To use properties inside an instance method, use self.property. */
12376 tree
12377 objc_lookup_ivar (tree other, tree id)
12379 tree ivar;
12381 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
12382 if (!objc_method_context)
12383 return other;
12385 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
12386 /* We have a message to super. */
12387 return get_super_receiver ();
12389 /* In a class method, look up an instance variable only as a last
12390 resort. */
12391 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
12392 && other && other != error_mark_node)
12393 return other;
12395 /* Look up the ivar, but do not use it if it is not accessible. */
12396 ivar = is_ivar (objc_ivar_chain, id);
12398 if (!ivar || is_private (ivar))
12399 return other;
12401 /* In an instance method, a local variable (or parameter) may hide the
12402 instance variable. */
12403 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
12404 && other && other != error_mark_node
12405 #ifdef OBJCPLUS
12406 && CP_DECL_CONTEXT (other) != global_namespace)
12407 #else
12408 && !DECL_FILE_SCOPE_P (other))
12409 #endif
12411 warning (0, "local declaration of %qE hides instance variable", id);
12413 return other;
12416 /* At this point, we are either in an instance method with no obscuring
12417 local definitions, or in a class method with no alternate definitions
12418 at all. */
12419 return build_ivar_reference (id);
12422 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
12423 needs to be done if we are calling a function through a cast. */
12425 tree
12426 objc_rewrite_function_call (tree function, tree first_param)
12428 if (TREE_CODE (function) == NOP_EXPR
12429 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
12430 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
12431 == FUNCTION_DECL)
12433 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
12434 TREE_OPERAND (function, 0),
12435 first_param, size_zero_node);
12438 return function;
12441 /* This is called to "gimplify" a PROPERTY_REF node. It builds the
12442 corresponding 'getter' function call. Note that we assume the
12443 PROPERTY_REF to be valid since we generated it while parsing. */
12444 static void
12445 objc_gimplify_property_ref (tree *expr_p)
12447 tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
12448 tree call_exp;
12450 if (getter == NULL_TREE)
12452 tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
12453 /* This can happen if DECL_ARTIFICIAL (*expr_p), but
12454 should be impossible for real properties, which always
12455 have a getter. */
12456 error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
12457 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
12458 /* Try to recover from the error to prevent an ICE. We take
12459 zero and cast it to the type of the property. */
12460 *expr_p = convert (TREE_TYPE (property_decl),
12461 integer_zero_node);
12462 return;
12465 call_exp = getter;
12466 #ifdef OBJCPLUS
12467 /* In C++, a getter which returns an aggregate value results in a
12468 target_expr which initializes a temporary to the call
12469 expression. */
12470 if (TREE_CODE (getter) == TARGET_EXPR)
12472 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
12473 gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
12474 call_exp = TREE_OPERAND (getter, 1);
12476 #endif
12477 gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
12479 *expr_p = call_exp;
12482 /* This is called when "gimplifying" the trees. We need to gimplify
12483 the Objective-C/Objective-C++ specific trees, then hand over the
12484 process to C/C++. */
12486 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
12488 enum tree_code code = TREE_CODE (*expr_p);
12489 switch (code)
12491 /* Look for the special case of OBJC_TYPE_REF with the address
12492 of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
12493 or one of its cousins). */
12494 case OBJ_TYPE_REF:
12495 if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
12496 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
12497 == FUNCTION_DECL)
12499 enum gimplify_status r0, r1;
12501 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
12502 value of the OBJ_TYPE_REF, so force them to be emitted
12503 during subexpression evaluation rather than after the
12504 OBJ_TYPE_REF. This permits objc_msgSend calls in
12505 Objective C to use direct rather than indirect calls when
12506 the object expression has a postincrement. */
12507 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
12508 is_gimple_val, fb_rvalue);
12509 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
12510 is_gimple_val, fb_rvalue);
12512 return MIN (r0, r1);
12514 break;
12515 case PROPERTY_REF:
12516 objc_gimplify_property_ref (expr_p);
12517 /* Do not return yet; let C/C++ gimplify the resulting expression. */
12518 break;
12519 default:
12520 break;
12523 #ifdef OBJCPLUS
12524 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
12525 #else
12526 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
12527 #endif
12530 /* This routine returns true if TYPE is a valid objc object type,
12531 suitable for messaging; false otherwise. If 'accept_class' is
12532 'true', then a Class object is considered valid for messaging and
12533 'true' is returned if 'type' refers to a Class. If 'accept_class'
12534 is 'false', then a Class object is not considered valid for
12535 messaging and 'false' is returned in that case. */
12537 static bool
12538 objc_type_valid_for_messaging (tree type, bool accept_classes)
12540 if (!POINTER_TYPE_P (type))
12541 return false;
12543 /* Remove the pointer indirection; don't remove more than one
12544 otherwise we'd consider "NSObject **" a valid type for messaging,
12545 which it isn't. */
12546 type = TREE_TYPE (type);
12548 if (TREE_CODE (type) != RECORD_TYPE)
12549 return false;
12551 if (objc_is_object_id (type))
12552 return true;
12554 if (accept_classes && objc_is_class_id (type))
12555 return true;
12557 if (TYPE_HAS_OBJC_INFO (type))
12558 return true;
12560 return false;
12563 /* Begin code generation for fast enumeration (foreach) ... */
12565 /* Defines
12567 struct __objcFastEnumerationState
12569 unsigned long state;
12570 id *itemsPtr;
12571 unsigned long *mutationsPtr;
12572 unsigned long extra[5];
12575 Confusingly enough, NSFastEnumeration is then defined by libraries
12576 to be the same structure.
12579 static void
12580 build_fast_enumeration_state_template (void)
12582 tree decls, *chain = NULL;
12584 /* { */
12585 objc_fast_enumeration_state_template = objc_start_struct (get_identifier
12586 (TAG_FAST_ENUMERATION_STATE));
12588 /* unsigned long state; */
12589 decls = add_field_decl (long_unsigned_type_node, "state", &chain);
12591 /* id *itemsPtr; */
12592 add_field_decl (build_pointer_type (objc_object_type),
12593 "itemsPtr", &chain);
12595 /* unsigned long *mutationsPtr; */
12596 add_field_decl (build_pointer_type (long_unsigned_type_node),
12597 "mutationsPtr", &chain);
12599 /* unsigned long extra[5]; */
12600 add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
12601 "extra", &chain);
12603 /* } */
12604 objc_finish_struct (objc_fast_enumeration_state_template, decls);
12608 'objc_finish_foreach_loop()' generates the code for an Objective-C
12609 foreach loop. The 'location' argument is the location of the 'for'
12610 that starts the loop. The 'object_expression' is the expression of
12611 the 'object' that iterates; the 'collection_expression' is the
12612 expression of the collection that we iterate over (we need to make
12613 sure we evaluate this only once); the 'for_body' is the set of
12614 statements to be executed in each iteration; 'break_label' and
12615 'continue_label' are the break and continue labels which we need to
12616 emit since the <statements> may be jumping to 'break_label' (if they
12617 contain 'break') or to 'continue_label' (if they contain
12618 'continue').
12620 The syntax is
12622 for (<object expression> in <collection expression>)
12623 <statements>
12625 which is compiled into the following blurb:
12628 id __objc_foreach_collection;
12629 __objc_fast_enumeration_state __objc_foreach_enum_state;
12630 unsigned long __objc_foreach_batchsize;
12631 id __objc_foreach_items[16];
12632 __objc_foreach_collection = <collection expression>;
12633 __objc_foreach_enum_state = { 0 };
12634 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
12636 if (__objc_foreach_batchsize == 0)
12637 <object expression> = nil;
12638 else
12640 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
12641 next_batch:
12643 unsigned long __objc_foreach_index;
12644 __objc_foreach_index = 0;
12646 next_object:
12647 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
12648 <object expression> = enumState.itemsPtr[__objc_foreach_index];
12649 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
12651 continue_label:
12652 __objc_foreach_index++;
12653 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
12654 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
12656 if (__objc_foreach_batchsize != 0) goto next_batch;
12657 <object expression> = nil;
12658 break_label:
12662 'statements' may contain a 'continue' or 'break' instruction, which
12663 the user expects to 'continue' or 'break' the entire foreach loop.
12664 We are provided the labels that 'break' and 'continue' jump to, so
12665 we place them where we want them to jump to when they pick them.
12667 Optimization TODO: we could cache the IMP of
12668 countByEnumeratingWithState:objects:count:.
12671 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
12672 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
12674 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
12675 #include "tree-pretty-print.h"
12676 #endif
12678 void
12679 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
12680 tree break_label, tree continue_label)
12682 /* A tree representing the __objcFastEnumerationState struct type,
12683 or NSFastEnumerationState struct, whatever we are using. */
12684 tree objc_fast_enumeration_state_type;
12686 /* The trees representing the declarations of each of the local variables. */
12687 tree objc_foreach_collection_decl;
12688 tree objc_foreach_enum_state_decl;
12689 tree objc_foreach_items_decl;
12690 tree objc_foreach_batchsize_decl;
12691 tree objc_foreach_mutations_pointer_decl;
12692 tree objc_foreach_index_decl;
12694 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
12695 tree selector_name;
12697 /* A tree representing the local bind. */
12698 tree bind;
12700 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
12701 tree first_if;
12703 /* A tree representing the 'else' part of 'first_if' */
12704 tree first_else;
12706 /* A tree representing the 'next_batch' label. */
12707 tree next_batch_label_decl;
12709 /* A tree representing the binding after the 'next_batch' label. */
12710 tree next_batch_bind;
12712 /* A tree representing the 'next_object' label. */
12713 tree next_object_label_decl;
12715 /* Temporary variables. */
12716 tree t;
12717 int i;
12719 if (flag_objc1_only)
12720 error_at (location, "fast enumeration is not available in Objective-C 1.0");
12722 if (object_expression == error_mark_node)
12723 return;
12725 if (collection_expression == error_mark_node)
12726 return;
12728 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
12730 error ("iterating variable in fast enumeration is not an object");
12731 return;
12734 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
12736 error ("collection in fast enumeration is not an object");
12737 return;
12740 /* TODO: Check that object_expression is either a variable
12741 declaration, or an lvalue. */
12743 /* This kludge is an idea from apple. We use the
12744 __objcFastEnumerationState struct implicitly defined by the
12745 compiler, unless a NSFastEnumerationState struct has been defined
12746 (by a Foundation library such as GNUstep Base) in which case, we
12747 use that one.
12749 objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
12751 tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
12753 if (objc_NSFastEnumeration_type)
12755 /* TODO: We really need to check that
12756 objc_NSFastEnumeration_type is the same as ours! */
12757 if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
12759 /* If it's a typedef, use the original type. */
12760 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
12761 objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
12762 else
12763 objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
12768 /* { */
12769 /* Done by c-parser.c. */
12771 /* type object; */
12772 /* Done by c-parser.c. */
12774 /* id __objc_foreach_collection */
12775 objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
12777 /* __objcFastEnumerationState __objc_foreach_enum_state; */
12778 objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
12779 TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
12781 /* id __objc_foreach_items[16]; */
12782 objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
12783 TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
12785 /* unsigned long __objc_foreach_batchsize; */
12786 objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
12787 TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
12789 /* Generate the local variable binding. */
12790 bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
12791 SET_EXPR_LOCATION (bind, location);
12792 TREE_SIDE_EFFECTS (bind) = 1;
12794 /* __objc_foreach_collection = <collection expression>; */
12795 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
12796 SET_EXPR_LOCATION (t, location);
12797 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12799 /* __objc_foreach_enum_state.state = 0; */
12800 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
12801 get_identifier ("state")),
12802 build_int_cst (long_unsigned_type_node, 0));
12803 SET_EXPR_LOCATION (t, location);
12804 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12806 /* __objc_foreach_enum_state.itemsPtr = NULL; */
12807 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
12808 get_identifier ("itemsPtr")),
12809 null_pointer_node);
12810 SET_EXPR_LOCATION (t, location);
12811 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12813 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
12814 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
12815 get_identifier ("mutationsPtr")),
12816 null_pointer_node);
12817 SET_EXPR_LOCATION (t, location);
12818 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12820 /* __objc_foreach_enum_state.extra[0] = 0; */
12821 /* __objc_foreach_enum_state.extra[1] = 0; */
12822 /* __objc_foreach_enum_state.extra[2] = 0; */
12823 /* __objc_foreach_enum_state.extra[3] = 0; */
12824 /* __objc_foreach_enum_state.extra[4] = 0; */
12825 for (i = 0; i < 5 ; i++)
12827 t = build2 (MODIFY_EXPR, void_type_node,
12828 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
12829 get_identifier ("extra")),
12830 build_int_cst (NULL_TREE, i)),
12831 build_int_cst (long_unsigned_type_node, 0));
12832 SET_EXPR_LOCATION (t, location);
12833 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12836 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
12837 selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
12838 #ifdef OBJCPLUS
12839 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
12840 /* Parameters. */
12841 tree_cons /* &__objc_foreach_enum_state */
12842 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
12843 tree_cons /* __objc_foreach_items */
12844 (NULL_TREE, objc_foreach_items_decl,
12845 tree_cons /* 16 */
12846 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
12847 #else
12848 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
12850 struct c_expr array;
12851 array.value = objc_foreach_items_decl;
12852 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
12853 /* Parameters. */
12854 tree_cons /* &__objc_foreach_enum_state */
12855 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
12856 tree_cons /* __objc_foreach_items */
12857 (NULL_TREE, default_function_array_conversion (location, array).value,
12858 tree_cons /* 16 */
12859 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
12861 #endif
12862 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
12863 convert (long_unsigned_type_node, t));
12864 SET_EXPR_LOCATION (t, location);
12865 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
12867 /* if (__objc_foreach_batchsize == 0) */
12868 first_if = build3 (COND_EXPR, void_type_node,
12869 /* Condition. */
12870 c_fully_fold
12871 (c_common_truthvalue_conversion
12872 (location,
12873 build_binary_op (location,
12874 EQ_EXPR,
12875 objc_foreach_batchsize_decl,
12876 build_int_cst (long_unsigned_type_node, 0), 1)),
12877 false, NULL),
12878 /* Then block (we fill it in later). */
12879 NULL_TREE,
12880 /* Else block (we fill it in later). */
12881 NULL_TREE);
12882 SET_EXPR_LOCATION (first_if, location);
12883 append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
12885 /* then <object expression> = nil; */
12886 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
12887 SET_EXPR_LOCATION (t, location);
12888 COND_EXPR_THEN (first_if) = t;
12890 /* Now we build the 'else' part of the if; once we finish building
12891 it, we attach it to first_if as the 'else' part. */
12893 /* else */
12894 /* { */
12896 /* unsigned long __objc_foreach_mutations_pointer; */
12897 objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
12899 /* Generate the local variable binding. */
12900 first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
12901 SET_EXPR_LOCATION (first_else, location);
12902 TREE_SIDE_EFFECTS (first_else) = 1;
12904 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
12905 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
12906 build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
12907 get_identifier ("mutationsPtr")),
12908 RO_UNARY_STAR));
12909 SET_EXPR_LOCATION (t, location);
12910 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12912 /* next_batch: */
12913 next_batch_label_decl = create_artificial_label (location);
12914 t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
12915 SET_EXPR_LOCATION (t, location);
12916 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
12918 /* { */
12920 /* unsigned long __objc_foreach_index; */
12921 objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
12923 /* Generate the local variable binding. */
12924 next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
12925 SET_EXPR_LOCATION (next_batch_bind, location);
12926 TREE_SIDE_EFFECTS (next_batch_bind) = 1;
12927 append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
12929 /* __objc_foreach_index = 0; */
12930 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
12931 build_int_cst (long_unsigned_type_node, 0));
12932 SET_EXPR_LOCATION (t, location);
12933 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12935 /* next_object: */
12936 next_object_label_decl = create_artificial_label (location);
12937 t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
12938 SET_EXPR_LOCATION (t, location);
12939 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12941 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
12942 t = build3 (COND_EXPR, void_type_node,
12943 /* Condition. */
12944 c_fully_fold
12945 (c_common_truthvalue_conversion
12946 (location,
12947 build_binary_op
12948 (location,
12949 NE_EXPR,
12950 objc_foreach_mutations_pointer_decl,
12951 build_indirect_ref (location,
12952 objc_build_component_ref (objc_foreach_enum_state_decl,
12953 get_identifier ("mutationsPtr")),
12954 RO_UNARY_STAR), 1)),
12955 false, NULL),
12956 /* Then block. */
12957 build_function_call (input_location,
12958 objc_enumeration_mutation_decl,
12959 tree_cons (NULL, collection_expression, NULL)),
12960 /* Else block. */
12961 NULL_TREE);
12962 SET_EXPR_LOCATION (t, location);
12963 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12965 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
12966 t = build2 (MODIFY_EXPR, void_type_node, object_expression,
12967 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
12968 get_identifier ("itemsPtr")),
12969 objc_foreach_index_decl));
12970 SET_EXPR_LOCATION (t, location);
12971 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12973 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
12974 append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
12976 /* continue_label: */
12977 if (continue_label)
12979 t = build1 (LABEL_EXPR, void_type_node, continue_label);
12980 SET_EXPR_LOCATION (t, location);
12981 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12984 /* __objc_foreach_index++; */
12985 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
12986 build_binary_op (location,
12987 PLUS_EXPR,
12988 objc_foreach_index_decl,
12989 build_int_cst (long_unsigned_type_node, 1), 1));
12990 SET_EXPR_LOCATION (t, location);
12991 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
12993 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
12994 t = build3 (COND_EXPR, void_type_node,
12995 /* Condition. */
12996 c_fully_fold
12997 (c_common_truthvalue_conversion
12998 (location,
12999 build_binary_op (location,
13000 LT_EXPR,
13001 objc_foreach_index_decl,
13002 objc_foreach_batchsize_decl, 1)),
13003 false, NULL),
13004 /* Then block. */
13005 build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
13006 /* Else block. */
13007 NULL_TREE);
13008 SET_EXPR_LOCATION (t, location);
13009 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13011 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
13012 #ifdef OBJCPLUS
13013 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13014 /* Parameters. */
13015 tree_cons /* &__objc_foreach_enum_state */
13016 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13017 tree_cons /* __objc_foreach_items */
13018 (NULL_TREE, objc_foreach_items_decl,
13019 tree_cons /* 16 */
13020 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13021 #else
13022 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
13024 struct c_expr array;
13025 array.value = objc_foreach_items_decl;
13026 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13027 /* Parameters. */
13028 tree_cons /* &__objc_foreach_enum_state */
13029 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13030 tree_cons /* __objc_foreach_items */
13031 (NULL_TREE, default_function_array_conversion (location, array).value,
13032 tree_cons /* 16 */
13033 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13035 #endif
13036 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
13037 convert (long_unsigned_type_node, t));
13038 SET_EXPR_LOCATION (t, location);
13039 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13041 /* } */
13043 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
13044 t = build3 (COND_EXPR, void_type_node,
13045 /* Condition. */
13046 c_fully_fold
13047 (c_common_truthvalue_conversion
13048 (location,
13049 build_binary_op (location,
13050 NE_EXPR,
13051 objc_foreach_batchsize_decl,
13052 build_int_cst (long_unsigned_type_node, 0), 1)),
13053 false, NULL),
13054 /* Then block. */
13055 build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
13056 /* Else block. */
13057 NULL_TREE);
13058 SET_EXPR_LOCATION (t, location);
13059 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13061 /* <object expression> = nil; */
13062 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13063 SET_EXPR_LOCATION (t, location);
13064 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13066 /* break_label: */
13067 if (break_label)
13069 t = build1 (LABEL_EXPR, void_type_node, break_label);
13070 SET_EXPR_LOCATION (t, location);
13071 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13074 /* } */
13075 COND_EXPR_ELSE (first_if) = first_else;
13077 /* Do the whole thing. */
13078 add_stmt (bind);
13080 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
13081 /* This will print to stderr the whole blurb generated by the
13082 compiler while compiling (assuming the compiler doesn't crash
13083 before getting here).
13085 debug_generic_stmt (bind);
13086 #endif
13088 /* } */
13089 /* Done by c-parser.c */
13092 /* Return true if we have an NxString object pointer. */
13094 bool
13095 objc_string_ref_type_p (tree strp)
13097 tree tmv;
13098 if (!strp || TREE_CODE (strp) != POINTER_TYPE)
13099 return false;
13101 tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
13102 tmv = OBJC_TYPE_NAME (tmv);
13103 return (tmv
13104 && TREE_CODE (tmv) == IDENTIFIER_NODE
13105 && IDENTIFIER_POINTER (tmv)
13106 && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
13109 /* At present the behavior of this is undefined and it does nothing. */
13110 void
13111 objc_check_format_arg (tree ARG_UNUSED (format_arg),
13112 tree ARG_UNUSED (args_list))
13116 #include "gt-objc-objc-act.h"