In gcc/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / gcc / objc / objc-act.c
blobefdf17f709ef59ae13e987fc268555a80a570100
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 "flags.h"
39 #include "langhooks.h"
40 #include "objc-act.h"
41 #include "input.h"
42 #include "function.h"
43 #include "output.h"
44 #include "toplev.h"
45 #include "ggc.h"
46 #include "debug.h"
47 #include "target.h"
48 #include "diagnostic-core.h"
49 #include "intl.h"
50 #include "cgraph.h"
51 #include "tree-iterator.h"
52 #include "hashtab.h"
53 #include "langhooks-def.h"
55 /* For default_tree_printer (). */
56 #include "tree-pretty-print.h"
58 /* For enum gimplify_status */
59 #include "gimple.h"
61 #define OBJC_VOID_AT_END void_list_node
63 static unsigned int should_call_super_dealloc = 0;
65 /* When building Objective-C++, we need in_late_binary_op. */
66 #ifdef OBJCPLUS
67 bool in_late_binary_op = false;
68 #endif /* OBJCPLUS */
70 /* When building Objective-C++, we are not linking against the C front-end
71 and so need to replicate the C tree-construction functions in some way. */
72 #ifdef OBJCPLUS
73 #define OBJCP_REMAP_FUNCTIONS
74 #include "objcp-decl.h"
75 #endif /* OBJCPLUS */
77 /* This is the default way of generating a method name. */
78 /* This has the problem that "test_method:argument:" and
79 "test:method_argument:" will generate the same name
80 ("_i_Test__test_method_argument_" for an instance method of the
81 class "Test"), so you can't have them both in the same class!
82 Moreover, the demangling (going from
83 "_i_Test__test_method_argument" back to the original name) is
84 undefined because there are two correct ways of demangling the
85 name. */
86 #ifndef OBJC_GEN_METHOD_LABEL
87 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
88 do { \
89 char *temp; \
90 sprintf ((BUF), "_%s_%s_%s_%s", \
91 ((IS_INST) ? "i" : "c"), \
92 (CLASS_NAME), \
93 ((CAT_NAME)? (CAT_NAME) : ""), \
94 (SEL_NAME)); \
95 for (temp = (BUF); *temp; temp++) \
96 if (*temp == ':') *temp = '_'; \
97 } while (0)
98 #endif
100 /* These need specifying. */
101 #ifndef OBJC_FORWARDING_STACK_OFFSET
102 #define OBJC_FORWARDING_STACK_OFFSET 0
103 #endif
105 #ifndef OBJC_FORWARDING_MIN_OFFSET
106 #define OBJC_FORWARDING_MIN_OFFSET 0
107 #endif
109 /* Set up for use of obstacks. */
111 #include "obstack.h"
113 /* This obstack is used to accumulate the encoding of a data type. */
114 static struct obstack util_obstack;
116 /* This points to the beginning of obstack contents, so we can free
117 the whole contents. */
118 char *util_firstobj;
120 /* The version identifies which language generation and runtime
121 the module (file) was compiled for, and is recorded in the
122 module descriptor. */
124 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
125 #define PROTOCOL_VERSION 2
127 /* (Decide if these can ever be validly changed.) */
128 #define OBJC_ENCODE_INLINE_DEFS 0
129 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
131 /*** Private Interface (procedures) ***/
133 /* Used by compile_file. */
135 static void init_objc (void);
136 static void finish_objc (void);
138 /* Code generation. */
140 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
141 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
142 static tree get_proto_encoding (tree);
143 static tree lookup_interface (tree);
144 static tree objc_add_static_instance (tree, tree);
146 static tree start_class (enum tree_code, tree, tree, tree);
147 static tree continue_class (tree);
148 static void finish_class (tree);
149 static void start_method_def (tree);
150 #ifdef OBJCPLUS
151 static void objc_start_function (tree, tree, tree, tree);
152 #else
153 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
154 #endif
155 static tree start_protocol (enum tree_code, tree, tree);
156 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
157 static tree objc_add_method (tree, tree, int, bool);
158 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
159 static tree build_ivar_reference (tree);
160 static tree is_ivar (tree, tree);
162 static void build_objc_exception_stuff (void);
163 static void build_next_objc_exception_stuff (void);
165 /* We only need the following for ObjC; ObjC++ will use C++'s definition
166 of DERIVED_FROM_P. */
167 #ifndef OBJCPLUS
168 static bool objc_derived_from_p (tree, tree);
169 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
170 #endif
172 /* Property. */
173 static void objc_gen_one_property_datum (tree, tree, tree, bool*);
174 static void objc_gen_property_data (tree, tree);
175 static void objc_synthesize_getter (tree, tree, tree);
176 static void objc_process_getter_setter (tree, tree, bool);
177 static void objc_synthesize_setter (tree, tree, tree);
178 static char *objc_build_property_ivar_name (tree);
179 static char *objc_build_property_setter_name (tree, bool);
180 static int match_proto_with_proto (tree, tree, int);
181 static tree lookup_property (tree, tree);
182 static tree lookup_property_in_list (tree, tree);
183 static tree lookup_property_in_protocol_list (tree, tree);
184 static tree objc_setter_func_call (tree, tree, tree);
185 static tree build_property_reference (tree, tree);
186 static tree is_property (tree, tree);
187 /* Set on a CALL_EXPR if it is for call to a getter function represented by an
188 objective-c property declaration. */
189 #define CALL_EXPR_OBJC_PROPERTY_GETTER(NODE) \
190 (CALL_EXPR_CHECK(NODE)->base.deprecated_flag)
192 static void objc_xref_basetypes (tree, tree);
194 static void build_class_template (void);
195 static void build_selector_template (void);
196 static void build_category_template (void);
197 static void build_super_template (void);
198 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
199 static tree get_class_ivars (tree, bool);
200 static tree generate_protocol_list (tree);
201 static void build_protocol_reference (tree);
203 static void build_fast_enumeration_state_template (void);
205 #ifdef OBJCPLUS
206 static void objc_generate_cxx_cdtors (void);
207 #endif
209 /* objc attribute */
210 static void objc_decl_method_attributes (tree*, tree, int);
211 static tree build_keyword_selector (tree);
212 static const char *synth_id_with_class_suffix (const char *, tree);
214 /* Hash tables to manage the global pool of method prototypes. */
216 hash *nst_method_hash_list = 0;
217 hash *cls_method_hash_list = 0;
219 /* Hash tables to manage the global pool of class names. */
221 hash *cls_name_hash_list = 0;
222 hash *als_name_hash_list = 0;
224 static void hash_class_name_enter (hash *, tree, tree);
225 static hash hash_class_name_lookup (hash *, tree);
227 static hash hash_lookup (hash *, tree);
228 static tree lookup_method (tree, tree);
229 static tree lookup_method_static (tree, tree, int);
231 static tree add_class (tree, tree);
232 static void add_category (tree, tree);
233 static inline tree lookup_category (tree, tree);
235 enum string_section
237 class_names, /* class, category, protocol, module names */
238 meth_var_names, /* method and variable names */
239 meth_var_types /* method and variable type descriptors */
242 static tree add_objc_string (tree, enum string_section);
243 static void build_selector_table_decl (void);
245 /* Protocol additions. */
247 static tree lookup_protocol (tree);
248 static tree lookup_and_install_protocols (tree);
250 /* Type encoding. */
252 static void encode_type_qualifiers (tree);
253 static void encode_type (tree, int, int);
254 static void encode_field_decl (tree, int, int);
256 #ifdef OBJCPLUS
257 static void really_start_method (tree, tree);
258 #else
259 static void really_start_method (tree, struct c_arg_info *);
260 #endif
261 static int comp_proto_with_proto (tree, tree, int);
262 static tree get_arg_type_list (tree, int, int);
263 static tree objc_decay_parm_type (tree);
264 static void objc_push_parm (tree);
265 #ifdef OBJCPLUS
266 static tree objc_get_parm_info (int);
267 #else
268 static struct c_arg_info *objc_get_parm_info (int);
269 #endif
271 /* Utilities for debugging and error diagnostics. */
273 static char *gen_type_name (tree);
274 static char *gen_type_name_0 (tree);
275 static char *gen_method_decl (tree);
276 static char *gen_declaration (tree);
278 /* Everything else. */
280 static tree create_field_decl (tree, const char *);
281 static void add_class_reference (tree);
282 static void build_protocol_template (void);
283 static tree encode_method_prototype (tree);
284 static void generate_classref_translation_entry (tree);
285 static void handle_class_ref (tree);
286 static void generate_struct_by_value_array (void)
287 ATTRIBUTE_NORETURN;
288 static void mark_referenced_methods (void);
289 static void generate_objc_image_info (void);
290 static bool objc_type_valid_for_messaging (tree typ);
292 /*** Private Interface (data) ***/
294 /* Reserved tag definitions. */
296 #define OBJECT_TYPEDEF_NAME "id"
297 #define CLASS_TYPEDEF_NAME "Class"
299 #define TAG_OBJECT "objc_object"
300 #define TAG_CLASS "objc_class"
301 #define TAG_SUPER "objc_super"
302 #define TAG_SELECTOR "objc_selector"
304 #define UTAG_CLASS "_objc_class"
305 #define UTAG_IVAR "_objc_ivar"
306 #define UTAG_IVAR_LIST "_objc_ivar_list"
307 #define UTAG_METHOD "_objc_method"
308 #define UTAG_METHOD_LIST "_objc_method_list"
309 #define UTAG_CATEGORY "_objc_category"
310 #define UTAG_MODULE "_objc_module"
311 #define UTAG_SYMTAB "_objc_symtab"
312 #define UTAG_SUPER "_objc_super"
313 #define UTAG_SELECTOR "_objc_selector"
315 #define UTAG_PROTOCOL "_objc_protocol"
316 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
317 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
319 /* Note that the string object global name is only needed for the
320 NeXT runtime. */
321 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
323 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
325 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
326 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
328 static const char *TAG_GETCLASS;
329 static const char *TAG_GETMETACLASS;
330 static const char *TAG_MSGSEND;
331 static const char *TAG_MSGSENDSUPER;
332 /* The NeXT Objective-C messenger may have two extra entry points, for use
333 when returning a structure. */
334 static const char *TAG_MSGSEND_STRET;
335 static const char *TAG_MSGSENDSUPER_STRET;
336 static const char *default_constant_string_class_name;
338 /* Runtime metadata flags. */
339 #define CLS_FACTORY 0x0001L
340 #define CLS_META 0x0002L
341 #define CLS_HAS_CXX_STRUCTORS 0x2000L
343 #define OBJC_MODIFIER_STATIC 0x00000001
344 #define OBJC_MODIFIER_FINAL 0x00000002
345 #define OBJC_MODIFIER_PUBLIC 0x00000004
346 #define OBJC_MODIFIER_PRIVATE 0x00000008
347 #define OBJC_MODIFIER_PROTECTED 0x00000010
348 #define OBJC_MODIFIER_NATIVE 0x00000020
349 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
350 #define OBJC_MODIFIER_ABSTRACT 0x00000080
351 #define OBJC_MODIFIER_VOLATILE 0x00000100
352 #define OBJC_MODIFIER_TRANSIENT 0x00000200
353 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
355 /* NeXT-specific tags. */
357 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
358 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
359 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
360 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
361 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
362 #define TAG_EXCEPTIONMATCH "objc_exception_match"
363 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
364 #define TAG_SYNCENTER "objc_sync_enter"
365 #define TAG_SYNCEXIT "objc_sync_exit"
366 #define TAG_SETJMP "_setjmp"
367 #define UTAG_EXCDATA "_objc_exception_data"
369 #define TAG_ASSIGNIVAR "objc_assign_ivar"
370 #define TAG_ASSIGNGLOBAL "objc_assign_global"
371 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
373 /* Branch entry points. All that matters here are the addresses;
374 functions with these names do not really exist in libobjc. */
376 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
377 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
379 #define TAG_CXX_CONSTRUCT ".cxx_construct"
380 #define TAG_CXX_DESTRUCT ".cxx_destruct"
382 /* GNU-specific tags. */
384 #define TAG_EXECCLASS "__objc_exec_class"
385 #define TAG_GNUINIT "__objc_gnu_init"
387 /* Flags for lookup_method_static(). */
388 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
389 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
391 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
392 tree objc_global_trees[OCTI_MAX];
394 static void handle_impent (struct imp_entry *);
396 struct imp_entry *imp_list = 0;
397 int imp_count = 0; /* `@implementation' */
398 int cat_count = 0; /* `@category' */
400 objc_ivar_visibility_kind objc_ivar_visibility;
402 /* Use to generate method labels. */
403 static int method_slot = 0;
405 /* Flag to say whether methods in a protocol are optional or
406 required. */
407 static bool objc_method_optional_flag = false;
409 static bool property_readonly;
410 static tree property_getter;
411 static tree property_setter;
412 static tree property_ivar;
413 static bool property_copies;
414 static bool in_objc_property_setter_name_context = false;
416 static int objc_collecting_ivars = 0;
418 #define BUFSIZE 1024
420 static char *errbuf; /* Buffer for error diagnostics */
422 /* Data imported from tree.c. */
424 extern enum debug_info_type write_symbols;
426 /* Data imported from toplev.c. */
428 extern const char *dump_base_name;
430 static int flag_typed_selectors;
432 /* Store all constructed constant strings in a hash table so that
433 they get uniqued properly. */
435 struct GTY(()) string_descriptor {
436 /* The literal argument . */
437 tree literal;
439 /* The resulting constant string. */
440 tree constructor;
443 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
445 FILE *gen_declaration_file;
447 /* Tells "encode_pointer/encode_aggregate" whether we are generating
448 type descriptors for instance variables (as opposed to methods).
449 Type descriptors for instance variables contain more information
450 than methods (for static typing and embedded structures). */
452 static int generating_instance_variables = 0;
454 /* For building an objc struct. These may not be used when this file
455 is compiled as part of obj-c++. */
457 static bool objc_building_struct;
458 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
460 /* Start building a struct for objc. */
462 static tree
463 objc_start_struct (tree name)
465 gcc_assert (!objc_building_struct);
466 objc_building_struct = true;
467 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
470 /* Finish building a struct for objc. */
472 static tree
473 objc_finish_struct (tree type, tree fieldlist)
475 gcc_assert (objc_building_struct);
476 objc_building_struct = false;
477 return finish_struct (input_location, type, fieldlist, NULL_TREE,
478 objc_struct_info);
481 static tree
482 build_sized_array_type (tree base_type, int size)
484 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
485 return build_array_type (base_type, index_type);
488 static tree
489 add_field_decl (tree type, const char *name, tree **chain)
491 tree field = create_field_decl (type, name);
493 if (*chain != NULL)
494 **chain = field;
495 *chain = &DECL_CHAIN (field);
497 return field;
500 /* Some platforms pass small structures through registers versus
501 through an invisible pointer. Determine at what size structure is
502 the transition point between the two possibilities. */
504 static void
505 generate_struct_by_value_array (void)
507 tree type;
508 tree decls;
509 int i, j;
510 int aggregate_in_mem[32];
511 int found = 0;
513 /* Presumably no platform passes 32 byte structures in a register. */
514 for (i = 1; i < 32; i++)
516 char buffer[5];
517 tree *chain = NULL;
519 /* Create an unnamed struct that has `i' character components */
520 type = objc_start_struct (NULL_TREE);
522 strcpy (buffer, "c1");
523 decls = add_field_decl (char_type_node, buffer, &chain);
525 for (j = 1; j < i; j++)
527 sprintf (buffer, "c%d", j + 1);
528 add_field_decl (char_type_node, buffer, &chain);
530 objc_finish_struct (type, decls);
532 aggregate_in_mem[i] = aggregate_value_p (type, 0);
533 if (!aggregate_in_mem[i])
534 found = 1;
537 /* We found some structures that are returned in registers instead of memory
538 so output the necessary data. */
539 if (found)
541 for (i = 31; i >= 0; i--)
542 if (!aggregate_in_mem[i])
543 break;
544 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
546 /* The first member of the structure is always 0 because we don't handle
547 structures with 0 members */
548 printf ("static int struct_forward_array[] = {\n 0");
550 for (j = 1; j <= i; j++)
551 printf (", %d", aggregate_in_mem[j]);
552 printf ("\n};\n");
555 exit (0);
558 bool
559 objc_init (void)
561 #ifdef OBJCPLUS
562 if (cxx_init () == false)
563 #else
564 if (c_objc_common_init () == false)
565 #endif
566 return false;
568 /* If gen_declaration desired, open the output file. */
569 if (flag_gen_declaration)
571 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
572 gen_declaration_file = fopen (dumpname, "w");
573 if (gen_declaration_file == 0)
574 fatal_error ("can't open %s: %m", dumpname);
575 free (dumpname);
578 if (flag_next_runtime)
580 TAG_GETCLASS = "objc_getClass";
581 TAG_GETMETACLASS = "objc_getMetaClass";
582 TAG_MSGSEND = "objc_msgSend";
583 TAG_MSGSENDSUPER = "objc_msgSendSuper";
584 TAG_MSGSEND_STRET = "objc_msgSend_stret";
585 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
586 default_constant_string_class_name = "NSConstantString";
588 else
590 TAG_GETCLASS = "objc_get_class";
591 TAG_GETMETACLASS = "objc_get_meta_class";
592 TAG_MSGSEND = "objc_msg_lookup";
593 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
594 /* GNU runtime does not provide special functions to support
595 structure-returning methods. */
596 default_constant_string_class_name = "NXConstantString";
597 flag_typed_selectors = 1;
598 /* GNU runtime does not need the compiler to change code
599 in order to do GC. */
600 if (flag_objc_gc)
602 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
603 flag_objc_gc=0;
607 init_objc ();
609 if (print_struct_values && !flag_compare_debug)
610 generate_struct_by_value_array ();
612 return true;
615 /* This is called automatically (at the very end of compilation) by
616 c_write_global_declarations and cp_write_global_declarations. */
617 void
618 objc_write_global_declarations (void)
620 mark_referenced_methods ();
622 /* Finalize Objective-C runtime data. */
623 finish_objc ();
625 if (gen_declaration_file)
626 fclose (gen_declaration_file);
629 /* Return the first occurrence of a method declaration corresponding
630 to sel_name in rproto_list. Search rproto_list recursively.
631 If is_class is 0, search for instance methods, otherwise for class
632 methods. */
633 static tree
634 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
635 int is_class)
637 tree rproto, p;
638 tree fnd = 0;
640 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
642 p = TREE_VALUE (rproto);
644 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
646 if ((fnd = lookup_method (is_class
647 ? PROTOCOL_CLS_METHODS (p)
648 : PROTOCOL_NST_METHODS (p), sel_name)))
650 else if (PROTOCOL_LIST (p))
651 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
652 sel_name, is_class);
654 else
656 ; /* An identifier...if we could not find a protocol. */
659 if (fnd)
660 return fnd;
663 return 0;
666 static tree
667 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
669 tree rproto, p;
671 /* Make sure the protocol is supported by the object on the rhs. */
672 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
674 tree fnd = 0;
675 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
677 p = TREE_VALUE (rproto);
679 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
681 if (lproto == p)
682 fnd = lproto;
684 else if (PROTOCOL_LIST (p))
685 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
688 if (fnd)
689 return fnd;
692 else
694 ; /* An identifier...if we could not find a protocol. */
697 return 0;
700 void
701 objc_start_class_interface (tree klass, tree super_class,
702 tree protos, tree attributes)
704 if (attributes)
705 warning_at (input_location, OPT_Wattributes,
706 "class attributes are not available in this version"
707 " of the compiler, (ignored)");
708 objc_interface_context
709 = objc_ivar_context
710 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
711 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
714 void
715 objc_start_category_interface (tree klass, tree categ,
716 tree protos, tree attributes)
718 if (attributes)
719 warning_at (input_location, OPT_Wattributes,
720 "category attributes are not available in this version"
721 " of the compiler, (ignored)");
722 objc_interface_context
723 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
724 objc_ivar_chain
725 = continue_class (objc_interface_context);
728 void
729 objc_start_protocol (tree name, tree protos, tree attributes)
731 if (attributes)
732 warning_at (input_location, OPT_Wattributes,
733 "protocol attributes are not available in this version"
734 " of the compiler, (ignored)");
735 objc_interface_context
736 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
737 objc_method_optional_flag = false;
740 void
741 objc_continue_interface (void)
743 objc_ivar_chain
744 = continue_class (objc_interface_context);
747 void
748 objc_finish_interface (void)
750 finish_class (objc_interface_context);
751 objc_interface_context = NULL_TREE;
752 objc_method_optional_flag = false;
755 void
756 objc_start_class_implementation (tree klass, tree super_class)
758 objc_implementation_context
759 = objc_ivar_context
760 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
761 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
764 void
765 objc_start_category_implementation (tree klass, tree categ)
767 objc_implementation_context
768 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
769 objc_ivar_chain
770 = continue_class (objc_implementation_context);
773 void
774 objc_continue_implementation (void)
776 objc_ivar_chain
777 = continue_class (objc_implementation_context);
780 void
781 objc_finish_implementation (void)
783 #ifdef OBJCPLUS
784 if (flag_objc_call_cxx_cdtors)
785 objc_generate_cxx_cdtors ();
786 #endif
788 if (objc_implementation_context)
790 finish_class (objc_implementation_context);
791 objc_ivar_chain = NULL_TREE;
792 objc_implementation_context = NULL_TREE;
794 else
795 warning (0, "%<@end%> must appear in an @implementation context");
798 void
799 objc_set_visibility (objc_ivar_visibility_kind visibility)
801 if (visibility == OBJC_IVAR_VIS_PACKAGE)
802 warning (0, "%<@package%> presently has the same effect as %<@public%>");
803 objc_ivar_visibility = visibility;
806 void
807 objc_set_method_opt (bool optional)
809 objc_method_optional_flag = optional;
810 if (!objc_interface_context
811 || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
813 error ("@optional/@required is allowed in @protocol context only.");
814 objc_method_optional_flag = false;
818 /* This routine gathers property attribute information from the attribute
819 portion of a property declaration. */
821 void
822 objc_set_property_attr (location_t loc, objc_property_attribute_kind attr,
823 tree ident)
825 static char string[BUFSIZE];
826 switch (attr)
828 case OBJC_PATTR_INIT: /* init */
829 property_readonly = property_copies = false;
830 property_setter = property_getter = property_ivar = NULL_TREE;
831 break;
832 case OBJC_PATTR_READONLY: /* readonly */
833 property_readonly = true;
834 break;
835 case OBJC_PATTR_GETTER: /* getter = ident */
836 if (property_getter != NULL_TREE)
837 error_at (loc, "the %<getter%> attribute may only be specified once");
838 property_getter = ident;
839 break;
840 case OBJC_PATTR_SETTER: /* setter = ident */
841 if (property_setter != NULL_TREE)
842 error_at (loc, "the %<setter%> attribute may only be specified once");
843 /* setters always have a trailing ':' in their name. In fact, this is the
844 only syntax that parser recognizes for a setter name. Must add a trailing
845 ':' here so name matches that of the declaration of user instance method
846 for the setter. */
847 sprintf (string, "%s:", IDENTIFIER_POINTER (ident));
848 property_setter = get_identifier (string);;
849 break;
850 case OBJC_PATTR_IVAR: /* ivar = ident */
851 if (property_ivar != NULL_TREE)
852 error_at (loc, "the %<ivar%> attribute may only be specified once");
853 else if (objc_interface_context)
855 warning_at (loc, 0, "the %<ivar%> attribute is ignored in an @interface");
856 property_ivar = NULL_TREE;
858 else
859 property_ivar = ident;
860 break;
861 case OBJC_PATTR_COPIES: /* copies */
862 property_copies = true;
863 break;
864 default:
865 break;
869 /* This routine builds a 'property_decl' tree node and adds it to the list
870 of such properties in the current class. It also checks for duplicates.
873 void
874 objc_add_property_declaration (location_t location, tree decl)
876 tree property_decl;
877 tree x;
878 tree interface = NULL_TREE;
880 if (objc_implementation_context)
882 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
883 if (!interface)
885 error_at (location, "no class property can be implemented without an interface");
886 return;
888 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
890 interface = lookup_category (interface,
891 CLASS_SUPER_NAME (objc_implementation_context));
892 if (!interface)
894 error_at (location, "no category property can be implemented without an interface");
895 return;
899 else if (!objc_interface_context)
901 error_at (location, "property declaration not in @interface or @implementation context");
902 return;
905 property_decl = make_node (PROPERTY_DECL);
906 TREE_TYPE (property_decl) = TREE_TYPE (decl);
908 PROPERTY_NAME (property_decl) = DECL_NAME (decl);
909 PROPERTY_GETTER_NAME (property_decl) = property_getter;
910 PROPERTY_SETTER_NAME (property_decl) = property_setter;
911 PROPERTY_IVAR_NAME (property_decl) = property_ivar;
912 PROPERTY_READONLY (property_decl) = property_readonly
913 ? boolean_true_node
914 : boolean_false_node;
915 PROPERTY_COPIES (property_decl) = property_copies
916 ? boolean_true_node
917 : boolean_false_node;
919 if (objc_interface_context)
921 /* Doing the property in interface declaration. */
923 /* Issue error if property and an ivar name match. */
924 if (TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE
925 && is_ivar (CLASS_IVARS (objc_interface_context), DECL_NAME (decl)))
926 error_at (location, "property %qD may not have the same name as an ivar in the class", decl);
927 /* must check for duplicate property declarations. */
928 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
930 if (PROPERTY_NAME (x) == DECL_NAME (decl))
932 error_at (location, "duplicate property declaration %qD", decl);
933 return;
936 TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
937 CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
939 else
941 /* Doing the property in implementation context. */
942 /* If property is not declared in the interface issue error. */
943 for (x = CLASS_PROPERTY_DECL (interface); x; x = TREE_CHAIN (x))
944 if (PROPERTY_NAME (x) == DECL_NAME (decl))
945 break;
946 if (!x)
948 error_at (location, "no declaration of property %qD found in the interface", decl);
949 return;
951 /* readonlys must also match. */
952 if (PROPERTY_READONLY (x) != PROPERTY_READONLY (property_decl))
954 error_at (location, "property %qD %<readonly%> attribute conflicts with its"
955 " interface version", decl);
957 /* copies must also match. */
958 if (PROPERTY_COPIES (x) != PROPERTY_COPIES (property_decl))
960 error_at (location, "property %qD %<copies%> attribute conflicts with its"
961 " interface version", decl);
963 /* Cannot have readonly and setter attribute for the same property. */
964 if (PROPERTY_READONLY (property_decl) == boolean_true_node &&
965 PROPERTY_SETTER_NAME (property_decl))
967 warning_at (location, 0, "a %<readonly%> property cannot have a setter (ignored)");
968 PROPERTY_SETTER_NAME (property_decl) = NULL_TREE;
970 /* Add the property to the list of properties for current implementation. */
971 TREE_CHAIN (property_decl) = IMPL_PROPERTY_DECL (objc_implementation_context);
972 IMPL_PROPERTY_DECL (objc_implementation_context) = property_decl;
976 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
977 PROTOCOL.
979 static tree
980 lookup_property_in_list (tree chain, tree property)
982 tree x;
983 for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
984 if (PROPERTY_NAME (x) == property)
985 return x;
986 return NULL_TREE;
989 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
991 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
993 tree rproto, x;
994 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
996 tree p = TREE_VALUE (rproto);
997 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
999 if ((x = lookup_property_in_list (p, property)))
1000 return x;
1001 if (PROTOCOL_LIST (p))
1002 return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
1004 else
1006 ; /* An identifier...if we could not find a protocol. */
1009 return NULL_TREE;
1012 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1013 chain of interface hierarchy.
1015 static tree
1016 lookup_property (tree interface_type, tree property)
1018 tree inter = interface_type;
1019 while (inter)
1021 tree x, category;
1022 if ((x = lookup_property_in_list (inter, property)))
1023 return x;
1024 /* Failing that, look for the property in each category of the class. */
1025 category = inter;
1026 while ((category = CLASS_CATEGORY_LIST (category)))
1027 if ((x = lookup_property_in_list (category, property)))
1028 return x;
1030 /* Failing to find in categories, look for property in protocol list. */
1031 if (CLASS_PROTOCOL_LIST (inter)
1032 && (x = lookup_property_in_protocol_list (
1033 CLASS_PROTOCOL_LIST (inter), property)))
1034 return x;
1036 /* Failing that, climb up the inheritance hierarchy. */
1037 inter = lookup_interface (CLASS_SUPER_NAME (inter));
1039 return inter;
1042 /* This routine recognizes a dot-notation for a propery reference and generates a call to
1043 the getter function for this property. In all other cases, it returns a NULL_TREE.
1046 tree
1047 objc_build_getter_call (tree receiver, tree component)
1049 tree x = NULL_TREE;
1050 tree rtype;
1052 if (receiver == NULL_TREE
1053 || receiver == error_mark_node
1054 || (rtype = TREE_TYPE (receiver)) == NULL_TREE)
1055 return NULL_TREE;
1057 if (component == NULL_TREE
1058 || component == error_mark_node
1059 || TREE_CODE (component) != IDENTIFIER_NODE)
1060 return NULL_TREE;
1062 if (objc_is_id (rtype))
1064 tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
1065 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
1066 : NULL_TREE);
1067 if (rprotos)
1068 x = lookup_property_in_protocol_list (rprotos, component);
1070 else
1072 tree basetype = TYPE_MAIN_VARIANT (rtype);
1074 if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1075 basetype = TREE_TYPE (basetype);
1076 else
1077 return NULL_TREE;
1079 while (basetype != NULL_TREE
1080 && TREE_CODE (basetype) == RECORD_TYPE
1081 && OBJC_TYPE_NAME (basetype)
1082 && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1083 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1084 basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1086 if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1088 tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1089 if (!interface_type)
1090 return NULL_TREE;
1091 x = lookup_property (interface_type, component);
1095 if (x)
1097 tree call_exp, getter;
1098 /* Get the getter name. */
1099 gcc_assert (PROPERTY_NAME (x));
1100 getter = objc_finish_message_expr (receiver, PROPERTY_NAME (x),
1101 NULL_TREE);
1102 call_exp = getter;
1103 #ifdef OBJCPLUS
1104 /* In C++, a getter which returns an aggregate value results in a
1105 target_expr which initializes a temporary to the call expression. */
1106 if (TREE_CODE (getter) == TARGET_EXPR)
1108 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
1109 gcc_assert (TREE_CODE (TREE_OPERAND (getter,0)) == VAR_DECL);
1110 call_exp = TREE_OPERAND (getter,1);
1112 #endif
1113 gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
1115 CALL_EXPR_OBJC_PROPERTY_GETTER (call_exp) = 1;
1116 return getter;
1118 return NULL_TREE;
1121 /* This routine builds a call to property's 'setter' function. RECEIVER is the
1122 receiving object for 'setter'. PROPERTY_IDENT is name of the property and
1123 RHS is the argument passed to the 'setter' function. */
1125 static tree
1126 objc_setter_func_call (tree receiver, tree property_ident, tree rhs)
1128 tree setter_argument = build_tree_list (NULL_TREE, rhs);
1129 char *setter_name = objc_build_property_setter_name (property_ident, true);
1130 tree setter;
1131 in_objc_property_setter_name_context = true;
1132 setter = objc_finish_message_expr (receiver, get_identifier (setter_name),
1133 setter_argument);
1134 in_objc_property_setter_name_context = false;
1135 return setter;
1138 /* Find the selector identifier from a reference. A somewhat tortuous way of
1139 obtaining the information to allow a setter to be written, given an
1140 existing getter. */
1142 static tree
1143 get_selector_from_reference (tree selref)
1145 tree chain;
1147 if (flag_next_runtime)
1149 /* Run through the selectors until we find the one we're looking for. */
1150 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1151 if (TREE_PURPOSE (chain) == selref)
1152 return TREE_VALUE (chain);
1154 else
1156 /* To find our way back to the selector for the GNU runtime is harder
1157 work, we need to decompose the representation of SELECTOR_TABLE[n]
1158 to find 'n'. This representation is in several forms. */
1159 if (TREE_CODE (selref) == POINTER_PLUS_EXPR)
1161 /* We need the element size to decode the array offset expression
1162 into an index. */
1163 unsigned size = (unsigned) TREE_INT_CST_LOW
1164 (TYPE_SIZE_UNIT
1165 (TREE_TYPE
1166 (TREE_TYPE
1167 (TREE_OPERAND
1168 (TREE_OPERAND
1169 (TREE_OPERAND (selref, 0), 0), 0)))));
1170 unsigned index =
1171 (unsigned) TREE_INT_CST_LOW (TREE_OPERAND (selref, 1))
1172 / size;
1173 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1174 if (!index--)
1175 return TREE_VALUE (chain);
1177 else if (TREE_CODE (selref) == NOP_EXPR)
1179 /* Either we have a base an index, or we have just a base (when the
1180 index is 0. */
1181 if (TREE_CODE (TREE_OPERAND (selref, 0)) == ADDR_EXPR
1182 && TREE_CODE
1183 (TREE_OPERAND
1184 (TREE_OPERAND (selref, 0), 0)) == ARRAY_REF)
1186 /* The Nth. */
1187 unsigned index = (unsigned) TREE_INT_CST_LOW
1188 (TREE_OPERAND
1189 (TREE_OPERAND
1190 (TREE_OPERAND (selref, 0), 0), 1));
1191 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1192 if (!index--)
1193 return TREE_VALUE (chain);
1195 else
1196 return TREE_VALUE (sel_ref_chain);
1197 } /* Else we don't know how to figure this out - which will produce a
1198 parse error - saying that the LHS is not writeable. */
1200 return NULL_TREE;
1203 /* This routine converts a previously synthesized 'getter' function call for
1204 a property and converts it to a 'setter' function call for the same
1205 property. */
1207 tree
1208 objc_build_setter_call (tree lhs, tree rhs)
1210 if (lhs
1211 && TREE_CODE (lhs) == CALL_EXPR
1212 && CALL_EXPR_OBJC_PROPERTY_GETTER (lhs))
1214 tree selector;
1215 /* Get the Object. */
1216 tree receiver = TREE_OPERAND (lhs, 3);
1217 /* Get the selector reference. */
1218 tree selector_reference = TREE_OPERAND (lhs, 4);
1219 gcc_assert (receiver && selector_reference);
1220 /* The style of the selector reference is different for GNU & NeXT. */
1221 selector = get_selector_from_reference (selector_reference);
1222 if (selector)
1223 return objc_setter_func_call (receiver, selector, rhs);
1225 return NULL_TREE;
1228 /* This routine checks to see if ID is a property name. If so, it
1229 returns property declaration. */
1231 static tree
1232 is_property (tree klass, tree id)
1234 tree x;
1236 for (x = CLASS_PROPERTY_DECL (klass); x; x = TREE_CHAIN (x))
1237 if (PROPERTY_NAME (x) == id)
1238 return x;
1239 return NULL_TREE;
1242 /* This routine returns call to property's getter when a property is
1243 used stand-alone (without self. notation). */
1245 static tree
1246 build_property_reference (tree property, tree id)
1248 tree getter;
1249 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
1251 error ("property %qs accessed in class method",
1252 IDENTIFIER_POINTER (id));
1253 return error_mark_node;
1256 getter = objc_finish_message_expr (self_decl, PROPERTY_NAME (property), NULL_TREE);
1257 CALL_EXPR_OBJC_PROPERTY_GETTER (getter) = 1;
1258 return getter;
1261 tree
1262 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1263 tree optparms, bool ellipsis)
1265 if (is_class_method)
1266 return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
1267 optparms, ellipsis);
1268 else
1269 return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
1270 optparms, ellipsis);
1273 void
1274 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
1276 if (!objc_interface_context)
1278 /* PS: At the moment, due to how the parser works, it should be
1279 impossible to get here. But it's good to have the check in
1280 case the parser changes.
1282 fatal_error ("method declaration not in @interface context");
1285 objc_decl_method_attributes (&decl, attributes, 0);
1286 objc_add_method (objc_interface_context,
1287 decl,
1288 is_class_method,
1289 objc_method_optional_flag);
1292 /* Return 'true' if the method definition could be started, and
1293 'false' if not (because we are outside an @implementation context).
1295 bool
1296 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
1298 if (!objc_implementation_context)
1300 error ("method definition not in @implementation context");
1301 return false;
1304 if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node)
1305 return false;
1307 #ifndef OBJCPLUS
1308 /* Indicate no valid break/continue context by setting these variables
1309 to some non-null, non-label value. We'll notice and emit the proper
1310 error message in c_finish_bc_stmt. */
1311 c_break_label = c_cont_label = size_zero_node;
1312 #endif
1314 objc_decl_method_attributes (&decl, attributes, 0);
1315 objc_add_method (objc_implementation_context,
1316 decl,
1317 is_class_method,
1318 /* is optional */ false);
1319 start_method_def (decl);
1320 return true;
1323 void
1324 objc_add_instance_variable (tree decl)
1326 (void) add_instance_variable (objc_ivar_context,
1327 objc_ivar_visibility,
1328 decl);
1331 /* Return true if TYPE is 'id'. */
1333 static bool
1334 objc_is_object_id (tree type)
1336 return OBJC_TYPE_NAME (type) == objc_object_id;
1339 static bool
1340 objc_is_class_id (tree type)
1342 return OBJC_TYPE_NAME (type) == objc_class_id;
1345 /* Construct a C struct with same name as KLASS, a base struct with tag
1346 SUPER_NAME (if any), and FIELDS indicated. */
1348 static tree
1349 objc_build_struct (tree klass, tree fields, tree super_name)
1351 tree name = CLASS_NAME (klass);
1352 tree s = objc_start_struct (name);
1353 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
1354 tree t;
1355 VEC(tree,heap) *objc_info = NULL;
1356 int i;
1358 if (super)
1360 /* Prepend a packed variant of the base class into the layout. This
1361 is necessary to preserve ObjC ABI compatibility. */
1362 tree base = build_decl (input_location,
1363 FIELD_DECL, NULL_TREE, super);
1364 tree field = TYPE_FIELDS (super);
1366 while (field && DECL_CHAIN (field)
1367 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
1368 field = DECL_CHAIN (field);
1370 /* For ObjC ABI purposes, the "packed" size of a base class is
1371 the sum of the offset and the size (in bits) of the last field
1372 in the class. */
1373 DECL_SIZE (base)
1374 = (field && TREE_CODE (field) == FIELD_DECL
1375 ? size_binop (PLUS_EXPR,
1376 size_binop (PLUS_EXPR,
1377 size_binop
1378 (MULT_EXPR,
1379 convert (bitsizetype,
1380 DECL_FIELD_OFFSET (field)),
1381 bitsize_int (BITS_PER_UNIT)),
1382 DECL_FIELD_BIT_OFFSET (field)),
1383 DECL_SIZE (field))
1384 : bitsize_zero_node);
1385 DECL_SIZE_UNIT (base)
1386 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
1387 size_int (BITS_PER_UNIT));
1388 DECL_ARTIFICIAL (base) = 1;
1389 DECL_ALIGN (base) = 1;
1390 DECL_FIELD_CONTEXT (base) = s;
1391 #ifdef OBJCPLUS
1392 DECL_FIELD_IS_BASE (base) = 1;
1394 if (fields)
1395 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
1396 #endif /* are following the ObjC ABI here. */
1397 DECL_CHAIN (base) = fields;
1398 fields = base;
1401 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1402 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1403 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1404 Hence, we must squirrel away the ObjC-specific information before calling
1405 finish_struct(), and then reinstate it afterwards. */
1407 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
1409 if (!TYPE_HAS_OBJC_INFO (t))
1411 INIT_TYPE_OBJC_INFO (t);
1412 TYPE_OBJC_INTERFACE (t) = klass;
1414 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
1417 /* Point the struct at its related Objective-C class. */
1418 INIT_TYPE_OBJC_INFO (s);
1419 TYPE_OBJC_INTERFACE (s) = klass;
1421 s = objc_finish_struct (s, fields);
1423 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
1425 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
1426 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1427 TYPE_OBJC_INTERFACE (t) = klass;
1429 VEC_free (tree, heap, objc_info);
1431 /* Use TYPE_BINFO structures to point at the super class, if any. */
1432 objc_xref_basetypes (s, super);
1434 /* Mark this struct as a class template. */
1435 CLASS_STATIC_TEMPLATE (klass) = s;
1437 return s;
1440 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1441 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1442 process. */
1443 static tree
1444 objc_build_volatilized_type (tree type)
1446 tree t;
1448 /* Check if we have not constructed the desired variant already. */
1449 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1451 /* The type qualifiers must (obviously) match up. */
1452 if (!TYPE_VOLATILE (t)
1453 || (TYPE_READONLY (t) != TYPE_READONLY (type))
1454 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
1455 continue;
1457 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1458 info, if any) must match up. */
1459 if (POINTER_TYPE_P (t)
1460 && (TREE_TYPE (t) != TREE_TYPE (type)))
1461 continue;
1463 /* Only match up the types which were previously volatilized in similar fashion and not
1464 because they were declared as such. */
1465 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
1466 continue;
1468 /* Everything matches up! */
1469 return t;
1472 /* Ok, we could not re-use any of the pre-existing variants. Create
1473 a new one. */
1474 t = build_variant_type_copy (type);
1475 TYPE_VOLATILE (t) = 1;
1477 TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
1478 tree_cons (get_identifier ("objc_volatilized"),
1479 NULL_TREE,
1480 NULL_TREE));
1481 if (TREE_CODE (t) == ARRAY_TYPE)
1482 TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
1484 /* Set up the canonical type information. */
1485 if (TYPE_STRUCTURAL_EQUALITY_P (type))
1486 SET_TYPE_STRUCTURAL_EQUALITY (t);
1487 else if (TYPE_CANONICAL (type) != type)
1488 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
1489 else
1490 TYPE_CANONICAL (t) = t;
1492 return t;
1495 /* Mark DECL as being 'volatile' for purposes of Darwin
1496 _setjmp()/_longjmp() exception handling. Called from
1497 objc_mark_locals_volatile(). */
1498 void
1499 objc_volatilize_decl (tree decl)
1501 /* Do not mess with variables that are 'static' or (already)
1502 'volatile'. */
1503 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
1504 && (TREE_CODE (decl) == VAR_DECL
1505 || TREE_CODE (decl) == PARM_DECL))
1507 tree t = TREE_TYPE (decl);
1509 t = objc_build_volatilized_type (t);
1511 TREE_TYPE (decl) = t;
1512 TREE_THIS_VOLATILE (decl) = 1;
1513 TREE_SIDE_EFFECTS (decl) = 1;
1514 DECL_REGISTER (decl) = 0;
1515 #ifndef OBJCPLUS
1516 C_DECL_REGISTER (decl) = 0;
1517 #endif
1521 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1522 (including its categories and superclasses) or by object type TYP.
1523 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1525 static bool
1526 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
1528 bool class_type = (cls != NULL_TREE);
1530 while (cls)
1532 tree c;
1534 /* Check protocols adopted by the class and its categories. */
1535 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1537 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1538 return true;
1541 /* Repeat for superclasses. */
1542 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1545 /* Check for any protocols attached directly to the object type. */
1546 if (TYPE_HAS_OBJC_INFO (typ))
1548 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1549 return true;
1552 if (warn)
1554 *errbuf = 0;
1555 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1556 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1557 "implementing" a given protocol, since they do not have an
1558 implementation. */
1559 if (class_type)
1560 warning (0, "class %qs does not implement the %qE protocol",
1561 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1562 else
1563 warning (0, "type %qs does not conform to the %qE protocol",
1564 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1567 return false;
1570 /* Check if class RCLS and instance struct type RTYP conform to at least the
1571 same protocols that LCLS and LTYP conform to. */
1573 static bool
1574 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1576 tree p;
1577 bool have_lproto = false;
1579 while (lcls)
1581 /* NB: We do _not_ look at categories defined for LCLS; these may or
1582 may not get loaded in, and therefore it is unreasonable to require
1583 that RCLS/RTYP must implement any of their protocols. */
1584 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1586 have_lproto = true;
1588 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1589 return warn;
1592 /* Repeat for superclasses. */
1593 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1596 /* Check for any protocols attached directly to the object type. */
1597 if (TYPE_HAS_OBJC_INFO (ltyp))
1599 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1601 have_lproto = true;
1603 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1604 return warn;
1608 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1609 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1610 away with simply checking for 'id' or 'Class' (!RCLS), since this
1611 routine will not get called in other cases. */
1612 return have_lproto || (rcls != NULL_TREE);
1615 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1616 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1617 compatible by objc_compare_types() below. */
1619 tree
1620 objc_common_type (tree type1, tree type2)
1622 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
1624 while (POINTER_TYPE_P (inner1))
1626 inner1 = TREE_TYPE (inner1);
1627 inner2 = TREE_TYPE (inner2);
1630 /* If one type is derived from another, return the base type. */
1631 if (DERIVED_FROM_P (inner1, inner2))
1632 return type1;
1633 else if (DERIVED_FROM_P (inner2, inner1))
1634 return type2;
1636 /* If both types are 'Class', return 'Class'. */
1637 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
1638 return objc_class_type;
1640 /* Otherwise, return 'id'. */
1641 return objc_object_type;
1644 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1645 an instance of RTYP to an instance of LTYP or to compare the two
1646 (if ARGNO is equal to -3), per ObjC type system rules. Before
1647 returning 'true', this routine may issue warnings related to, e.g.,
1648 protocol conformance. When returning 'false', the routine must
1649 produce absolutely no warnings; the C or C++ front-end will do so
1650 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1651 the routine must return 'false'.
1653 The ARGNO parameter is encoded as follows:
1654 >= 1 Parameter number (CALLEE contains function being called);
1655 0 Return value;
1656 -1 Assignment;
1657 -2 Initialization;
1658 -3 Comparison (LTYP and RTYP may match in either direction);
1659 -4 Silent comparison (for C++ overload resolution).
1662 bool
1663 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1665 tree lcls, rcls, lproto, rproto;
1666 bool pointers_compatible;
1668 /* We must be dealing with pointer types */
1669 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1670 return false;
1674 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1675 rtyp = TREE_TYPE (rtyp);
1677 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1679 /* We must also handle function pointers, since ObjC is a bit more
1680 lenient than C or C++ on this. */
1681 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
1683 /* Return types must be covariant. */
1684 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
1685 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
1686 argno, callee))
1687 return false;
1689 /* Argument types must be contravariant. */
1690 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
1691 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
1693 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
1694 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
1695 argno, callee))
1696 return false;
1699 return (ltyp == rtyp);
1702 /* Past this point, we are only interested in ObjC class instances,
1703 or 'id' or 'Class'. */
1704 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1705 return false;
1707 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1708 && !TYPE_HAS_OBJC_INFO (ltyp))
1709 return false;
1711 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1712 && !TYPE_HAS_OBJC_INFO (rtyp))
1713 return false;
1715 /* Past this point, we are committed to returning 'true' to the caller
1716 (unless performing a silent comparison; see below). However, we can
1717 still warn about type and/or protocol mismatches. */
1719 if (TYPE_HAS_OBJC_INFO (ltyp))
1721 lcls = TYPE_OBJC_INTERFACE (ltyp);
1722 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1724 else
1725 lcls = lproto = NULL_TREE;
1727 if (TYPE_HAS_OBJC_INFO (rtyp))
1729 rcls = TYPE_OBJC_INTERFACE (rtyp);
1730 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1732 else
1733 rcls = rproto = NULL_TREE;
1735 /* If we could not find an @interface declaration, we must have
1736 only seen a @class declaration; for purposes of type comparison,
1737 treat it as a stand-alone (root) class. */
1739 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1740 lcls = NULL_TREE;
1742 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1743 rcls = NULL_TREE;
1745 /* If either type is an unqualified 'id', we're done. */
1746 if ((!lproto && objc_is_object_id (ltyp))
1747 || (!rproto && objc_is_object_id (rtyp)))
1748 return true;
1750 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1752 /* If the underlying types are the same, and at most one of them has
1753 a protocol list, we do not need to issue any diagnostics. */
1754 if (pointers_compatible && (!lproto || !rproto))
1755 return true;
1757 /* If exactly one of the types is 'Class', issue a diagnostic; any
1758 exceptions of this rule have already been handled. */
1759 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1760 pointers_compatible = false;
1761 /* Otherwise, check for inheritance relations. */
1762 else
1764 if (!pointers_compatible)
1765 pointers_compatible
1766 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1768 if (!pointers_compatible)
1769 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1771 if (!pointers_compatible && argno <= -3)
1772 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1775 /* If the pointers match modulo protocols, check for protocol conformance
1776 mismatches. */
1777 if (pointers_compatible)
1779 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1780 argno != -3);
1782 if (!pointers_compatible && argno == -3)
1783 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1784 argno != -3);
1787 if (!pointers_compatible)
1789 /* The two pointers are not exactly compatible. Issue a warning, unless
1790 we are performing a silent comparison, in which case return 'false'
1791 instead. */
1792 /* NB: For the time being, we shall make our warnings look like their
1793 C counterparts. In the future, we may wish to make them more
1794 ObjC-specific. */
1795 switch (argno)
1797 case -4:
1798 return false;
1800 case -3:
1801 warning (0, "comparison of distinct Objective-C types lacks a cast");
1802 break;
1804 case -2:
1805 warning (0, "initialization from distinct Objective-C type");
1806 break;
1808 case -1:
1809 warning (0, "assignment from distinct Objective-C type");
1810 break;
1812 case 0:
1813 warning (0, "distinct Objective-C type in return");
1814 break;
1816 default:
1817 warning (0, "passing argument %d of %qE from distinct "
1818 "Objective-C type", argno, callee);
1819 break;
1823 return true;
1826 /* This routine is similar to objc_compare_types except that function-pointers are
1827 excluded. This is because, caller assumes that common types are of (id, Object*)
1828 variety and calls objc_common_type to obtain a common type. There is no commonolty
1829 between two function-pointers in this regard. */
1831 bool
1832 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
1834 if (objc_compare_types (ltyp, rtyp, argno, callee))
1836 /* exclude function-pointer types. */
1839 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1840 rtyp = TREE_TYPE (rtyp);
1842 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1843 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
1845 return false;
1848 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1849 lives in the volatilized hash table, ignore the 'volatile' bit when
1850 making the comparison. */
1852 bool
1853 objc_type_quals_match (tree ltyp, tree rtyp)
1855 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1857 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
1858 lquals &= ~TYPE_QUAL_VOLATILE;
1860 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
1861 rquals &= ~TYPE_QUAL_VOLATILE;
1863 return (lquals == rquals);
1866 #ifndef OBJCPLUS
1867 /* Determine if CHILD is derived from PARENT. The routine assumes that
1868 both parameters are RECORD_TYPEs, and is non-reflexive. */
1870 static bool
1871 objc_derived_from_p (tree parent, tree child)
1873 parent = TYPE_MAIN_VARIANT (parent);
1875 for (child = TYPE_MAIN_VARIANT (child);
1876 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1878 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1879 (TYPE_BINFO (child),
1880 0)));
1882 if (child == parent)
1883 return true;
1886 return false;
1888 #endif
1890 static tree
1891 objc_build_component_ref (tree datum, tree component)
1893 /* If COMPONENT is NULL, the caller is referring to the anonymous
1894 base class field. */
1895 if (!component)
1897 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1899 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1902 /* The 'build_component_ref' routine has been removed from the C++
1903 front-end, but 'finish_class_member_access_expr' seems to be
1904 a worthy substitute. */
1905 #ifdef OBJCPLUS
1906 return finish_class_member_access_expr (datum, component, false,
1907 tf_warning_or_error);
1908 #else
1909 return build_component_ref (input_location, datum, component);
1910 #endif
1913 /* Recursively copy inheritance information rooted at BINFO. To do this,
1914 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1916 static tree
1917 objc_copy_binfo (tree binfo)
1919 tree btype = BINFO_TYPE (binfo);
1920 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1921 tree base_binfo;
1922 int ix;
1924 BINFO_TYPE (binfo2) = btype;
1925 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1926 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1928 /* Recursively copy base binfos of BINFO. */
1929 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1931 tree base_binfo2 = objc_copy_binfo (base_binfo);
1933 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1934 BINFO_BASE_APPEND (binfo2, base_binfo2);
1937 return binfo2;
1940 /* Record superclass information provided in BASETYPE for ObjC class REF.
1941 This is loosely based on cp/decl.c:xref_basetypes(). */
1943 static void
1944 objc_xref_basetypes (tree ref, tree basetype)
1946 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1948 TYPE_BINFO (ref) = binfo;
1949 BINFO_OFFSET (binfo) = size_zero_node;
1950 BINFO_TYPE (binfo) = ref;
1952 if (basetype)
1954 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1956 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1957 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1958 BINFO_BASE_APPEND (binfo, base_binfo);
1959 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1963 /* Called from finish_decl. */
1965 void
1966 objc_check_decl (tree decl)
1968 tree type = TREE_TYPE (decl);
1970 if (TREE_CODE (type) != RECORD_TYPE)
1971 return;
1972 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1973 error ("statically allocated instance of Objective-C class %qE",
1974 type);
1977 void
1978 objc_check_global_decl (tree decl)
1980 tree id = DECL_NAME (decl);
1981 if (objc_is_class_name (id) && global_bindings_p())
1982 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
1985 /* Return a non-volatalized version of TYPE. */
1987 tree
1988 objc_non_volatilized_type (tree type)
1990 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
1991 type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
1992 return type;
1995 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1996 either name an Objective-C class, or refer to the special 'id' or 'Class'
1997 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1999 tree
2000 objc_get_protocol_qualified_type (tree interface, tree protocols)
2002 /* If INTERFACE is not provided, default to 'id'. */
2003 tree type = (interface ? objc_is_id (interface) : objc_object_type);
2004 bool is_ptr = (type != NULL_TREE);
2006 if (!is_ptr)
2008 type = objc_is_class_name (interface);
2010 if (type)
2012 /* If looking at a typedef, retrieve the precise type it
2013 describes. */
2014 if (TREE_CODE (interface) == IDENTIFIER_NODE)
2015 interface = identifier_global_value (interface);
2017 type = ((interface && TREE_CODE (interface) == TYPE_DECL
2018 && DECL_ORIGINAL_TYPE (interface))
2019 ? DECL_ORIGINAL_TYPE (interface)
2020 : xref_tag (RECORD_TYPE, type));
2022 else
2023 return interface;
2026 if (protocols)
2028 type = build_variant_type_copy (type);
2030 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2031 to the pointee. */
2032 if (is_ptr)
2034 tree orig_pointee_type = TREE_TYPE (type);
2035 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2037 /* Set up the canonical type information. */
2038 TYPE_CANONICAL (type)
2039 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2041 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2042 type = TREE_TYPE (type);
2045 /* Look up protocols and install in lang specific list. */
2046 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2047 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2049 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2050 return the pointer to the new pointee variant. */
2051 if (is_ptr)
2052 type = TYPE_POINTER_TO (type);
2053 else
2054 TYPE_OBJC_INTERFACE (type)
2055 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2058 return type;
2061 /* Check for circular dependencies in protocols. The arguments are
2062 PROTO, the protocol to check, and LIST, a list of protocol it
2063 conforms to. */
2065 static void
2066 check_protocol_recursively (tree proto, tree list)
2068 tree p;
2070 for (p = list; p; p = TREE_CHAIN (p))
2072 tree pp = TREE_VALUE (p);
2074 if (TREE_CODE (pp) == IDENTIFIER_NODE)
2075 pp = lookup_protocol (pp);
2077 if (pp == proto)
2078 fatal_error ("protocol %qE has circular dependency",
2079 PROTOCOL_NAME (pp));
2080 if (pp)
2081 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2085 /* Look up PROTOCOLS, and return a list of those that are found.
2086 If none are found, return NULL. */
2088 static tree
2089 lookup_and_install_protocols (tree protocols)
2091 tree proto;
2092 tree return_value = NULL_TREE;
2094 if (protocols == error_mark_node)
2095 return NULL;
2097 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2099 tree ident = TREE_VALUE (proto);
2100 tree p = lookup_protocol (ident);
2102 if (p)
2103 return_value = chainon (return_value,
2104 build_tree_list (NULL_TREE, p));
2105 else if (ident != error_mark_node)
2106 error ("cannot find protocol declaration for %qE",
2107 ident);
2110 return return_value;
2113 /* Create a declaration for field NAME of a given TYPE. */
2115 static tree
2116 create_field_decl (tree type, const char *name)
2118 return build_decl (input_location,
2119 FIELD_DECL, get_identifier (name), type);
2122 /* Create a global, static declaration for variable NAME of a given TYPE. The
2123 finish_var_decl() routine will need to be called on it afterwards. */
2125 static tree
2126 start_var_decl (tree type, const char *name)
2128 tree var = build_decl (input_location,
2129 VAR_DECL, get_identifier (name), type);
2131 TREE_STATIC (var) = 1;
2132 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
2133 DECL_IGNORED_P (var) = 1;
2134 DECL_ARTIFICIAL (var) = 1;
2135 DECL_CONTEXT (var) = NULL_TREE;
2136 #ifdef OBJCPLUS
2137 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2138 #endif
2140 return var;
2143 /* Finish off the variable declaration created by start_var_decl(). */
2145 static void
2146 finish_var_decl (tree var, tree initializer)
2148 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2151 /* Find the decl for the constant string class reference. This is only
2152 used for the NeXT runtime. */
2154 static tree
2155 setup_string_decl (void)
2157 char *name;
2158 size_t length;
2160 /* %s in format will provide room for terminating null */
2161 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2162 + strlen (constant_string_class_name);
2163 name = XNEWVEC (char, length);
2164 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2165 constant_string_class_name);
2166 constant_string_global_id = get_identifier (name);
2167 string_class_decl = lookup_name (constant_string_global_id);
2169 return string_class_decl;
2172 /* Purpose: "play" parser, creating/installing representations
2173 of the declarations that are required by Objective-C.
2175 Model:
2177 type_spec--------->sc_spec
2178 (tree_list) (tree_list)
2181 identifier_node identifier_node */
2183 static void
2184 synth_module_prologue (void)
2186 tree type;
2187 enum debug_info_type save_write_symbols = write_symbols;
2188 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2190 /* Suppress outputting debug symbols, because
2191 dbxout_init hasn't been called yet. */
2192 write_symbols = NO_DEBUG;
2193 debug_hooks = &do_nothing_debug_hooks;
2195 #ifdef OBJCPLUS
2196 push_lang_context (lang_name_c); /* extern "C" */
2197 #endif
2199 /* The following are also defined in <objc/objc.h> and friends. */
2201 objc_object_id = get_identifier (TAG_OBJECT);
2202 objc_class_id = get_identifier (TAG_CLASS);
2204 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2205 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2207 objc_object_type = build_pointer_type (objc_object_reference);
2208 objc_class_type = build_pointer_type (objc_class_reference);
2210 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2211 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2213 /* Declare the 'id' and 'Class' typedefs. */
2215 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2216 TYPE_DECL,
2217 objc_object_name,
2218 objc_object_type));
2219 TREE_NO_WARNING (type) = 1;
2220 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2221 TYPE_DECL,
2222 objc_class_name,
2223 objc_class_type));
2224 TREE_NO_WARNING (type) = 1;
2226 /* Forward-declare '@interface Protocol'. */
2228 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
2229 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
2230 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
2231 type));
2233 /* Declare type of selector-objects that represent an operation name. */
2235 if (flag_next_runtime)
2236 /* `struct objc_selector *' */
2237 objc_selector_type
2238 = build_pointer_type (xref_tag (RECORD_TYPE,
2239 get_identifier (TAG_SELECTOR)));
2240 else
2241 /* `const struct objc_selector *' */
2242 objc_selector_type
2243 = build_pointer_type
2244 (build_qualified_type (xref_tag (RECORD_TYPE,
2245 get_identifier (TAG_SELECTOR)),
2246 TYPE_QUAL_CONST));
2248 /* Declare receiver type used for dispatching messages to 'super'. */
2250 /* `struct objc_super *' */
2251 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
2252 get_identifier (TAG_SUPER)));
2254 /* Declare pointers to method and ivar lists. */
2255 objc_method_list_ptr = build_pointer_type
2256 (xref_tag (RECORD_TYPE,
2257 get_identifier (UTAG_METHOD_LIST)));
2258 objc_method_proto_list_ptr
2259 = build_pointer_type (xref_tag (RECORD_TYPE,
2260 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2261 objc_ivar_list_ptr = build_pointer_type
2262 (xref_tag (RECORD_TYPE,
2263 get_identifier (UTAG_IVAR_LIST)));
2265 /* TREE_NOTHROW is cleared for the message-sending functions,
2266 because the function that gets called can throw in Obj-C++, or
2267 could itself call something that can throw even in Obj-C. */
2269 if (flag_next_runtime)
2271 /* NB: In order to call one of the ..._stret (struct-returning)
2272 functions, the function *MUST* first be cast to a signature that
2273 corresponds to the actual ObjC method being invoked. This is
2274 what is done by the build_objc_method_call() routine below. */
2276 /* id objc_msgSend (id, SEL, ...); */
2277 /* id objc_msgSendNonNil (id, SEL, ...); */
2278 /* id objc_msgSend_stret (id, SEL, ...); */
2279 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2280 type
2281 = build_varargs_function_type_list (objc_object_type,
2282 objc_object_type,
2283 objc_selector_type,
2284 NULL_TREE);
2285 umsg_decl = add_builtin_function (TAG_MSGSEND,
2286 type, 0, NOT_BUILT_IN,
2287 NULL, NULL_TREE);
2288 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
2289 type, 0, NOT_BUILT_IN,
2290 NULL, NULL_TREE);
2291 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
2292 type, 0, NOT_BUILT_IN,
2293 NULL, NULL_TREE);
2294 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
2295 type, 0, NOT_BUILT_IN,
2296 NULL, NULL_TREE);
2298 /* These can throw, because the function that gets called can throw
2299 in Obj-C++, or could itself call something that can throw even
2300 in Obj-C. */
2301 TREE_NOTHROW (umsg_decl) = 0;
2302 TREE_NOTHROW (umsg_nonnil_decl) = 0;
2303 TREE_NOTHROW (umsg_stret_decl) = 0;
2304 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
2306 /* id objc_msgSend_Fast (id, SEL, ...)
2307 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2308 #ifdef OFFS_MSGSEND_FAST
2309 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
2310 type, 0, NOT_BUILT_IN,
2311 NULL, NULL_TREE);
2312 TREE_NOTHROW (umsg_fast_decl) = 0;
2313 DECL_ATTRIBUTES (umsg_fast_decl)
2314 = tree_cons (get_identifier ("hard_coded_address"),
2315 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
2316 NULL_TREE);
2317 #else
2318 /* No direct dispatch available. */
2319 umsg_fast_decl = umsg_decl;
2320 #endif
2322 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2323 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2324 type
2325 = build_varargs_function_type_list (objc_object_type,
2326 objc_super_type,
2327 objc_selector_type,
2328 NULL_TREE);
2329 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2330 type, 0, NOT_BUILT_IN,
2331 NULL, NULL_TREE);
2332 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
2333 type, 0, NOT_BUILT_IN, 0,
2334 NULL_TREE);
2335 TREE_NOTHROW (umsg_super_decl) = 0;
2336 TREE_NOTHROW (umsg_super_stret_decl) = 0;
2338 else
2340 /* GNU runtime messenger entry points. */
2342 /* typedef id (*IMP)(id, SEL, ...); */
2343 tree ftype =
2344 build_varargs_function_type_list (objc_object_type,
2345 objc_object_type,
2346 objc_selector_type,
2347 NULL_TREE);
2348 tree IMP_type = build_pointer_type (ftype);
2350 /* IMP objc_msg_lookup (id, SEL); */
2351 type = build_function_type_list (IMP_type,
2352 objc_object_type,
2353 objc_selector_type,
2354 NULL_TREE);
2355 umsg_decl = add_builtin_function (TAG_MSGSEND,
2356 type, 0, NOT_BUILT_IN,
2357 NULL, NULL_TREE);
2358 TREE_NOTHROW (umsg_decl) = 0;
2360 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2361 type
2362 = build_function_type_list (IMP_type,
2363 objc_super_type,
2364 objc_selector_type,
2365 NULL_TREE);
2366 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2367 type, 0, NOT_BUILT_IN,
2368 NULL, NULL_TREE);
2369 TREE_NOTHROW (umsg_super_decl) = 0;
2371 /* The following GNU runtime entry point is called to initialize
2372 each module:
2374 __objc_exec_class (void *); */
2375 type
2376 = build_function_type_list (void_type_node,
2377 ptr_type_node,
2378 NULL_TREE);
2379 execclass_decl = add_builtin_function (TAG_EXECCLASS,
2380 type, 0, NOT_BUILT_IN,
2381 NULL, NULL_TREE);
2384 /* id objc_getClass (const char *); */
2386 type = build_function_type_list (objc_object_type,
2387 const_string_type_node,
2388 NULL_TREE);
2390 objc_get_class_decl
2391 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
2392 NULL, NULL_TREE);
2394 /* id objc_getMetaClass (const char *); */
2396 objc_get_meta_class_decl
2397 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
2399 build_class_template ();
2400 build_super_template ();
2401 build_protocol_template ();
2402 build_category_template ();
2403 build_objc_exception_stuff ();
2405 if (flag_next_runtime)
2406 build_next_objc_exception_stuff ();
2408 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2410 if (! flag_next_runtime)
2411 build_selector_table_decl ();
2413 /* Forward declare constant_string_id and constant_string_type. */
2414 if (!constant_string_class_name)
2415 constant_string_class_name = default_constant_string_class_name;
2417 constant_string_id = get_identifier (constant_string_class_name);
2418 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
2420 /* Pre-build the following entities - for speed/convenience. */
2421 self_id = get_identifier ("self");
2422 ucmd_id = get_identifier ("_cmd");
2424 /* Declare struct _objc_fast_enumeration_state { ... }; */
2425 build_fast_enumeration_state_template ();
2427 /* void objc_enumeration_mutation (id) */
2428 type = build_function_type (void_type_node,
2429 tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
2430 objc_enumeration_mutation_decl
2431 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
2432 NULL, NULL_TREE);
2433 TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
2435 #ifdef OBJCPLUS
2436 pop_lang_context ();
2437 #endif
2439 write_symbols = save_write_symbols;
2440 debug_hooks = save_hooks;
2443 /* Ensure that the ivar list for NSConstantString/NXConstantString
2444 (or whatever was specified via `-fconstant-string-class')
2445 contains fields at least as large as the following three, so that
2446 the runtime can stomp on them with confidence:
2448 struct STRING_OBJECT_CLASS_NAME
2450 Object isa;
2451 char *cString;
2452 unsigned int length;
2453 }; */
2455 static int
2456 check_string_class_template (void)
2458 tree field_decl = objc_get_class_ivars (constant_string_id);
2460 #define AT_LEAST_AS_LARGE_AS(F, T) \
2461 (F && TREE_CODE (F) == FIELD_DECL \
2462 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2463 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2465 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2466 return 0;
2468 field_decl = DECL_CHAIN (field_decl);
2469 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2470 return 0;
2472 field_decl = DECL_CHAIN (field_decl);
2473 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
2475 #undef AT_LEAST_AS_LARGE_AS
2478 /* Avoid calling `check_string_class_template ()' more than once. */
2479 static GTY(()) int string_layout_checked;
2481 /* Construct an internal string layout to be used as a template for
2482 creating NSConstantString/NXConstantString instances. */
2484 static tree
2485 objc_build_internal_const_str_type (void)
2487 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
2488 tree fields = build_decl (input_location,
2489 FIELD_DECL, NULL_TREE, ptr_type_node);
2490 tree field = build_decl (input_location,
2491 FIELD_DECL, NULL_TREE, ptr_type_node);
2493 DECL_CHAIN (field) = fields; fields = field;
2494 field = build_decl (input_location,
2495 FIELD_DECL, NULL_TREE, unsigned_type_node);
2496 DECL_CHAIN (field) = fields; fields = field;
2497 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2498 reverse order! */
2499 finish_builtin_struct (type, "__builtin_ObjCString",
2500 fields, NULL_TREE);
2502 return type;
2505 /* Custom build_string which sets TREE_TYPE! */
2507 static tree
2508 my_build_string (int len, const char *str)
2510 return fix_string_type (build_string (len, str));
2513 /* Build a string with contents STR and length LEN and convert it to a
2514 pointer. */
2516 static tree
2517 my_build_string_pointer (int len, const char *str)
2519 tree string = my_build_string (len, str);
2520 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
2521 return build1 (ADDR_EXPR, ptrtype, string);
2524 static hashval_t
2525 string_hash (const void *ptr)
2527 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
2528 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
2529 int i, len = TREE_STRING_LENGTH (str);
2530 hashval_t h = len;
2532 for (i = 0; i < len; i++)
2533 h = ((h * 613) + p[i]);
2535 return h;
2538 static int
2539 string_eq (const void *ptr1, const void *ptr2)
2541 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
2542 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
2543 int len1 = TREE_STRING_LENGTH (str1);
2545 return (len1 == TREE_STRING_LENGTH (str2)
2546 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
2547 len1));
2550 /* Given a chain of STRING_CST's, build a static instance of
2551 NXConstantString which points at the concatenation of those
2552 strings. We place the string object in the __string_objects
2553 section of the __OBJC segment. The Objective-C runtime will
2554 initialize the isa pointers of the string objects to point at the
2555 NXConstantString class object. */
2557 tree
2558 objc_build_string_object (tree string)
2560 tree constant_string_class;
2561 int length;
2562 tree fields, addr;
2563 struct string_descriptor *desc, key;
2564 void **loc;
2566 /* Prep the string argument. */
2567 string = fix_string_type (string);
2568 TREE_SET_CODE (string, STRING_CST);
2569 length = TREE_STRING_LENGTH (string) - 1;
2571 /* The target may have different ideas on how to construct an ObjC string
2572 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
2573 constant CFString reference instead.
2574 At present, this is only supported for the NeXT runtime. */
2575 if (flag_next_runtime && targetcm.objc_construct_string)
2577 tree constructor = (*targetcm.objc_construct_string) (string);
2578 if (constructor)
2579 return build1 (NOP_EXPR, objc_object_type, constructor);
2582 /* Check whether the string class being used actually exists and has the
2583 correct ivar layout. */
2584 if (!string_layout_checked)
2586 string_layout_checked = -1;
2587 constant_string_class = lookup_interface (constant_string_id);
2588 internal_const_str_type = objc_build_internal_const_str_type ();
2590 if (!constant_string_class
2591 || !(constant_string_type
2592 = CLASS_STATIC_TEMPLATE (constant_string_class)))
2593 error ("cannot find interface declaration for %qE",
2594 constant_string_id);
2595 /* The NSConstantString/NXConstantString ivar layout is now known. */
2596 else if (!check_string_class_template ())
2597 error ("interface %qE does not have valid constant string layout",
2598 constant_string_id);
2599 /* For the NeXT runtime, we can generate a literal reference
2600 to the string class, don't need to run a constructor. */
2601 else if (flag_next_runtime && !setup_string_decl ())
2602 error ("cannot find reference tag for class %qE",
2603 constant_string_id);
2604 else
2606 string_layout_checked = 1; /* Success! */
2607 add_class_reference (constant_string_id);
2611 if (string_layout_checked == -1)
2612 return error_mark_node;
2614 /* Perhaps we already constructed a constant string just like this one? */
2615 key.literal = string;
2616 loc = htab_find_slot (string_htab, &key, INSERT);
2617 desc = (struct string_descriptor *) *loc;
2619 if (!desc)
2621 tree var, constructor;
2622 VEC(constructor_elt,gc) *v = NULL;
2623 *loc = desc = ggc_alloc_string_descriptor ();
2624 desc->literal = string;
2626 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2627 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2628 fields = TYPE_FIELDS (internal_const_str_type);
2629 CONSTRUCTOR_APPEND_ELT (v, fields,
2630 flag_next_runtime
2631 ? build_unary_op (input_location,
2632 ADDR_EXPR, string_class_decl, 0)
2633 : build_int_cst (NULL_TREE, 0));
2634 fields = DECL_CHAIN (fields);
2635 CONSTRUCTOR_APPEND_ELT (v, fields,
2636 build_unary_op (input_location,
2637 ADDR_EXPR, string, 1));
2638 fields = DECL_CHAIN (fields);
2639 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
2640 constructor = objc_build_constructor (internal_const_str_type, v);
2642 if (!flag_next_runtime)
2643 constructor
2644 = objc_add_static_instance (constructor, constant_string_type);
2645 else
2647 var = build_decl (input_location,
2648 CONST_DECL, NULL, TREE_TYPE (constructor));
2649 DECL_INITIAL (var) = constructor;
2650 TREE_STATIC (var) = 1;
2651 pushdecl_top_level (var);
2652 constructor = var;
2654 desc->constructor = constructor;
2657 addr = convert (build_pointer_type (constant_string_type),
2658 build_unary_op (input_location,
2659 ADDR_EXPR, desc->constructor, 1));
2661 return addr;
2664 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2666 static GTY(()) int num_static_inst;
2668 static tree
2669 objc_add_static_instance (tree constructor, tree class_decl)
2671 tree *chain, decl;
2672 char buf[256];
2674 /* Find the list of static instances for the CLASS_DECL. Create one if
2675 not found. */
2676 for (chain = &objc_static_instances;
2677 *chain && TREE_VALUE (*chain) != class_decl;
2678 chain = &TREE_CHAIN (*chain));
2679 if (!*chain)
2681 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2682 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2685 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2686 decl = build_decl (input_location,
2687 VAR_DECL, get_identifier (buf), class_decl);
2688 TREE_STATIC (decl) = 1;
2689 DECL_ARTIFICIAL (decl) = 1;
2690 TREE_USED (decl) = 1;
2691 DECL_INITIAL (decl) = constructor;
2693 /* We may be writing something else just now.
2694 Postpone till end of input. */
2695 DECL_DEFER_OUTPUT (decl) = 1;
2696 pushdecl_top_level (decl);
2697 rest_of_decl_compilation (decl, 1, 0);
2699 /* Add the DECL to the head of this CLASS' list. */
2700 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2702 return decl;
2705 /* Build a static constant CONSTRUCTOR
2706 with type TYPE and elements ELTS. */
2708 static tree
2709 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
2711 tree constructor = build_constructor (type, elts);
2713 TREE_CONSTANT (constructor) = 1;
2714 TREE_STATIC (constructor) = 1;
2715 TREE_READONLY (constructor) = 1;
2717 #ifdef OBJCPLUS
2718 /* Adjust for impedance mismatch. We should figure out how to build
2719 CONSTRUCTORs that consistently please both the C and C++ gods. */
2720 if (!VEC_index (constructor_elt, elts, 0)->index)
2721 TREE_TYPE (constructor) = init_list_type_node;
2722 #endif
2724 return constructor;
2727 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2729 /* Predefine the following data type:
2731 struct _objc_symtab
2733 long sel_ref_cnt;
2734 SEL *refs;
2735 short cls_def_cnt;
2736 short cat_def_cnt;
2737 void *defs[cls_def_cnt + cat_def_cnt];
2738 }; */
2740 static void
2741 build_objc_symtab_template (void)
2743 tree fields, *chain = NULL;
2745 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2747 /* long sel_ref_cnt; */
2748 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
2750 /* SEL *refs; */
2751 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
2753 /* short cls_def_cnt; */
2754 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
2756 /* short cat_def_cnt; */
2757 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2759 if (imp_count || cat_count || !flag_next_runtime)
2761 /* void *defs[imp_count + cat_count (+ 1)]; */
2762 /* NB: The index is one less than the size of the array. */
2763 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
2764 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
2765 add_field_decl (array_type, "defs", &chain);
2768 objc_finish_struct (objc_symtab_template, fields);
2771 /* Create the initial value for the `defs' field of _objc_symtab.
2772 This is a CONSTRUCTOR. */
2774 static tree
2775 init_def_list (tree type)
2777 tree expr;
2778 struct imp_entry *impent;
2779 VEC(constructor_elt,gc) *v = NULL;
2781 if (imp_count)
2782 for (impent = imp_list; impent; impent = impent->next)
2784 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2786 expr = build_unary_op (input_location,
2787 ADDR_EXPR, impent->class_decl, 0);
2788 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2792 if (cat_count)
2793 for (impent = imp_list; impent; impent = impent->next)
2795 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2797 expr = build_unary_op (input_location,
2798 ADDR_EXPR, impent->class_decl, 0);
2799 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2803 if (!flag_next_runtime)
2805 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2806 if (static_instances_decl)
2807 expr = build_unary_op (input_location,
2808 ADDR_EXPR, static_instances_decl, 0);
2809 else
2810 expr = integer_zero_node;
2812 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2815 return objc_build_constructor (type, v);
2818 /* Construct the initial value for all of _objc_symtab. */
2820 static tree
2821 init_objc_symtab (tree type)
2823 VEC(constructor_elt,gc) *v = NULL;
2825 /* sel_ref_cnt = { ..., 5, ... } */
2827 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2828 build_int_cst (long_integer_type_node, 0));
2830 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2832 if (flag_next_runtime || ! sel_ref_chain)
2833 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
2834 build_pointer_type (objc_selector_type),
2835 integer_zero_node));
2836 else
2838 tree expr = build_unary_op (input_location, ADDR_EXPR,
2839 UOBJC_SELECTOR_TABLE_decl, 1);
2841 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2842 convert (build_pointer_type (objc_selector_type),
2843 expr));
2846 /* cls_def_cnt = { ..., 5, ... } */
2848 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2849 build_int_cst (short_integer_type_node, imp_count));
2851 /* cat_def_cnt = { ..., 5, ... } */
2853 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2854 build_int_cst (short_integer_type_node, cat_count));
2856 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2858 if (imp_count || cat_count || !flag_next_runtime)
2861 tree field = TYPE_FIELDS (type);
2862 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2864 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2867 return objc_build_constructor (type, v);
2870 /* Generate forward declarations for metadata such as
2871 'OBJC_CLASS_...'. */
2873 static tree
2874 build_metadata_decl (const char *name, tree type)
2876 tree decl;
2878 /* struct TYPE NAME_<name>; */
2879 decl = start_var_decl (type, synth_id_with_class_suffix
2880 (name,
2881 objc_implementation_context));
2883 return decl;
2886 /* Push forward-declarations of all the categories so that
2887 init_def_list can use them in a CONSTRUCTOR. */
2889 static void
2890 forward_declare_categories (void)
2892 struct imp_entry *impent;
2893 tree sav = objc_implementation_context;
2895 for (impent = imp_list; impent; impent = impent->next)
2897 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2899 /* Set an invisible arg to synth_id_with_class_suffix. */
2900 objc_implementation_context = impent->imp_context;
2901 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2902 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2903 objc_category_template);
2906 objc_implementation_context = sav;
2909 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2910 and initialized appropriately. */
2912 static void
2913 generate_objc_symtab_decl (void)
2916 build_objc_symtab_template ();
2917 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2918 finish_var_decl (UOBJC_SYMBOLS_decl,
2919 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2922 static tree
2923 init_module_descriptor (tree type)
2925 tree expr;
2926 VEC(constructor_elt,gc) *v = NULL;
2928 /* version = { 1, ... } */
2930 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2931 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2933 /* size = { ..., sizeof (struct _objc_module), ... } */
2935 expr = convert (long_integer_type_node,
2936 size_in_bytes (objc_module_template));
2937 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2939 /* Don't provide any file name for security reasons. */
2940 /* name = { ..., "", ... } */
2942 expr = add_objc_string (get_identifier (""), class_names);
2943 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2945 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2947 if (UOBJC_SYMBOLS_decl)
2948 expr = build_unary_op (input_location,
2949 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2950 else
2951 expr = null_pointer_node;
2952 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2954 return objc_build_constructor (type, v);
2957 /* Write out the data structures to describe Objective C classes defined.
2959 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2961 static void
2962 build_module_descriptor (void)
2964 tree decls, *chain = NULL;
2966 #ifdef OBJCPLUS
2967 push_lang_context (lang_name_c); /* extern "C" */
2968 #endif
2970 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2972 /* long version; */
2973 decls = add_field_decl (long_integer_type_node, "version", &chain);
2975 /* long size; */
2976 add_field_decl (long_integer_type_node, "size", &chain);
2978 /* char *name; */
2979 add_field_decl (string_type_node, "name", &chain);
2981 /* struct _objc_symtab *symtab; */
2982 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
2983 get_identifier (UTAG_SYMTAB))),
2984 "symtab", &chain);
2986 objc_finish_struct (objc_module_template, decls);
2988 /* Create an instance of "_objc_module". */
2989 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2990 /* This is the root of the metadata for defined classes and categories, it
2991 is referenced by the runtime and, therefore, needed. */
2992 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
2993 finish_var_decl (UOBJC_MODULES_decl,
2994 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2996 #ifdef OBJCPLUS
2997 pop_lang_context ();
2998 #endif
3001 /* The GNU runtime requires us to provide a static initializer function
3002 for each module:
3004 static void __objc_gnu_init (void) {
3005 __objc_exec_class (&L_OBJC_MODULES);
3006 } */
3008 static void
3009 build_module_initializer_routine (void)
3011 tree body;
3013 #ifdef OBJCPLUS
3014 push_lang_context (lang_name_c); /* extern "C" */
3015 #endif
3017 objc_push_parm (build_decl (input_location,
3018 PARM_DECL, NULL_TREE, void_type_node));
3019 #ifdef OBJCPLUS
3020 objc_start_function (get_identifier (TAG_GNUINIT),
3021 build_function_type_list (void_type_node, NULL_TREE),
3022 NULL_TREE, NULL_TREE);
3023 #else
3024 objc_start_function (get_identifier (TAG_GNUINIT),
3025 build_function_type_list (void_type_node, NULL_TREE),
3026 NULL_TREE, objc_get_parm_info (0));
3027 #endif
3028 body = c_begin_compound_stmt (true);
3029 add_stmt (build_function_call
3030 (input_location,
3031 execclass_decl,
3032 build_tree_list
3033 (NULL_TREE,
3034 build_unary_op (input_location, ADDR_EXPR,
3035 UOBJC_MODULES_decl, 0))));
3036 add_stmt (c_end_compound_stmt (input_location, body, true));
3038 TREE_PUBLIC (current_function_decl) = 0;
3040 #ifndef OBJCPLUS
3041 /* For Objective-C++, we will need to call __objc_gnu_init
3042 from objc_generate_static_init_call() below. */
3043 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3044 #endif
3046 GNU_INIT_decl = current_function_decl;
3047 finish_function ();
3049 #ifdef OBJCPLUS
3050 pop_lang_context ();
3051 #endif
3054 #ifdef OBJCPLUS
3055 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3056 to be called by the module initializer routine. */
3059 objc_static_init_needed_p (void)
3061 return (GNU_INIT_decl != NULL_TREE);
3064 /* Generate a call to the __objc_gnu_init initializer function. */
3066 tree
3067 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3069 add_stmt (build_stmt (input_location, EXPR_STMT,
3070 build_function_call (input_location,
3071 GNU_INIT_decl, NULL_TREE)));
3073 return ctors;
3075 #endif /* OBJCPLUS */
3077 /* Return the DECL of the string IDENT in the SECTION. */
3079 static tree
3080 get_objc_string_decl (tree ident, enum string_section section)
3082 tree chain;
3084 switch (section)
3086 case class_names:
3087 chain = class_names_chain;
3088 break;
3089 case meth_var_names:
3090 chain = meth_var_names_chain;
3091 break;
3092 case meth_var_types:
3093 chain = meth_var_types_chain;
3094 break;
3095 default:
3096 gcc_unreachable ();
3099 for (; chain != 0; chain = TREE_CHAIN (chain))
3100 if (TREE_VALUE (chain) == ident)
3101 return (TREE_PURPOSE (chain));
3103 gcc_unreachable ();
3104 return NULL_TREE;
3107 /* Output references to all statically allocated objects. Return the DECL
3108 for the array built. */
3110 static void
3111 generate_static_references (void)
3113 tree expr = NULL_TREE;
3114 tree class_name, klass, decl;
3115 tree cl_chain, in_chain, type
3116 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3117 int num_inst, num_class;
3118 char buf[256];
3119 VEC(constructor_elt,gc) *decls = NULL;
3121 if (flag_next_runtime)
3122 gcc_unreachable ();
3124 for (cl_chain = objc_static_instances, num_class = 0;
3125 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3127 VEC(constructor_elt,gc) *v = NULL;
3129 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3130 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3132 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3133 decl = start_var_decl (type, buf);
3135 /* Output {class_name, ...}. */
3136 klass = TREE_VALUE (cl_chain);
3137 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3138 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3139 build_unary_op (input_location,
3140 ADDR_EXPR, class_name, 1));
3142 /* Output {..., instance, ...}. */
3143 for (in_chain = TREE_PURPOSE (cl_chain);
3144 in_chain; in_chain = TREE_CHAIN (in_chain))
3146 expr = build_unary_op (input_location,
3147 ADDR_EXPR, TREE_VALUE (in_chain), 1);
3148 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3151 /* Output {..., NULL}. */
3152 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3154 expr = objc_build_constructor (TREE_TYPE (decl), v);
3155 finish_var_decl (decl, expr);
3156 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3157 build_unary_op (input_location,
3158 ADDR_EXPR, decl, 1));
3161 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3162 expr = objc_build_constructor (type, decls);
3163 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3164 finish_var_decl (static_instances_decl, expr);
3167 static GTY(()) int selector_reference_idx;
3169 static tree
3170 build_selector_reference_decl (void)
3172 tree decl;
3173 char buf[256];
3175 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3176 decl = start_var_decl (objc_selector_type, buf);
3178 return decl;
3181 static void
3182 build_selector_table_decl (void)
3184 tree temp;
3186 if (flag_typed_selectors)
3188 build_selector_template ();
3189 temp = build_array_type (objc_selector_template, NULL_TREE);
3191 else
3192 temp = build_array_type (objc_selector_type, NULL_TREE);
3194 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3197 /* Just a handy wrapper for add_objc_string. */
3199 static tree
3200 build_selector (tree ident)
3202 return convert (objc_selector_type,
3203 add_objc_string (ident, meth_var_names));
3206 /* Used only by build_*_selector_translation_table (). */
3207 static void
3208 diagnose_missing_method (tree meth, location_t here)
3210 tree method_chain;
3211 bool found = false;
3212 for (method_chain = meth_var_names_chain;
3213 method_chain;
3214 method_chain = TREE_CHAIN (method_chain))
3216 if (TREE_VALUE (method_chain) == meth)
3218 found = true;
3219 break;
3223 if (!found)
3224 warning_at (here, 0, "creating selector for nonexistent method %qE",
3225 meth);
3228 static void
3229 build_next_selector_translation_table (void)
3231 tree chain;
3232 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3234 tree expr;
3235 tree decl = TREE_PURPOSE (chain);
3236 if (warn_selector && objc_implementation_context)
3238 location_t loc;
3239 if (decl)
3240 loc = DECL_SOURCE_LOCATION (decl);
3241 else
3242 loc = input_location;
3243 diagnose_missing_method (TREE_VALUE (chain), loc);
3246 expr = build_selector (TREE_VALUE (chain));
3248 if (decl)
3250 /* Entries of this form are used for references to methods.
3251 The runtime re-writes these on start-up, but the compiler can't see
3252 that and optimizes it away unless we force it. */
3253 DECL_PRESERVE_P (decl) = 1;
3254 finish_var_decl (decl, expr);
3259 static void
3260 build_gnu_selector_translation_table (void)
3262 tree chain;
3263 /* int offset = 0;
3264 tree decl = NULL_TREE;*/
3265 VEC(constructor_elt,gc) *inits = NULL;
3267 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3269 tree expr;
3271 if (warn_selector && objc_implementation_context)
3272 diagnose_missing_method (TREE_VALUE (chain), input_location);
3274 expr = build_selector (TREE_VALUE (chain));
3275 /* add one for the '\0' character
3276 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3279 if (flag_typed_selectors)
3281 VEC(constructor_elt,gc) *v = NULL;
3282 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
3283 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3284 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
3285 expr = objc_build_constructor (objc_selector_template, v);
3288 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3290 } /* each element in the chain */
3293 /* Cause the selector table (previously forward-declared)
3294 to be actually output. */
3295 tree expr;
3297 if (flag_typed_selectors)
3299 VEC(constructor_elt,gc) *v = NULL;
3300 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3301 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3302 expr = objc_build_constructor (objc_selector_template, v);
3304 else
3305 expr = integer_zero_node;
3307 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3308 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
3309 inits);
3310 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
3314 static tree
3315 get_proto_encoding (tree proto)
3317 tree encoding;
3318 if (proto)
3320 if (! METHOD_ENCODING (proto))
3322 encoding = encode_method_prototype (proto);
3323 METHOD_ENCODING (proto) = encoding;
3325 else
3326 encoding = METHOD_ENCODING (proto);
3328 return add_objc_string (encoding, meth_var_types);
3330 else
3331 return build_int_cst (NULL_TREE, 0);
3334 /* sel_ref_chain is a list whose "value" fields will be instances of
3335 identifier_node that represent the selector. LOC is the location of
3336 the @selector. */
3338 static tree
3339 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
3341 tree *chain = &sel_ref_chain;
3342 tree expr;
3343 int index = 0;
3345 while (*chain)
3347 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
3348 goto return_at_index;
3350 index++;
3351 chain = &TREE_CHAIN (*chain);
3354 *chain = tree_cons (prototype, ident, NULL_TREE);
3356 return_at_index:
3357 expr = build_unary_op (loc, ADDR_EXPR,
3358 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3359 build_int_cst (NULL_TREE, index)),
3361 return convert (objc_selector_type, expr);
3364 static tree
3365 build_selector_reference (location_t loc, tree ident)
3367 tree *chain = &sel_ref_chain;
3368 tree expr;
3369 int index = 0;
3371 while (*chain)
3373 if (TREE_VALUE (*chain) == ident)
3374 return (flag_next_runtime
3375 ? TREE_PURPOSE (*chain)
3376 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3377 build_int_cst (NULL_TREE, index)));
3379 index++;
3380 chain = &TREE_CHAIN (*chain);
3383 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
3385 *chain = tree_cons (expr, ident, NULL_TREE);
3387 return (flag_next_runtime
3388 ? expr
3389 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3390 build_int_cst (NULL_TREE, index)));
3393 static GTY(()) int class_reference_idx;
3395 static tree
3396 build_class_reference_decl (void)
3398 tree decl;
3399 char buf[256];
3401 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
3402 decl = start_var_decl (objc_class_type, buf);
3404 return decl;
3407 /* Create a class reference, but don't create a variable to reference
3408 it. */
3410 static void
3411 add_class_reference (tree ident)
3413 tree chain;
3415 if ((chain = cls_ref_chain))
3417 tree tail;
3420 if (ident == TREE_VALUE (chain))
3421 return;
3423 tail = chain;
3424 chain = TREE_CHAIN (chain);
3426 while (chain);
3428 /* Append to the end of the list */
3429 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
3431 else
3432 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
3435 /* Get a class reference, creating it if necessary. Also create the
3436 reference variable. */
3438 tree
3439 objc_get_class_reference (tree ident)
3441 tree orig_ident = (DECL_P (ident)
3442 ? DECL_NAME (ident)
3443 : TYPE_P (ident)
3444 ? OBJC_TYPE_NAME (ident)
3445 : ident);
3446 bool local_scope = false;
3448 #ifdef OBJCPLUS
3449 if (processing_template_decl)
3450 /* Must wait until template instantiation time. */
3451 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
3452 #endif
3454 if (TREE_CODE (ident) == TYPE_DECL)
3455 ident = (DECL_ORIGINAL_TYPE (ident)
3456 ? DECL_ORIGINAL_TYPE (ident)
3457 : TREE_TYPE (ident));
3459 #ifdef OBJCPLUS
3460 if (TYPE_P (ident)
3461 && CP_TYPE_CONTEXT (ident) != global_namespace)
3462 local_scope = true;
3463 #endif
3465 if (local_scope || !(ident = objc_is_class_name (ident)))
3467 error ("%qE is not an Objective-C class name or alias",
3468 orig_ident);
3469 return error_mark_node;
3472 if (flag_next_runtime && !flag_zero_link)
3474 tree *chain;
3475 tree decl;
3477 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
3478 if (TREE_VALUE (*chain) == ident)
3480 if (! TREE_PURPOSE (*chain))
3481 TREE_PURPOSE (*chain) = build_class_reference_decl ();
3483 return TREE_PURPOSE (*chain);
3486 decl = build_class_reference_decl ();
3487 *chain = tree_cons (decl, ident, NULL_TREE);
3488 return decl;
3490 else
3492 tree params;
3494 add_class_reference (ident);
3496 params = build_tree_list (NULL_TREE,
3497 my_build_string_pointer
3498 (IDENTIFIER_LENGTH (ident) + 1,
3499 IDENTIFIER_POINTER (ident)));
3501 assemble_external (objc_get_class_decl);
3502 return build_function_call (input_location, objc_get_class_decl, params);
3506 /* For each string section we have a chain which maps identifier nodes
3507 to decls for the strings. */
3509 static GTY(()) int class_names_idx;
3510 static GTY(()) int meth_var_names_idx;
3511 static GTY(()) int meth_var_types_idx;
3513 static tree
3514 add_objc_string (tree ident, enum string_section section)
3516 tree *chain, decl, type, string_expr;
3517 char buf[256];
3519 buf[0] = 0;
3520 switch (section)
3522 case class_names:
3523 chain = &class_names_chain;
3524 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
3525 break;
3526 case meth_var_names:
3527 chain = &meth_var_names_chain;
3528 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
3529 break;
3530 case meth_var_types:
3531 chain = &meth_var_types_chain;
3532 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
3533 break;
3534 default:
3535 gcc_unreachable ();
3538 while (*chain)
3540 if (TREE_VALUE (*chain) == ident)
3541 return convert (string_type_node,
3542 build_unary_op (input_location,
3543 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
3545 chain = &TREE_CHAIN (*chain);
3548 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
3549 decl = start_var_decl (type, buf);
3550 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
3551 IDENTIFIER_POINTER (ident));
3552 TREE_CONSTANT (decl) = 1;
3553 finish_var_decl (decl, string_expr);
3555 *chain = tree_cons (decl, ident, NULL_TREE);
3557 return convert (string_type_node, build_unary_op (input_location,
3558 ADDR_EXPR, decl, 1));
3561 void
3562 objc_declare_alias (tree alias_ident, tree class_ident)
3564 tree underlying_class;
3566 #ifdef OBJCPLUS
3567 if (current_namespace != global_namespace) {
3568 error ("Objective-C declarations may only appear in global scope");
3570 #endif /* OBJCPLUS */
3572 if (!(underlying_class = objc_is_class_name (class_ident)))
3573 warning (0, "cannot find class %qE", class_ident);
3574 else if (objc_is_class_name (alias_ident))
3575 warning (0, "class %qE already exists", alias_ident);
3576 else
3578 /* Implement @compatibility_alias as a typedef. */
3579 #ifdef OBJCPLUS
3580 push_lang_context (lang_name_c); /* extern "C" */
3581 #endif
3582 lang_hooks.decls.pushdecl (build_decl
3583 (input_location,
3584 TYPE_DECL,
3585 alias_ident,
3586 xref_tag (RECORD_TYPE, underlying_class)));
3587 #ifdef OBJCPLUS
3588 pop_lang_context ();
3589 #endif
3590 hash_class_name_enter (als_name_hash_list, alias_ident,
3591 underlying_class);
3595 void
3596 objc_declare_class (tree ident_list)
3598 tree list;
3599 #ifdef OBJCPLUS
3600 if (current_namespace != global_namespace) {
3601 error ("Objective-C declarations may only appear in global scope");
3603 #endif /* OBJCPLUS */
3605 for (list = ident_list; list; list = TREE_CHAIN (list))
3607 tree ident = TREE_VALUE (list);
3609 if (! objc_is_class_name (ident))
3611 tree record = lookup_name (ident), type = record;
3613 if (record)
3615 if (TREE_CODE (record) == TYPE_DECL)
3616 type = DECL_ORIGINAL_TYPE (record) ?
3617 DECL_ORIGINAL_TYPE (record) :
3618 TREE_TYPE (record);
3620 if (!TYPE_HAS_OBJC_INFO (type)
3621 || !TYPE_OBJC_INTERFACE (type))
3623 error ("%qE redeclared as different kind of symbol",
3624 ident);
3625 error ("previous declaration of %q+D",
3626 record);
3630 record = xref_tag (RECORD_TYPE, ident);
3631 INIT_TYPE_OBJC_INFO (record);
3632 TYPE_OBJC_INTERFACE (record) = ident;
3633 hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
3638 tree
3639 objc_is_class_name (tree ident)
3641 hash target;
3643 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3644 && identifier_global_value (ident))
3645 ident = identifier_global_value (ident);
3646 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3647 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3649 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3650 ident = OBJC_TYPE_NAME (ident);
3651 #ifdef OBJCPLUS
3652 if (ident && TREE_CODE (ident) == TYPE_DECL)
3654 tree type = TREE_TYPE (ident);
3655 if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
3656 return NULL_TREE;
3657 ident = DECL_NAME (ident);
3659 #endif
3660 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3661 return NULL_TREE;
3663 if (lookup_interface (ident))
3664 return ident;
3666 target = hash_class_name_lookup (cls_name_hash_list, ident);
3667 if (target)
3668 return target->key;
3670 target = hash_class_name_lookup (als_name_hash_list, ident);
3671 if (target)
3673 gcc_assert (target->list && target->list->value);
3674 return target->list->value;
3677 return 0;
3680 /* Check whether TYPE is either 'id' or 'Class'. */
3682 tree
3683 objc_is_id (tree type)
3685 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3686 && identifier_global_value (type))
3687 type = identifier_global_value (type);
3689 if (type && TREE_CODE (type) == TYPE_DECL)
3690 type = TREE_TYPE (type);
3692 /* NB: This function may be called before the ObjC front-end has
3693 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3694 return (objc_object_type && type
3695 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3696 ? type
3697 : NULL_TREE);
3700 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3701 class instance. This is needed by other parts of the compiler to
3702 handle ObjC types gracefully. */
3704 tree
3705 objc_is_object_ptr (tree type)
3707 tree ret;
3709 type = TYPE_MAIN_VARIANT (type);
3710 if (!POINTER_TYPE_P (type))
3711 return 0;
3713 ret = objc_is_id (type);
3714 if (!ret)
3715 ret = objc_is_class_name (TREE_TYPE (type));
3717 return ret;
3720 static int
3721 objc_is_gcable_type (tree type, int or_strong_p)
3723 tree name;
3725 if (!TYPE_P (type))
3726 return 0;
3727 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3728 return 1;
3729 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3730 return 1;
3731 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3732 return 0;
3733 type = TREE_TYPE (type);
3734 if (TREE_CODE (type) != RECORD_TYPE)
3735 return 0;
3736 name = TYPE_NAME (type);
3737 return (objc_is_class_name (name) != NULL_TREE);
3740 static tree
3741 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3743 if (expr == oldexpr)
3744 return newexpr;
3746 switch (TREE_CODE (expr))
3748 case COMPONENT_REF:
3749 return objc_build_component_ref
3750 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3751 oldexpr,
3752 newexpr),
3753 DECL_NAME (TREE_OPERAND (expr, 1)));
3754 case ARRAY_REF:
3755 return build_array_ref (input_location,
3756 objc_substitute_decl (TREE_OPERAND (expr, 0),
3757 oldexpr,
3758 newexpr),
3759 TREE_OPERAND (expr, 1));
3760 case INDIRECT_REF:
3761 return build_indirect_ref (input_location,
3762 objc_substitute_decl (TREE_OPERAND (expr, 0),
3763 oldexpr,
3764 newexpr), RO_ARROW);
3765 default:
3766 return expr;
3770 static tree
3771 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3773 tree func_params;
3774 /* The LHS parameter contains the expression 'outervar->memberspec';
3775 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3776 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3778 tree offs
3779 = objc_substitute_decl
3780 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3781 tree func
3782 = (flag_objc_direct_dispatch
3783 ? objc_assign_ivar_fast_decl
3784 : objc_assign_ivar_decl);
3786 offs = convert (integer_type_node, build_unary_op (input_location,
3787 ADDR_EXPR, offs, 0));
3788 offs = fold (offs);
3789 func_params = tree_cons (NULL_TREE,
3790 convert (objc_object_type, rhs),
3791 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3792 tree_cons (NULL_TREE, offs,
3793 NULL_TREE)));
3795 assemble_external (func);
3796 return build_function_call (input_location, func, func_params);
3799 static tree
3800 objc_build_global_assignment (tree lhs, tree rhs)
3802 tree func_params = tree_cons (NULL_TREE,
3803 convert (objc_object_type, rhs),
3804 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3805 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3806 NULL_TREE));
3808 assemble_external (objc_assign_global_decl);
3809 return build_function_call (input_location,
3810 objc_assign_global_decl, func_params);
3813 static tree
3814 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3816 tree func_params = tree_cons (NULL_TREE,
3817 convert (objc_object_type, rhs),
3818 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3819 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3820 NULL_TREE));
3822 assemble_external (objc_assign_strong_cast_decl);
3823 return build_function_call (input_location,
3824 objc_assign_strong_cast_decl, func_params);
3827 static int
3828 objc_is_gcable_p (tree expr)
3830 return (TREE_CODE (expr) == COMPONENT_REF
3831 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3832 : TREE_CODE (expr) == ARRAY_REF
3833 ? (objc_is_gcable_p (TREE_TYPE (expr))
3834 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3835 : TREE_CODE (expr) == ARRAY_TYPE
3836 ? objc_is_gcable_p (TREE_TYPE (expr))
3837 : TYPE_P (expr)
3838 ? objc_is_gcable_type (expr, 1)
3839 : (objc_is_gcable_p (TREE_TYPE (expr))
3840 || (DECL_P (expr)
3841 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3844 static int
3845 objc_is_ivar_reference_p (tree expr)
3847 return (TREE_CODE (expr) == ARRAY_REF
3848 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3849 : TREE_CODE (expr) == COMPONENT_REF
3850 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3851 : 0);
3854 static int
3855 objc_is_global_reference_p (tree expr)
3857 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3858 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3859 : DECL_P (expr)
3860 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
3861 : 0);
3864 tree
3865 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3867 tree result = NULL_TREE, outer;
3868 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3870 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3871 will have been transformed to the form '*(type *)&expr'. */
3872 if (TREE_CODE (lhs) == INDIRECT_REF)
3874 outer = TREE_OPERAND (lhs, 0);
3876 while (!strong_cast_p
3877 && (CONVERT_EXPR_P (outer)
3878 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3880 tree lhstype = TREE_TYPE (outer);
3882 /* Descend down the cast chain, and record the first objc_gc
3883 attribute found. */
3884 if (POINTER_TYPE_P (lhstype))
3886 tree attr
3887 = lookup_attribute ("objc_gc",
3888 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3890 if (attr)
3891 strong_cast_p = 1;
3894 outer = TREE_OPERAND (outer, 0);
3898 /* If we have a __strong cast, it trumps all else. */
3899 if (strong_cast_p)
3901 if (modifycode != NOP_EXPR)
3902 goto invalid_pointer_arithmetic;
3904 if (warn_assign_intercept)
3905 warning (0, "strong-cast assignment has been intercepted");
3907 result = objc_build_strong_cast_assignment (lhs, rhs);
3909 goto exit_point;
3912 /* the lhs must be of a suitable type, regardless of its underlying
3913 structure. */
3914 if (!objc_is_gcable_p (lhs))
3915 goto exit_point;
3917 outer = lhs;
3919 while (outer
3920 && (TREE_CODE (outer) == COMPONENT_REF
3921 || TREE_CODE (outer) == ARRAY_REF))
3922 outer = TREE_OPERAND (outer, 0);
3924 if (TREE_CODE (outer) == INDIRECT_REF)
3926 outer = TREE_OPERAND (outer, 0);
3927 indirect_p = 1;
3930 outer_gc_p = objc_is_gcable_p (outer);
3932 /* Handle ivar assignments. */
3933 if (objc_is_ivar_reference_p (lhs))
3935 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3936 doesn't cut it here), the best we can do here is suggest a cast. */
3937 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3939 /* We may still be able to use the global write barrier... */
3940 if (!indirect_p && objc_is_global_reference_p (outer))
3941 goto global_reference;
3943 suggest_cast:
3944 if (modifycode == NOP_EXPR)
3946 if (warn_assign_intercept)
3947 warning (0, "strong-cast may possibly be needed");
3950 goto exit_point;
3953 if (modifycode != NOP_EXPR)
3954 goto invalid_pointer_arithmetic;
3956 if (warn_assign_intercept)
3957 warning (0, "instance variable assignment has been intercepted");
3959 result = objc_build_ivar_assignment (outer, lhs, rhs);
3961 goto exit_point;
3964 /* Likewise, intercept assignment to global/static variables if their type is
3965 GC-marked. */
3966 if (objc_is_global_reference_p (outer))
3968 if (indirect_p)
3969 goto suggest_cast;
3971 global_reference:
3972 if (modifycode != NOP_EXPR)
3974 invalid_pointer_arithmetic:
3975 if (outer_gc_p)
3976 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3978 goto exit_point;
3981 if (warn_assign_intercept)
3982 warning (0, "global/static variable assignment has been intercepted");
3984 result = objc_build_global_assignment (lhs, rhs);
3987 /* In all other cases, fall back to the normal mechanism. */
3988 exit_point:
3989 return result;
3992 struct GTY(()) interface_tuple {
3993 tree id;
3994 tree class_name;
3997 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3999 static hashval_t
4000 hash_interface (const void *p)
4002 const struct interface_tuple *d = (const struct interface_tuple *) p;
4003 return IDENTIFIER_HASH_VALUE (d->id);
4006 static int
4007 eq_interface (const void *p1, const void *p2)
4009 const struct interface_tuple *d = (const struct interface_tuple *) p1;
4010 return d->id == p2;
4013 static tree
4014 lookup_interface (tree ident)
4016 #ifdef OBJCPLUS
4017 if (ident && TREE_CODE (ident) == TYPE_DECL)
4018 ident = DECL_NAME (ident);
4019 #endif
4021 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4022 return NULL_TREE;
4025 struct interface_tuple **slot;
4026 tree i = NULL_TREE;
4028 if (interface_htab)
4030 slot = (struct interface_tuple **)
4031 htab_find_slot_with_hash (interface_htab, ident,
4032 IDENTIFIER_HASH_VALUE (ident),
4033 NO_INSERT);
4034 if (slot && *slot)
4035 i = (*slot)->class_name;
4037 return i;
4041 /* Implement @defs (<classname>) within struct bodies. */
4043 tree
4044 objc_get_class_ivars (tree class_name)
4046 tree interface = lookup_interface (class_name);
4048 if (interface)
4049 return get_class_ivars (interface, true);
4051 error ("cannot find interface declaration for %qE",
4052 class_name);
4054 return error_mark_node;
4057 /* Called when checking the variables in a struct. If we are not
4058 doing the ivars list inside an @interface context, then returns
4059 fieldlist unchanged. Else, returns the list of class ivars.
4061 tree
4062 objc_get_interface_ivars (tree fieldlist)
4064 if (!objc_collecting_ivars || !objc_interface_context
4065 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4066 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4067 return fieldlist;
4069 return get_class_ivars (objc_interface_context, true);
4072 /* Used by: build_private_template, continue_class,
4073 and for @defs constructs. */
4075 static tree
4076 get_class_ivars (tree interface, bool inherited)
4078 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4080 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4081 by the current class (i.e., they do not include super-class ivars).
4082 However, the CLASS_IVARS list will be side-effected by a call to
4083 finish_struct(), which will fill in field offsets. */
4084 if (!CLASS_IVARS (interface))
4085 CLASS_IVARS (interface) = ivar_chain;
4087 if (!inherited)
4088 return ivar_chain;
4090 while (CLASS_SUPER_NAME (interface))
4092 /* Prepend super-class ivars. */
4093 interface = lookup_interface (CLASS_SUPER_NAME (interface));
4094 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4095 ivar_chain);
4098 return ivar_chain;
4101 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4102 the specified name, else use no name. Returns the declaration of
4103 the type. The 'name' is mostly useful for debugging.
4105 static tree
4106 objc_create_temporary_var (tree type, const char *name)
4108 tree decl;
4110 if (name != NULL)
4112 decl = build_decl (input_location,
4113 VAR_DECL, get_identifier (name), type);
4115 else
4117 decl = build_decl (input_location,
4118 VAR_DECL, NULL_TREE, type);
4120 TREE_USED (decl) = 1;
4121 DECL_ARTIFICIAL (decl) = 1;
4122 DECL_IGNORED_P (decl) = 1;
4123 DECL_CONTEXT (decl) = current_function_decl;
4125 return decl;
4128 /* Exception handling constructs. We begin by having the parser do most
4129 of the work and passing us blocks. What we do next depends on whether
4130 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4131 We abstract all of this in a handful of appropriately named routines. */
4133 /* Stack of open try blocks. */
4135 struct objc_try_context
4137 struct objc_try_context *outer;
4139 /* Statements (or statement lists) as processed by the parser. */
4140 tree try_body;
4141 tree finally_body;
4143 /* Some file position locations. */
4144 location_t try_locus;
4145 location_t end_try_locus;
4146 location_t end_catch_locus;
4147 location_t finally_locus;
4148 location_t end_finally_locus;
4150 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4151 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4152 tree catch_list;
4154 /* The CATCH_EXPR of an open @catch clause. */
4155 tree current_catch;
4157 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4158 tree caught_decl;
4159 tree stack_decl;
4160 tree rethrow_decl;
4163 static struct objc_try_context *cur_try_context;
4165 static GTY(()) tree objc_eh_personality_decl;
4167 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4168 that represents TYPE. For Objective-C, this is just the class name. */
4169 /* ??? Isn't there a class object or some such? Is it easy to get? */
4171 #ifndef OBJCPLUS
4172 tree
4173 objc_eh_runtime_type (tree type)
4175 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4178 tree
4179 objc_eh_personality (void)
4181 if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4182 objc_eh_personality_decl = build_personality_function ("gnu_objc");
4183 return objc_eh_personality_decl;
4185 #endif
4187 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4188 of Darwin, we'll arrange for it to be initialized (and associated
4189 with a binding) later. */
4191 static tree
4192 objc_build_exc_ptr (void)
4194 if (flag_objc_sjlj_exceptions)
4196 tree var = cur_try_context->caught_decl;
4197 if (!var)
4199 var = objc_create_temporary_var (objc_object_type, NULL);
4200 cur_try_context->caught_decl = var;
4202 return var;
4204 else
4206 tree t;
4207 t = built_in_decls[BUILT_IN_EH_POINTER];
4208 t = build_call_expr (t, 1, integer_zero_node);
4209 return fold_convert (objc_object_type, t);
4213 /* Build "objc_exception_try_exit(&_stack)". */
4215 static tree
4216 next_sjlj_build_try_exit (void)
4218 tree t;
4219 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4220 t = tree_cons (NULL, t, NULL);
4221 t = build_function_call (input_location,
4222 objc_exception_try_exit_decl, t);
4223 return t;
4226 /* Build
4227 objc_exception_try_enter (&_stack);
4228 if (_setjmp(&_stack.buf))
4230 else
4232 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4233 empty, ready for the caller to fill them in. */
4235 static tree
4236 next_sjlj_build_enter_and_setjmp (void)
4238 tree t, enter, sj, cond;
4240 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4241 t = tree_cons (NULL, t, NULL);
4242 enter = build_function_call (input_location,
4243 objc_exception_try_enter_decl, t);
4245 t = objc_build_component_ref (cur_try_context->stack_decl,
4246 get_identifier ("buf"));
4247 t = build_fold_addr_expr_loc (input_location, t);
4248 #ifdef OBJCPLUS
4249 /* Convert _setjmp argument to type that is expected. */
4250 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
4251 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
4252 else
4253 t = convert (ptr_type_node, t);
4254 #else
4255 t = convert (ptr_type_node, t);
4256 #endif
4257 t = tree_cons (NULL, t, NULL);
4258 sj = build_function_call (input_location,
4259 objc_setjmp_decl, t);
4261 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
4262 cond = c_common_truthvalue_conversion (input_location, cond);
4264 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
4267 /* Build:
4269 DECL = objc_exception_extract(&_stack); */
4271 static tree
4272 next_sjlj_build_exc_extract (tree decl)
4274 tree t;
4276 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4277 t = tree_cons (NULL, t, NULL);
4278 t = build_function_call (input_location,
4279 objc_exception_extract_decl, t);
4280 t = convert (TREE_TYPE (decl), t);
4281 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4283 return t;
4286 /* Build
4287 if (objc_exception_match(obj_get_class(TYPE), _caught)
4288 BODY
4289 else if (...)
4291 else
4293 _rethrow = _caught;
4294 objc_exception_try_exit(&_stack);
4296 from the sequence of CATCH_EXPRs in the current try context. */
4298 static tree
4299 next_sjlj_build_catch_list (void)
4301 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4302 tree catch_seq, t;
4303 tree *last = &catch_seq;
4304 bool saw_id = false;
4306 for (; !tsi_end_p (i); tsi_next (&i))
4308 tree stmt = tsi_stmt (i);
4309 tree type = CATCH_TYPES (stmt);
4310 tree body = CATCH_BODY (stmt);
4312 if (type == NULL)
4314 *last = body;
4315 saw_id = true;
4316 break;
4318 else
4320 tree args, cond;
4322 if (type == error_mark_node)
4323 cond = error_mark_node;
4324 else
4326 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
4327 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
4328 args = tree_cons (NULL, t, args);
4329 t = build_function_call (input_location,
4330 objc_exception_match_decl, args);
4331 cond = c_common_truthvalue_conversion (input_location, t);
4333 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
4334 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
4336 *last = t;
4337 last = &COND_EXPR_ELSE (t);
4341 if (!saw_id)
4343 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
4344 cur_try_context->caught_decl);
4345 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4346 append_to_statement_list (t, last);
4348 t = next_sjlj_build_try_exit ();
4349 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4350 append_to_statement_list (t, last);
4353 return catch_seq;
4356 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4357 exception handling. We aim to build:
4360 struct _objc_exception_data _stack;
4361 id _rethrow = 0;
4364 objc_exception_try_enter (&_stack);
4365 if (_setjmp(&_stack.buf))
4367 id _caught = objc_exception_extract(&_stack);
4368 objc_exception_try_enter (&_stack);
4369 if (_setjmp(&_stack.buf))
4370 _rethrow = objc_exception_extract(&_stack);
4371 else
4372 CATCH-LIST
4374 else
4375 TRY-BLOCK
4377 finally
4379 if (!_rethrow)
4380 objc_exception_try_exit(&_stack);
4381 FINALLY-BLOCK
4382 if (_rethrow)
4383 objc_exception_throw(_rethrow);
4387 If CATCH-LIST is empty, we can omit all of the block containing
4388 "_caught" except for the setting of _rethrow. Note the use of
4389 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4390 but handles goto and other exits from the block. */
4392 static tree
4393 next_sjlj_build_try_catch_finally (void)
4395 tree rethrow_decl, stack_decl, t;
4396 tree catch_seq, try_fin, bind;
4398 /* Create the declarations involved. */
4399 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
4400 stack_decl = objc_create_temporary_var (t, NULL);
4401 cur_try_context->stack_decl = stack_decl;
4403 rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
4404 cur_try_context->rethrow_decl = rethrow_decl;
4405 TREE_CHAIN (rethrow_decl) = stack_decl;
4407 /* Build the outermost variable binding level. */
4408 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
4409 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
4410 TREE_SIDE_EFFECTS (bind) = 1;
4412 /* Initialize rethrow_decl. */
4413 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
4414 convert (objc_object_type, null_pointer_node));
4415 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4416 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4418 /* Build the outermost TRY_FINALLY_EXPR. */
4419 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
4420 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
4421 TREE_SIDE_EFFECTS (try_fin) = 1;
4422 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
4424 /* Create the complete catch sequence. */
4425 if (cur_try_context->catch_list)
4427 tree caught_decl = objc_build_exc_ptr ();
4428 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
4429 TREE_SIDE_EFFECTS (catch_seq) = 1;
4431 t = next_sjlj_build_exc_extract (caught_decl);
4432 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4434 t = next_sjlj_build_enter_and_setjmp ();
4435 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
4436 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
4437 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4439 else
4440 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
4441 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
4443 /* Build the main register-and-try if statement. */
4444 t = next_sjlj_build_enter_and_setjmp ();
4445 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4446 COND_EXPR_THEN (t) = catch_seq;
4447 COND_EXPR_ELSE (t) = cur_try_context->try_body;
4448 TREE_OPERAND (try_fin, 0) = t;
4450 /* Build the complete FINALLY statement list. */
4451 t = next_sjlj_build_try_exit ();
4452 t = build_stmt (input_location, COND_EXPR,
4453 c_common_truthvalue_conversion
4454 (input_location, rethrow_decl),
4455 NULL, t);
4456 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
4457 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4459 append_to_statement_list (cur_try_context->finally_body,
4460 &TREE_OPERAND (try_fin, 1));
4462 t = tree_cons (NULL, rethrow_decl, NULL);
4463 t = build_function_call (input_location,
4464 objc_exception_throw_decl, t);
4465 t = build_stmt (input_location, COND_EXPR,
4466 c_common_truthvalue_conversion (input_location,
4467 rethrow_decl),
4468 t, NULL);
4469 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
4470 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4472 return bind;
4475 /* Called just after parsing the @try and its associated BODY. We now
4476 must prepare for the tricky bits -- handling the catches and finally. */
4478 void
4479 objc_begin_try_stmt (location_t try_locus, tree body)
4481 struct objc_try_context *c = XCNEW (struct objc_try_context);
4482 c->outer = cur_try_context;
4483 c->try_body = body;
4484 c->try_locus = try_locus;
4485 c->end_try_locus = input_location;
4486 cur_try_context = c;
4488 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4489 For example, on Darwin, ObjC exceptions require a sufficiently
4490 recent version of the runtime, so the user must ask for them
4491 explicitly. On other platforms, at the moment -fobjc-exceptions
4492 triggers -fexceptions which again is required for exceptions to
4493 work.
4495 if (!flag_objc_exceptions)
4497 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4500 if (flag_objc_sjlj_exceptions)
4501 objc_mark_locals_volatile (NULL);
4504 /* Called just after parsing "@catch (parm)". Open a binding level,
4505 enter DECL into the binding level, and initialize it. Leave the
4506 binding level open while the body of the compound statement is parsed. */
4508 void
4509 objc_begin_catch_clause (tree decl)
4511 tree compound, type, t;
4513 /* Begin a new scope that the entire catch clause will live in. */
4514 compound = c_begin_compound_stmt (true);
4516 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4517 decl = build_decl (input_location,
4518 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
4519 lang_hooks.decls.pushdecl (decl);
4521 /* Since a decl is required here by syntax, don't warn if its unused. */
4522 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4523 be what the previous objc implementation did. */
4524 TREE_USED (decl) = 1;
4525 DECL_READ_P (decl) = 1;
4527 /* Verify that the type of the catch is valid. It must be a pointer
4528 to an Objective-C class, or "id" (which is catch-all). */
4529 type = TREE_TYPE (decl);
4531 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
4532 type = NULL;
4533 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
4535 error ("@catch parameter is not a known Objective-C class type");
4536 type = error_mark_node;
4538 else if (cur_try_context->catch_list)
4540 /* Examine previous @catch clauses and see if we've already
4541 caught the type in question. */
4542 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4543 for (; !tsi_end_p (i); tsi_next (&i))
4545 tree stmt = tsi_stmt (i);
4546 t = CATCH_TYPES (stmt);
4547 if (t == error_mark_node)
4548 continue;
4549 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
4551 warning (0, "exception of type %<%T%> will be caught",
4552 TREE_TYPE (type));
4553 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
4554 TREE_TYPE (t ? t : objc_object_type));
4555 break;
4560 /* Record the data for the catch in the try context so that we can
4561 finalize it later. */
4562 t = build_stmt (input_location, CATCH_EXPR, type, compound);
4563 cur_try_context->current_catch = t;
4565 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4566 t = objc_build_exc_ptr ();
4567 t = convert (TREE_TYPE (decl), t);
4568 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4569 add_stmt (t);
4572 /* Called just after parsing the closing brace of a @catch clause. Close
4573 the open binding level, and record a CATCH_EXPR for it. */
4575 void
4576 objc_finish_catch_clause (void)
4578 tree c = cur_try_context->current_catch;
4579 cur_try_context->current_catch = NULL;
4580 cur_try_context->end_catch_locus = input_location;
4582 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
4583 append_to_statement_list (c, &cur_try_context->catch_list);
4586 /* Called after parsing a @finally clause and its associated BODY.
4587 Record the body for later placement. */
4589 void
4590 objc_build_finally_clause (location_t finally_locus, tree body)
4592 cur_try_context->finally_body = body;
4593 cur_try_context->finally_locus = finally_locus;
4594 cur_try_context->end_finally_locus = input_location;
4597 /* Called to finalize a @try construct. */
4599 tree
4600 objc_finish_try_stmt (void)
4602 struct objc_try_context *c = cur_try_context;
4603 tree stmt;
4605 if (c->catch_list == NULL && c->finally_body == NULL)
4606 error ("%<@try%> without %<@catch%> or %<@finally%>");
4608 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4609 if (flag_objc_sjlj_exceptions)
4611 bool save = in_late_binary_op;
4612 in_late_binary_op = true;
4613 if (!cur_try_context->finally_body)
4615 cur_try_context->finally_locus = input_location;
4616 cur_try_context->end_finally_locus = input_location;
4618 stmt = next_sjlj_build_try_catch_finally ();
4619 in_late_binary_op = save;
4621 else
4623 /* Otherwise, nest the CATCH inside a FINALLY. */
4624 stmt = c->try_body;
4625 if (c->catch_list)
4627 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
4628 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4630 if (c->finally_body)
4632 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
4633 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4636 add_stmt (stmt);
4638 cur_try_context = c->outer;
4639 free (c);
4640 return stmt;
4643 tree
4644 objc_build_throw_stmt (location_t loc, tree throw_expr)
4646 tree args;
4648 if (!flag_objc_exceptions)
4650 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4653 if (throw_expr == NULL)
4655 /* If we're not inside a @catch block, there is no "current
4656 exception" to be rethrown. */
4657 if (cur_try_context == NULL
4658 || cur_try_context->current_catch == NULL)
4660 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
4661 return NULL_TREE;
4664 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4665 value that we get from the runtime. */
4666 throw_expr = objc_build_exc_ptr ();
4669 /* A throw is just a call to the runtime throw function with the
4670 object as a parameter. */
4671 args = tree_cons (NULL, throw_expr, NULL);
4672 return add_stmt (build_function_call (loc,
4673 objc_exception_throw_decl, args));
4676 tree
4677 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4679 tree args, call;
4681 /* First lock the mutex. */
4682 mutex = save_expr (mutex);
4683 args = tree_cons (NULL, mutex, NULL);
4684 call = build_function_call (input_location,
4685 objc_sync_enter_decl, args);
4686 SET_EXPR_LOCATION (call, start_locus);
4687 add_stmt (call);
4689 /* Build the mutex unlock. */
4690 args = tree_cons (NULL, mutex, NULL);
4691 call = build_function_call (input_location,
4692 objc_sync_exit_decl, args);
4693 SET_EXPR_LOCATION (call, input_location);
4695 /* Put the that and the body in a TRY_FINALLY. */
4696 objc_begin_try_stmt (start_locus, body);
4697 objc_build_finally_clause (input_location, call);
4698 return objc_finish_try_stmt ();
4702 /* Predefine the following data type:
4704 struct _objc_exception_data
4706 int buf[OBJC_JBLEN];
4707 void *pointers[4];
4708 }; */
4710 /* The following yuckiness should prevent users from having to #include
4711 <setjmp.h> in their code... */
4713 /* Define to a harmless positive value so the below code doesn't die. */
4714 #ifndef OBJC_JBLEN
4715 #define OBJC_JBLEN 18
4716 #endif
4718 static void
4719 build_next_objc_exception_stuff (void)
4721 tree decls, temp_type, *chain = NULL;
4723 objc_exception_data_template
4724 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4726 /* int buf[OBJC_JBLEN]; */
4728 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
4729 decls = add_field_decl (temp_type, "buf", &chain);
4731 /* void *pointers[4]; */
4733 temp_type = build_sized_array_type (ptr_type_node, 4);
4734 add_field_decl (temp_type, "pointers", &chain);
4736 objc_finish_struct (objc_exception_data_template, decls);
4738 /* int _setjmp(...); */
4739 /* If the user includes <setjmp.h>, this shall be superseded by
4740 'int _setjmp(jmp_buf);' */
4741 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
4742 objc_setjmp_decl
4743 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4745 /* id objc_exception_extract(struct _objc_exception_data *); */
4746 temp_type
4747 = build_function_type_list (objc_object_type,
4748 build_pointer_type (objc_exception_data_template),
4749 NULL_TREE);
4750 objc_exception_extract_decl
4751 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4752 NULL_TREE);
4753 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4754 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4755 temp_type
4756 = build_function_type_list (void_type_node,
4757 build_pointer_type (objc_exception_data_template),
4758 NULL_TREE);
4759 objc_exception_try_enter_decl
4760 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4761 NULL_TREE);
4762 objc_exception_try_exit_decl
4763 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4764 NULL_TREE);
4766 /* int objc_exception_match(id, id); */
4767 temp_type
4768 = build_function_type_list (integer_type_node,
4769 objc_object_type, objc_object_type, NULL_TREE);
4770 objc_exception_match_decl
4771 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4772 NULL_TREE);
4774 /* id objc_assign_ivar (id, id, unsigned int); */
4775 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4776 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4777 temp_type
4778 = build_function_type_list (objc_object_type,
4779 objc_object_type,
4780 objc_object_type,
4781 unsigned_type_node,
4782 NULL_TREE);
4783 objc_assign_ivar_decl
4784 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4785 NULL, NULL_TREE);
4786 #ifdef OFFS_ASSIGNIVAR_FAST
4787 objc_assign_ivar_fast_decl
4788 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4789 NOT_BUILT_IN, NULL, NULL_TREE);
4790 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4791 = tree_cons (get_identifier ("hard_coded_address"),
4792 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4793 NULL_TREE);
4794 #else
4795 /* Default to slower ivar method. */
4796 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4797 #endif
4799 /* id objc_assign_global (id, id *); */
4800 /* id objc_assign_strongCast (id, id *); */
4801 temp_type = build_function_type_list (objc_object_type,
4802 objc_object_type,
4803 build_pointer_type (objc_object_type),
4804 NULL_TREE);
4805 objc_assign_global_decl
4806 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4807 NULL_TREE);
4808 objc_assign_strong_cast_decl
4809 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4810 NULL_TREE);
4813 static void
4814 build_objc_exception_stuff (void)
4816 tree noreturn_list, nothrow_list, temp_type;
4818 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4819 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4821 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4822 /* void objc_sync_enter(id); */
4823 /* void objc_sync_exit(id); */
4824 temp_type = build_function_type_list (void_type_node,
4825 objc_object_type,
4826 NULL_TREE);
4827 objc_exception_throw_decl
4828 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4829 noreturn_list);
4830 objc_sync_enter_decl
4831 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4832 NULL, nothrow_list);
4833 objc_sync_exit_decl
4834 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4835 NULL, nothrow_list);
4838 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4839 name as the class:
4841 struct <classname> {
4842 struct _objc_class *isa;
4844 }; */
4846 static void
4847 build_private_template (tree klass)
4849 if (!CLASS_STATIC_TEMPLATE (klass))
4851 tree record = objc_build_struct (klass,
4852 get_class_ivars (klass, false),
4853 CLASS_SUPER_NAME (klass));
4855 /* Set the TREE_USED bit for this struct, so that stab generator
4856 can emit stabs for this struct type. */
4857 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4858 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4862 /* Begin code generation for protocols... */
4864 /* struct _objc_protocol {
4865 struct _objc_class *isa;
4866 char *protocol_name;
4867 struct _objc_protocol **protocol_list;
4868 struct _objc__method_prototype_list *instance_methods;
4869 struct _objc__method_prototype_list *class_methods;
4870 }; */
4872 static void
4873 build_protocol_template (void)
4875 tree ptype, decls, *chain = NULL;
4877 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4879 /* struct _objc_class *isa; */
4880 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4881 get_identifier (UTAG_CLASS)));
4882 decls = add_field_decl (ptype, "isa", &chain);
4884 /* char *protocol_name; */
4885 add_field_decl (string_type_node, "protocol_name", &chain);
4887 /* struct _objc_protocol **protocol_list; */
4888 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4889 add_field_decl (ptype, "protocol_list", &chain);
4891 /* struct _objc__method_prototype_list *instance_methods; */
4892 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
4894 /* struct _objc__method_prototype_list *class_methods; */
4895 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
4897 objc_finish_struct (objc_protocol_template, decls);
4900 static tree
4901 build_descriptor_table_initializer (tree type, tree entries)
4903 VEC(constructor_elt,gc) *inits = NULL;
4907 VEC(constructor_elt,gc) *elts = NULL;
4909 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4910 build_selector (METHOD_SEL_NAME (entries)));
4911 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4912 add_objc_string (METHOD_ENCODING (entries),
4913 meth_var_types));
4915 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
4916 objc_build_constructor (type, elts));
4918 entries = DECL_CHAIN (entries);
4920 while (entries);
4922 return objc_build_constructor (build_array_type (type, 0), inits);
4925 /* struct objc_method_prototype_list {
4926 int count;
4927 struct objc_method_prototype {
4928 SEL name;
4929 char *types;
4930 } list[1];
4931 }; */
4933 static tree
4934 build_method_prototype_list_template (tree list_type, int size)
4936 tree objc_ivar_list_record;
4937 tree array_type, decls, *chain = NULL;
4939 /* Generate an unnamed struct definition. */
4941 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4943 /* int method_count; */
4944 decls = add_field_decl (integer_type_node, "method_count", &chain);
4946 /* struct objc_method method_list[]; */
4947 array_type = build_sized_array_type (list_type, size);
4948 add_field_decl (array_type, "method_list", &chain);
4950 objc_finish_struct (objc_ivar_list_record, decls);
4952 return objc_ivar_list_record;
4955 static tree
4956 build_method_prototype_template (void)
4958 tree proto_record;
4959 tree decls, *chain = NULL;
4961 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4963 /* SEL _cmd; */
4964 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
4966 /* char *method_types; */
4967 add_field_decl (string_type_node, "method_types", &chain);
4969 objc_finish_struct (proto_record, decls);
4971 return proto_record;
4974 static tree
4975 objc_method_parm_type (tree type)
4977 type = TREE_VALUE (TREE_TYPE (type));
4978 if (TREE_CODE (type) == TYPE_DECL)
4979 type = TREE_TYPE (type);
4980 return type;
4983 static int
4984 objc_encoded_type_size (tree type)
4986 int sz = int_size_in_bytes (type);
4988 /* Make all integer and enum types at least as large
4989 as an int. */
4990 if (sz > 0 && INTEGRAL_TYPE_P (type))
4991 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4992 /* Treat arrays as pointers, since that's how they're
4993 passed in. */
4994 else if (TREE_CODE (type) == ARRAY_TYPE)
4995 sz = int_size_in_bytes (ptr_type_node);
4996 return sz;
4999 /* Encode a method prototype.
5001 The format is described in gcc/doc/objc.texi, section 'Method
5002 signatures'.
5004 static tree
5005 encode_method_prototype (tree method_decl)
5007 tree parms;
5008 int parm_offset, i;
5009 char buf[40];
5010 tree result;
5012 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5013 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5015 /* Encode return type. */
5016 encode_type (objc_method_parm_type (method_decl),
5017 obstack_object_size (&util_obstack),
5018 OBJC_ENCODE_INLINE_DEFS);
5020 /* Stack size. */
5021 /* The first two arguments (self and _cmd) are pointers; account for
5022 their size. */
5023 i = int_size_in_bytes (ptr_type_node);
5024 parm_offset = 2 * i;
5025 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5026 parms = DECL_CHAIN (parms))
5028 tree type = objc_method_parm_type (parms);
5029 int sz = objc_encoded_type_size (type);
5031 /* If a type size is not known, bail out. */
5032 if (sz < 0)
5034 error ("type %q+D does not have a known size",
5035 type);
5036 /* Pretend that the encoding succeeded; the compilation will
5037 fail nevertheless. */
5038 goto finish_encoding;
5040 parm_offset += sz;
5043 sprintf (buf, "%d@0:%d", parm_offset, i);
5044 obstack_grow (&util_obstack, buf, strlen (buf));
5046 /* Argument types. */
5047 parm_offset = 2 * i;
5048 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5049 parms = DECL_CHAIN (parms))
5051 tree type = objc_method_parm_type (parms);
5053 /* Process argument qualifiers for user supplied arguments. */
5054 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5056 /* Type. */
5057 encode_type (type, obstack_object_size (&util_obstack),
5058 OBJC_ENCODE_INLINE_DEFS);
5060 /* Compute offset. */
5061 sprintf (buf, "%d", parm_offset);
5062 parm_offset += objc_encoded_type_size (type);
5064 obstack_grow (&util_obstack, buf, strlen (buf));
5067 finish_encoding:
5068 obstack_1grow (&util_obstack, '\0');
5069 result = get_identifier (XOBFINISH (&util_obstack, char *));
5070 obstack_free (&util_obstack, util_firstobj);
5071 return result;
5074 static tree
5075 generate_descriptor_table (tree type, const char *name, int size, tree list,
5076 tree proto)
5078 tree decl;
5079 VEC(constructor_elt,gc) *v = NULL;
5081 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5083 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5084 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5086 finish_var_decl (decl, objc_build_constructor (type, v));
5088 return decl;
5091 static void
5092 generate_method_descriptors (tree protocol)
5094 tree initlist, chain, method_list_template;
5095 int size;
5097 if (!objc_method_prototype_template)
5098 objc_method_prototype_template = build_method_prototype_template ();
5100 chain = PROTOCOL_CLS_METHODS (protocol);
5101 if (chain)
5103 size = list_length (chain);
5105 method_list_template
5106 = build_method_prototype_list_template (objc_method_prototype_template,
5107 size);
5109 initlist
5110 = build_descriptor_table_initializer (objc_method_prototype_template,
5111 chain);
5113 UOBJC_CLASS_METHODS_decl
5114 = generate_descriptor_table (method_list_template,
5115 "_OBJC_PROTOCOL_CLASS_METHODS",
5116 size, initlist, protocol);
5118 else
5119 UOBJC_CLASS_METHODS_decl = 0;
5121 chain = PROTOCOL_NST_METHODS (protocol);
5122 if (chain)
5124 size = list_length (chain);
5126 method_list_template
5127 = build_method_prototype_list_template (objc_method_prototype_template,
5128 size);
5129 initlist
5130 = build_descriptor_table_initializer (objc_method_prototype_template,
5131 chain);
5133 UOBJC_INSTANCE_METHODS_decl
5134 = generate_descriptor_table (method_list_template,
5135 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5136 size, initlist, protocol);
5138 else
5139 UOBJC_INSTANCE_METHODS_decl = 0;
5142 static void
5143 generate_protocol_references (tree plist)
5145 tree lproto;
5147 /* Forward declare protocols referenced. */
5148 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5150 tree proto = TREE_VALUE (lproto);
5152 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5153 && PROTOCOL_NAME (proto))
5155 if (! PROTOCOL_FORWARD_DECL (proto))
5156 build_protocol_reference (proto);
5158 if (PROTOCOL_LIST (proto))
5159 generate_protocol_references (PROTOCOL_LIST (proto));
5164 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5165 current class. */
5166 #ifdef OBJCPLUS
5167 static void
5168 objc_generate_cxx_ctor_or_dtor (bool dtor)
5170 tree fn, body, compound_stmt, ivar;
5172 /* - (id) .cxx_construct { ... return self; } */
5173 /* - (void) .cxx_construct { ... } */
5175 objc_start_method_definition
5176 (false /* is_class_method */,
5177 objc_build_method_signature (false /* is_class_method */,
5178 build_tree_list (NULL_TREE,
5179 dtor
5180 ? void_type_node
5181 : objc_object_type),
5182 get_identifier (dtor
5183 ? TAG_CXX_DESTRUCT
5184 : TAG_CXX_CONSTRUCT),
5185 make_node (TREE_LIST),
5186 false), NULL);
5187 body = begin_function_body ();
5188 compound_stmt = begin_compound_stmt (0);
5190 ivar = CLASS_IVARS (implementation_template);
5191 /* Destroy ivars in reverse order. */
5192 if (dtor)
5193 ivar = nreverse (copy_list (ivar));
5195 for (; ivar; ivar = TREE_CHAIN (ivar))
5197 if (TREE_CODE (ivar) == FIELD_DECL)
5199 tree type = TREE_TYPE (ivar);
5201 /* Call the ivar's default constructor or destructor. Do not
5202 call the destructor unless a corresponding constructor call
5203 has also been made (or is not needed). */
5204 if (MAYBE_CLASS_TYPE_P (type)
5205 && (dtor
5206 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5207 && (!TYPE_NEEDS_CONSTRUCTING (type)
5208 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5209 : (TYPE_NEEDS_CONSTRUCTING (type)
5210 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5211 finish_expr_stmt
5212 (build_special_member_call
5213 (build_ivar_reference (DECL_NAME (ivar)),
5214 dtor ? complete_dtor_identifier : complete_ctor_identifier,
5215 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5219 /* The constructor returns 'self'. */
5220 if (!dtor)
5221 finish_return_stmt (self_decl);
5223 finish_compound_stmt (compound_stmt);
5224 finish_function_body (body);
5225 fn = current_function_decl;
5226 finish_function ();
5227 objc_finish_method_definition (fn);
5230 /* The following routine will examine the current @interface for any
5231 non-POD C++ ivars requiring non-trivial construction and/or
5232 destruction, and then synthesize special '- .cxx_construct' and/or
5233 '- .cxx_destruct' methods which will run the appropriate
5234 construction or destruction code. Note that ivars inherited from
5235 super-classes are _not_ considered. */
5236 static void
5237 objc_generate_cxx_cdtors (void)
5239 bool need_ctor = false, need_dtor = false;
5240 tree ivar;
5242 /* Error case, due to possibly an extra @end. */
5243 if (!objc_implementation_context)
5244 return;
5246 /* We do not want to do this for categories, since they do not have
5247 their own ivars. */
5249 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
5250 return;
5252 /* First, determine if we even need a constructor and/or destructor. */
5254 for (ivar = CLASS_IVARS (implementation_template); ivar;
5255 ivar = TREE_CHAIN (ivar))
5257 if (TREE_CODE (ivar) == FIELD_DECL)
5259 tree type = TREE_TYPE (ivar);
5261 if (MAYBE_CLASS_TYPE_P (type))
5263 if (TYPE_NEEDS_CONSTRUCTING (type)
5264 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
5265 /* NB: If a default constructor is not available, we will not
5266 be able to initialize this ivar; the add_instance_variable()
5267 routine will already have warned about this. */
5268 need_ctor = true;
5270 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5271 && (!TYPE_NEEDS_CONSTRUCTING (type)
5272 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5273 /* NB: If a default constructor is not available, we will not
5274 call the destructor either, for symmetry. */
5275 need_dtor = true;
5280 /* Generate '- .cxx_construct' if needed. */
5282 if (need_ctor)
5283 objc_generate_cxx_ctor_or_dtor (false);
5285 /* Generate '- .cxx_destruct' if needed. */
5287 if (need_dtor)
5288 objc_generate_cxx_ctor_or_dtor (true);
5290 /* The 'imp_list' variable points at an imp_entry record for the current
5291 @implementation. Record the existence of '- .cxx_construct' and/or
5292 '- .cxx_destruct' methods therein; it will be included in the
5293 metadata for the class. */
5294 if (flag_next_runtime)
5295 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
5297 #endif
5299 /* For each protocol which was referenced either from a @protocol()
5300 expression, or because a class/category implements it (then a
5301 pointer to the protocol is stored in the struct describing the
5302 class/category), we create a statically allocated instance of the
5303 Protocol class. The code is written in such a way as to generate
5304 as few Protocol objects as possible; we generate a unique Protocol
5305 instance for each protocol, and we don't generate a Protocol
5306 instance if the protocol is never referenced (either from a
5307 @protocol() or from a class/category implementation). These
5308 statically allocated objects can be referred to via the static
5309 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5311 The statically allocated Protocol objects that we generate here
5312 need to be fixed up at runtime in order to be used: the 'isa'
5313 pointer of the objects need to be set up to point to the 'Protocol'
5314 class, as known at runtime.
5316 The NeXT runtime fixes up all protocols at program startup time,
5317 before main() is entered. It uses a low-level trick to look up all
5318 those symbols, then loops on them and fixes them up.
5320 The GNU runtime as well fixes up all protocols before user code
5321 from the module is executed; it requires pointers to those symbols
5322 to be put in the objc_symtab (which is then passed as argument to
5323 the function __objc_exec_class() which the compiler sets up to be
5324 executed automatically when the module is loaded); setup of those
5325 Protocol objects happen in two ways in the GNU runtime: all
5326 Protocol objects referred to by a class or category implementation
5327 are fixed up when the class/category is loaded; all Protocol
5328 objects referred to by a @protocol() expression are added by the
5329 compiler to the list of statically allocated instances to fixup
5330 (the same list holding the statically allocated constant string
5331 objects). Because, as explained above, the compiler generates as
5332 few Protocol objects as possible, some Protocol object might end up
5333 being referenced multiple times when compiled with the GNU runtime,
5334 and end up being fixed up multiple times at runtime initialization.
5335 But that doesn't hurt, it's just a little inefficient. */
5337 static void
5338 generate_protocols (void)
5340 tree p, encoding;
5341 tree decl;
5342 tree initlist, protocol_name_expr, refs_decl, refs_expr;
5344 /* If a protocol was directly referenced, pull in indirect references. */
5345 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5346 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
5347 generate_protocol_references (PROTOCOL_LIST (p));
5349 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5351 tree nst_methods = PROTOCOL_NST_METHODS (p);
5352 tree cls_methods = PROTOCOL_CLS_METHODS (p);
5354 /* If protocol wasn't referenced, don't generate any code. */
5355 decl = PROTOCOL_FORWARD_DECL (p);
5357 if (!decl)
5358 continue;
5360 /* Make sure we link in the Protocol class. */
5361 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5363 while (nst_methods)
5365 if (! METHOD_ENCODING (nst_methods))
5367 encoding = encode_method_prototype (nst_methods);
5368 METHOD_ENCODING (nst_methods) = encoding;
5370 nst_methods = DECL_CHAIN (nst_methods);
5373 while (cls_methods)
5375 if (! METHOD_ENCODING (cls_methods))
5377 encoding = encode_method_prototype (cls_methods);
5378 METHOD_ENCODING (cls_methods) = encoding;
5381 cls_methods = DECL_CHAIN (cls_methods);
5383 generate_method_descriptors (p);
5385 if (PROTOCOL_LIST (p))
5386 refs_decl = generate_protocol_list (p);
5387 else
5388 refs_decl = 0;
5390 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5391 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
5393 if (refs_decl)
5394 refs_expr = convert (build_pointer_type (build_pointer_type
5395 (objc_protocol_template)),
5396 build_unary_op (input_location,
5397 ADDR_EXPR, refs_decl, 0));
5398 else
5399 refs_expr = build_int_cst (NULL_TREE, 0);
5401 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5402 by generate_method_descriptors, which is called above. */
5403 initlist = build_protocol_initializer (TREE_TYPE (decl),
5404 protocol_name_expr, refs_expr,
5405 UOBJC_INSTANCE_METHODS_decl,
5406 UOBJC_CLASS_METHODS_decl);
5407 finish_var_decl (decl, initlist);
5411 static tree
5412 build_protocol_initializer (tree type, tree protocol_name,
5413 tree protocol_list, tree instance_methods,
5414 tree class_methods)
5416 tree expr;
5417 tree cast_type = build_pointer_type
5418 (xref_tag (RECORD_TYPE,
5419 get_identifier (UTAG_CLASS)));
5420 VEC(constructor_elt,gc) *inits = NULL;
5422 /* Filling the "isa" in with one allows the runtime system to
5423 detect that the version change...should remove before final release. */
5425 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
5426 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5427 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
5428 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
5430 if (!instance_methods)
5431 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5432 else
5434 expr = convert (objc_method_proto_list_ptr,
5435 build_unary_op (input_location,
5436 ADDR_EXPR, instance_methods, 0));
5437 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5440 if (!class_methods)
5441 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5442 else
5444 expr = convert (objc_method_proto_list_ptr,
5445 build_unary_op (input_location,
5446 ADDR_EXPR, class_methods, 0));
5447 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5450 return objc_build_constructor (type, inits);
5453 /* struct _objc_category {
5454 char *category_name;
5455 char *class_name;
5456 struct _objc_method_list *instance_methods;
5457 struct _objc_method_list *class_methods;
5458 struct _objc_protocol_list *protocols;
5459 }; */
5461 static void
5462 build_category_template (void)
5464 tree ptype, decls, *chain = NULL;
5466 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
5468 /* char *category_name; */
5469 decls = add_field_decl (string_type_node, "category_name", &chain);
5471 /* char *class_name; */
5472 add_field_decl (string_type_node, "class_name", &chain);
5474 /* struct _objc_method_list *instance_methods; */
5475 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
5477 /* struct _objc_method_list *class_methods; */
5478 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
5480 /* struct _objc_protocol **protocol_list; */
5481 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5482 add_field_decl (ptype, "protocol_list", &chain);
5484 objc_finish_struct (objc_category_template, decls);
5487 /* struct _objc_selector {
5488 SEL sel_id;
5489 char *sel_type;
5490 }; */
5492 static void
5493 build_selector_template (void)
5495 tree decls, *chain = NULL;
5497 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
5499 /* SEL sel_id; */
5500 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
5502 /* char *sel_type; */
5503 add_field_decl (string_type_node, "sel_type", &chain);
5505 objc_finish_struct (objc_selector_template, decls);
5508 /* struct _objc_class {
5509 struct _objc_class *isa;
5510 struct _objc_class *super_class;
5511 char *name;
5512 long version;
5513 long info;
5514 long instance_size;
5515 struct _objc_ivar_list *ivars;
5516 struct _objc_method_list *methods;
5517 #ifdef __NEXT_RUNTIME__
5518 struct objc_cache *cache;
5519 #else
5520 struct sarray *dtable;
5521 struct _objc_class *subclass_list;
5522 struct _objc_class *sibling_class;
5523 #endif
5524 struct _objc_protocol_list *protocols;
5525 #ifdef __NEXT_RUNTIME__
5526 void *sel_id;
5527 #endif
5528 void *gc_object_type;
5529 }; */
5531 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5532 the NeXT/Apple runtime; still, the compiler must generate them to
5533 maintain backward binary compatibility (and to allow for future
5534 expansion). */
5536 static void
5537 build_class_template (void)
5539 tree ptype, decls, *chain = NULL;
5541 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
5543 /* struct _objc_class *isa; */
5544 decls = add_field_decl (build_pointer_type (objc_class_template),
5545 "isa", &chain);
5547 /* struct _objc_class *super_class; */
5548 add_field_decl (build_pointer_type (objc_class_template),
5549 "super_class", &chain);
5551 /* char *name; */
5552 add_field_decl (string_type_node, "name", &chain);
5554 /* long version; */
5555 add_field_decl (long_integer_type_node, "version", &chain);
5557 /* long info; */
5558 add_field_decl (long_integer_type_node, "info", &chain);
5560 /* long instance_size; */
5561 add_field_decl (long_integer_type_node, "instance_size", &chain);
5563 /* struct _objc_ivar_list *ivars; */
5564 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
5566 /* struct _objc_method_list *methods; */
5567 add_field_decl (objc_method_list_ptr, "methods", &chain);
5569 if (flag_next_runtime)
5571 /* struct objc_cache *cache; */
5572 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5573 get_identifier ("objc_cache")));
5574 add_field_decl (ptype, "cache", &chain);
5576 else
5578 /* struct sarray *dtable; */
5579 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
5580 get_identifier ("sarray")));
5581 add_field_decl (ptype, "dtable", &chain);
5583 /* struct objc_class *subclass_list; */
5584 ptype = build_pointer_type (objc_class_template);
5585 add_field_decl (ptype, "subclass_list", &chain);
5587 /* struct objc_class *sibling_class; */
5588 ptype = build_pointer_type (objc_class_template);
5589 add_field_decl (ptype, "sibling_class", &chain);
5592 /* struct _objc_protocol **protocol_list; */
5593 ptype = build_pointer_type (build_pointer_type
5594 (xref_tag (RECORD_TYPE,
5595 get_identifier (UTAG_PROTOCOL))));
5596 add_field_decl (ptype, "protocol_list", &chain);
5598 if (flag_next_runtime)
5600 /* void *sel_id; */
5601 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
5604 /* void *gc_object_type; */
5605 add_field_decl (build_pointer_type (void_type_node),
5606 "gc_object_type", &chain);
5608 objc_finish_struct (objc_class_template, decls);
5611 /* Generate appropriate forward declarations for an implementation. */
5613 static void
5614 synth_forward_declarations (void)
5616 tree an_id;
5618 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5619 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5620 objc_class_template);
5622 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5623 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5624 objc_class_template);
5626 /* Pre-build the following entities - for speed/convenience. */
5628 an_id = get_identifier ("super_class");
5629 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5630 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5633 static void
5634 error_with_ivar (const char *message, tree decl)
5636 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5637 message, identifier_to_locale (gen_declaration (decl)));
5641 static void
5642 check_ivars (tree inter, tree imp)
5644 tree intdecls = CLASS_RAW_IVARS (inter);
5645 tree impdecls = CLASS_RAW_IVARS (imp);
5647 while (1)
5649 tree t1, t2;
5651 #ifdef OBJCPLUS
5652 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5653 intdecls = TREE_CHAIN (intdecls);
5654 #endif
5655 if (intdecls == 0 && impdecls == 0)
5656 break;
5657 if (intdecls == 0 || impdecls == 0)
5659 error ("inconsistent instance variable specification");
5660 break;
5663 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5665 if (!comptypes (t1, t2)
5666 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5667 DECL_INITIAL (impdecls)))
5669 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5671 error_with_ivar ("conflicting instance variable type",
5672 impdecls);
5673 error_with_ivar ("previous declaration of",
5674 intdecls);
5676 else /* both the type and the name don't match */
5678 error ("inconsistent instance variable specification");
5679 break;
5683 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5685 error_with_ivar ("conflicting instance variable name",
5686 impdecls);
5687 error_with_ivar ("previous declaration of",
5688 intdecls);
5691 intdecls = DECL_CHAIN (intdecls);
5692 impdecls = DECL_CHAIN (impdecls);
5696 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5697 This needs to be done just once per compilation. */
5699 /* struct _objc_super {
5700 struct _objc_object *self;
5701 struct _objc_class *super_class;
5702 }; */
5704 static void
5705 build_super_template (void)
5707 tree decls, *chain = NULL;
5709 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5711 /* struct _objc_object *self; */
5712 decls = add_field_decl (objc_object_type, "self", &chain);
5714 /* struct _objc_class *super_class; */
5715 add_field_decl (build_pointer_type (objc_class_template),
5716 "super_class", &chain);
5718 objc_finish_struct (objc_super_template, decls);
5721 /* struct _objc_ivar {
5722 char *ivar_name;
5723 char *ivar_type;
5724 int ivar_offset;
5725 }; */
5727 static tree
5728 build_ivar_template (void)
5730 tree objc_ivar_id, objc_ivar_record;
5731 tree decls, *chain = NULL;
5733 objc_ivar_id = get_identifier (UTAG_IVAR);
5734 objc_ivar_record = objc_start_struct (objc_ivar_id);
5736 /* char *ivar_name; */
5737 decls = add_field_decl (string_type_node, "ivar_name", &chain);
5739 /* char *ivar_type; */
5740 add_field_decl (string_type_node, "ivar_type", &chain);
5742 /* int ivar_offset; */
5743 add_field_decl (integer_type_node, "ivar_offset", &chain);
5745 objc_finish_struct (objc_ivar_record, decls);
5747 return objc_ivar_record;
5750 /* struct {
5751 int ivar_count;
5752 struct objc_ivar ivar_list[ivar_count];
5753 }; */
5755 static tree
5756 build_ivar_list_template (tree list_type, int size)
5758 tree objc_ivar_list_record;
5759 tree array_type, decls, *chain = NULL;
5761 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5763 /* int ivar_count; */
5764 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
5766 /* struct objc_ivar ivar_list[]; */
5767 array_type = build_sized_array_type (list_type, size);
5768 add_field_decl (array_type, "ivar_list", &chain);
5770 objc_finish_struct (objc_ivar_list_record, decls);
5772 return objc_ivar_list_record;
5775 /* struct {
5776 struct _objc__method_prototype_list *method_next;
5777 int method_count;
5778 struct objc_method method_list[method_count];
5779 }; */
5781 static tree
5782 build_method_list_template (tree list_type, int size)
5784 tree objc_ivar_list_record;
5785 tree array_type, decls, *chain = NULL;
5787 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5789 /* struct _objc__method_prototype_list *method_next; */
5790 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
5792 /* int method_count; */
5793 add_field_decl (integer_type_node, "method_count", &chain);
5795 /* struct objc_method method_list[]; */
5796 array_type = build_sized_array_type (list_type, size);
5797 add_field_decl (array_type, "method_list", &chain);
5799 objc_finish_struct (objc_ivar_list_record, decls);
5801 return objc_ivar_list_record;
5804 static tree
5805 build_ivar_list_initializer (tree type, tree field_decl)
5807 VEC(constructor_elt,gc) *inits = NULL;
5811 VEC(constructor_elt,gc) *ivar = NULL;
5812 tree id;
5814 /* Set name. */
5815 if (DECL_NAME (field_decl))
5816 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
5817 add_objc_string (DECL_NAME (field_decl),
5818 meth_var_names));
5819 else
5820 /* Unnamed bit-field ivar (yuck). */
5821 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
5823 /* Set type. */
5824 encode_field_decl (field_decl,
5825 obstack_object_size (&util_obstack),
5826 OBJC_ENCODE_DONT_INLINE_DEFS);
5828 /* Null terminate string. */
5829 obstack_1grow (&util_obstack, 0);
5830 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5831 meth_var_types);
5832 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
5833 obstack_free (&util_obstack, util_firstobj);
5835 /* Set offset. */
5836 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
5837 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5838 objc_build_constructor (type, ivar));
5840 field_decl = DECL_CHAIN (field_decl);
5841 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5843 while (field_decl);
5845 return objc_build_constructor (build_array_type (type, 0), inits);
5848 static tree
5849 generate_ivars_list (tree type, const char *name, int size, tree list)
5851 tree decl;
5852 VEC(constructor_elt,gc) *inits = NULL;
5854 decl = start_var_decl (type, synth_id_with_class_suffix
5855 (name, objc_implementation_context));
5857 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
5858 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
5860 finish_var_decl (decl,
5861 objc_build_constructor (TREE_TYPE (decl), inits));
5863 return decl;
5866 /* Count only the fields occurring in T. */
5868 static int
5869 ivar_list_length (tree t)
5871 int count = 0;
5873 for (; t; t = DECL_CHAIN (t))
5874 if (TREE_CODE (t) == FIELD_DECL)
5875 ++count;
5877 return count;
5880 static void
5881 generate_ivar_lists (void)
5883 tree initlist, ivar_list_template, chain;
5884 int size;
5886 generating_instance_variables = 1;
5888 if (!objc_ivar_template)
5889 objc_ivar_template = build_ivar_template ();
5891 /* Only generate class variables for the root of the inheritance
5892 hierarchy since these will be the same for every class. */
5894 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5895 && (chain = TYPE_FIELDS (objc_class_template)))
5897 size = ivar_list_length (chain);
5899 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5900 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5902 UOBJC_CLASS_VARIABLES_decl
5903 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5904 size, initlist);
5906 else
5907 UOBJC_CLASS_VARIABLES_decl = 0;
5909 chain = CLASS_IVARS (implementation_template);
5910 if (chain)
5912 size = ivar_list_length (chain);
5913 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5914 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5916 UOBJC_INSTANCE_VARIABLES_decl
5917 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5918 size, initlist);
5920 else
5921 UOBJC_INSTANCE_VARIABLES_decl = 0;
5923 generating_instance_variables = 0;
5926 static tree
5927 build_dispatch_table_initializer (tree type, tree entries)
5929 VEC(constructor_elt,gc) *inits = NULL;
5933 VEC(constructor_elt,gc) *elems = NULL;
5934 tree expr;
5936 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5937 build_selector (METHOD_SEL_NAME (entries)));
5939 /* Generate the method encoding if we don't have one already. */
5940 if (! METHOD_ENCODING (entries))
5941 METHOD_ENCODING (entries) =
5942 encode_method_prototype (entries);
5944 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5945 add_objc_string (METHOD_ENCODING (entries),
5946 meth_var_types));
5948 expr = convert (ptr_type_node,
5949 build_unary_op (input_location, ADDR_EXPR,
5950 METHOD_DEFINITION (entries), 1));
5951 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
5953 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5954 objc_build_constructor (type, elems));
5956 entries = DECL_CHAIN (entries);
5958 while (entries);
5960 return objc_build_constructor (build_array_type (type, 0), inits);
5963 /* To accomplish method prototyping without generating all kinds of
5964 inane warnings, the definition of the dispatch table entries were
5965 changed from:
5967 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5969 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5971 static tree
5972 build_method_template (void)
5974 tree _SLT_record;
5975 tree decls, *chain = NULL;
5977 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5979 /* SEL _cmd; */
5980 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5982 /* char *method_types; */
5983 add_field_decl (string_type_node, "method_types", &chain);
5985 /* void *_imp; */
5986 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
5988 objc_finish_struct (_SLT_record, decls);
5990 return _SLT_record;
5994 static tree
5995 generate_dispatch_table (tree type, const char *name, int size, tree list)
5997 tree decl;
5998 VEC(constructor_elt,gc) *v = NULL;
6000 decl = start_var_decl (type, synth_id_with_class_suffix
6001 (name, objc_implementation_context));
6003 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6004 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6005 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6007 finish_var_decl (decl,
6008 objc_build_constructor (TREE_TYPE (decl), v));
6010 return decl;
6013 static void
6014 mark_referenced_methods (void)
6016 struct imp_entry *impent;
6017 tree chain;
6019 for (impent = imp_list; impent; impent = impent->next)
6021 chain = CLASS_CLS_METHODS (impent->imp_context);
6022 while (chain)
6024 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6025 chain = DECL_CHAIN (chain);
6028 chain = CLASS_NST_METHODS (impent->imp_context);
6029 while (chain)
6031 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6032 chain = DECL_CHAIN (chain);
6037 static void
6038 generate_dispatch_tables (void)
6040 tree initlist, chain, method_list_template;
6041 int size;
6043 if (!objc_method_template)
6044 objc_method_template = build_method_template ();
6046 chain = CLASS_CLS_METHODS (objc_implementation_context);
6047 if (chain)
6049 size = list_length (chain);
6051 method_list_template
6052 = build_method_list_template (objc_method_template, size);
6053 initlist
6054 = build_dispatch_table_initializer (objc_method_template, chain);
6056 UOBJC_CLASS_METHODS_decl
6057 = generate_dispatch_table (method_list_template,
6058 ((TREE_CODE (objc_implementation_context)
6059 == CLASS_IMPLEMENTATION_TYPE)
6060 ? "_OBJC_CLASS_METHODS"
6061 : "_OBJC_CATEGORY_CLASS_METHODS"),
6062 size, initlist);
6064 else
6065 UOBJC_CLASS_METHODS_decl = 0;
6067 chain = CLASS_NST_METHODS (objc_implementation_context);
6068 if (chain)
6070 size = list_length (chain);
6072 method_list_template
6073 = build_method_list_template (objc_method_template, size);
6074 initlist
6075 = build_dispatch_table_initializer (objc_method_template, chain);
6077 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6078 UOBJC_INSTANCE_METHODS_decl
6079 = generate_dispatch_table (method_list_template,
6080 "_OBJC_INSTANCE_METHODS",
6081 size, initlist);
6082 else
6083 /* We have a category. */
6084 UOBJC_INSTANCE_METHODS_decl
6085 = generate_dispatch_table (method_list_template,
6086 "_OBJC_CATEGORY_INSTANCE_METHODS",
6087 size, initlist);
6089 else
6090 UOBJC_INSTANCE_METHODS_decl = 0;
6093 static tree
6094 generate_protocol_list (tree i_or_p)
6096 tree array_type, ptype, refs_decl, lproto, e, plist;
6097 int size = 0;
6098 const char *ref_name;
6099 VEC(constructor_elt,gc) *v = NULL;
6101 switch (TREE_CODE (i_or_p))
6103 case CLASS_INTERFACE_TYPE:
6104 case CATEGORY_INTERFACE_TYPE:
6105 plist = CLASS_PROTOCOL_LIST (i_or_p);
6106 break;
6107 case PROTOCOL_INTERFACE_TYPE:
6108 plist = PROTOCOL_LIST (i_or_p);
6109 break;
6110 default:
6111 gcc_unreachable ();
6114 /* Compute size. */
6115 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6116 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6117 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6118 size++;
6120 /* Build initializer. */
6121 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6122 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6123 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6125 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6127 tree pval = TREE_VALUE (lproto);
6129 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6130 && PROTOCOL_FORWARD_DECL (pval))
6132 e = build_unary_op (input_location, ADDR_EXPR,
6133 PROTOCOL_FORWARD_DECL (pval), 0);
6134 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6138 /* static struct objc_protocol *refs[n]; */
6140 switch (TREE_CODE (i_or_p))
6142 case PROTOCOL_INTERFACE_TYPE:
6143 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6144 break;
6145 case CLASS_INTERFACE_TYPE:
6146 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6147 break;
6148 case CATEGORY_INTERFACE_TYPE:
6149 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6150 break;
6151 default:
6152 gcc_unreachable ();
6155 ptype = build_pointer_type (objc_protocol_template);
6156 array_type = build_sized_array_type (ptype, size + 3);
6157 refs_decl = start_var_decl (array_type, ref_name);
6159 finish_var_decl (refs_decl,
6160 objc_build_constructor (TREE_TYPE (refs_decl), v));
6162 return refs_decl;
6165 static tree
6166 build_category_initializer (tree type, tree cat_name, tree class_name,
6167 tree instance_methods, tree class_methods,
6168 tree protocol_list)
6170 tree expr;
6171 VEC(constructor_elt,gc) *v = NULL;
6173 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6174 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6176 if (!instance_methods)
6177 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6178 else
6180 expr = convert (objc_method_list_ptr,
6181 build_unary_op (input_location, ADDR_EXPR,
6182 instance_methods, 0));
6183 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6185 if (!class_methods)
6186 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6187 else
6189 expr = convert (objc_method_list_ptr,
6190 build_unary_op (input_location, ADDR_EXPR,
6191 class_methods, 0));
6192 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6195 /* protocol_list = */
6196 if (!protocol_list)
6197 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6198 else
6200 expr = convert (build_pointer_type
6201 (build_pointer_type
6202 (objc_protocol_template)),
6203 build_unary_op (input_location, ADDR_EXPR,
6204 protocol_list, 0));
6205 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6208 return objc_build_constructor (type, v);
6211 /* struct _objc_class {
6212 struct objc_class *isa;
6213 struct objc_class *super_class;
6214 char *name;
6215 long version;
6216 long info;
6217 long instance_size;
6218 struct objc_ivar_list *ivars;
6219 struct objc_method_list *methods;
6220 if (flag_next_runtime)
6221 struct objc_cache *cache;
6222 else {
6223 struct sarray *dtable;
6224 struct objc_class *subclass_list;
6225 struct objc_class *sibling_class;
6227 struct objc_protocol_list *protocols;
6228 if (flag_next_runtime)
6229 void *sel_id;
6230 void *gc_object_type;
6231 }; */
6233 static tree
6234 build_shared_structure_initializer (tree type, tree isa, tree super,
6235 tree name, tree size, int status,
6236 tree dispatch_table, tree ivar_list,
6237 tree protocol_list)
6239 tree expr;
6240 VEC(constructor_elt,gc) *v = NULL;
6242 /* isa = */
6243 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
6245 /* super_class = */
6246 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
6248 /* name = */
6249 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
6251 /* version = */
6252 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6253 build_int_cst (long_integer_type_node, 0));
6255 /* info = */
6256 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6257 build_int_cst (long_integer_type_node, status));
6259 /* instance_size = */
6260 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6261 convert (long_integer_type_node, size));
6263 /* objc_ivar_list = */
6264 if (!ivar_list)
6265 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6266 else
6268 expr = convert (objc_ivar_list_ptr,
6269 build_unary_op (input_location, ADDR_EXPR,
6270 ivar_list, 0));
6271 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6274 /* objc_method_list = */
6275 if (!dispatch_table)
6276 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6277 else
6279 expr = convert (objc_method_list_ptr,
6280 build_unary_op (input_location, ADDR_EXPR,
6281 dispatch_table, 0));
6282 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6285 if (flag_next_runtime)
6286 /* method_cache = */
6287 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6288 else
6290 /* dtable = */
6291 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6293 /* subclass_list = */
6294 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6296 /* sibling_class = */
6297 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6300 /* protocol_list = */
6301 if (! protocol_list)
6302 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6303 else
6305 expr = convert (build_pointer_type
6306 (build_pointer_type
6307 (objc_protocol_template)),
6308 build_unary_op (input_location, ADDR_EXPR,
6309 protocol_list, 0));
6310 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6313 if (flag_next_runtime)
6314 /* sel_id = NULL */
6315 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6317 /* gc_object_type = NULL */
6318 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6320 return objc_build_constructor (type, v);
6323 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6325 static inline tree
6326 lookup_category (tree klass, tree cat_name)
6328 tree category = CLASS_CATEGORY_LIST (klass);
6330 while (category && CLASS_SUPER_NAME (category) != cat_name)
6331 category = CLASS_CATEGORY_LIST (category);
6332 return category;
6335 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6337 static void
6338 generate_category (struct imp_entry *impent)
6340 tree initlist, cat_name_expr, class_name_expr;
6341 tree protocol_decl, category;
6342 tree cat = impent->imp_context;
6344 implementation_template = impent->imp_template;
6345 UOBJC_CLASS_decl = impent->class_decl;
6346 UOBJC_METACLASS_decl = impent->meta_decl;
6348 add_class_reference (CLASS_NAME (cat));
6349 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
6351 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
6353 category = lookup_category (implementation_template,
6354 CLASS_SUPER_NAME (cat));
6356 if (category && CLASS_PROTOCOL_LIST (category))
6358 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
6359 protocol_decl = generate_protocol_list (category);
6361 else
6362 protocol_decl = 0;
6364 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
6365 cat_name_expr, class_name_expr,
6366 UOBJC_INSTANCE_METHODS_decl,
6367 UOBJC_CLASS_METHODS_decl,
6368 protocol_decl);
6369 /* Finish and initialize the forward decl. */
6370 finish_var_decl (UOBJC_CLASS_decl, initlist);
6373 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6374 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6376 static void
6377 generate_shared_structures (struct imp_entry *impent)
6379 tree name_expr, super_expr, root_expr;
6380 tree my_root_id, my_super_id;
6381 tree cast_type, initlist, protocol_decl;
6382 int cls_flags;
6384 objc_implementation_context = impent->imp_context;
6385 implementation_template = impent->imp_template;
6386 UOBJC_CLASS_decl = impent->class_decl;
6387 UOBJC_METACLASS_decl = impent->meta_decl;
6388 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
6390 my_super_id = CLASS_SUPER_NAME (implementation_template);
6391 if (my_super_id)
6393 add_class_reference (my_super_id);
6395 /* Compute "my_root_id" - this is required for code generation.
6396 the "isa" for all meta class structures points to the root of
6397 the inheritance hierarchy (e.g. "__Object")... */
6398 my_root_id = my_super_id;
6401 tree my_root_int = lookup_interface (my_root_id);
6403 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
6404 my_root_id = CLASS_SUPER_NAME (my_root_int);
6405 else
6406 break;
6408 while (1);
6410 else
6411 /* No super class. */
6412 my_root_id = CLASS_NAME (implementation_template);
6414 cast_type = build_pointer_type (objc_class_template);
6415 name_expr = add_objc_string (CLASS_NAME (implementation_template),
6416 class_names);
6418 /* Install class `isa' and `super' pointers at runtime. */
6419 if (my_super_id)
6420 super_expr = add_objc_string (my_super_id, class_names);
6421 else
6422 super_expr = integer_zero_node;
6424 super_expr = build_c_cast (input_location,
6425 cast_type, super_expr); /* cast! */
6427 root_expr = add_objc_string (my_root_id, class_names);
6428 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
6430 if (CLASS_PROTOCOL_LIST (implementation_template))
6432 generate_protocol_references
6433 (CLASS_PROTOCOL_LIST (implementation_template));
6434 protocol_decl = generate_protocol_list (implementation_template);
6436 else
6437 protocol_decl = 0;
6439 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6441 initlist
6442 = build_shared_structure_initializer
6443 (TREE_TYPE (UOBJC_METACLASS_decl),
6444 root_expr, super_expr, name_expr,
6445 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
6446 2 /*CLS_META*/,
6447 UOBJC_CLASS_METHODS_decl,
6448 UOBJC_CLASS_VARIABLES_decl,
6449 protocol_decl);
6451 finish_var_decl (UOBJC_METACLASS_decl, initlist);
6453 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6455 initlist
6456 = build_shared_structure_initializer
6457 (TREE_TYPE (UOBJC_CLASS_decl),
6458 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
6459 super_expr, name_expr,
6460 convert (integer_type_node,
6461 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6462 (implementation_template))),
6463 1 /*CLS_FACTORY*/ | cls_flags,
6464 UOBJC_INSTANCE_METHODS_decl,
6465 UOBJC_INSTANCE_VARIABLES_decl,
6466 protocol_decl);
6468 finish_var_decl (UOBJC_CLASS_decl, initlist);
6472 static const char *
6473 synth_id_with_class_suffix (const char *preamble, tree ctxt)
6475 static char string[BUFSIZE];
6477 switch (TREE_CODE (ctxt))
6479 case CLASS_IMPLEMENTATION_TYPE:
6480 case CLASS_INTERFACE_TYPE:
6481 sprintf (string, "%s_%s", preamble,
6482 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
6483 break;
6484 case CATEGORY_IMPLEMENTATION_TYPE:
6485 case CATEGORY_INTERFACE_TYPE:
6487 /* We have a category. */
6488 const char *const class_name
6489 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6490 const char *const class_super_name
6491 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
6492 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
6493 break;
6495 case PROTOCOL_INTERFACE_TYPE:
6497 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
6498 sprintf (string, "%s_%s", preamble, protocol_name);
6499 break;
6501 default:
6502 gcc_unreachable ();
6505 return string;
6508 /* If type is empty or only type qualifiers are present, add default
6509 type of id (otherwise grokdeclarator will default to int). */
6510 static inline tree
6511 adjust_type_for_id_default (tree type)
6513 if (!type)
6514 type = make_node (TREE_LIST);
6516 if (!TREE_VALUE (type))
6517 TREE_VALUE (type) = objc_object_type;
6518 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
6519 && TYPED_OBJECT (TREE_VALUE (type)))
6520 error ("can not use an object as parameter to a method");
6522 return type;
6525 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
6526 arg_name and attributes. (TODO: Rename KEYWORD_DECL to
6527 OBJC_METHOD_PARM_DECL ?)
6529 A KEYWORD_DECL is a tree representing the declaration of a
6530 parameter of an Objective-C method. It is produced when parsing a
6531 fragment of Objective-C method declaration of the form
6533 keyworddecl:
6534 selector ':' '(' typename ')' identifier
6536 For example, take the Objective-C method
6538 -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
6540 the two fragments "pathForResource:(NSString *)resource" and
6541 "ofType:(NSString *)type" will generate a KEYWORD_DECL each. The
6542 KEYWORD_DECL stores the 'key_name' (eg, identifier for
6543 "pathForResource"), the 'arg_type' (eg, tree representing a
6544 NSString *), the 'arg_name' (eg identifier for "resource") and
6545 potentially some attributes (for example, a tree representing
6546 __attribute__ ((unused)) if such an attribute was attached to a
6547 certain parameter). You can access this information using the
6548 TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
6549 KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
6551 'key_name' is an identifier node (and is optional as you can omit
6552 it in Objective-C methods).
6553 'arg_type' is a tree list (and is optional too if no parameter type
6554 was specified).
6555 'arg_name' is an identifier node and is required.
6556 'attributes' is an optional tree containing parameter attributes. */
6557 tree
6558 objc_build_keyword_decl (tree key_name, tree arg_type,
6559 tree arg_name, tree attributes)
6561 tree keyword_decl;
6563 /* If no type is specified, default to "id". */
6564 arg_type = adjust_type_for_id_default (arg_type);
6566 keyword_decl = make_node (KEYWORD_DECL);
6568 TREE_TYPE (keyword_decl) = arg_type;
6569 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
6570 KEYWORD_KEY_NAME (keyword_decl) = key_name;
6571 DECL_ATTRIBUTES (keyword_decl) = attributes;
6573 return keyword_decl;
6576 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6577 static tree
6578 build_keyword_selector (tree selector)
6580 int len = 0;
6581 tree key_chain, key_name;
6582 char *buf;
6584 /* Scan the selector to see how much space we'll need. */
6585 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6587 switch (TREE_CODE (selector))
6589 case KEYWORD_DECL:
6590 key_name = KEYWORD_KEY_NAME (key_chain);
6591 break;
6592 case TREE_LIST:
6593 key_name = TREE_PURPOSE (key_chain);
6594 break;
6595 default:
6596 gcc_unreachable ();
6599 if (key_name)
6600 len += IDENTIFIER_LENGTH (key_name) + 1;
6601 else
6602 /* Just a ':' arg. */
6603 len++;
6606 buf = (char *) alloca (len + 1);
6607 /* Start the buffer out as an empty string. */
6608 buf[0] = '\0';
6610 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6612 switch (TREE_CODE (selector))
6614 case KEYWORD_DECL:
6615 key_name = KEYWORD_KEY_NAME (key_chain);
6616 break;
6617 case TREE_LIST:
6618 key_name = TREE_PURPOSE (key_chain);
6619 /* The keyword decl chain will later be used as a function
6620 argument chain. Unhook the selector itself so as to not
6621 confuse other parts of the compiler. */
6622 TREE_PURPOSE (key_chain) = NULL_TREE;
6623 break;
6624 default:
6625 gcc_unreachable ();
6628 if (key_name)
6629 strcat (buf, IDENTIFIER_POINTER (key_name));
6630 strcat (buf, ":");
6633 return get_identifier (buf);
6636 /* Used for declarations and definitions. */
6638 static tree
6639 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6640 tree add_args, bool ellipsis)
6642 tree method_decl;
6644 /* If no type is specified, default to "id". */
6645 ret_type = adjust_type_for_id_default (ret_type);
6647 method_decl = make_node (code);
6648 TREE_TYPE (method_decl) = ret_type;
6650 /* If we have a keyword selector, create an identifier_node that
6651 represents the full selector name (`:' included)... */
6652 if (TREE_CODE (selector) == KEYWORD_DECL)
6654 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6655 METHOD_SEL_ARGS (method_decl) = selector;
6656 METHOD_ADD_ARGS (method_decl) = add_args;
6657 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6659 else
6661 METHOD_SEL_NAME (method_decl) = selector;
6662 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6663 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6666 return method_decl;
6669 #define METHOD_DEF 0
6670 #define METHOD_REF 1
6672 /* This routine processes objective-c method attributes. */
6674 static void
6675 objc_decl_method_attributes (tree *node, tree attributes, int flags)
6677 tree sentinel_attr = lookup_attribute ("sentinel", attributes);
6678 if (sentinel_attr)
6680 /* hackery to make an obj method look like a function type. */
6681 tree rettype = TREE_TYPE (*node);
6682 TREE_TYPE (*node) = build_function_type (TREE_VALUE (rettype),
6683 get_arg_type_list (*node, METHOD_REF, 0));
6684 decl_attributes (node, attributes, flags);
6685 METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
6686 TREE_TYPE (*node) = rettype;
6688 else
6689 decl_attributes (node, attributes, flags);
6692 bool
6693 objc_method_decl (enum tree_code opcode)
6695 return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
6698 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6699 an argument list for method METH. CONTEXT is either METHOD_DEF or
6700 METHOD_REF, saying whether we are trying to define a method or call
6701 one. SUPERFLAG says this is for a send to super; this makes a
6702 difference for the NeXT calling sequence in which the lookup and
6703 the method call are done together. If METH is null, user-defined
6704 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6706 static tree
6707 get_arg_type_list (tree meth, int context, int superflag)
6709 tree arglist, akey;
6711 /* Receiver type. */
6712 if (flag_next_runtime && superflag)
6713 arglist = build_tree_list (NULL_TREE, objc_super_type);
6714 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6715 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6716 else
6717 arglist = build_tree_list (NULL_TREE, objc_object_type);
6719 /* Selector type - will eventually change to `int'. */
6720 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6722 /* No actual method prototype given -- assume that remaining arguments
6723 are `...'. */
6724 if (!meth)
6725 return arglist;
6727 /* Build a list of argument types. */
6728 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
6730 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6732 /* Decay argument types for the underlying C function as appropriate. */
6733 arg_type = objc_decay_parm_type (arg_type);
6735 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6738 if (METHOD_ADD_ARGS (meth))
6740 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6741 akey; akey = TREE_CHAIN (akey))
6743 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6745 arg_type = objc_decay_parm_type (arg_type);
6747 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6750 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6751 goto lack_of_ellipsis;
6753 else
6755 lack_of_ellipsis:
6756 chainon (arglist, OBJC_VOID_AT_END);
6759 return arglist;
6762 static tree
6763 check_duplicates (hash hsh, int methods, int is_class)
6765 tree meth = NULL_TREE;
6767 if (hsh)
6769 meth = hsh->key;
6771 if (hsh->list)
6773 /* We have two or more methods with the same name but
6774 different types. */
6775 attr loop;
6777 /* But just how different are those types? If
6778 -Wno-strict-selector-match is specified, we shall not
6779 complain if the differences are solely among types with
6780 identical size and alignment. */
6781 if (!warn_strict_selector_match)
6783 for (loop = hsh->list; loop; loop = loop->next)
6784 if (!comp_proto_with_proto (meth, loop->value, 0))
6785 goto issue_warning;
6787 return meth;
6790 issue_warning:
6791 if (methods)
6793 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6795 warning_at (input_location, 0,
6796 "multiple methods named %<%c%E%> found",
6797 (is_class ? '+' : '-'),
6798 METHOD_SEL_NAME (meth));
6799 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6800 (type ? '-' : '+'),
6801 identifier_to_locale (gen_method_decl (meth)));
6803 else
6805 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6807 warning_at (input_location, 0,
6808 "multiple selectors named %<%c%E%> found",
6809 (is_class ? '+' : '-'),
6810 METHOD_SEL_NAME (meth));
6811 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6812 (type ? '-' : '+'),
6813 identifier_to_locale (gen_method_decl (meth)));
6816 for (loop = hsh->list; loop; loop = loop->next)
6818 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6820 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6821 (type ? '-' : '+'),
6822 identifier_to_locale (gen_method_decl (loop->value)));
6826 return meth;
6829 /* If RECEIVER is a class reference, return the identifier node for
6830 the referenced class. RECEIVER is created by objc_get_class_reference,
6831 so we check the exact form created depending on which runtimes are
6832 used. */
6834 static tree
6835 receiver_is_class_object (tree receiver, int self, int super)
6837 tree chain, exp, arg;
6839 /* The receiver is 'self' or 'super' in the context of a class method. */
6840 if (objc_method_context
6841 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6842 && (self || super))
6843 return (super
6844 ? CLASS_SUPER_NAME (implementation_template)
6845 : CLASS_NAME (implementation_template));
6847 if (flag_next_runtime)
6849 /* The receiver is a variable created by
6850 build_class_reference_decl. */
6851 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6852 /* Look up the identifier. */
6853 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6854 if (TREE_PURPOSE (chain) == receiver)
6855 return TREE_VALUE (chain);
6858 /* The receiver is a function call that returns an id. Check if
6859 it is a call to objc_getClass, if so, pick up the class name. */
6860 if (TREE_CODE (receiver) == CALL_EXPR
6861 && (exp = CALL_EXPR_FN (receiver))
6862 && TREE_CODE (exp) == ADDR_EXPR
6863 && (exp = TREE_OPERAND (exp, 0))
6864 && TREE_CODE (exp) == FUNCTION_DECL
6865 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6866 prototypes for objc_get_class(). Thankfully, they seem to share the
6867 same function type. */
6868 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6869 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6870 /* We have a call to objc_get_class/objc_getClass! */
6871 && (arg = CALL_EXPR_ARG (receiver, 0)))
6873 STRIP_NOPS (arg);
6874 if (TREE_CODE (arg) == ADDR_EXPR
6875 && (arg = TREE_OPERAND (arg, 0))
6876 && TREE_CODE (arg) == STRING_CST)
6877 /* Finally, we have the class name. */
6878 return get_identifier (TREE_STRING_POINTER (arg));
6880 return 0;
6883 /* If we are currently building a message expr, this holds
6884 the identifier of the selector of the message. This is
6885 used when printing warnings about argument mismatches. */
6887 static tree current_objc_message_selector = 0;
6889 tree
6890 objc_message_selector (void)
6892 return current_objc_message_selector;
6895 /* Construct an expression for sending a message.
6896 MESS has the object to send to in TREE_PURPOSE
6897 and the argument list (including selector) in TREE_VALUE.
6899 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6900 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6902 tree
6903 objc_build_message_expr (tree mess)
6905 tree receiver = TREE_PURPOSE (mess);
6906 tree sel_name;
6907 #ifdef OBJCPLUS
6908 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6909 #else
6910 tree args = TREE_VALUE (mess);
6911 #endif
6912 tree method_params = NULL_TREE;
6914 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6915 return error_mark_node;
6917 /* Obtain the full selector name. */
6918 switch (TREE_CODE (args))
6920 case IDENTIFIER_NODE:
6921 /* A unary selector. */
6922 sel_name = args;
6923 break;
6924 case TREE_LIST:
6925 sel_name = build_keyword_selector (args);
6926 break;
6927 default:
6928 gcc_unreachable ();
6931 /* Build the parameter list to give to the method. */
6932 if (TREE_CODE (args) == TREE_LIST)
6933 #ifdef OBJCPLUS
6934 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6935 #else
6937 tree chain = args, prev = NULL_TREE;
6939 /* We have a keyword selector--check for comma expressions. */
6940 while (chain)
6942 tree element = TREE_VALUE (chain);
6944 /* We have a comma expression, must collapse... */
6945 if (TREE_CODE (element) == TREE_LIST)
6947 if (prev)
6948 TREE_CHAIN (prev) = element;
6949 else
6950 args = element;
6952 prev = chain;
6953 chain = TREE_CHAIN (chain);
6955 method_params = args;
6957 #endif
6959 #ifdef OBJCPLUS
6960 if (processing_template_decl)
6961 /* Must wait until template instantiation time. */
6962 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6963 method_params);
6964 #endif
6966 return objc_finish_message_expr (receiver, sel_name, method_params);
6969 /* Look up method SEL_NAME that would be suitable for receiver
6970 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6971 nonzero), and report on any duplicates. */
6973 static tree
6974 lookup_method_in_hash_lists (tree sel_name, int is_class)
6976 hash method_prototype = NULL;
6978 if (!is_class)
6979 method_prototype = hash_lookup (nst_method_hash_list,
6980 sel_name);
6982 if (!method_prototype)
6984 method_prototype = hash_lookup (cls_method_hash_list,
6985 sel_name);
6986 is_class = 1;
6989 return check_duplicates (method_prototype, 1, is_class);
6992 /* The 'objc_finish_message_expr' routine is called from within
6993 'objc_build_message_expr' for non-template functions. In the case of
6994 C++ template functions, it is called from 'build_expr_from_tree'
6995 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6997 tree
6998 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7000 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7001 tree selector, retval, class_tree;
7002 int self, super, have_cast;
7004 /* We have used the receiver, so mark it as read. */
7005 mark_exp_read (receiver);
7007 /* Extract the receiver of the message, as well as its type
7008 (where the latter may take the form of a cast or be inferred
7009 from the implementation context). */
7010 rtype = receiver;
7011 while (TREE_CODE (rtype) == COMPOUND_EXPR
7012 || TREE_CODE (rtype) == MODIFY_EXPR
7013 || CONVERT_EXPR_P (rtype)
7014 || TREE_CODE (rtype) == COMPONENT_REF)
7015 rtype = TREE_OPERAND (rtype, 0);
7017 self = (rtype == self_decl);
7018 super = (rtype == UOBJC_SUPER_decl);
7019 rtype = TREE_TYPE (receiver);
7021 have_cast = (TREE_CODE (receiver) == NOP_EXPR
7022 || (TREE_CODE (receiver) == COMPOUND_EXPR
7023 && !IS_SUPER (rtype)));
7025 /* If we are calling [super dealloc], reset our warning flag. */
7026 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7027 should_call_super_dealloc = 0;
7029 /* If the receiver is a class object, retrieve the corresponding
7030 @interface, if one exists. */
7031 class_tree = receiver_is_class_object (receiver, self, super);
7033 /* Now determine the receiver type (if an explicit cast has not been
7034 provided). */
7035 if (!have_cast)
7037 if (class_tree)
7038 rtype = lookup_interface (class_tree);
7039 /* Handle `self' and `super'. */
7040 else if (super)
7042 if (!CLASS_SUPER_NAME (implementation_template))
7044 error ("no super class declared in @interface for %qE",
7045 CLASS_NAME (implementation_template));
7046 return error_mark_node;
7048 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7050 else if (self)
7051 rtype = lookup_interface (CLASS_NAME (implementation_template));
7054 /* If receiver is of type `id' or `Class' (or if the @interface for a
7055 class is not visible), we shall be satisfied with the existence of
7056 any instance or class method. */
7057 if (objc_is_id (rtype))
7059 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7060 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7061 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7062 : NULL_TREE);
7063 rtype = NULL_TREE;
7065 if (rprotos)
7067 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7068 in protocols themselves for the method prototype. */
7069 method_prototype
7070 = lookup_method_in_protocol_list (rprotos, sel_name,
7071 class_tree != NULL_TREE);
7073 /* If messaging 'Class <Proto>' but did not find a class method
7074 prototype, search for an instance method instead, and warn
7075 about having done so. */
7076 if (!method_prototype && !rtype && class_tree != NULL_TREE)
7078 method_prototype
7079 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7081 if (method_prototype)
7082 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7083 sel_name, sel_name);
7087 else if (rtype)
7089 tree orig_rtype = rtype;
7091 if (TREE_CODE (rtype) == POINTER_TYPE)
7092 rtype = TREE_TYPE (rtype);
7093 /* Traverse typedef aliases */
7094 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7095 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7096 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7097 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7098 if (TYPED_OBJECT (rtype))
7100 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7101 rtype = TYPE_OBJC_INTERFACE (rtype);
7103 /* If we could not find an @interface declaration, we must have
7104 only seen a @class declaration; so, we cannot say anything
7105 more intelligent about which methods the receiver will
7106 understand. */
7107 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7109 rtype = NULL_TREE;
7110 /* We could not find an @interface declaration, yet Message maybe in a
7111 @class's protocol. */
7112 if (!method_prototype && rprotos)
7113 method_prototype
7114 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7116 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7117 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7119 /* We have a valid ObjC class name. Look up the method name
7120 in the published @interface for the class (and its
7121 superclasses). */
7122 method_prototype
7123 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7125 /* If the method was not found in the @interface, it may still
7126 exist locally as part of the @implementation. */
7127 if (!method_prototype && objc_implementation_context
7128 && CLASS_NAME (objc_implementation_context)
7129 == OBJC_TYPE_NAME (rtype))
7130 method_prototype
7131 = lookup_method
7132 ((class_tree
7133 ? CLASS_CLS_METHODS (objc_implementation_context)
7134 : CLASS_NST_METHODS (objc_implementation_context)),
7135 sel_name);
7137 /* If we haven't found a candidate method by now, try looking for
7138 it in the protocol list. */
7139 if (!method_prototype && rprotos)
7140 method_prototype
7141 = lookup_method_in_protocol_list (rprotos, sel_name,
7142 class_tree != NULL_TREE);
7144 else
7146 warning (0, "invalid receiver type %qs",
7147 identifier_to_locale (gen_type_name (orig_rtype)));
7148 /* After issuing the "invalid receiver" warning, perform method
7149 lookup as if we were messaging 'id'. */
7150 rtype = rprotos = NULL_TREE;
7155 /* For 'id' or 'Class' receivers, search in the global hash table
7156 as a last resort. For all receivers, warn if protocol searches
7157 have failed. */
7158 if (!method_prototype)
7160 if (rprotos)
7161 warning (0, "%<%c%E%> not found in protocol(s)",
7162 (class_tree ? '+' : '-'),
7163 sel_name);
7165 if (!rtype)
7166 method_prototype
7167 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
7170 if (!method_prototype && in_objc_property_setter_name_context)
7171 error ("readonly property can not be set");
7172 else if (!method_prototype)
7174 static bool warn_missing_methods = false;
7176 if (rtype)
7177 warning (0, "%qE may not respond to %<%c%E%>",
7178 OBJC_TYPE_NAME (rtype),
7179 (class_tree ? '+' : '-'),
7180 sel_name);
7181 /* If we are messaging an 'id' or 'Class' object and made it here,
7182 then we have failed to find _any_ instance or class method,
7183 respectively. */
7184 else
7185 warning (0, "no %<%c%E%> method found",
7186 (class_tree ? '+' : '-'),
7187 sel_name);
7189 if (!warn_missing_methods)
7191 warning_at (input_location,
7192 0, "(Messages without a matching method signature");
7193 warning_at (input_location,
7194 0, "will be assumed to return %<id%> and accept");
7195 warning_at (input_location,
7196 0, "%<...%> as arguments.)");
7197 warn_missing_methods = true;
7201 /* Save the selector name for printing error messages. */
7202 current_objc_message_selector = sel_name;
7204 /* Build the parameters list for looking up the method.
7205 These are the object itself and the selector. */
7207 if (flag_typed_selectors)
7208 selector = build_typed_selector_reference (input_location,
7209 sel_name, method_prototype);
7210 else
7211 selector = build_selector_reference (input_location, sel_name);
7213 retval = build_objc_method_call (input_location, super, method_prototype,
7214 receiver,
7215 selector, method_params);
7217 current_objc_message_selector = 0;
7219 return retval;
7222 /* Build a tree expression to send OBJECT the operation SELECTOR,
7223 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7224 assuming the method has prototype METHOD_PROTOTYPE.
7225 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7226 LOC is the location of the expression to build.
7227 Use METHOD_PARAMS as list of args to pass to the method.
7228 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7230 static tree
7231 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
7232 tree lookup_object, tree selector,
7233 tree method_params)
7235 tree sender = (super_flag ? umsg_super_decl :
7236 (!flag_next_runtime || flag_nil_receivers
7237 ? (flag_objc_direct_dispatch
7238 ? umsg_fast_decl
7239 : umsg_decl)
7240 : umsg_nonnil_decl));
7241 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
7242 VEC(tree, gc) *parms = NULL;
7243 unsigned nparm = (method_params ? list_length (method_params) : 0);
7245 /* If a prototype for the method to be called exists, then cast
7246 the sender's return type and arguments to match that of the method.
7247 Otherwise, leave sender as is. */
7248 tree ret_type
7249 = (method_prototype
7250 ? TREE_VALUE (TREE_TYPE (method_prototype))
7251 : objc_object_type);
7253 tree method_param_types =
7254 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
7255 tree ftype = build_function_type (ret_type, method_param_types);
7256 tree sender_cast;
7257 tree method, t;
7259 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
7260 ftype = build_type_attribute_variant (
7261 ftype, METHOD_TYPE_ATTRIBUTES (method_prototype));
7263 sender_cast = build_pointer_type (ftype);
7265 if (method_prototype && TREE_DEPRECATED (method_prototype))
7266 warn_deprecated_use (method_prototype, NULL_TREE);
7268 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
7270 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7271 lookup_object = save_expr (lookup_object);
7273 /* Param list + 2 slots for object and selector. */
7274 parms = VEC_alloc (tree, gc, nparm + 2);
7276 if (flag_next_runtime)
7278 /* If we are returning a struct in memory, and the address
7279 of that memory location is passed as a hidden first
7280 argument, then change which messenger entry point this
7281 expr will call. NB: Note that sender_cast remains
7282 unchanged (it already has a struct return type). */
7283 if (!targetm.calls.struct_value_rtx (0, 0)
7284 && (TREE_CODE (ret_type) == RECORD_TYPE
7285 || TREE_CODE (ret_type) == UNION_TYPE)
7286 && targetm.calls.return_in_memory (ret_type, 0))
7287 sender = (super_flag ? umsg_super_stret_decl :
7288 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
7290 method = build_fold_addr_expr_loc (input_location, sender);
7291 /* Pass the object to the method. */
7292 VEC_quick_push (tree, parms, lookup_object);
7294 else
7296 /* This is the portable (GNU) way. */
7297 /* First, call the lookup function to get a pointer to the method,
7298 then cast the pointer, then call it with the method arguments. */
7299 VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
7300 VEC_quick_push (tree, tv, lookup_object);
7301 VEC_quick_push (tree, tv, selector);
7302 method = build_function_call_vec (loc, sender, tv, NULL);
7303 VEC_free (tree, gc, tv);
7305 /* Pass the appropriate object to the method. */
7306 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
7309 /* Pass the selector to the method. */
7310 VEC_quick_push (tree, parms, selector);
7311 /* Now append the remainder of the parms. */
7312 if (nparm)
7313 for (; method_params; method_params = TREE_CHAIN (method_params))
7314 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
7316 /* Build an obj_type_ref, with the correct cast for the method call. */
7317 t = build3 (OBJ_TYPE_REF, sender_cast, method,
7318 lookup_object, size_zero_node);
7319 t = build_function_call_vec (loc, t, parms, NULL);\
7320 VEC_free (tree, gc, parms);
7321 return t;
7324 static void
7325 build_protocol_reference (tree p)
7327 tree decl;
7328 const char *proto_name;
7330 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7332 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
7333 decl = start_var_decl (objc_protocol_template, proto_name);
7335 PROTOCOL_FORWARD_DECL (p) = decl;
7338 /* This function is called by the parser when (and only when) a
7339 @protocol() expression is found, in order to compile it. */
7340 tree
7341 objc_build_protocol_expr (tree protoname)
7343 tree expr;
7344 tree p = lookup_protocol (protoname);
7346 if (!p)
7348 error ("cannot find protocol declaration for %qE",
7349 protoname);
7350 return error_mark_node;
7353 if (!PROTOCOL_FORWARD_DECL (p))
7354 build_protocol_reference (p);
7356 expr = build_unary_op (input_location,
7357 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
7359 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7360 if we have it, rather than converting it here. */
7361 expr = convert (objc_protocol_type, expr);
7363 /* The @protocol() expression is being compiled into a pointer to a
7364 statically allocated instance of the Protocol class. To become
7365 usable at runtime, the 'isa' pointer of the instance need to be
7366 fixed up at runtime by the runtime library, to point to the
7367 actual 'Protocol' class. */
7369 /* For the GNU runtime, put the static Protocol instance in the list
7370 of statically allocated instances, so that we make sure that its
7371 'isa' pointer is fixed up at runtime by the GNU runtime library
7372 to point to the Protocol class (at runtime, when loading the
7373 module, the GNU runtime library loops on the statically allocated
7374 instances (as found in the defs field in objc_symtab) and fixups
7375 all the 'isa' pointers of those objects). */
7376 if (! flag_next_runtime)
7378 /* This type is a struct containing the fields of a Protocol
7379 object. (Cfr. objc_protocol_type instead is the type of a pointer
7380 to such a struct). */
7381 tree protocol_struct_type = xref_tag
7382 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
7383 tree *chain;
7385 /* Look for the list of Protocol statically allocated instances
7386 to fixup at runtime. Create a new list to hold Protocol
7387 statically allocated instances, if the list is not found. At
7388 present there is only another list, holding NSConstantString
7389 static instances to be fixed up at runtime. */
7390 for (chain = &objc_static_instances;
7391 *chain && TREE_VALUE (*chain) != protocol_struct_type;
7392 chain = &TREE_CHAIN (*chain));
7393 if (!*chain)
7395 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
7396 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
7397 class_names);
7400 /* Add this statically allocated instance to the Protocol list. */
7401 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
7402 PROTOCOL_FORWARD_DECL (p),
7403 TREE_PURPOSE (*chain));
7407 return expr;
7410 /* This function is called by the parser when a @selector() expression
7411 is found, in order to compile it. It is only called by the parser
7412 and only to compile a @selector(). LOC is the location of the
7413 @selector. */
7414 tree
7415 objc_build_selector_expr (location_t loc, tree selnamelist)
7417 tree selname;
7419 /* Obtain the full selector name. */
7420 switch (TREE_CODE (selnamelist))
7422 case IDENTIFIER_NODE:
7423 /* A unary selector. */
7424 selname = selnamelist;
7425 break;
7426 case TREE_LIST:
7427 selname = build_keyword_selector (selnamelist);
7428 break;
7429 default:
7430 gcc_unreachable ();
7433 /* If we are required to check @selector() expressions as they
7434 are found, check that the selector has been declared. */
7435 if (warn_undeclared_selector)
7437 /* Look the selector up in the list of all known class and
7438 instance methods (up to this line) to check that the selector
7439 exists. */
7440 hash hsh;
7442 /* First try with instance methods. */
7443 hsh = hash_lookup (nst_method_hash_list, selname);
7445 /* If not found, try with class methods. */
7446 if (!hsh)
7448 hsh = hash_lookup (cls_method_hash_list, selname);
7451 /* If still not found, print out a warning. */
7452 if (!hsh)
7454 warning (0, "undeclared selector %qE", selname);
7459 if (flag_typed_selectors)
7460 return build_typed_selector_reference (loc, selname, 0);
7461 else
7462 return build_selector_reference (loc, selname);
7465 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7466 section '@encode'. */
7467 tree
7468 objc_build_encode_expr (tree type)
7470 tree result;
7471 const char *string;
7473 encode_type (type, obstack_object_size (&util_obstack),
7474 OBJC_ENCODE_INLINE_DEFS);
7475 obstack_1grow (&util_obstack, 0); /* null terminate string */
7476 string = XOBFINISH (&util_obstack, const char *);
7478 /* Synthesize a string that represents the encoded struct/union. */
7479 result = my_build_string (strlen (string) + 1, string);
7480 obstack_free (&util_obstack, util_firstobj);
7481 return result;
7484 static tree
7485 build_ivar_reference (tree id)
7487 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7489 /* Historically, a class method that produced objects (factory
7490 method) would assign `self' to the instance that it
7491 allocated. This would effectively turn the class method into
7492 an instance method. Following this assignment, the instance
7493 variables could be accessed. That practice, while safe,
7494 violates the simple rule that a class method should not refer
7495 to an instance variable. It's better to catch the cases
7496 where this is done unknowingly than to support the above
7497 paradigm. */
7498 warning (0, "instance variable %qE accessed in class method",
7499 id);
7500 self_decl = convert (objc_instance_type, self_decl); /* cast */
7503 return objc_build_component_ref (build_indirect_ref (input_location,
7504 self_decl, RO_ARROW),
7505 id);
7508 /* Compute a hash value for a given method SEL_NAME. */
7510 static size_t
7511 hash_func (tree sel_name)
7513 const unsigned char *s
7514 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
7515 size_t h = 0;
7517 while (*s)
7518 h = h * 67 + *s++ - 113;
7519 return h;
7522 static void
7523 hash_init (void)
7525 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7526 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7528 cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7529 als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7531 /* Initialize the hash table used to hold the constant string objects. */
7532 string_htab = htab_create_ggc (31, string_hash,
7533 string_eq, NULL);
7536 /* This routine adds sel_name to the hash list. sel_name is a class or alias
7537 name for the class. If alias name, then value is its underlying class.
7538 If class, the value is NULL_TREE. */
7540 static void
7541 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
7543 hash obj;
7544 int slot = hash_func (sel_name) % SIZEHASHTABLE;
7546 obj = ggc_alloc_hashed_entry ();
7547 if (value != NULL_TREE)
7549 /* Save the underlying class for the 'alias' in the hash table */
7550 attr obj_attr = ggc_alloc_hashed_attribute ();
7551 obj_attr->value = value;
7552 obj->list = obj_attr;
7554 else
7555 obj->list = 0;
7556 obj->next = hashlist[slot];
7557 obj->key = sel_name;
7559 hashlist[slot] = obj; /* append to front */
7564 Searches in the hash table looking for a match for class or alias name.
7567 static hash
7568 hash_class_name_lookup (hash *hashlist, tree sel_name)
7570 hash target;
7572 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7574 while (target)
7576 if (sel_name == target->key)
7577 return target;
7579 target = target->next;
7581 return 0;
7584 /* WARNING!!!! hash_enter is called with a method, and will peek
7585 inside to find its selector! But hash_lookup is given a selector
7586 directly, and looks for the selector that's inside the found
7587 entry's key (method) for comparison. */
7589 static void
7590 hash_enter (hash *hashlist, tree method)
7592 hash obj;
7593 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
7595 obj = ggc_alloc_hashed_entry ();
7596 obj->list = 0;
7597 obj->next = hashlist[slot];
7598 obj->key = method;
7600 hashlist[slot] = obj; /* append to front */
7603 static hash
7604 hash_lookup (hash *hashlist, tree sel_name)
7606 hash target;
7608 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7610 while (target)
7612 if (sel_name == METHOD_SEL_NAME (target->key))
7613 return target;
7615 target = target->next;
7617 return 0;
7620 static void
7621 hash_add_attr (hash entry, tree value)
7623 attr obj;
7625 obj = ggc_alloc_hashed_attribute ();
7626 obj->next = entry->list;
7627 obj->value = value;
7629 entry->list = obj; /* append to front */
7632 static tree
7633 lookup_method (tree mchain, tree method)
7635 tree key;
7637 if (TREE_CODE (method) == IDENTIFIER_NODE)
7638 key = method;
7639 else
7640 key = METHOD_SEL_NAME (method);
7642 while (mchain)
7644 if (METHOD_SEL_NAME (mchain) == key)
7645 return mchain;
7647 mchain = DECL_CHAIN (mchain);
7649 return NULL_TREE;
7652 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7653 in INTERFACE, along with any categories and protocols attached thereto.
7654 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7655 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7656 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7657 be found in INTERFACE or any of its superclasses, look for an _instance_
7658 method of the same name in the root class as a last resort.
7660 If a suitable method cannot be found, return NULL_TREE. */
7662 static tree
7663 lookup_method_static (tree interface, tree ident, int flags)
7665 tree meth = NULL_TREE, root_inter = NULL_TREE;
7666 tree inter = interface;
7667 int is_class = (flags & OBJC_LOOKUP_CLASS);
7668 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
7670 while (inter)
7672 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
7673 tree category = inter;
7675 /* First, look up the method in the class itself. */
7676 if ((meth = lookup_method (chain, ident)))
7677 return meth;
7679 /* Failing that, look for the method in each category of the class. */
7680 while ((category = CLASS_CATEGORY_LIST (category)))
7682 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
7684 /* Check directly in each category. */
7685 if ((meth = lookup_method (chain, ident)))
7686 return meth;
7688 /* Failing that, check in each category's protocols. */
7689 if (CLASS_PROTOCOL_LIST (category))
7691 if ((meth = (lookup_method_in_protocol_list
7692 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
7693 return meth;
7697 /* If not found in categories, check in protocols of the main class. */
7698 if (CLASS_PROTOCOL_LIST (inter))
7700 if ((meth = (lookup_method_in_protocol_list
7701 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
7702 return meth;
7705 /* If we were instructed not to look in superclasses, don't. */
7706 if (no_superclasses)
7707 return NULL_TREE;
7709 /* Failing that, climb up the inheritance hierarchy. */
7710 root_inter = inter;
7711 inter = lookup_interface (CLASS_SUPER_NAME (inter));
7713 while (inter);
7715 /* If no class (factory) method was found, check if an _instance_
7716 method of the same name exists in the root class. This is what
7717 the Objective-C runtime will do. If an instance method was not
7718 found, return 0. */
7719 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
7722 /* Add the method to the hash list if it doesn't contain an identical
7723 method already. */
7725 static void
7726 add_method_to_hash_list (hash *hash_list, tree method)
7728 hash hsh;
7730 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7732 /* Install on a global chain. */
7733 hash_enter (hash_list, method);
7735 else
7737 /* Check types against those; if different, add to a list. */
7738 attr loop;
7739 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7740 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7741 already_there |= comp_proto_with_proto (method, loop->value, 1);
7742 if (!already_there)
7743 hash_add_attr (hsh, method);
7747 static tree
7748 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
7750 tree mth;
7752 /* @optional methods are added to protocol's OPTIONAL list */
7753 if (is_optional)
7755 gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
7756 if (!(mth = lookup_method (is_class
7757 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
7758 : PROTOCOL_OPTIONAL_NST_METHODS (klass),
7759 method)))
7761 if (is_class)
7763 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
7764 PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
7766 else
7768 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
7769 PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
7773 else if (!(mth = lookup_method (is_class
7774 ? CLASS_CLS_METHODS (klass)
7775 : CLASS_NST_METHODS (klass), method)))
7777 /* put method on list in reverse order */
7778 if (is_class)
7780 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
7781 CLASS_CLS_METHODS (klass) = method;
7783 else
7785 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
7786 CLASS_NST_METHODS (klass) = method;
7789 else
7791 /* When processing an @interface for a class or category, give hard
7792 errors on methods with identical selectors but differing argument
7793 and/or return types. We do not do this for @implementations, because
7794 C/C++ will do it for us (i.e., there will be duplicate function
7795 definition errors). */
7796 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7797 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7798 && !comp_proto_with_proto (method, mth, 1))
7799 error ("duplicate declaration of method %<%c%E%>",
7800 is_class ? '+' : '-',
7801 METHOD_SEL_NAME (mth));
7804 if (is_class)
7805 add_method_to_hash_list (cls_method_hash_list, method);
7806 else
7808 add_method_to_hash_list (nst_method_hash_list, method);
7810 /* Instance methods in root classes (and categories thereof)
7811 may act as class methods as a last resort. We also add
7812 instance methods listed in @protocol declarations to
7813 the class hash table, on the assumption that @protocols
7814 may be adopted by root classes or categories. */
7815 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7816 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7817 klass = lookup_interface (CLASS_NAME (klass));
7819 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7820 || !CLASS_SUPER_NAME (klass))
7821 add_method_to_hash_list (cls_method_hash_list, method);
7824 return method;
7827 static tree
7828 add_class (tree class_name, tree name)
7830 struct interface_tuple **slot;
7832 /* Put interfaces on list in reverse order. */
7833 TREE_CHAIN (class_name) = interface_chain;
7834 interface_chain = class_name;
7836 if (interface_htab == NULL)
7837 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7838 slot = (struct interface_tuple **)
7839 htab_find_slot_with_hash (interface_htab, name,
7840 IDENTIFIER_HASH_VALUE (name),
7841 INSERT);
7842 if (!*slot)
7844 *slot = ggc_alloc_cleared_interface_tuple ();
7845 (*slot)->id = name;
7847 (*slot)->class_name = class_name;
7849 return interface_chain;
7852 static void
7853 add_category (tree klass, tree category)
7855 /* Put categories on list in reverse order. */
7856 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7858 if (cat)
7860 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7861 CLASS_NAME (klass),
7862 CLASS_SUPER_NAME (category));
7864 else
7866 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7867 CLASS_CATEGORY_LIST (klass) = category;
7871 /* Called after parsing each instance variable declaration. Necessary to
7872 preserve typedefs and implement public/private...
7874 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7876 static tree
7877 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
7878 tree field_decl)
7880 tree field_type = TREE_TYPE (field_decl);
7881 const char *ivar_name = DECL_NAME (field_decl)
7882 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7883 : _("<unnamed>");
7885 #ifdef OBJCPLUS
7886 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7888 error ("illegal reference type specified for instance variable %qs",
7889 ivar_name);
7890 /* Return class as is without adding this ivar. */
7891 return klass;
7893 #endif
7895 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7896 || TYPE_SIZE (field_type) == error_mark_node)
7897 /* 'type[0]' is allowed, but 'type[]' is not! */
7899 error ("instance variable %qs has unknown size", ivar_name);
7900 /* Return class as is without adding this ivar. */
7901 return klass;
7904 #ifdef OBJCPLUS
7905 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7906 need to either (1) warn the user about it or (2) generate suitable
7907 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7908 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7909 if (MAYBE_CLASS_TYPE_P (field_type)
7910 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7911 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7912 || TYPE_POLYMORPHIC_P (field_type)))
7914 tree type_name = OBJC_TYPE_NAME (field_type);
7916 if (flag_objc_call_cxx_cdtors)
7918 /* Since the ObjC runtime will be calling the constructors and
7919 destructors for us, the only thing we can't handle is the lack
7920 of a default constructor. */
7921 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7922 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7924 warning (0, "type %qE has no default constructor to call",
7925 type_name);
7927 /* If we cannot call a constructor, we should also avoid
7928 calling the destructor, for symmetry. */
7929 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7930 warning (0, "destructor for %qE shall not be run either",
7931 type_name);
7934 else
7936 static bool warn_cxx_ivars = false;
7938 if (TYPE_POLYMORPHIC_P (field_type))
7940 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7941 initialize them. */
7942 error ("type %qE has virtual member functions", type_name);
7943 error ("illegal aggregate type %qE specified "
7944 "for instance variable %qs",
7945 type_name, ivar_name);
7946 /* Return class as is without adding this ivar. */
7947 return klass;
7950 /* User-defined constructors and destructors are not known to Obj-C
7951 and hence will not be called. This may or may not be a problem. */
7952 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7953 warning (0, "type %qE has a user-defined constructor", type_name);
7954 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7955 warning (0, "type %qE has a user-defined destructor", type_name);
7957 if (!warn_cxx_ivars)
7959 warning (0, "C++ constructors and destructors will not "
7960 "be invoked for Objective-C fields");
7961 warn_cxx_ivars = true;
7965 #endif
7967 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7968 switch (visibility)
7970 case OBJC_IVAR_VIS_PROTECTED:
7971 TREE_PUBLIC (field_decl) = 0;
7972 TREE_PRIVATE (field_decl) = 0;
7973 TREE_PROTECTED (field_decl) = 1;
7974 break;
7976 case OBJC_IVAR_VIS_PACKAGE:
7977 /* TODO: Implement the package variant. */
7978 case OBJC_IVAR_VIS_PUBLIC:
7979 TREE_PUBLIC (field_decl) = 1;
7980 TREE_PRIVATE (field_decl) = 0;
7981 TREE_PROTECTED (field_decl) = 0;
7982 break;
7984 case OBJC_IVAR_VIS_PRIVATE:
7985 TREE_PUBLIC (field_decl) = 0;
7986 TREE_PRIVATE (field_decl) = 1;
7987 TREE_PROTECTED (field_decl) = 0;
7988 break;
7992 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7994 return klass;
7997 static tree
7998 is_ivar (tree decl_chain, tree ident)
8000 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8001 if (DECL_NAME (decl_chain) == ident)
8002 return decl_chain;
8003 return NULL_TREE;
8006 /* True if the ivar is private and we are not in its implementation. */
8008 static int
8009 is_private (tree decl)
8011 return (TREE_PRIVATE (decl)
8012 && ! is_ivar (CLASS_IVARS (implementation_template),
8013 DECL_NAME (decl)));
8016 /* We have an instance variable reference;, check to see if it is public. */
8019 objc_is_public (tree expr, tree identifier)
8021 tree basetype, decl;
8023 #ifdef OBJCPLUS
8024 if (processing_template_decl)
8025 return 1;
8026 #endif
8028 if (TREE_TYPE (expr) == error_mark_node)
8029 return 1;
8031 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8033 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8035 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8037 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8039 if (!klass)
8041 error ("cannot find interface declaration for %qE",
8042 OBJC_TYPE_NAME (basetype));
8043 return 0;
8046 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8048 if (TREE_PUBLIC (decl))
8049 return 1;
8051 /* Important difference between the Stepstone translator:
8052 all instance variables should be public within the context
8053 of the implementation. */
8054 if (objc_implementation_context
8055 && ((TREE_CODE (objc_implementation_context)
8056 == CLASS_IMPLEMENTATION_TYPE)
8057 || (TREE_CODE (objc_implementation_context)
8058 == CATEGORY_IMPLEMENTATION_TYPE)))
8060 tree curtype = TYPE_MAIN_VARIANT
8061 (CLASS_STATIC_TEMPLATE
8062 (implementation_template));
8064 if (basetype == curtype
8065 || DERIVED_FROM_P (basetype, curtype))
8067 int priv = is_private (decl);
8069 if (priv)
8070 error ("instance variable %qE is declared private",
8071 DECL_NAME (decl));
8073 return !priv;
8077 /* The 2.95.2 compiler sometimes allowed C functions to access
8078 non-@public ivars. We will let this slide for now... */
8079 if (!objc_method_context)
8081 warning (0, "instance variable %qE is %s; "
8082 "this will be a hard error in the future",
8083 identifier,
8084 TREE_PRIVATE (decl) ? "@private" : "@protected");
8085 return 1;
8088 error ("instance variable %qE is declared %s",
8089 identifier,
8090 TREE_PRIVATE (decl) ? "private" : "protected");
8091 return 0;
8096 return 1;
8099 /* Make sure all entries in CHAIN are also in LIST. */
8101 static int
8102 check_methods (tree chain, tree list, int mtype)
8104 int first = 1;
8106 while (chain)
8108 if (!lookup_method (list, chain))
8110 if (first)
8112 switch (TREE_CODE (objc_implementation_context))
8114 case CLASS_IMPLEMENTATION_TYPE:
8115 warning (0, "incomplete implementation of class %qE",
8116 CLASS_NAME (objc_implementation_context));
8117 break;
8118 case CATEGORY_IMPLEMENTATION_TYPE:
8119 warning (0, "incomplete implementation of category %qE",
8120 CLASS_SUPER_NAME (objc_implementation_context));
8121 break;
8122 default:
8123 gcc_unreachable ();
8125 first = 0;
8128 warning (0, "method definition for %<%c%E%> not found",
8129 mtype, METHOD_SEL_NAME (chain));
8132 chain = DECL_CHAIN (chain);
8135 return first;
8138 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8140 static int
8141 conforms_to_protocol (tree klass, tree protocol)
8143 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
8145 tree p = CLASS_PROTOCOL_LIST (klass);
8146 while (p && TREE_VALUE (p) != protocol)
8147 p = TREE_CHAIN (p);
8149 if (!p)
8151 tree super = (CLASS_SUPER_NAME (klass)
8152 ? lookup_interface (CLASS_SUPER_NAME (klass))
8153 : NULL_TREE);
8154 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
8155 if (!tmp)
8156 return 0;
8160 return 1;
8163 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8164 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8166 static int
8167 check_methods_accessible (tree chain, tree context, int mtype)
8169 int first = 1;
8170 tree list;
8171 tree base_context = context;
8173 while (chain)
8175 context = base_context;
8176 while (context)
8178 if (mtype == '+')
8179 list = CLASS_CLS_METHODS (context);
8180 else
8181 list = CLASS_NST_METHODS (context);
8183 if (lookup_method (list, chain))
8184 break;
8186 switch (TREE_CODE (context))
8188 case CLASS_IMPLEMENTATION_TYPE:
8189 case CLASS_INTERFACE_TYPE:
8190 context = (CLASS_SUPER_NAME (context)
8191 ? lookup_interface (CLASS_SUPER_NAME (context))
8192 : NULL_TREE);
8193 break;
8194 case CATEGORY_IMPLEMENTATION_TYPE:
8195 case CATEGORY_INTERFACE_TYPE:
8196 context = (CLASS_NAME (context)
8197 ? lookup_interface (CLASS_NAME (context))
8198 : NULL_TREE);
8199 break;
8200 default:
8201 gcc_unreachable ();
8205 if (context == NULL_TREE)
8207 if (first)
8209 switch (TREE_CODE (objc_implementation_context))
8211 case CLASS_IMPLEMENTATION_TYPE:
8212 warning (0, "incomplete implementation of class %qE",
8213 CLASS_NAME (objc_implementation_context));
8214 break;
8215 case CATEGORY_IMPLEMENTATION_TYPE:
8216 warning (0, "incomplete implementation of category %qE",
8217 CLASS_SUPER_NAME (objc_implementation_context));
8218 break;
8219 default:
8220 gcc_unreachable ();
8222 first = 0;
8224 warning (0, "method definition for %<%c%E%> not found",
8225 mtype, METHOD_SEL_NAME (chain));
8228 chain = TREE_CHAIN (chain); /* next method... */
8230 return first;
8233 /* Check whether the current interface (accessible via
8234 'objc_implementation_context') actually implements protocol P, along
8235 with any protocols that P inherits. */
8237 static void
8238 check_protocol (tree p, const char *type, tree name)
8240 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
8242 int f1, f2;
8244 /* Ensure that all protocols have bodies! */
8245 if (warn_protocol)
8247 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
8248 CLASS_CLS_METHODS (objc_implementation_context),
8249 '+');
8250 f2 = check_methods (PROTOCOL_NST_METHODS (p),
8251 CLASS_NST_METHODS (objc_implementation_context),
8252 '-');
8254 else
8256 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
8257 objc_implementation_context,
8258 '+');
8259 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
8260 objc_implementation_context,
8261 '-');
8264 if (!f1 || !f2)
8265 warning (0, "%s %qE does not fully implement the %qE protocol",
8266 type, name, PROTOCOL_NAME (p));
8269 /* Check protocols recursively. */
8270 if (PROTOCOL_LIST (p))
8272 tree subs = PROTOCOL_LIST (p);
8273 tree super_class =
8274 lookup_interface (CLASS_SUPER_NAME (implementation_template));
8276 while (subs)
8278 tree sub = TREE_VALUE (subs);
8280 /* If the superclass does not conform to the protocols
8281 inherited by P, then we must! */
8282 if (!super_class || !conforms_to_protocol (super_class, sub))
8283 check_protocol (sub, type, name);
8284 subs = TREE_CHAIN (subs);
8289 /* Check whether the current interface (accessible via
8290 'objc_implementation_context') actually implements the protocols listed
8291 in PROTO_LIST. */
8293 static void
8294 check_protocols (tree proto_list, const char *type, tree name)
8296 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
8298 tree p = TREE_VALUE (proto_list);
8300 check_protocol (p, type, name);
8304 /* Make sure that the class CLASS_NAME is defined
8305 CODE says which kind of thing CLASS_NAME ought to be.
8306 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8307 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8309 static tree
8310 start_class (enum tree_code code, tree class_name, tree super_name,
8311 tree protocol_list)
8313 tree klass, decl;
8315 #ifdef OBJCPLUS
8316 if (current_namespace != global_namespace) {
8317 error ("Objective-C declarations may only appear in global scope");
8319 #endif /* OBJCPLUS */
8321 if (objc_implementation_context)
8323 warning (0, "%<@end%> missing in implementation context");
8324 finish_class (objc_implementation_context);
8325 objc_ivar_chain = NULL_TREE;
8326 objc_implementation_context = NULL_TREE;
8329 klass = make_node (code);
8330 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
8332 /* Check for existence of the super class, if one was specified. Note
8333 that we must have seen an @interface, not just a @class. If we
8334 are looking at a @compatibility_alias, traverse it first. */
8335 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
8336 && super_name)
8338 tree super = objc_is_class_name (super_name);
8340 if (!super || !lookup_interface (super))
8342 error ("cannot find interface declaration for %qE, superclass of %qE",
8343 super ? super : super_name,
8344 class_name);
8345 super_name = NULL_TREE;
8347 else
8348 super_name = super;
8351 CLASS_NAME (klass) = class_name;
8352 CLASS_SUPER_NAME (klass) = super_name;
8353 CLASS_CLS_METHODS (klass) = NULL_TREE;
8355 if (! objc_is_class_name (class_name)
8356 && (decl = lookup_name (class_name)))
8358 error ("%qE redeclared as different kind of symbol",
8359 class_name);
8360 error ("previous declaration of %q+D",
8361 decl);
8364 switch (code)
8366 case CLASS_IMPLEMENTATION_TYPE:
8368 tree chain;
8370 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
8371 if (TREE_VALUE (chain) == class_name)
8373 error ("reimplementation of class %qE",
8374 class_name);
8375 return error_mark_node;
8377 implemented_classes = tree_cons (NULL_TREE, class_name,
8378 implemented_classes);
8381 /* Reset for multiple classes per file. */
8382 method_slot = 0;
8384 objc_implementation_context = klass;
8386 /* Lookup the interface for this implementation. */
8388 if (!(implementation_template = lookup_interface (class_name)))
8390 warning (0, "cannot find interface declaration for %qE",
8391 class_name);
8392 add_class (implementation_template = objc_implementation_context,
8393 class_name);
8396 /* If a super class has been specified in the implementation,
8397 insure it conforms to the one specified in the interface. */
8399 if (super_name
8400 && (super_name != CLASS_SUPER_NAME (implementation_template)))
8402 tree previous_name = CLASS_SUPER_NAME (implementation_template);
8403 error ("conflicting super class name %qE",
8404 super_name);
8405 if (previous_name)
8406 error ("previous declaration of %qE", previous_name);
8407 else
8408 error ("previous declaration");
8411 else if (! super_name)
8413 CLASS_SUPER_NAME (objc_implementation_context)
8414 = CLASS_SUPER_NAME (implementation_template);
8416 break;
8418 case CLASS_INTERFACE_TYPE:
8419 if (lookup_interface (class_name))
8420 #ifdef OBJCPLUS
8421 error ("duplicate interface declaration for class %qE", class_name);
8422 #else
8423 warning (0, "duplicate interface declaration for class %qE", class_name);
8424 #endif
8425 else
8426 add_class (klass, class_name);
8428 if (protocol_list)
8429 CLASS_PROTOCOL_LIST (klass)
8430 = lookup_and_install_protocols (protocol_list);
8431 break;
8433 case CATEGORY_INTERFACE_TYPE:
8435 tree class_category_is_assoc_with;
8437 /* For a category, class_name is really the name of the class that
8438 the following set of methods will be associated with. We must
8439 find the interface so that can derive the objects template. */
8440 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
8442 error ("cannot find interface declaration for %qE",
8443 class_name);
8444 exit (FATAL_EXIT_CODE);
8446 else
8447 add_category (class_category_is_assoc_with, klass);
8449 if (protocol_list)
8450 CLASS_PROTOCOL_LIST (klass)
8451 = lookup_and_install_protocols (protocol_list);
8453 break;
8455 case CATEGORY_IMPLEMENTATION_TYPE:
8456 /* Reset for multiple classes per file. */
8457 method_slot = 0;
8459 objc_implementation_context = klass;
8461 /* For a category, class_name is really the name of the class that
8462 the following set of methods will be associated with. We must
8463 find the interface so that can derive the objects template. */
8465 if (!(implementation_template = lookup_interface (class_name)))
8467 error ("cannot find interface declaration for %qE",
8468 class_name);
8469 exit (FATAL_EXIT_CODE);
8471 break;
8472 default:
8473 gcc_unreachable ();
8475 return klass;
8478 static tree
8479 continue_class (tree klass)
8481 switch (TREE_CODE (klass))
8483 case CLASS_IMPLEMENTATION_TYPE:
8484 case CATEGORY_IMPLEMENTATION_TYPE:
8486 struct imp_entry *imp_entry;
8488 /* Check consistency of the instance variables. */
8490 if (CLASS_RAW_IVARS (klass))
8491 check_ivars (implementation_template, klass);
8493 /* code generation */
8494 #ifdef OBJCPLUS
8495 push_lang_context (lang_name_c);
8496 #endif
8497 build_private_template (implementation_template);
8498 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
8499 objc_instance_type = build_pointer_type (uprivate_record);
8501 imp_entry = ggc_alloc_imp_entry ();
8503 imp_entry->next = imp_list;
8504 imp_entry->imp_context = klass;
8505 imp_entry->imp_template = implementation_template;
8507 synth_forward_declarations ();
8508 imp_entry->class_decl = UOBJC_CLASS_decl;
8509 imp_entry->meta_decl = UOBJC_METACLASS_decl;
8510 imp_entry->has_cxx_cdtors = 0;
8512 /* Append to front and increment count. */
8513 imp_list = imp_entry;
8514 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
8515 imp_count++;
8516 else
8517 cat_count++;
8518 #ifdef OBJCPLUS
8519 pop_lang_context ();
8520 #endif /* OBJCPLUS */
8522 return get_class_ivars (implementation_template, true);
8523 break;
8525 case CLASS_INTERFACE_TYPE:
8527 #ifdef OBJCPLUS
8528 push_lang_context (lang_name_c);
8529 #endif /* OBJCPLUS */
8530 objc_collecting_ivars = 1;
8531 build_private_template (klass);
8532 objc_collecting_ivars = 0;
8533 #ifdef OBJCPLUS
8534 pop_lang_context ();
8535 #endif /* OBJCPLUS */
8536 return NULL_TREE;
8537 break;
8539 default:
8540 return error_mark_node;
8544 /* This routine builds a property ivar name. */
8546 static char *
8547 objc_build_property_ivar_name (tree property_decl)
8549 static char string[BUFSIZE];
8550 sprintf (string, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
8551 return string;
8554 /* This routine builds name of the setter synthesized function. */
8556 static char *
8557 objc_build_property_setter_name (tree ident, bool delimit_colon)
8559 static char string[BUFSIZE];
8560 if (delimit_colon)
8561 sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
8562 else
8563 sprintf (string, "set%s", IDENTIFIER_POINTER (ident));
8564 string[3] = TOUPPER (string[3]);
8565 return string;
8568 /* This routine does all the work for generating data and code per each
8569 property declared in current implementation. */
8571 static void
8572 objc_gen_one_property_datum (tree klass, tree property, tree class_methods, bool *ivar_added)
8574 tree mth;
8576 /* If getter, check that it is already declared in user code. */
8577 if (PROPERTY_GETTER_NAME (property))
8579 mth = lookup_method (CLASS_NST_METHODS (class_methods),
8580 PROPERTY_GETTER_NAME (property));
8581 if (!mth)
8582 error ("property getter %qs not declared in class %qs",
8583 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property)),
8584 IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
8586 /* If setter, check that it is already declared in user code. */
8587 if (PROPERTY_SETTER_NAME (property))
8589 mth = lookup_method (CLASS_NST_METHODS (class_methods),
8590 PROPERTY_SETTER_NAME (property));
8591 if (!mth)
8592 error ("property setter %qs not declared in class %qs",
8593 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)),
8594 IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
8596 /* If ivar attribute specified, check that it is already declared. */
8597 if (PROPERTY_IVAR_NAME (property))
8599 if (!is_ivar (CLASS_IVARS (klass),
8600 PROPERTY_IVAR_NAME (property)))
8601 error ("ivar %qs in property declaration must be an existing ivar",
8602 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)));
8604 else if (!PROPERTY_GETTER_NAME (property)
8605 || (PROPERTY_READONLY (property) == boolean_false_node
8606 && !PROPERTY_SETTER_NAME (property)))
8608 /* Setter and/or getter must be synthesize and there was no user-specified
8609 ivar. Must create an ivar and add to to current class's ivar list. */
8610 tree record = CLASS_STATIC_TEMPLATE (klass);
8611 tree type = TREE_TYPE (property);
8612 tree field_decl, field;
8613 field_decl = create_field_decl (type,
8614 objc_build_property_ivar_name (property));
8615 DECL_CONTEXT (field_decl) = record;
8616 (void) add_instance_variable (klass,
8617 OBJC_IVAR_VIS_PUBLIC, field_decl);
8618 /* Unfortunately, CLASS_IVARS is completed when interface is completed.
8619 Must add the new ivar by hand to its list here. */
8621 CLASS_IVARS (klass) =
8622 chainon (CLASS_IVARS (klass),
8623 copy_node (field_decl));
8624 gcc_assert (record);
8625 /* Must also add this ivar to the end of list of fields for this class. */
8626 field = TYPE_FIELDS (record);
8627 if (field && field != CLASS_IVARS (klass))
8628 /* class has a hidden field, attach ivar list after the hiddent field. */
8629 TREE_CHAIN (field) = CLASS_IVARS (klass);
8630 else
8631 TYPE_FIELDS (record) = CLASS_IVARS (klass);
8632 *ivar_added = true;
8636 /* This routine processes an existing getter or setter attribute.
8637 It aliases internal property getter or setter to the user implemented
8638 getter or setter.
8641 static void
8642 objc_process_getter_setter (tree klass, tree property, bool getter)
8644 tree prop_mth_decl;
8645 tree prop_getter_mth_decl;
8646 tree name_ident;
8648 if (getter)
8649 /* getter name is same as property name. */
8650 name_ident = PROPERTY_NAME (property);
8651 else
8652 /* Must synthesize setter name from property name. */
8653 name_ident = get_identifier (objc_build_property_setter_name (
8654 PROPERTY_NAME (property), true));
8656 /* Find declaration of instance method for the property in its class. */
8657 prop_mth_decl = lookup_method (CLASS_NST_METHODS (klass), name_ident);
8659 if (!prop_mth_decl)
8660 return;
8662 prop_getter_mth_decl = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8663 getter ? PROPERTY_GETTER_NAME (property)
8664 : PROPERTY_SETTER_NAME (property));
8666 if (!prop_getter_mth_decl)
8667 return;
8669 if (!match_proto_with_proto (prop_getter_mth_decl, prop_mth_decl, 1))
8671 error ("User %s %qs does not match property %qs type",
8672 getter ? "getter" : "setter",
8673 IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl)),
8674 IDENTIFIER_POINTER (PROPERTY_NAME (property)));
8675 return;
8677 /* We alias internal property getter to the user implemented getter by copying relevant
8678 entries from user's implementation to the internal one. */
8679 prop_mth_decl = copy_node (prop_mth_decl);
8680 METHOD_ENCODING (prop_mth_decl) = METHOD_ENCODING (prop_getter_mth_decl);
8681 METHOD_DEFINITION (prop_mth_decl) = METHOD_DEFINITION (prop_getter_mth_decl);
8682 objc_add_method (objc_implementation_context, prop_mth_decl, 0, 0);
8685 /* This routine synthesizes a 'getter' method. */
8687 static void
8688 objc_synthesize_getter (tree klass, tree class_method, tree property)
8690 tree fn, decl;
8691 tree body;
8692 tree ret_val;
8693 tree ivar_ident;
8695 /* If user has implemented a getter with same name then do nothing. */
8696 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8697 PROPERTY_NAME (property)))
8698 return;
8700 /* Find declaration of the property in the interface. There must be one. */
8701 decl = lookup_method (CLASS_NST_METHODS (class_method),
8702 PROPERTY_NAME (property));
8704 /* If one not declared in the interface, this condition has already been reported
8705 as user error (because property was not declared in the interface). */
8706 if (!decl)
8707 return;
8709 /* For now no attributes. */
8710 objc_start_method_definition (false /* is_class_method */, copy_node (decl), NULL_TREE);
8712 body = c_begin_compound_stmt (true);
8713 /* return self->_property_name; */
8714 /* If user specified an ivar, use it in generation of the getter. */
8715 ivar_ident = PROPERTY_IVAR_NAME (property)
8716 ? PROPERTY_IVAR_NAME (property)
8717 : get_identifier (objc_build_property_ivar_name (property));
8719 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8720 is added *after* user ivar is parsed and objc_continue_implementation
8721 has already been called. */
8722 objc_ivar_chain = CLASS_IVARS (klass);
8723 ret_val = objc_lookup_ivar (NULL_TREE, ivar_ident);
8724 /* If ivar attribute is not a user declared attribute, this condition has
8725 already been repored as error. */
8726 gcc_assert (ret_val || PROPERTY_IVAR_NAME (property));
8728 if (ret_val)
8730 #ifdef OBJCPLUS
8731 finish_return_stmt (ret_val);
8732 #else
8733 (void)c_finish_return (input_location, ret_val, NULL);
8734 #endif
8736 add_stmt (c_end_compound_stmt (input_location, body, true));
8737 fn = current_function_decl;
8738 #ifdef OBJCPLUS
8739 finish_function ();
8740 #endif
8741 objc_finish_method_definition (fn);
8744 /* This routine synthesizes a 'setter' method. */
8746 static void
8747 objc_synthesize_setter (tree klass, tree class_method, tree property)
8749 tree fn, decl, ivar_ident, lhs, rhs;
8750 tree body;
8751 char *setter_name = objc_build_property_setter_name (
8752 PROPERTY_NAME (property), true);
8753 tree setter_ident = get_identifier (setter_name);
8755 /* If user has implemented a setter with same name then do nothing. */
8756 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8757 setter_ident))
8758 return;
8760 /* Find declaration of the property in the interface. There must be one. */
8761 decl = lookup_method (CLASS_NST_METHODS (class_method), setter_ident);
8763 /* If one not declared in the inerface, this condition has already been reported
8764 as user error (because property was not declared in the interface. */
8765 if (!decl)
8766 return;
8768 /* For now, no attributes. */
8769 objc_start_method_definition (false /* is_class_method */, copy_node (decl), NULL_TREE);
8771 body = c_begin_compound_stmt (true);
8772 /* _property_name = _value; */
8773 /* If user specified an ivar, use it in generation of the setter. */
8774 ivar_ident = PROPERTY_IVAR_NAME (property)
8775 ? PROPERTY_IVAR_NAME (property)
8776 : get_identifier (objc_build_property_ivar_name (property));
8778 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8779 is added *after* user ivar is parsed and objc_continue_implementation
8780 has already been called. */
8781 objc_ivar_chain = CLASS_IVARS (klass);
8782 lhs = objc_lookup_ivar (NULL_TREE, ivar_ident);
8783 /* If ivar attribute is not a user declared attribute, this condition has
8784 already been repored as error. */
8785 gcc_assert (lhs || PROPERTY_IVAR_NAME (property));
8786 if (lhs)
8788 rhs = lookup_name (get_identifier ("_value"));
8789 gcc_assert (rhs);
8790 /* FIXME: NULL types to get compile. */
8791 add_stmt (build_modify_expr (input_location,
8792 lhs, NULL_TREE, NOP_EXPR,
8793 input_location, rhs, NULL_TREE));
8795 add_stmt (c_end_compound_stmt (input_location, body, true));
8796 fn = current_function_decl;
8797 #ifdef OBJCPLUS
8798 finish_function ();
8799 #endif
8800 objc_finish_method_definition (fn);
8803 /* This function is called by the parser after a @synthesize
8804 expression is parsed. 'start_locus' is the location of the
8805 @synthesize expression, and 'property_and_ivar_list' is a chained
8806 list of the property and ivar names.
8808 void
8809 objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_and_ivar_list ATTRIBUTE_UNUSED)
8811 if (property_and_ivar_list == error_mark_node)
8812 return;
8814 if (!objc_implementation_context)
8816 /* We can get here only in Objective-C; the Objective-C++ parser
8817 detects the problem while parsing, outputs the error
8818 "misplaced '@synthesize' Objective-C++ construct" and skips
8819 the declaration. */
8820 error ("%<@synthesize%> not in @implementation context");
8821 return;
8824 /* TODO */
8825 error ("%<@synthesize%> is not supported in this version of the compiler");
8828 /* This function is called by the parser after a @dynamic expression
8829 is parsed. 'start_locus' is the location of the @dynamic
8830 expression, and 'property_list' is a chained list of all the
8831 property names. */
8832 void
8833 objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_list ATTRIBUTE_UNUSED)
8835 if (property_list == error_mark_node)
8836 return;
8838 if (!objc_implementation_context)
8840 /* We can get here only in Objective-C; the Objective-C++ parser
8841 detects the problem while parsing, outputs the error
8842 "misplaced '@dynamic' Objective-C++ construct" and skips the
8843 declaration. */
8844 error ("%<@dynamic%> not in @implementation context");
8845 return;
8848 /* TODO */
8849 error ("%<@dynamic%> is not supported in this version of the compiler");
8852 /* Main routine to generate code/data for all the property information for
8853 current implementation (class or category). CLASS is the interface where
8854 ivars are declared. CLASS_METHODS is where methods are found which
8855 could be a class or a category depending on whether we are implementing
8856 property of a class or a category. */
8858 static void
8859 objc_gen_property_data (tree klass, tree class_methods)
8861 tree x;
8862 bool ivar_added = false;
8863 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
8864 objc_gen_one_property_datum (klass, x, class_methods, &ivar_added);
8866 if (ivar_added)
8868 tree record = CLASS_STATIC_TEMPLATE (klass);
8869 /* Ugh, must recalculate struct layout since at least one ivar was added. */
8870 TYPE_SIZE (record) = 0;
8871 layout_type (record);
8874 /* Synthesize all getters for properties. */
8875 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
8877 /* Property has a getter attribute, no need to synthesize one. */
8878 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
8879 objc_synthesize_getter (klass, class_methods, x);
8880 else
8881 objc_process_getter_setter (class_methods, x, true);
8883 if (PROPERTY_READONLY (x) == boolean_false_node)
8885 /* not a readonly property. */
8886 if (PROPERTY_SETTER_NAME (x) == NULL_TREE)
8887 objc_synthesize_setter (klass, class_methods, x);
8888 else
8889 objc_process_getter_setter (class_methods, x, false);
8894 /* This is called once we see the "@end" in an interface/implementation. */
8896 static void
8897 finish_class (tree klass)
8899 switch (TREE_CODE (klass))
8901 case CLASS_IMPLEMENTATION_TYPE:
8903 /* All code generation is done in finish_objc. */
8905 /* Generate what needed for property; setters, getters, etc. */
8906 objc_gen_property_data (implementation_template, implementation_template);
8908 if (implementation_template != objc_implementation_context)
8910 /* Ensure that all method listed in the interface contain bodies. */
8911 check_methods (CLASS_CLS_METHODS (implementation_template),
8912 CLASS_CLS_METHODS (objc_implementation_context), '+');
8913 check_methods (CLASS_NST_METHODS (implementation_template),
8914 CLASS_NST_METHODS (objc_implementation_context), '-');
8916 if (CLASS_PROTOCOL_LIST (implementation_template))
8917 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
8918 "class",
8919 CLASS_NAME (objc_implementation_context));
8921 break;
8923 case CATEGORY_IMPLEMENTATION_TYPE:
8925 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
8927 if (category)
8929 /* Generate what needed for property; setters, getters, etc. */
8930 objc_gen_property_data (implementation_template, category);
8932 /* Ensure all method listed in the interface contain bodies. */
8933 check_methods (CLASS_CLS_METHODS (category),
8934 CLASS_CLS_METHODS (objc_implementation_context), '+');
8935 check_methods (CLASS_NST_METHODS (category),
8936 CLASS_NST_METHODS (objc_implementation_context), '-');
8938 if (CLASS_PROTOCOL_LIST (category))
8939 check_protocols (CLASS_PROTOCOL_LIST (category),
8940 "category",
8941 CLASS_SUPER_NAME (objc_implementation_context));
8943 break;
8945 default:
8947 /* Process properties of the class. */
8948 tree x;
8949 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
8951 tree type = TREE_TYPE (x);
8952 tree prop_name = PROPERTY_NAME (x);
8953 /* Build an instance method declaration: - (type) prop_name; */
8954 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
8956 /* No getter attribute specified. Generate an instance method for the
8957 getter. */
8958 tree rettype = build_tree_list (NULL_TREE, type);
8959 tree getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
8960 rettype, prop_name,
8961 NULL_TREE, false);
8962 objc_add_method (objc_interface_context, getter_decl, false, false);
8963 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
8965 else
8966 warning (0, "getter = %qs may not be specified in an interface",
8967 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x)));
8969 /* Build an instance method declaration: - (void) setName: (type)value; */
8970 if (PROPERTY_SETTER_NAME (x) == NULL_TREE
8971 && PROPERTY_READONLY (x) == boolean_false_node)
8973 /* Declare a setter instance method in the interface. */
8974 tree key_name, arg_type, arg_name;
8975 tree setter_decl, selector;
8976 tree ret_type = build_tree_list (NULL_TREE, void_type_node);
8977 /* setter name. */
8978 key_name = get_identifier (objc_build_property_setter_name
8979 (PROPERTY_NAME (x), false));
8980 arg_type = build_tree_list (NULL_TREE, type);
8981 arg_name = get_identifier ("_value");
8982 /* For now, no attributes. */
8983 selector = objc_build_keyword_decl (key_name, arg_type, arg_name, NULL);
8984 setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
8985 ret_type, selector,
8986 build_tree_list (NULL_TREE, NULL_TREE),
8987 false);
8988 objc_add_method (objc_interface_context, setter_decl, false, false);
8989 METHOD_PROPERTY_CONTEXT (setter_decl) = x;
8991 else if (PROPERTY_SETTER_NAME (x))
8992 warning (0, "setter = %qs may not be specified in an interface",
8993 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)));
8994 if (PROPERTY_IVAR_NAME (x))
8995 warning (0, "ivar = %qs attribute may not be specified in an interface",
8996 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (x)));
9002 static tree
9003 add_protocol (tree protocol)
9005 /* Put protocol on list in reverse order. */
9006 TREE_CHAIN (protocol) = protocol_chain;
9007 protocol_chain = protocol;
9008 return protocol_chain;
9011 static tree
9012 lookup_protocol (tree ident)
9014 tree chain;
9016 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
9017 if (ident == PROTOCOL_NAME (chain))
9018 return chain;
9020 return NULL_TREE;
9023 /* This function forward declares the protocols named by NAMES. If
9024 they are already declared or defined, the function has no effect. */
9026 void
9027 objc_declare_protocols (tree names)
9029 tree list;
9031 #ifdef OBJCPLUS
9032 if (current_namespace != global_namespace) {
9033 error ("Objective-C declarations may only appear in global scope");
9035 #endif /* OBJCPLUS */
9037 for (list = names; list; list = TREE_CHAIN (list))
9039 tree name = TREE_VALUE (list);
9041 if (lookup_protocol (name) == NULL_TREE)
9043 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
9045 TYPE_LANG_SLOT_1 (protocol)
9046 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9047 PROTOCOL_NAME (protocol) = name;
9048 PROTOCOL_LIST (protocol) = NULL_TREE;
9049 add_protocol (protocol);
9050 PROTOCOL_DEFINED (protocol) = 0;
9051 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9056 static tree
9057 start_protocol (enum tree_code code, tree name, tree list)
9059 tree protocol;
9061 #ifdef OBJCPLUS
9062 if (current_namespace != global_namespace) {
9063 error ("Objective-C declarations may only appear in global scope");
9065 #endif /* OBJCPLUS */
9067 protocol = lookup_protocol (name);
9069 if (!protocol)
9071 protocol = make_node (code);
9072 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9074 PROTOCOL_NAME (protocol) = name;
9075 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9076 add_protocol (protocol);
9077 PROTOCOL_DEFINED (protocol) = 1;
9078 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9080 check_protocol_recursively (protocol, list);
9082 else if (! PROTOCOL_DEFINED (protocol))
9084 PROTOCOL_DEFINED (protocol) = 1;
9085 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9087 check_protocol_recursively (protocol, list);
9089 else
9091 warning (0, "duplicate declaration for protocol %qE",
9092 name);
9094 return protocol;
9098 /* "Encode" a data type into a string, which grows in util_obstack.
9100 The format is described in gcc/doc/objc.texi, section 'Type
9101 encoding'.
9103 Most of the encode_xxx functions have a 'type' argument, which is
9104 the type to encode, and an integer 'curtype' argument, which is the
9105 index in the encoding string of the beginning of the encoding of
9106 the current type, and allows you to find what characters have
9107 already been written for the current type (they are the ones in the
9108 current encoding string starting from 'curtype').
9110 For example, if we are encoding a method which returns 'int' and
9111 takes a 'char **' argument, then when we get to the point of
9112 encoding the 'char **' argument, the encoded string already
9113 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9114 'curtype' will be set to 7 when starting to encode 'char **'.
9115 During the whole of the encoding of 'char **', 'curtype' will be
9116 fixed at 7, so the routine encoding the second pointer can find out
9117 that it's actually encoding a pointer to a pointer by looking
9118 backwards at what has already been encoded for the current type,
9119 and seeing there is a "^" (meaning a pointer) in there.
9123 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9124 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9125 'const', instead, is encoded directly as part of the type.
9128 static void
9129 encode_type_qualifiers (tree declspecs)
9131 tree spec;
9133 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
9135 /* FIXME: Shouldn't we use token->keyword here ? */
9136 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
9137 obstack_1grow (&util_obstack, 'n');
9138 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
9139 obstack_1grow (&util_obstack, 'N');
9140 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
9141 obstack_1grow (&util_obstack, 'o');
9142 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
9143 obstack_1grow (&util_obstack, 'O');
9144 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
9145 obstack_1grow (&util_obstack, 'R');
9146 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
9147 obstack_1grow (&util_obstack, 'V');
9148 else
9149 gcc_unreachable ();
9153 /* Determine if a pointee is marked read-only. Only used by the NeXT
9154 runtime to be compatible with gcc-3.3. */
9156 static bool
9157 pointee_is_readonly (tree pointee)
9159 while (POINTER_TYPE_P (pointee))
9160 pointee = TREE_TYPE (pointee);
9162 return TYPE_READONLY (pointee);
9165 /* Encode a pointer type. */
9167 static void
9168 encode_pointer (tree type, int curtype, int format)
9170 tree pointer_to = TREE_TYPE (type);
9172 if (flag_next_runtime)
9174 /* This code is used to be compatible with gcc-3.3. */
9175 /* For historical/compatibility reasons, the read-only qualifier
9176 of the pointee gets emitted _before_ the '^'. The read-only
9177 qualifier of the pointer itself gets ignored, _unless_ we are
9178 looking at a typedef! Also, do not emit the 'r' for anything
9179 but the outermost type! */
9180 if (!generating_instance_variables
9181 && (obstack_object_size (&util_obstack) - curtype <= 1)
9182 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
9183 ? TYPE_READONLY (type)
9184 : pointee_is_readonly (pointer_to)))
9185 obstack_1grow (&util_obstack, 'r');
9188 if (TREE_CODE (pointer_to) == RECORD_TYPE)
9190 if (OBJC_TYPE_NAME (pointer_to)
9191 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
9193 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
9195 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
9197 obstack_1grow (&util_obstack, '@');
9198 return;
9200 else if (TYPE_HAS_OBJC_INFO (pointer_to)
9201 && TYPE_OBJC_INTERFACE (pointer_to))
9203 if (generating_instance_variables)
9205 obstack_1grow (&util_obstack, '@');
9206 obstack_1grow (&util_obstack, '"');
9207 obstack_grow (&util_obstack, name, strlen (name));
9208 obstack_1grow (&util_obstack, '"');
9209 return;
9211 else
9213 obstack_1grow (&util_obstack, '@');
9214 return;
9217 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
9219 obstack_1grow (&util_obstack, '#');
9220 return;
9222 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
9224 obstack_1grow (&util_obstack, ':');
9225 return;
9229 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
9230 && TYPE_MODE (pointer_to) == QImode)
9232 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
9233 ? OBJC_TYPE_NAME (pointer_to)
9234 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
9236 /* (BOOL *) are an exception and are encoded as ^c, while all
9237 other pointers to char are encoded as *. */
9238 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
9240 if (!flag_next_runtime)
9242 /* The NeXT runtime adds the 'r' before getting here. */
9244 /* It appears that "r*" means "const char *" rather than
9245 "char *const". "char *const" is encoded as "*",
9246 which is identical to "char *", so the "const" is
9247 unfortunately lost. */
9248 if (TYPE_READONLY (pointer_to))
9249 obstack_1grow (&util_obstack, 'r');
9252 obstack_1grow (&util_obstack, '*');
9253 return;
9257 /* We have a normal pointer type that does not get special treatment. */
9258 obstack_1grow (&util_obstack, '^');
9259 encode_type (pointer_to, curtype, format);
9262 static void
9263 encode_array (tree type, int curtype, int format)
9265 tree an_int_cst = TYPE_SIZE (type);
9266 tree array_of = TREE_TYPE (type);
9267 char buffer[40];
9269 if (an_int_cst == NULL)
9271 /* We are trying to encode an incomplete array. An incomplete
9272 array is forbidden as part of an instance variable. */
9273 if (generating_instance_variables)
9275 /* TODO: Detect this error earlier. */
9276 error ("instance variable has unknown size");
9277 return;
9280 /* So the only case in which an incomplete array could occur is
9281 if we are encoding the arguments or return value of a method.
9282 In that case, an incomplete array argument or return value
9283 (eg, -(void)display: (char[])string) is treated like a
9284 pointer because that is how the compiler does the function
9285 call. A special, more complicated case, is when the
9286 incomplete array is the last member of a struct (eg, if we
9287 are encoding "struct { unsigned long int a;double b[];}"),
9288 which is again part of a method argument/return value. In
9289 that case, we really need to communicate to the runtime that
9290 there is an incomplete array (not a pointer!) there. So, we
9291 detect that special case and encode it as a zero-length
9292 array.
9294 Try to detect that we are part of a struct. We do this by
9295 searching for '=' in the type encoding for the current type.
9296 NB: This hack assumes that you can't use '=' as part of a C
9297 identifier.
9300 char *enc = obstack_base (&util_obstack) + curtype;
9301 if (memchr (enc, '=',
9302 obstack_object_size (&util_obstack) - curtype) == NULL)
9304 /* We are not inside a struct. Encode the array as a
9305 pointer. */
9306 encode_pointer (type, curtype, format);
9307 return;
9311 /* Else, we are in a struct, and we encode it as a zero-length
9312 array. */
9313 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
9315 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
9316 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
9317 else
9318 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
9319 TREE_INT_CST_LOW (an_int_cst)
9320 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
9322 obstack_grow (&util_obstack, buffer, strlen (buffer));
9323 encode_type (array_of, curtype, format);
9324 obstack_1grow (&util_obstack, ']');
9325 return;
9328 /* Encode a vector. The vector type is a GCC extension to C. */
9329 static void
9330 encode_vector (tree type, int curtype, int format)
9332 tree vector_of = TREE_TYPE (type);
9333 char buffer[40];
9335 /* Vectors are like simple fixed-size arrays. */
9337 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
9338 alignment of the vector, and <code> is the base type. Eg, int
9339 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
9340 assuming that the alignment is 32 bytes. We include size and
9341 alignment in bytes so that the runtime does not have to have any
9342 knowledge of the actual types.
9344 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
9345 /* We want to compute the equivalent of sizeof (<vector>).
9346 Code inspired by c_sizeof_or_alignof_type. */
9347 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
9348 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
9349 /* We want to compute the equivalent of __alignof__
9350 (<vector>). Code inspired by
9351 c_sizeof_or_alignof_type. */
9352 TYPE_ALIGN_UNIT (type));
9353 obstack_grow (&util_obstack, buffer, strlen (buffer));
9354 encode_type (vector_of, curtype, format);
9355 obstack_1grow (&util_obstack, ']');
9356 return;
9359 static void
9360 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
9362 tree field = TYPE_FIELDS (type);
9364 for (; field; field = DECL_CHAIN (field))
9366 #ifdef OBJCPLUS
9367 /* C++ static members, and things that are not field at all,
9368 should not appear in the encoding. */
9369 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
9370 continue;
9371 #endif
9373 /* Recursively encode fields of embedded base classes. */
9374 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
9375 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
9377 encode_aggregate_fields (TREE_TYPE (field),
9378 pointed_to, curtype, format);
9379 continue;
9382 if (generating_instance_variables && !pointed_to)
9384 tree fname = DECL_NAME (field);
9386 obstack_1grow (&util_obstack, '"');
9388 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
9389 obstack_grow (&util_obstack,
9390 IDENTIFIER_POINTER (fname),
9391 strlen (IDENTIFIER_POINTER (fname)));
9393 obstack_1grow (&util_obstack, '"');
9396 encode_field_decl (field, curtype, format);
9400 static void
9401 encode_aggregate_within (tree type, int curtype, int format, int left,
9402 int right)
9404 tree name;
9405 /* NB: aggregates that are pointed to have slightly different encoding
9406 rules in that you never encode the names of instance variables. */
9407 int ob_size = obstack_object_size (&util_obstack);
9408 bool inline_contents = false;
9409 bool pointed_to = false;
9411 if (flag_next_runtime)
9413 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
9414 pointed_to = true;
9416 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
9417 && (!pointed_to || ob_size - curtype == 1
9418 || (ob_size - curtype == 2
9419 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
9420 inline_contents = true;
9422 else
9424 /* c0 and c1 are the last two characters in the encoding of the
9425 current type; if the last two characters were '^' or '^r',
9426 then we are encoding an aggregate that is "pointed to". The
9427 comment above applies: in that case we should avoid encoding
9428 the names of instance variables.
9430 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
9431 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
9433 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
9434 pointed_to = true;
9436 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
9438 if (!pointed_to)
9439 inline_contents = true;
9440 else
9442 /* Note that the check (ob_size - curtype < 2) prevents
9443 infinite recursion when encoding a structure which is
9444 a linked list (eg, struct node { struct node *next;
9445 }). Each time we follow a pointer, we add one
9446 character to ob_size, and curtype is fixed, so after
9447 at most two pointers we stop inlining contents and
9448 break the loop.
9450 The other case where we don't inline is "^r", which
9451 is a pointer to a constant struct.
9453 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
9454 inline_contents = true;
9459 /* Traverse struct aliases; it is important to get the
9460 original struct and its tag name (if any). */
9461 type = TYPE_MAIN_VARIANT (type);
9462 name = OBJC_TYPE_NAME (type);
9463 /* Open parenth/bracket. */
9464 obstack_1grow (&util_obstack, left);
9466 /* Encode the struct/union tag name, or '?' if a tag was
9467 not provided. Typedef aliases do not qualify. */
9468 #ifdef OBJCPLUS
9469 /* For compatibility with the NeXT runtime, ObjC++ encodes template
9470 args as a composite struct tag name. */
9471 if (name && TREE_CODE (name) == IDENTIFIER_NODE
9472 /* Did this struct have a tag? */
9473 && !TYPE_WAS_ANONYMOUS (type))
9474 obstack_grow (&util_obstack,
9475 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
9476 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
9477 #else
9478 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
9479 obstack_grow (&util_obstack,
9480 IDENTIFIER_POINTER (name),
9481 strlen (IDENTIFIER_POINTER (name)));
9482 #endif
9483 else
9484 obstack_1grow (&util_obstack, '?');
9486 /* Encode the types (and possibly names) of the inner fields,
9487 if required. */
9488 if (inline_contents)
9490 obstack_1grow (&util_obstack, '=');
9491 encode_aggregate_fields (type, pointed_to, curtype, format);
9493 /* Close parenth/bracket. */
9494 obstack_1grow (&util_obstack, right);
9497 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
9498 field type. */
9500 static void
9501 encode_next_bitfield (int width)
9503 char buffer[40];
9504 sprintf (buffer, "b%d", width);
9505 obstack_grow (&util_obstack, buffer, strlen (buffer));
9509 /* Encodes 'type', ignoring type qualifiers (which you should encode
9510 beforehand if needed) with the exception of 'const', which is
9511 encoded by encode_type. See above for the explanation of
9512 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
9513 OBJC_ENCODE_DONT_INLINE_DEFS.
9515 static void
9516 encode_type (tree type, int curtype, int format)
9518 enum tree_code code = TREE_CODE (type);
9520 /* Ignore type qualifiers other than 'const' when encoding a
9521 type. */
9523 if (type == error_mark_node)
9524 return;
9526 if (!flag_next_runtime)
9528 if (TYPE_READONLY (type))
9529 obstack_1grow (&util_obstack, 'r');
9532 switch (code)
9534 case ENUMERAL_TYPE:
9535 if (flag_next_runtime)
9537 /* Kludge for backwards-compatibility with gcc-3.3: enums
9538 are always encoded as 'i' no matter what type they
9539 actually are (!). */
9540 obstack_1grow (&util_obstack, 'i');
9541 break;
9543 /* Else, they are encoded exactly like the integer type that is
9544 used by the compiler to store them. */
9545 case INTEGER_TYPE:
9547 char c;
9548 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
9550 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
9551 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
9552 case 32:
9554 tree int_type = type;
9555 if (flag_next_runtime)
9557 /* Another legacy kludge for compatiblity with
9558 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
9559 but not always. For typedefs, we need to use 'i'
9560 or 'I' instead if encoding a struct field, or a
9561 pointer! */
9562 int_type = ((!generating_instance_variables
9563 && (obstack_object_size (&util_obstack)
9564 == (unsigned) curtype))
9565 ? TYPE_MAIN_VARIANT (type)
9566 : type);
9568 if (int_type == long_unsigned_type_node
9569 || int_type == long_integer_type_node)
9570 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
9571 else
9572 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
9574 break;
9575 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
9576 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
9577 default: gcc_unreachable ();
9579 obstack_1grow (&util_obstack, c);
9580 break;
9582 case REAL_TYPE:
9584 char c;
9585 /* Floating point types. */
9586 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
9588 case 32: c = 'f'; break;
9589 case 64: c = 'd'; break;
9590 case 96:
9591 case 128: c = 'D'; break;
9592 default: gcc_unreachable ();
9594 obstack_1grow (&util_obstack, c);
9595 break;
9597 case VOID_TYPE:
9598 obstack_1grow (&util_obstack, 'v');
9599 break;
9601 case BOOLEAN_TYPE:
9602 obstack_1grow (&util_obstack, 'B');
9603 break;
9605 case ARRAY_TYPE:
9606 encode_array (type, curtype, format);
9607 break;
9609 case POINTER_TYPE:
9610 #ifdef OBJCPLUS
9611 case REFERENCE_TYPE:
9612 #endif
9613 encode_pointer (type, curtype, format);
9614 break;
9616 case RECORD_TYPE:
9617 encode_aggregate_within (type, curtype, format, '{', '}');
9618 break;
9620 case UNION_TYPE:
9621 encode_aggregate_within (type, curtype, format, '(', ')');
9622 break;
9624 case FUNCTION_TYPE: /* '?' means an unknown type. */
9625 obstack_1grow (&util_obstack, '?');
9626 break;
9628 case COMPLEX_TYPE:
9629 /* A complex is encoded as 'j' followed by the inner type (eg,
9630 "_Complex int" is encoded as 'ji'). */
9631 obstack_1grow (&util_obstack, 'j');
9632 encode_type (TREE_TYPE (type), curtype, format);
9633 break;
9635 case VECTOR_TYPE:
9636 encode_vector (type, curtype, format);
9637 break;
9639 default:
9640 warning (0, "unknown type %s found during Objective-C encoding",
9641 gen_type_name (type));
9642 obstack_1grow (&util_obstack, '?');
9643 break;
9646 if (flag_next_runtime)
9648 /* Super-kludge. Some ObjC qualifier and type combinations need
9649 to be rearranged for compatibility with gcc-3.3. */
9650 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
9652 char *enc = obstack_base (&util_obstack) + curtype;
9654 /* Rewrite "in const" from "nr" to "rn". */
9655 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
9656 strncpy (enc - 1, "rn", 2);
9661 static void
9662 encode_gnu_bitfield (int position, tree type, int size)
9664 enum tree_code code = TREE_CODE (type);
9665 char buffer[40];
9666 char charType = '?';
9668 /* This code is only executed for the GNU runtime, so we can ignore
9669 the NeXT runtime kludge of always encoding enums as 'i' no matter
9670 what integers they actually are. */
9671 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
9673 if (integer_zerop (TYPE_MIN_VALUE (type)))
9674 /* Unsigned integer types. */
9676 switch (TYPE_MODE (type))
9678 case QImode:
9679 charType = 'C'; break;
9680 case HImode:
9681 charType = 'S'; break;
9682 case SImode:
9684 if (type == long_unsigned_type_node)
9685 charType = 'L';
9686 else
9687 charType = 'I';
9688 break;
9690 case DImode:
9691 charType = 'Q'; break;
9692 default:
9693 gcc_unreachable ();
9696 else
9697 /* Signed integer types. */
9699 switch (TYPE_MODE (type))
9701 case QImode:
9702 charType = 'c'; break;
9703 case HImode:
9704 charType = 's'; break;
9705 case SImode:
9707 if (type == long_integer_type_node)
9708 charType = 'l';
9709 else
9710 charType = 'i';
9711 break;
9713 case DImode:
9714 charType = 'q'; break;
9715 default:
9716 gcc_unreachable ();
9720 else
9722 /* Do not do any encoding, produce an error and keep going. */
9723 error ("trying to encode non-integer type as a bitfield");
9724 return;
9727 sprintf (buffer, "b%d%c%d", position, charType, size);
9728 obstack_grow (&util_obstack, buffer, strlen (buffer));
9731 static void
9732 encode_field_decl (tree field_decl, int curtype, int format)
9734 #ifdef OBJCPLUS
9735 /* C++ static members, and things that are not fields at all,
9736 should not appear in the encoding. */
9737 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
9738 return;
9739 #endif
9741 /* Generate the bitfield typing information, if needed. Note the difference
9742 between GNU and NeXT runtimes. */
9743 if (DECL_BIT_FIELD_TYPE (field_decl))
9745 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
9747 if (flag_next_runtime)
9748 encode_next_bitfield (size);
9749 else
9750 encode_gnu_bitfield (int_bit_position (field_decl),
9751 DECL_BIT_FIELD_TYPE (field_decl), size);
9753 else
9754 encode_type (TREE_TYPE (field_decl), curtype, format);
9757 /* Decay array and function parameters into pointers. */
9759 static tree
9760 objc_decay_parm_type (tree type)
9762 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
9763 type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
9764 ? TREE_TYPE (type)
9765 : type);
9767 return type;
9770 static GTY(()) tree objc_parmlist = NULL_TREE;
9772 /* Append PARM to a list of formal parameters of a method, making a necessary
9773 array-to-pointer adjustment along the way. */
9775 static void
9776 objc_push_parm (tree parm)
9778 tree type;
9780 if (TREE_TYPE (parm) == error_mark_node)
9782 objc_parmlist = chainon (objc_parmlist, parm);
9783 return;
9786 /* Decay arrays and functions into pointers. */
9787 type = objc_decay_parm_type (TREE_TYPE (parm));
9789 /* If the parameter type has been decayed, a new PARM_DECL needs to be
9790 built as well. */
9791 if (type != TREE_TYPE (parm))
9792 parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
9794 DECL_ARG_TYPE (parm)
9795 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
9797 /* Record constancy and volatility. */
9798 c_apply_type_quals_to_decl
9799 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
9800 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
9801 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
9803 objc_parmlist = chainon (objc_parmlist, parm);
9806 /* Retrieve the formal parameter list constructed via preceding calls to
9807 objc_push_parm(). */
9809 #ifdef OBJCPLUS
9810 static tree
9811 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
9812 #else
9813 static struct c_arg_info *
9814 objc_get_parm_info (int have_ellipsis)
9815 #endif
9817 #ifdef OBJCPLUS
9818 tree parm_info = objc_parmlist;
9819 objc_parmlist = NULL_TREE;
9821 return parm_info;
9822 #else
9823 tree parm_info = objc_parmlist;
9824 struct c_arg_info *arg_info;
9825 /* The C front-end requires an elaborate song and dance at
9826 this point. */
9827 push_scope ();
9828 declare_parm_level ();
9829 while (parm_info)
9831 tree next = DECL_CHAIN (parm_info);
9833 DECL_CHAIN (parm_info) = NULL_TREE;
9834 parm_info = pushdecl (parm_info);
9835 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
9836 parm_info = next;
9838 arg_info = get_parm_info (have_ellipsis);
9839 pop_scope ();
9840 objc_parmlist = NULL_TREE;
9841 return arg_info;
9842 #endif
9845 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
9846 method definitions. In the case of instance methods, we can be more
9847 specific as to the type of 'self'. */
9849 static void
9850 synth_self_and_ucmd_args (void)
9852 tree self_type;
9854 if (objc_method_context
9855 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
9856 self_type = objc_instance_type;
9857 else
9858 /* Really a `struct objc_class *'. However, we allow people to
9859 assign to self, which changes its type midstream. */
9860 self_type = objc_object_type;
9862 /* id self; */
9863 objc_push_parm (build_decl (input_location,
9864 PARM_DECL, self_id, self_type));
9866 /* SEL _cmd; */
9867 objc_push_parm (build_decl (input_location,
9868 PARM_DECL, ucmd_id, objc_selector_type));
9871 /* Transform an Objective-C method definition into a static C function
9872 definition, synthesizing the first two arguments, "self" and "_cmd",
9873 in the process. */
9875 static void
9876 start_method_def (tree method)
9878 tree parmlist;
9879 #ifdef OBJCPLUS
9880 tree parm_info;
9881 #else
9882 struct c_arg_info *parm_info;
9883 #endif
9884 int have_ellipsis = 0;
9886 /* If we are defining a "dealloc" method in a non-root class, we
9887 will need to check if a [super dealloc] is missing, and warn if
9888 it is. */
9889 if(CLASS_SUPER_NAME (objc_implementation_context)
9890 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
9891 should_call_super_dealloc = 1;
9892 else
9893 should_call_super_dealloc = 0;
9895 /* Required to implement _msgSuper. */
9896 objc_method_context = method;
9897 UOBJC_SUPER_decl = NULL_TREE;
9899 /* Generate prototype declarations for arguments..."new-style". */
9900 synth_self_and_ucmd_args ();
9902 /* Generate argument declarations if a keyword_decl. */
9903 parmlist = METHOD_SEL_ARGS (method);
9904 while (parmlist)
9906 /* parmlist is a KEYWORD_DECL. */
9907 tree type = TREE_VALUE (TREE_TYPE (parmlist));
9908 tree parm;
9910 parm = build_decl (input_location,
9911 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
9912 decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
9913 objc_push_parm (parm);
9914 parmlist = DECL_CHAIN (parmlist);
9917 if (METHOD_ADD_ARGS (method))
9919 tree akey;
9921 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
9922 akey; akey = TREE_CHAIN (akey))
9924 objc_push_parm (TREE_VALUE (akey));
9927 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9928 have_ellipsis = 1;
9931 parm_info = objc_get_parm_info (have_ellipsis);
9933 really_start_method (objc_method_context, parm_info);
9936 /* Return 1 if TYPE1 is equivalent to TYPE2
9937 for purposes of method overloading. */
9939 static int
9940 objc_types_are_equivalent (tree type1, tree type2)
9942 if (type1 == type2)
9943 return 1;
9945 /* Strip away indirections. */
9946 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
9947 && (TREE_CODE (type1) == TREE_CODE (type2)))
9948 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
9949 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
9950 return 0;
9952 type1 = (TYPE_HAS_OBJC_INFO (type1)
9953 ? TYPE_OBJC_PROTOCOL_LIST (type1)
9954 : NULL_TREE);
9955 type2 = (TYPE_HAS_OBJC_INFO (type2)
9956 ? TYPE_OBJC_PROTOCOL_LIST (type2)
9957 : NULL_TREE);
9959 if (list_length (type1) == list_length (type2))
9961 for (; type2; type2 = TREE_CHAIN (type2))
9962 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
9963 return 0;
9964 return 1;
9966 return 0;
9969 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
9971 static int
9972 objc_types_share_size_and_alignment (tree type1, tree type2)
9974 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
9975 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
9978 /* Return 1 if PROTO1 is equivalent to PROTO2
9979 for purposes of method overloading. Ordinarily, the type signatures
9980 should match up exactly, unless STRICT is zero, in which case we
9981 shall allow differences in which the size and alignment of a type
9982 is the same. */
9984 static int
9985 comp_proto_with_proto (tree proto1, tree proto2, int strict)
9987 /* The following test is needed in case there are hashing
9988 collisions. */
9989 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
9990 return 0;
9992 return match_proto_with_proto (proto1, proto2, strict);
9995 static int
9996 match_proto_with_proto (tree proto1, tree proto2, int strict)
9998 tree type1, type2;
10000 /* Compare return types. */
10001 type1 = TREE_VALUE (TREE_TYPE (proto1));
10002 type2 = TREE_VALUE (TREE_TYPE (proto2));
10004 if (!objc_types_are_equivalent (type1, type2)
10005 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
10006 return 0;
10008 /* Compare argument types. */
10009 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
10010 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
10011 type1 && type2;
10012 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
10014 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
10015 && (strict
10016 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
10017 TREE_VALUE (type2))))
10018 return 0;
10021 return (!type1 && !type2);
10024 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
10025 this occurs. ObjC method dispatches are _not_ like C++ virtual
10026 member function dispatches, and we account for the difference here. */
10027 tree
10028 #ifdef OBJCPLUS
10029 objc_fold_obj_type_ref (tree ref, tree known_type)
10030 #else
10031 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
10032 tree known_type ATTRIBUTE_UNUSED)
10033 #endif
10035 #ifdef OBJCPLUS
10036 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
10038 /* If the receiver does not have virtual member functions, there
10039 is nothing we can (or need to) do here. */
10040 if (!v)
10041 return NULL_TREE;
10043 /* Let C++ handle C++ virtual functions. */
10044 return cp_fold_obj_type_ref (ref, known_type);
10045 #else
10046 /* For plain ObjC, we currently do not need to do anything. */
10047 return NULL_TREE;
10048 #endif
10051 static void
10052 objc_start_function (tree name, tree type, tree attrs,
10053 #ifdef OBJCPLUS
10054 tree params
10055 #else
10056 struct c_arg_info *params
10057 #endif
10060 tree fndecl = build_decl (input_location,
10061 FUNCTION_DECL, name, type);
10063 #ifdef OBJCPLUS
10064 DECL_ARGUMENTS (fndecl) = params;
10065 DECL_INITIAL (fndecl) = error_mark_node;
10066 DECL_EXTERNAL (fndecl) = 0;
10067 TREE_STATIC (fndecl) = 1;
10068 retrofit_lang_decl (fndecl);
10069 cplus_decl_attributes (&fndecl, attrs, 0);
10070 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
10071 #else
10072 current_function_returns_value = 0; /* Assume, until we see it does. */
10073 current_function_returns_null = 0;
10074 decl_attributes (&fndecl, attrs, 0);
10075 announce_function (fndecl);
10076 DECL_INITIAL (fndecl) = error_mark_node;
10077 DECL_EXTERNAL (fndecl) = 0;
10078 TREE_STATIC (fndecl) = 1;
10079 current_function_decl = pushdecl (fndecl);
10080 push_scope ();
10081 declare_parm_level ();
10082 DECL_RESULT (current_function_decl)
10083 = build_decl (input_location,
10084 RESULT_DECL, NULL_TREE,
10085 TREE_TYPE (TREE_TYPE (current_function_decl)));
10086 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
10087 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
10088 start_fname_decls ();
10089 store_parm_decls_from (params);
10090 #endif
10092 TREE_USED (current_function_decl) = 1;
10095 /* - Generate an identifier for the function. the format is "_n_cls",
10096 where 1 <= n <= nMethods, and cls is the name the implementation we
10097 are processing.
10098 - Install the return type from the method declaration.
10099 - If we have a prototype, check for type consistency. */
10101 static void
10102 really_start_method (tree method,
10103 #ifdef OBJCPLUS
10104 tree parmlist
10105 #else
10106 struct c_arg_info *parmlist
10107 #endif
10110 tree ret_type, meth_type;
10111 tree method_id;
10112 const char *sel_name, *class_name, *cat_name;
10113 char *buf;
10115 /* Synth the storage class & assemble the return type. */
10116 ret_type = TREE_VALUE (TREE_TYPE (method));
10118 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
10119 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
10120 cat_name = ((TREE_CODE (objc_implementation_context)
10121 == CLASS_IMPLEMENTATION_TYPE)
10122 ? NULL
10123 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
10124 method_slot++;
10126 /* Make sure this is big enough for any plausible method label. */
10127 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
10128 + (cat_name ? strlen (cat_name) : 0));
10130 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
10131 class_name, cat_name, sel_name, method_slot);
10133 method_id = get_identifier (buf);
10135 #ifdef OBJCPLUS
10136 /* Objective-C methods cannot be overloaded, so we don't need
10137 the type encoding appended. It looks bad anyway... */
10138 push_lang_context (lang_name_c);
10139 #endif
10141 meth_type
10142 = build_function_type (ret_type,
10143 get_arg_type_list (method, METHOD_DEF, 0));
10144 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
10146 /* Set self_decl from the first argument. */
10147 self_decl = DECL_ARGUMENTS (current_function_decl);
10149 /* Suppress unused warnings. */
10150 TREE_USED (self_decl) = 1;
10151 DECL_READ_P (self_decl) = 1;
10152 TREE_USED (DECL_CHAIN (self_decl)) = 1;
10153 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
10154 #ifdef OBJCPLUS
10155 pop_lang_context ();
10156 #endif
10158 METHOD_DEFINITION (method) = current_function_decl;
10160 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10162 if (implementation_template != objc_implementation_context)
10164 tree proto
10165 = lookup_method_static (implementation_template,
10166 METHOD_SEL_NAME (method),
10167 ((TREE_CODE (method) == CLASS_METHOD_DECL)
10168 | OBJC_LOOKUP_NO_SUPER));
10170 if (proto)
10172 if (!comp_proto_with_proto (method, proto, 1))
10174 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
10176 warning_at (DECL_SOURCE_LOCATION (method), 0,
10177 "conflicting types for %<%c%s%>",
10178 (type ? '-' : '+'),
10179 identifier_to_locale (gen_method_decl (method)));
10180 inform (DECL_SOURCE_LOCATION (proto),
10181 "previous declaration of %<%c%s%>",
10182 (type ? '-' : '+'),
10183 identifier_to_locale (gen_method_decl (proto)));
10186 else
10188 /* We have a method @implementation even though we did not
10189 see a corresponding @interface declaration (which is allowed
10190 by Objective-C rules). Go ahead and place the method in
10191 the @interface anyway, so that message dispatch lookups
10192 will see it. */
10193 tree interface = implementation_template;
10195 if (TREE_CODE (objc_implementation_context)
10196 == CATEGORY_IMPLEMENTATION_TYPE)
10197 interface = lookup_category
10198 (interface,
10199 CLASS_SUPER_NAME (objc_implementation_context));
10201 if (interface)
10202 objc_add_method (interface, copy_node (method),
10203 TREE_CODE (method) == CLASS_METHOD_DECL,
10204 /* is_optional= */ false);
10209 static void *UOBJC_SUPER_scope = 0;
10211 /* _n_Method (id self, SEL sel, ...)
10213 struct objc_super _S;
10214 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10215 } */
10217 static tree
10218 get_super_receiver (void)
10220 if (objc_method_context)
10222 tree super_expr, super_expr_list;
10224 if (!UOBJC_SUPER_decl)
10226 UOBJC_SUPER_decl = build_decl (input_location,
10227 VAR_DECL, get_identifier (TAG_SUPER),
10228 objc_super_template);
10229 /* This prevents `unused variable' warnings when compiling with -Wall. */
10230 TREE_USED (UOBJC_SUPER_decl) = 1;
10231 DECL_READ_P (UOBJC_SUPER_decl) = 1;
10232 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
10233 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
10234 NULL_TREE);
10235 UOBJC_SUPER_scope = objc_get_current_scope ();
10238 /* Set receiver to self. */
10239 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
10240 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
10241 NOP_EXPR, input_location, self_decl,
10242 NULL_TREE);
10243 super_expr_list = super_expr;
10245 /* Set class to begin searching. */
10246 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
10247 get_identifier ("super_class"));
10249 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
10251 /* [_cls, __cls]Super are "pre-built" in
10252 synth_forward_declarations. */
10254 super_expr = build_modify_expr (input_location, super_expr,
10255 NULL_TREE, NOP_EXPR,
10256 input_location,
10257 ((TREE_CODE (objc_method_context)
10258 == INSTANCE_METHOD_DECL)
10259 ? ucls_super_ref
10260 : uucls_super_ref),
10261 NULL_TREE);
10264 else
10265 /* We have a category. */
10267 tree super_name = CLASS_SUPER_NAME (implementation_template);
10268 tree super_class;
10270 /* Barf if super used in a category of Object. */
10271 if (!super_name)
10273 error ("no super class declared in interface for %qE",
10274 CLASS_NAME (implementation_template));
10275 return error_mark_node;
10278 if (flag_next_runtime && !flag_zero_link)
10280 super_class = objc_get_class_reference (super_name);
10281 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
10282 /* If we are in a class method, we must retrieve the
10283 _metaclass_ for the current class, pointed at by
10284 the class's "isa" pointer. The following assumes that
10285 "isa" is the first ivar in a class (which it must be). */
10286 super_class
10287 = build_indirect_ref
10288 (input_location,
10289 build_c_cast (input_location,
10290 build_pointer_type (objc_class_type),
10291 super_class), RO_UNARY_STAR);
10293 else
10295 add_class_reference (super_name);
10296 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
10297 ? objc_get_class_decl : objc_get_meta_class_decl);
10298 assemble_external (super_class);
10299 super_class
10300 = build_function_call
10301 (input_location,
10302 super_class,
10303 build_tree_list
10304 (NULL_TREE,
10305 my_build_string_pointer
10306 (IDENTIFIER_LENGTH (super_name) + 1,
10307 IDENTIFIER_POINTER (super_name))));
10310 super_expr
10311 = build_modify_expr (input_location, super_expr, NULL_TREE,
10312 NOP_EXPR,
10313 input_location,
10314 build_c_cast (input_location,
10315 TREE_TYPE (super_expr),
10316 super_class),
10317 NULL_TREE);
10320 super_expr_list = build_compound_expr (input_location,
10321 super_expr_list, super_expr);
10323 super_expr = build_unary_op (input_location,
10324 ADDR_EXPR, UOBJC_SUPER_decl, 0);
10325 super_expr_list = build_compound_expr (input_location,
10326 super_expr_list, super_expr);
10328 return super_expr_list;
10330 else
10332 error ("[super ...] must appear in a method context");
10333 return error_mark_node;
10337 /* When exiting a scope, sever links to a 'super' declaration (if any)
10338 therein contained. */
10340 void
10341 objc_clear_super_receiver (void)
10343 if (objc_method_context
10344 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
10345 UOBJC_SUPER_decl = 0;
10346 UOBJC_SUPER_scope = 0;
10350 void
10351 objc_finish_method_definition (tree fndecl)
10353 /* We cannot validly inline ObjC methods, at least not without a language
10354 extension to declare that a method need not be dynamically
10355 dispatched, so suppress all thoughts of doing so. */
10356 DECL_UNINLINABLE (fndecl) = 1;
10358 #ifndef OBJCPLUS
10359 /* The C++ front-end will have called finish_function() for us. */
10360 finish_function ();
10361 #endif
10363 METHOD_ENCODING (objc_method_context)
10364 = encode_method_prototype (objc_method_context);
10366 /* Required to implement _msgSuper. This must be done AFTER finish_function,
10367 since the optimizer may find "may be used before set" errors. */
10368 objc_method_context = NULL_TREE;
10370 if (should_call_super_dealloc)
10371 warning (0, "method possibly missing a [super dealloc] call");
10374 /* Given a tree DECL node, produce a printable description of it in the given
10375 buffer, overwriting the buffer. */
10377 static char *
10378 gen_declaration (tree decl)
10380 errbuf[0] = '\0';
10382 if (DECL_P (decl))
10384 gen_type_name_0 (TREE_TYPE (decl));
10386 if (DECL_NAME (decl))
10388 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
10389 strcat (errbuf, " ");
10391 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
10394 if (DECL_INITIAL (decl)
10395 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
10396 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
10397 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
10400 return errbuf;
10403 /* Given a tree TYPE node, produce a printable description of it in the given
10404 buffer, overwriting the buffer. */
10406 static char *
10407 gen_type_name_0 (tree type)
10409 tree orig = type, proto;
10411 if (TYPE_P (type) && TYPE_NAME (type))
10412 type = TYPE_NAME (type);
10413 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
10415 tree inner = TREE_TYPE (type);
10417 while (TREE_CODE (inner) == ARRAY_TYPE)
10418 inner = TREE_TYPE (inner);
10420 gen_type_name_0 (inner);
10422 if (!POINTER_TYPE_P (inner))
10423 strcat (errbuf, " ");
10425 if (POINTER_TYPE_P (type))
10426 strcat (errbuf, "*");
10427 else
10428 while (type != inner)
10430 strcat (errbuf, "[");
10432 if (TYPE_DOMAIN (type))
10434 char sz[20];
10436 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
10437 (TREE_INT_CST_LOW
10438 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
10439 strcat (errbuf, sz);
10442 strcat (errbuf, "]");
10443 type = TREE_TYPE (type);
10446 goto exit_function;
10449 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
10450 type = DECL_NAME (type);
10452 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
10453 ? IDENTIFIER_POINTER (type)
10454 : "");
10456 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
10457 if (objc_is_id (orig))
10458 orig = TREE_TYPE (orig);
10460 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
10462 if (proto)
10464 strcat (errbuf, " <");
10466 while (proto) {
10467 strcat (errbuf,
10468 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
10469 proto = TREE_CHAIN (proto);
10470 strcat (errbuf, proto ? ", " : ">");
10474 exit_function:
10475 return errbuf;
10478 static char *
10479 gen_type_name (tree type)
10481 errbuf[0] = '\0';
10483 return gen_type_name_0 (type);
10486 /* Given a method tree, put a printable description into the given
10487 buffer (overwriting) and return a pointer to the buffer. */
10489 static char *
10490 gen_method_decl (tree method)
10492 tree chain;
10494 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
10495 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
10496 strcat (errbuf, ")");
10497 chain = METHOD_SEL_ARGS (method);
10499 if (chain)
10501 /* We have a chain of keyword_decls. */
10504 if (KEYWORD_KEY_NAME (chain))
10505 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
10507 strcat (errbuf, ":(");
10508 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
10509 strcat (errbuf, ")");
10511 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
10512 if ((chain = DECL_CHAIN (chain)))
10513 strcat (errbuf, " ");
10515 while (chain);
10517 if (METHOD_ADD_ARGS (method))
10519 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
10521 /* Know we have a chain of parm_decls. */
10522 while (chain)
10524 strcat (errbuf, ", ");
10525 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
10526 chain = TREE_CHAIN (chain);
10529 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
10530 strcat (errbuf, ", ...");
10534 else
10535 /* We have a unary selector. */
10536 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
10538 return errbuf;
10541 /* Debug info. */
10544 /* Dump an @interface declaration of the supplied class CHAIN to the
10545 supplied file FP. Used to implement the -gen-decls option (which
10546 prints out an @interface declaration of all classes compiled in
10547 this run); potentially useful for debugging the compiler too. */
10548 static void
10549 dump_interface (FILE *fp, tree chain)
10551 /* FIXME: A heap overflow here whenever a method (or ivar)
10552 declaration is so long that it doesn't fit in the buffer. The
10553 code and all the related functions should be rewritten to avoid
10554 using fixed size buffers. */
10555 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
10556 tree ivar_decls = CLASS_RAW_IVARS (chain);
10557 tree nst_methods = CLASS_NST_METHODS (chain);
10558 tree cls_methods = CLASS_CLS_METHODS (chain);
10560 fprintf (fp, "\n@interface %s", my_name);
10562 /* CLASS_SUPER_NAME is used to store the superclass name for
10563 classes, and the category name for categories. */
10564 if (CLASS_SUPER_NAME (chain))
10566 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
10568 switch (TREE_CODE (chain))
10570 case CATEGORY_IMPLEMENTATION_TYPE:
10571 case CATEGORY_INTERFACE_TYPE:
10572 fprintf (fp, " (%s)\n", name);
10573 break;
10574 default:
10575 fprintf (fp, " : %s\n", name);
10576 break;
10579 else
10580 fprintf (fp, "\n");
10582 /* FIXME - the following doesn't seem to work at the moment. */
10583 if (ivar_decls)
10585 fprintf (fp, "{\n");
10588 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
10589 ivar_decls = TREE_CHAIN (ivar_decls);
10591 while (ivar_decls);
10592 fprintf (fp, "}\n");
10595 while (nst_methods)
10597 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
10598 nst_methods = TREE_CHAIN (nst_methods);
10601 while (cls_methods)
10603 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
10604 cls_methods = TREE_CHAIN (cls_methods);
10607 fprintf (fp, "@end\n");
10610 #if 0
10611 /* Produce the pretty printing for an Objective-C method. This is
10612 currently unused, but could be handy while reorganizing the pretty
10613 printing to be more robust. */
10614 static const char *
10615 objc_pretty_print_method (bool is_class_method,
10616 const char *class_name,
10617 const char *category_name,
10618 const char *selector)
10620 if (category_name)
10622 char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
10623 + strlen (selector) + 7);
10625 if (is_class_method)
10626 sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
10627 else
10628 sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
10630 return result;
10632 else
10634 char *result = XNEWVEC (char, strlen (class_name)
10635 + strlen (selector) + 5);
10637 if (is_class_method)
10638 sprintf (result, "+[%s %s]", class_name, selector);
10639 else
10640 sprintf (result, "-[%s %s]", class_name, selector);
10642 return result;
10645 #endif
10647 /* Demangle function for Objective-C. Attempt to demangle the
10648 function name associated with a method (eg, going from
10649 "_i_NSObject__class" to "-[NSObject class]"); usually for the
10650 purpose of pretty printing or error messages. Return the demangled
10651 name, or NULL if the string is not an Objective-C mangled method
10652 name.
10654 Because of how the mangling is done, any method that has a '_' in
10655 its original name is at risk of being demangled incorrectly. In
10656 some cases there are multiple valid ways to demangle a method name
10657 and there is no way we can decide.
10659 TODO: objc_demangle() can't always get it right; the right way to
10660 get this correct for all method names would be to store the
10661 Objective-C method name somewhere in the function decl. Then,
10662 there is no demangling to do; we'd just pull the method name out of
10663 the decl. As an additional bonus, when printing error messages we
10664 could check for such a method name, and if we find it, we know the
10665 function is actually an Objective-C method and we could print error
10666 messages saying "In method '+[NSObject class]" instead of "In
10667 function '+[NSObject class]" as we do now. */
10668 static const char *
10669 objc_demangle (const char *mangled)
10671 char *demangled, *cp;
10673 if (mangled[0] == '_' &&
10674 (mangled[1] == 'i' || mangled[1] == 'c') &&
10675 mangled[2] == '_')
10677 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
10678 if (mangled[1] == 'i')
10679 *cp++ = '-'; /* for instance method */
10680 else
10681 *cp++ = '+'; /* for class method */
10682 *cp++ = '['; /* opening left brace */
10683 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
10684 while (*cp && *cp == '_')
10685 cp++; /* skip any initial underbars in class name */
10686 cp = strchr(cp, '_'); /* find first non-initial underbar */
10687 if (cp == NULL)
10689 free(demangled); /* not mangled name */
10690 return NULL;
10692 if (cp[1] == '_') /* easy case: no category name */
10694 *cp++ = ' '; /* replace two '_' with one ' ' */
10695 strcpy(cp, mangled + (cp - demangled) + 2);
10697 else
10699 *cp++ = '('; /* less easy case: category name */
10700 cp = strchr(cp, '_');
10701 if (cp == 0)
10703 free(demangled); /* not mangled name */
10704 return NULL;
10706 *cp++ = ')';
10707 *cp++ = ' '; /* overwriting 1st char of method name... */
10708 strcpy(cp, mangled + (cp - demangled)); /* get it back */
10710 /* Now we have the method name. We need to generally replace
10711 '_' with ':' but trying to preserve '_' if it could only have
10712 been in the mangled string because it was already in the
10713 original name. In cases where it's ambiguous, we assume that
10714 any '_' originated from a ':'. */
10716 /* Initial '_'s in method name can't have been generating by
10717 converting ':'s. Skip them. */
10718 while (*cp && *cp == '_')
10719 cp++;
10721 /* If the method name does not end with '_', then it has no
10722 arguments and there was no replacement of ':'s with '_'s
10723 during mangling. Check for that case, and skip any
10724 replacement if so. This at least guarantees that methods
10725 with no arguments are always demangled correctly (unless the
10726 original name ends with '_'). */
10727 if (*(mangled + strlen (mangled) - 1) != '_')
10729 /* Skip to the end. */
10730 for (; *cp; cp++)
10733 else
10735 /* Replace remaining '_' with ':'. This may get it wrong if
10736 there were '_'s in the original name. In most cases it
10737 is impossible to disambiguate. */
10738 for (; *cp; cp++)
10739 if (*cp == '_')
10740 *cp = ':';
10742 *cp++ = ']'; /* closing right brace */
10743 *cp++ = 0; /* string terminator */
10744 return demangled;
10746 else
10747 return NULL; /* not an objc mangled name */
10750 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
10751 specific decl, return the printable name for it. If not, return
10752 NULL. */
10753 const char *
10754 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
10756 switch (TREE_CODE (decl))
10758 case FUNCTION_DECL:
10759 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
10760 break;
10762 /* The following happens when we are printing a deprecation
10763 warning for a method. The warn_deprecation() will end up
10764 trying to print the decl for INSTANCE_METHOD_DECL or
10765 CLASS_METHOD_DECL. It would be nice to be able to print
10766 "-[NSObject autorelease] is deprecated", but to do that, we'd
10767 need to store the class and method name in the method decl,
10768 which we currently don't do. For now, just return the name
10769 of the method. We don't return NULL, because that may
10770 trigger further attempts to pretty-print the decl in C/C++,
10771 but they wouldn't know how to pretty-print it. */
10772 case INSTANCE_METHOD_DECL:
10773 case CLASS_METHOD_DECL:
10774 return IDENTIFIER_POINTER (DECL_NAME (decl));
10775 break;
10776 default:
10777 return NULL;
10778 break;
10782 /* Return a printable name for 'decl'. This first tries
10783 objc_maybe_printable_name(), and if that fails, it returns the name
10784 in the decl. This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
10785 Objective-C; in Objective-C++, setting the hook is not enough
10786 because lots of C++ Front-End code calls cxx_printable_name,
10787 dump_decl and other C++ functions directly. So instead we have
10788 modified dump_decl to call objc_maybe_printable_name directly. */
10789 const char *
10790 objc_printable_name (tree decl, int v)
10792 const char *demangled_name = objc_maybe_printable_name (decl, v);
10794 if (demangled_name != NULL)
10795 return demangled_name;
10796 else
10797 return IDENTIFIER_POINTER (DECL_NAME (decl));
10800 static void
10801 init_objc (void)
10803 gcc_obstack_init (&util_obstack);
10804 util_firstobj = (char *) obstack_finish (&util_obstack);
10806 errbuf = XNEWVEC (char, 1024 * 10);
10807 hash_init ();
10808 synth_module_prologue ();
10811 static void
10812 finish_objc (void)
10814 struct imp_entry *impent;
10815 tree chain;
10816 /* The internally generated initializers appear to have missing braces.
10817 Don't warn about this. */
10818 int save_warn_missing_braces = warn_missing_braces;
10819 warn_missing_braces = 0;
10821 /* A missing @end may not be detected by the parser. */
10822 if (objc_implementation_context)
10824 warning (0, "%<@end%> missing in implementation context");
10825 finish_class (objc_implementation_context);
10826 objc_ivar_chain = NULL_TREE;
10827 objc_implementation_context = NULL_TREE;
10830 /* Process the static instances here because initialization of objc_symtab
10831 depends on them. */
10832 if (objc_static_instances)
10833 generate_static_references ();
10835 /* forward declare categories */
10836 if (cat_count)
10837 forward_declare_categories ();
10839 for (impent = imp_list; impent; impent = impent->next)
10841 objc_implementation_context = impent->imp_context;
10842 implementation_template = impent->imp_template;
10844 /* FIXME: This needs reworking to be more obvious. */
10846 UOBJC_CLASS_decl = impent->class_decl;
10847 UOBJC_METACLASS_decl = impent->meta_decl;
10849 /* Dump the @interface of each class as we compile it, if the
10850 -gen-decls option is in use. TODO: Dump the classes in the
10851 order they were found, rather than in reverse order as we
10852 are doing now. */
10853 if (flag_gen_declaration)
10855 dump_interface (gen_declaration_file, objc_implementation_context);
10858 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
10860 /* all of the following reference the string pool... */
10861 generate_ivar_lists ();
10862 generate_dispatch_tables ();
10863 generate_shared_structures (impent);
10865 else
10867 generate_dispatch_tables ();
10868 generate_category (impent);
10871 impent->class_decl = UOBJC_CLASS_decl;
10872 impent->meta_decl = UOBJC_METACLASS_decl;
10875 /* If we are using an array of selectors, we must always
10876 finish up the array decl even if no selectors were used. */
10877 if (flag_next_runtime)
10878 build_next_selector_translation_table ();
10879 else
10880 build_gnu_selector_translation_table ();
10882 if (protocol_chain)
10883 generate_protocols ();
10885 if (flag_next_runtime)
10886 generate_objc_image_info ();
10888 if (imp_list || class_names_chain
10889 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
10890 generate_objc_symtab_decl ();
10892 /* Arrange for ObjC data structures to be initialized at run time. */
10893 if (objc_implementation_context || class_names_chain || objc_static_instances
10894 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
10896 build_module_descriptor ();
10898 if (!flag_next_runtime)
10899 build_module_initializer_routine ();
10902 /* Dump the class references. This forces the appropriate classes
10903 to be linked into the executable image, preserving unix archive
10904 semantics. This can be removed when we move to a more dynamically
10905 linked environment. */
10907 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
10909 handle_class_ref (chain);
10910 if (TREE_PURPOSE (chain))
10911 generate_classref_translation_entry (chain);
10914 for (impent = imp_list; impent; impent = impent->next)
10915 handle_impent (impent);
10917 if (warn_selector)
10919 int slot;
10920 hash hsh;
10922 /* Run through the selector hash tables and print a warning for any
10923 selector which has multiple methods. */
10925 for (slot = 0; slot < SIZEHASHTABLE; slot++)
10927 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
10928 check_duplicates (hsh, 0, 1);
10929 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
10930 check_duplicates (hsh, 0, 1);
10934 warn_missing_braces = save_warn_missing_braces;
10937 /* Subroutines of finish_objc. */
10939 static void
10940 generate_classref_translation_entry (tree chain)
10942 tree expr, decl, type;
10944 decl = TREE_PURPOSE (chain);
10945 type = TREE_TYPE (decl);
10947 expr = add_objc_string (TREE_VALUE (chain), class_names);
10948 expr = convert (type, expr); /* cast! */
10950 /* This is a class reference. It is re-written by the runtime,
10951 but will be optimized away unless we force it. */
10952 DECL_PRESERVE_P (decl) = 1;
10953 finish_var_decl (decl, expr);
10954 return;
10957 static void
10958 handle_class_ref (tree chain)
10960 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
10961 char *string = (char *) alloca (strlen (name) + 30);
10962 tree decl;
10963 tree exp;
10965 sprintf (string, "%sobjc_class_name_%s",
10966 (flag_next_runtime ? "." : "__"), name);
10968 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
10969 if (flag_next_runtime)
10971 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
10972 return;
10974 #endif
10976 /* Make a decl for this name, so we can use its address in a tree. */
10977 decl = build_decl (input_location,
10978 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
10979 DECL_EXTERNAL (decl) = 1;
10980 TREE_PUBLIC (decl) = 1;
10981 pushdecl (decl);
10982 finish_var_decl (decl, 0);
10984 /* Make a decl for the address. */
10985 sprintf (string, "%sobjc_class_ref_%s",
10986 (flag_next_runtime ? "." : "__"), name);
10987 exp = build1 (ADDR_EXPR, string_type_node, decl);
10988 decl = build_decl (input_location,
10989 VAR_DECL, get_identifier (string), string_type_node);
10990 TREE_STATIC (decl) = 1;
10991 TREE_USED (decl) = 1;
10992 DECL_READ_P (decl) = 1;
10993 DECL_ARTIFICIAL (decl) = 1;
10994 DECL_INITIAL (decl) = error_mark_node;
10996 /* We must force the reference. */
10997 DECL_PRESERVE_P (decl) = 1;
10999 pushdecl (decl);
11000 finish_var_decl (decl, exp);
11003 static void
11004 handle_impent (struct imp_entry *impent)
11006 char *string;
11008 objc_implementation_context = impent->imp_context;
11009 implementation_template = impent->imp_template;
11011 switch (TREE_CODE (impent->imp_context))
11013 case CLASS_IMPLEMENTATION_TYPE:
11015 const char *const class_name =
11016 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
11018 string = (char *) alloca (strlen (class_name) + 30);
11020 sprintf (string, "%sobjc_class_name_%s",
11021 (flag_next_runtime ? "." : "__"), class_name);
11022 break;
11024 case CATEGORY_IMPLEMENTATION_TYPE:
11026 const char *const class_name =
11027 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
11028 const char *const class_super_name =
11029 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
11031 string = (char *) alloca (strlen (class_name)
11032 + strlen (class_super_name) + 30);
11034 /* Do the same for categories. Even though no references to
11035 these symbols are generated automatically by the compiler,
11036 it gives you a handle to pull them into an archive by
11037 hand. */
11038 sprintf (string, "*%sobjc_category_name_%s_%s",
11039 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
11040 break;
11042 default:
11043 return;
11046 #ifdef ASM_DECLARE_CLASS_REFERENCE
11047 if (flag_next_runtime)
11049 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
11050 return;
11052 else
11053 #endif
11055 tree decl, init;
11057 init = integer_zero_node;
11058 decl = build_decl (input_location,
11059 VAR_DECL, get_identifier (string), TREE_TYPE (init));
11060 TREE_PUBLIC (decl) = 1;
11061 TREE_READONLY (decl) = 1;
11062 TREE_USED (decl) = 1;
11063 TREE_CONSTANT (decl) = 1;
11064 DECL_CONTEXT (decl) = NULL_TREE;
11065 DECL_ARTIFICIAL (decl) = 1;
11066 TREE_STATIC (decl) = 1;
11067 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
11068 /* We must force the reference. */
11069 DECL_PRESERVE_P (decl) = 1;
11071 finish_var_decl(decl, init) ;
11075 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
11076 later requires that ObjC translation units participating in F&C be
11077 specially marked. The following routine accomplishes this. */
11079 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
11081 static void
11082 generate_objc_image_info (void)
11084 tree decl;
11085 int flags
11086 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
11087 | (flag_objc_gc ? 2 : 0));
11088 VEC(constructor_elt,gc) *v = NULL;
11089 tree array_type;
11091 if (!flags)
11092 return; /* No need for an image_info entry. */
11094 array_type = build_sized_array_type (integer_type_node, 2);
11096 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
11098 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
11099 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
11100 /* If we need this (determined above) it is because the runtime wants to
11101 refer to it in a manner hidden from the compiler. So we must force the
11102 output. */
11103 DECL_PRESERVE_P (decl) = 1;
11104 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
11107 /* Routine is called to issue diagnostic when reference to a private
11108 ivar is made and no other variable with same name is found in
11109 current scope. */
11110 bool
11111 objc_diagnose_private_ivar (tree id)
11113 tree ivar;
11114 if (!objc_method_context)
11115 return false;
11116 ivar = is_ivar (objc_ivar_chain, id);
11117 if (ivar && is_private (ivar))
11119 error ("instance variable %qs is declared private",
11120 IDENTIFIER_POINTER (id));
11121 return true;
11123 return false;
11126 /* Look up ID as an instance variable. OTHER contains the result of
11127 the C or C++ lookup, which we may want to use instead. */
11128 /* Also handle use of property as setter/getter. */
11129 tree
11130 objc_lookup_ivar (tree other, tree id)
11132 tree ivar, property;
11134 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
11135 if (!objc_method_context)
11136 return other;
11138 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
11139 /* We have a message to super. */
11140 return get_super_receiver ();
11142 /* In a class method, look up an instance variable only as a last
11143 resort. */
11144 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
11145 && other && other != error_mark_node)
11146 return other;
11148 property = NULL_TREE;
11149 if (objc_implementation_context)
11150 property = is_property (objc_implementation_context, id);
11152 if (!property)
11154 /* Look up the ivar, but do not use it if it is not accessible. */
11155 ivar = is_ivar (objc_ivar_chain, id);
11157 if (!ivar || is_private (ivar))
11158 return other;
11161 /* In an instance method, a local variable (or parameter) may hide the
11162 instance variable. */
11163 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11164 && other && other != error_mark_node
11165 #ifdef OBJCPLUS
11166 && CP_DECL_CONTEXT (other) != global_namespace)
11167 #else
11168 && !DECL_FILE_SCOPE_P (other))
11169 #endif
11171 if (property)
11172 warning (0, "local declaration of %qE hides property", id);
11173 else
11174 warning (0, "local declaration of %qE hides instance variable", id);
11176 return other;
11179 if (property)
11180 return build_property_reference (property, id);
11182 /* At this point, we are either in an instance method with no obscuring
11183 local definitions, or in a class method with no alternate definitions
11184 at all. */
11185 return build_ivar_reference (id);
11188 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
11189 needs to be done if we are calling a function through a cast. */
11191 tree
11192 objc_rewrite_function_call (tree function, tree first_param)
11194 if (TREE_CODE (function) == NOP_EXPR
11195 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
11196 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
11197 == FUNCTION_DECL)
11199 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
11200 TREE_OPERAND (function, 0),
11201 first_param, size_zero_node);
11204 return function;
11207 /* Look for the special case of OBJC_TYPE_REF with the address of
11208 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
11209 of its cousins). */
11212 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
11214 enum gimplify_status r0, r1;
11215 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
11216 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
11217 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
11218 == FUNCTION_DECL)
11220 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
11221 value of the OBJ_TYPE_REF, so force them to be emitted
11222 during subexpression evaluation rather than after the
11223 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
11224 C to use direct rather than indirect calls when the
11225 object expression has a postincrement. */
11226 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
11227 is_gimple_val, fb_rvalue);
11228 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
11229 is_gimple_val, fb_rvalue);
11231 return MIN (r0, r1);
11234 #ifdef OBJCPLUS
11235 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
11236 #else
11237 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
11238 #endif
11241 /* This routine returns true if TYP is a valid objc object type,
11242 suitable for messaging; false otherwise.
11245 static bool
11246 objc_type_valid_for_messaging (tree typ)
11248 if (!POINTER_TYPE_P (typ))
11249 return false;
11252 typ = TREE_TYPE (typ); /* Remove indirections. */
11253 while (POINTER_TYPE_P (typ));
11255 if (TREE_CODE (typ) != RECORD_TYPE)
11256 return false;
11258 return objc_is_object_id (typ) || TYPE_HAS_OBJC_INFO (typ);
11261 /* Begin code generation for fast enumeration (foreach) ... */
11263 /* Defines
11265 struct __objcFastEnumerationState
11267 unsigned long state;
11268 id *itemsPtr;
11269 unsigned long *mutationsPtr;
11270 unsigned long extra[5];
11273 Confusingly enough, NSFastEnumeration is then defined by libraries
11274 to be the same structure.
11277 static void
11278 build_fast_enumeration_state_template (void)
11280 tree decls, *chain = NULL;
11282 /* { */
11283 objc_fast_enumeration_state_template = objc_start_struct (get_identifier
11284 (TAG_FAST_ENUMERATION_STATE));
11286 /* unsigned long state; */
11287 decls = add_field_decl (long_unsigned_type_node, "state", &chain);
11289 /* id *itemsPtr; */
11290 add_field_decl (build_pointer_type (objc_object_type),
11291 "itemsPtr", &chain);
11293 /* unsigned long *mutationsPtr; */
11294 add_field_decl (build_pointer_type (long_unsigned_type_node),
11295 "mutationsPtr", &chain);
11297 /* unsigned long extra[5]; */
11298 add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
11299 "extra", &chain);
11301 /* } */
11302 objc_finish_struct (objc_fast_enumeration_state_template, decls);
11306 'objc_finish_foreach_loop()' generates the code for an Objective-C
11307 foreach loop. The 'location' argument is the location of the 'for'
11308 that starts the loop. The 'object_expression' is the expression of
11309 the 'object' that iterates; the 'collection_expression' is the
11310 expression of the collection that we iterate over (we need to make
11311 sure we evaluate this only once); the 'for_body' is the set of
11312 statements to be executed in each iteration; 'break_label' and
11313 'continue_label' are the break and continue labels which we need to
11314 emit since the <statements> may be jumping to 'break_label' (if they
11315 contain 'break') or to 'continue_label' (if they contain
11316 'continue').
11318 The syntax is
11320 for (<object expression> in <collection expression>)
11321 <statements>
11323 which is compiled into the following blurb:
11326 id __objc_foreach_collection;
11327 __objc_fast_enumeration_state __objc_foreach_enum_state;
11328 unsigned long __objc_foreach_batchsize;
11329 id __objc_foreach_items[16];
11330 __objc_foreach_collection = <collection expression>;
11331 __objc_foreach_enum_state = { 0 };
11332 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11334 if (__objc_foreach_batchsize == 0)
11335 <object expression> = nil;
11336 else
11338 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
11339 next_batch:
11341 unsigned long __objc_foreach_index;
11342 __objc_foreach_index = 0;
11344 next_object:
11345 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
11346 <object expression> = enumState.itemsPtr[__objc_foreach_index];
11347 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
11349 continue_label:
11350 __objc_foreach_index++;
11351 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
11352 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11354 if (__objc_foreach_batchsize != 0) goto next_batch;
11355 <object expression> = nil;
11356 break_label:
11360 'statements' may contain a 'continue' or 'break' instruction, which
11361 the user expects to 'continue' or 'break' the entire foreach loop.
11362 We are provided the labels that 'break' and 'continue' jump to, so
11363 we place them where we want them to jump to when they pick them.
11365 Optimization TODO: we could cache the IMP of
11366 countByEnumeratingWithState:objects:count:.
11369 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
11370 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
11372 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11373 #include "tree-pretty-print.h"
11374 #endif
11376 void
11377 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
11378 tree break_label, tree continue_label)
11380 /* A tree representing the __objcFastEnumerationState struct type,
11381 or NSFastEnumerationState struct, whatever we are using. */
11382 tree objc_fast_enumeration_state_type;
11384 /* The trees representing the declarations of each of the local variables. */
11385 tree objc_foreach_collection_decl;
11386 tree objc_foreach_enum_state_decl;
11387 tree objc_foreach_items_decl;
11388 tree objc_foreach_batchsize_decl;
11389 tree objc_foreach_mutations_pointer_decl;
11390 tree objc_foreach_index_decl;
11392 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
11393 tree selector_name;
11395 /* A tree representing the local bind. */
11396 tree bind;
11398 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
11399 tree first_if;
11401 /* A tree representing the 'else' part of 'first_if' */
11402 tree first_else;
11404 /* A tree representing the 'next_batch' label. */
11405 tree next_batch_label_decl;
11407 /* A tree representing the binding after the 'next_batch' label. */
11408 tree next_batch_bind;
11410 /* A tree representing the 'next_object' label. */
11411 tree next_object_label_decl;
11413 /* Temporary variables. */
11414 tree t;
11415 int i;
11417 if (object_expression == error_mark_node)
11418 return;
11420 if (collection_expression == error_mark_node)
11421 return;
11423 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression)))
11425 error ("iterating variable in fast enumeration is not an object");
11426 return;
11429 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression)))
11431 error ("collection in fast enumeration is not an object");
11432 return;
11435 /* TODO: Check that object_expression is either a variable
11436 declaration, or an lvalue. */
11438 /* This kludge is an idea from apple. We use the
11439 __objcFastEnumerationState struct implicitly defined by the
11440 compiler, unless a NSFastEnumerationState struct has been defined
11441 (by a Foundation library such as GNUstep Base) in which case, we
11442 use that one.
11444 objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
11446 tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
11448 if (objc_NSFastEnumeration_type)
11450 /* TODO: We really need to check that
11451 objc_NSFastEnumeration_type is the same as ours! */
11452 if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
11454 /* If it's a typedef, use the original type. */
11455 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
11456 objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
11457 else
11458 objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
11463 /* { */
11464 /* Done by c-parser.c. */
11466 /* type object; */
11467 /* Done by c-parser.c. */
11469 /* id __objc_foreach_collection */
11470 objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
11472 /* __objcFastEnumerationState __objc_foreach_enum_state; */
11473 objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
11474 TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
11476 /* id __objc_foreach_items[16]; */
11477 objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
11478 TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
11480 /* unsigned long __objc_foreach_batchsize; */
11481 objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
11482 TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
11484 /* Generate the local variable binding. */
11485 bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
11486 SET_EXPR_LOCATION (bind, location);
11487 TREE_SIDE_EFFECTS (bind) = 1;
11489 /* __objc_foreach_collection = <collection expression>; */
11490 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
11491 SET_EXPR_LOCATION (t, location);
11492 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11494 /* __objc_foreach_enum_state.state = 0; */
11495 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11496 get_identifier ("state")),
11497 build_int_cst (long_unsigned_type_node, 0));
11498 SET_EXPR_LOCATION (t, location);
11499 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11501 /* __objc_foreach_enum_state.itemsPtr = NULL; */
11502 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11503 get_identifier ("itemsPtr")),
11504 null_pointer_node);
11505 SET_EXPR_LOCATION (t, location);
11506 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11508 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
11509 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11510 get_identifier ("mutationsPtr")),
11511 null_pointer_node);
11512 SET_EXPR_LOCATION (t, location);
11513 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11515 /* __objc_foreach_enum_state.extra[0] = 0; */
11516 /* __objc_foreach_enum_state.extra[1] = 0; */
11517 /* __objc_foreach_enum_state.extra[2] = 0; */
11518 /* __objc_foreach_enum_state.extra[3] = 0; */
11519 /* __objc_foreach_enum_state.extra[4] = 0; */
11520 for (i = 0; i < 5 ; i++)
11522 t = build2 (MODIFY_EXPR, void_type_node,
11523 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11524 get_identifier ("extra")),
11525 build_int_cst (NULL_TREE, i)),
11526 build_int_cst (long_unsigned_type_node, 0));
11527 SET_EXPR_LOCATION (t, location);
11528 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11531 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11532 selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
11533 #ifdef OBJCPLUS
11534 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11535 /* Parameters. */
11536 tree_cons /* &__objc_foreach_enum_state */
11537 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11538 tree_cons /* __objc_foreach_items */
11539 (NULL_TREE, objc_foreach_items_decl,
11540 tree_cons /* 16 */
11541 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11542 #else
11543 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11545 struct c_expr array;
11546 array.value = objc_foreach_items_decl;
11547 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11548 /* Parameters. */
11549 tree_cons /* &__objc_foreach_enum_state */
11550 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11551 tree_cons /* __objc_foreach_items */
11552 (NULL_TREE, default_function_array_conversion (location, array).value,
11553 tree_cons /* 16 */
11554 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11556 #endif
11557 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
11558 convert (long_unsigned_type_node, t));
11559 SET_EXPR_LOCATION (t, location);
11560 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11562 /* if (__objc_foreach_batchsize == 0) */
11563 first_if = build3 (COND_EXPR, void_type_node,
11564 /* Condition. */
11565 c_fully_fold
11566 (c_common_truthvalue_conversion
11567 (location,
11568 build_binary_op (location,
11569 EQ_EXPR,
11570 objc_foreach_batchsize_decl,
11571 build_int_cst (long_unsigned_type_node, 0), 1)),
11572 false, NULL),
11573 /* Then block (we fill it in later). */
11574 NULL_TREE,
11575 /* Else block (we fill it in later). */
11576 NULL_TREE);
11577 SET_EXPR_LOCATION (first_if, location);
11578 append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
11580 /* then <object expression> = nil; */
11581 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
11582 SET_EXPR_LOCATION (t, location);
11583 COND_EXPR_THEN (first_if) = t;
11585 /* Now we build the 'else' part of the if; once we finish building
11586 it, we attach it to first_if as the 'else' part. */
11588 /* else */
11589 /* { */
11591 /* unsigned long __objc_foreach_mutations_pointer; */
11592 objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
11594 /* Generate the local variable binding. */
11595 first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
11596 SET_EXPR_LOCATION (first_else, location);
11597 TREE_SIDE_EFFECTS (first_else) = 1;
11599 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
11600 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
11601 build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11602 get_identifier ("mutationsPtr")),
11603 RO_UNARY_STAR));
11604 SET_EXPR_LOCATION (t, location);
11605 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11607 /* next_batch: */
11608 next_batch_label_decl = create_artificial_label (location);
11609 t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
11610 SET_EXPR_LOCATION (t, location);
11611 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11613 /* { */
11615 /* unsigned long __objc_foreach_index; */
11616 objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
11618 /* Generate the local variable binding. */
11619 next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
11620 SET_EXPR_LOCATION (next_batch_bind, location);
11621 TREE_SIDE_EFFECTS (next_batch_bind) = 1;
11622 append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
11624 /* __objc_foreach_index = 0; */
11625 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
11626 build_int_cst (long_unsigned_type_node, 0));
11627 SET_EXPR_LOCATION (t, location);
11628 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11630 /* next_object: */
11631 next_object_label_decl = create_artificial_label (location);
11632 t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
11633 SET_EXPR_LOCATION (t, location);
11634 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11636 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
11637 t = build3 (COND_EXPR, void_type_node,
11638 /* Condition. */
11639 c_fully_fold
11640 (c_common_truthvalue_conversion
11641 (location,
11642 build_binary_op
11643 (location,
11644 NE_EXPR,
11645 objc_foreach_mutations_pointer_decl,
11646 build_indirect_ref (location,
11647 objc_build_component_ref (objc_foreach_enum_state_decl,
11648 get_identifier ("mutationsPtr")),
11649 RO_UNARY_STAR), 1)),
11650 false, NULL),
11651 /* Then block. */
11652 build_function_call (input_location,
11653 objc_enumeration_mutation_decl,
11654 tree_cons (NULL, collection_expression, NULL)),
11655 /* Else block. */
11656 NULL_TREE);
11657 SET_EXPR_LOCATION (t, location);
11658 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11660 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
11661 t = build2 (MODIFY_EXPR, void_type_node, object_expression,
11662 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11663 get_identifier ("itemsPtr")),
11664 objc_foreach_index_decl));
11665 SET_EXPR_LOCATION (t, location);
11666 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11668 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
11669 append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
11671 /* continue_label: */
11672 if (continue_label)
11674 t = build1 (LABEL_EXPR, void_type_node, continue_label);
11675 SET_EXPR_LOCATION (t, location);
11676 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11679 /* __objc_foreach_index++; */
11680 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
11681 build_binary_op (location,
11682 PLUS_EXPR,
11683 objc_foreach_index_decl,
11684 build_int_cst (long_unsigned_type_node, 1), 1));
11685 SET_EXPR_LOCATION (t, location);
11686 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11688 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
11689 t = build3 (COND_EXPR, void_type_node,
11690 /* Condition. */
11691 c_fully_fold
11692 (c_common_truthvalue_conversion
11693 (location,
11694 build_binary_op (location,
11695 LT_EXPR,
11696 objc_foreach_index_decl,
11697 objc_foreach_batchsize_decl, 1)),
11698 false, NULL),
11699 /* Then block. */
11700 build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
11701 /* Else block. */
11702 NULL_TREE);
11703 SET_EXPR_LOCATION (t, location);
11704 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11706 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11707 #ifdef OBJCPLUS
11708 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11709 /* Parameters. */
11710 tree_cons /* &__objc_foreach_enum_state */
11711 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11712 tree_cons /* __objc_foreach_items */
11713 (NULL_TREE, objc_foreach_items_decl,
11714 tree_cons /* 16 */
11715 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11716 #else
11717 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11719 struct c_expr array;
11720 array.value = objc_foreach_items_decl;
11721 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11722 /* Parameters. */
11723 tree_cons /* &__objc_foreach_enum_state */
11724 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11725 tree_cons /* __objc_foreach_items */
11726 (NULL_TREE, default_function_array_conversion (location, array).value,
11727 tree_cons /* 16 */
11728 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11730 #endif
11731 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
11732 convert (long_unsigned_type_node, t));
11733 SET_EXPR_LOCATION (t, location);
11734 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11736 /* } */
11738 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
11739 t = build3 (COND_EXPR, void_type_node,
11740 /* Condition. */
11741 c_fully_fold
11742 (c_common_truthvalue_conversion
11743 (location,
11744 build_binary_op (location,
11745 NE_EXPR,
11746 objc_foreach_batchsize_decl,
11747 build_int_cst (long_unsigned_type_node, 0), 1)),
11748 false, NULL),
11749 /* Then block. */
11750 build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
11751 /* Else block. */
11752 NULL_TREE);
11753 SET_EXPR_LOCATION (t, location);
11754 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11756 /* <object expression> = nil; */
11757 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
11758 SET_EXPR_LOCATION (t, location);
11759 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11761 /* break_label: */
11762 if (break_label)
11764 t = build1 (LABEL_EXPR, void_type_node, break_label);
11765 SET_EXPR_LOCATION (t, location);
11766 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11769 /* } */
11770 COND_EXPR_ELSE (first_if) = first_else;
11772 /* Do the whole thing. */
11773 add_stmt (bind);
11775 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11776 /* This will print to stderr the whole blurb generated by the
11777 compiler while compiling (assuming the compiler doesn't crash
11778 before getting here).
11780 debug_generic_stmt (bind);
11781 #endif
11783 /* } */
11784 /* Done by c-parser.c */
11787 #include "gt-objc-objc-act.h"