In gcc/cp/: 2010-10-23 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / gcc / objc / objc-act.c
blob97ac0e8066b5d333b323dac1de396b85005abe09
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 /* FIXME: We need to intercept calls to warn_deprecated_use, since that
559 ultimately calls warning () with a "qD" formatter for decls. The 'D'
560 formatter does not handle ObjC-specific decls (in ObjC++). For now, we
561 interpose a switch to the default handler which simply prints the decl
562 identifier.
563 Eventually, we should handle this within the objc{,p}/ code. */
565 static void
566 objc_warn_deprecated_use (tree depitem, tree attr)
568 if (DECL_P (depitem))
570 static bool (*sav_printer) (pretty_printer *, text_info *, const char *,
571 int, bool, bool, bool) = NULL ;
572 if (sav_printer == NULL)
573 sav_printer = diagnostic_format_decoder (global_dc) ;
574 diagnostic_format_decoder (global_dc) = &default_tree_printer;
575 warn_deprecated_use (depitem, attr);
576 diagnostic_format_decoder (global_dc) = sav_printer;
578 else
579 warn_deprecated_use (depitem, attr);
582 bool
583 objc_init (void)
585 #ifdef OBJCPLUS
586 if (cxx_init () == false)
587 #else
588 if (c_objc_common_init () == false)
589 #endif
590 return false;
592 /* If gen_declaration desired, open the output file. */
593 if (flag_gen_declaration)
595 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
596 gen_declaration_file = fopen (dumpname, "w");
597 if (gen_declaration_file == 0)
598 fatal_error ("can't open %s: %m", dumpname);
599 free (dumpname);
602 if (flag_next_runtime)
604 TAG_GETCLASS = "objc_getClass";
605 TAG_GETMETACLASS = "objc_getMetaClass";
606 TAG_MSGSEND = "objc_msgSend";
607 TAG_MSGSENDSUPER = "objc_msgSendSuper";
608 TAG_MSGSEND_STRET = "objc_msgSend_stret";
609 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
610 default_constant_string_class_name = "NSConstantString";
612 else
614 TAG_GETCLASS = "objc_get_class";
615 TAG_GETMETACLASS = "objc_get_meta_class";
616 TAG_MSGSEND = "objc_msg_lookup";
617 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
618 /* GNU runtime does not provide special functions to support
619 structure-returning methods. */
620 default_constant_string_class_name = "NXConstantString";
621 flag_typed_selectors = 1;
622 /* GNU runtime does not need the compiler to change code
623 in order to do GC. */
624 if (flag_objc_gc)
626 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
627 flag_objc_gc=0;
631 init_objc ();
633 if (print_struct_values && !flag_compare_debug)
634 generate_struct_by_value_array ();
636 return true;
639 /* This is called automatically (at the very end of compilation) by
640 c_write_global_declarations and cp_write_global_declarations. */
641 void
642 objc_write_global_declarations (void)
644 mark_referenced_methods ();
646 /* Finalize Objective-C runtime data. */
647 finish_objc ();
649 if (gen_declaration_file)
650 fclose (gen_declaration_file);
653 /* Return the first occurrence of a method declaration corresponding
654 to sel_name in rproto_list. Search rproto_list recursively.
655 If is_class is 0, search for instance methods, otherwise for class
656 methods. */
657 static tree
658 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
659 int is_class)
661 tree rproto, p;
662 tree fnd = 0;
664 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
666 p = TREE_VALUE (rproto);
668 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
670 if ((fnd = lookup_method (is_class
671 ? PROTOCOL_CLS_METHODS (p)
672 : PROTOCOL_NST_METHODS (p), sel_name)))
674 else if (PROTOCOL_LIST (p))
675 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
676 sel_name, is_class);
678 else
680 ; /* An identifier...if we could not find a protocol. */
683 if (fnd)
684 return fnd;
687 return 0;
690 static tree
691 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
693 tree rproto, p;
695 /* Make sure the protocol is supported by the object on the rhs. */
696 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
698 tree fnd = 0;
699 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
701 p = TREE_VALUE (rproto);
703 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
705 if (lproto == p)
706 fnd = lproto;
708 else if (PROTOCOL_LIST (p))
709 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
712 if (fnd)
713 return fnd;
716 else
718 ; /* An identifier...if we could not find a protocol. */
721 return 0;
724 void
725 objc_start_class_interface (tree klass, tree super_class,
726 tree protos, tree attributes)
728 if (attributes)
729 warning_at (input_location, OPT_Wattributes,
730 "class attributes are not available in this version"
731 " of the compiler, (ignored)");
732 objc_interface_context
733 = objc_ivar_context
734 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
735 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
738 void
739 objc_start_category_interface (tree klass, tree categ,
740 tree protos, tree attributes)
742 if (attributes)
743 warning_at (input_location, OPT_Wattributes,
744 "category attributes are not available in this version"
745 " of the compiler, (ignored)");
746 objc_interface_context
747 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
748 objc_ivar_chain
749 = continue_class (objc_interface_context);
752 void
753 objc_start_protocol (tree name, tree protos, tree attributes)
755 if (attributes)
756 warning_at (input_location, OPT_Wattributes,
757 "protocol attributes are not available in this version"
758 " of the compiler, (ignored)");
759 objc_interface_context
760 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
761 objc_method_optional_flag = false;
764 void
765 objc_continue_interface (void)
767 objc_ivar_chain
768 = continue_class (objc_interface_context);
771 void
772 objc_finish_interface (void)
774 finish_class (objc_interface_context);
775 objc_interface_context = NULL_TREE;
776 objc_method_optional_flag = false;
779 void
780 objc_start_class_implementation (tree klass, tree super_class)
782 objc_implementation_context
783 = objc_ivar_context
784 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
785 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
788 void
789 objc_start_category_implementation (tree klass, tree categ)
791 objc_implementation_context
792 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
793 objc_ivar_chain
794 = continue_class (objc_implementation_context);
797 void
798 objc_continue_implementation (void)
800 objc_ivar_chain
801 = continue_class (objc_implementation_context);
804 void
805 objc_finish_implementation (void)
807 #ifdef OBJCPLUS
808 if (flag_objc_call_cxx_cdtors)
809 objc_generate_cxx_cdtors ();
810 #endif
812 if (objc_implementation_context)
814 finish_class (objc_implementation_context);
815 objc_ivar_chain = NULL_TREE;
816 objc_implementation_context = NULL_TREE;
818 else
819 warning (0, "%<@end%> must appear in an @implementation context");
822 void
823 objc_set_visibility (objc_ivar_visibility_kind visibility)
825 if (visibility == OBJC_IVAR_VIS_PACKAGE)
826 warning (0, "%<@package%> presently has the same effect as %<@public%>");
827 objc_ivar_visibility = visibility;
830 void
831 objc_set_method_opt (bool optional)
833 objc_method_optional_flag = optional;
834 if (!objc_interface_context
835 || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
837 error ("@optional/@required is allowed in @protocol context only.");
838 objc_method_optional_flag = false;
842 /* This routine gathers property attribute information from the attribute
843 portion of a property declaration. */
845 void
846 objc_set_property_attr (location_t loc, objc_property_attribute_kind attr,
847 tree ident)
849 static char string[BUFSIZE];
850 switch (attr)
852 case OBJC_PATTR_INIT: /* init */
853 property_readonly = property_copies = false;
854 property_setter = property_getter = property_ivar = NULL_TREE;
855 break;
856 case OBJC_PATTR_READONLY: /* readonly */
857 property_readonly = true;
858 break;
859 case OBJC_PATTR_GETTER: /* getter = ident */
860 if (property_getter != NULL_TREE)
861 error_at (loc, "the %<getter%> attribute may only be specified once");
862 property_getter = ident;
863 break;
864 case OBJC_PATTR_SETTER: /* setter = ident */
865 if (property_setter != NULL_TREE)
866 error_at (loc, "the %<setter%> attribute may only be specified once");
867 /* setters always have a trailing ':' in their name. In fact, this is the
868 only syntax that parser recognizes for a setter name. Must add a trailing
869 ':' here so name matches that of the declaration of user instance method
870 for the setter. */
871 sprintf (string, "%s:", IDENTIFIER_POINTER (ident));
872 property_setter = get_identifier (string);;
873 break;
874 case OBJC_PATTR_IVAR: /* ivar = ident */
875 if (property_ivar != NULL_TREE)
876 error_at (loc, "the %<ivar%> attribute may only be specified once");
877 else if (objc_interface_context)
879 warning_at (loc, 0, "the %<ivar%> attribute is ignored in an @interface");
880 property_ivar = NULL_TREE;
882 else
883 property_ivar = ident;
884 break;
885 case OBJC_PATTR_COPIES: /* copies */
886 property_copies = true;
887 break;
888 default:
889 break;
893 /* This routine builds a 'property_decl' tree node and adds it to the list
894 of such properties in the current class. It also checks for duplicates.
897 void
898 objc_add_property_variable (tree decl)
900 tree property_decl;
901 tree x;
902 tree interface = NULL_TREE;
904 if (objc_implementation_context)
906 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
907 if (!interface)
909 error ("no class property can be implemented without an interface");
910 return;
912 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
914 interface = lookup_category (interface,
915 CLASS_SUPER_NAME (objc_implementation_context));
916 if (!interface)
918 error ("no category property can be implemented without an interface");
919 return;
923 else if (!objc_interface_context)
925 fatal_error ("property declaration not in @interface or @implementation context");
926 return;
929 property_decl = make_node (PROPERTY_DECL);
930 TREE_TYPE (property_decl) = TREE_TYPE (decl);
932 PROPERTY_NAME (property_decl) = DECL_NAME (decl);
933 PROPERTY_GETTER_NAME (property_decl) = property_getter;
934 PROPERTY_SETTER_NAME (property_decl) = property_setter;
935 PROPERTY_IVAR_NAME (property_decl) = property_ivar;
936 PROPERTY_READONLY (property_decl) = property_readonly
937 ? boolean_true_node
938 : boolean_false_node;
939 PROPERTY_COPIES (property_decl) = property_copies
940 ? boolean_true_node
941 : boolean_false_node;
943 if (objc_interface_context)
945 /* Doing the property in interface declaration. */
947 /* Issue error if property and an ivar name match. */
948 if (TREE_CODE (objc_interface_context) == CLASS_INTERFACE_TYPE
949 && is_ivar (CLASS_IVARS (objc_interface_context), DECL_NAME (decl)))
950 error ("property %qD may not have the same name as an ivar in the class", decl);
951 /* must check for duplicate property declarations. */
952 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
954 if (PROPERTY_NAME (x) == DECL_NAME (decl))
956 error ("duplicate property declaration %qD", decl);
957 return;
960 TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
961 CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
963 else
965 /* Doing the property in implementation context. */
966 /* If property is not declared in the interface issue error. */
967 for (x = CLASS_PROPERTY_DECL (interface); x; x = TREE_CHAIN (x))
968 if (PROPERTY_NAME (x) == DECL_NAME (decl))
969 break;
970 if (!x)
972 error ("no declaration of property %qD found in the interface", decl);
973 return;
975 /* readonlys must also match. */
976 if (PROPERTY_READONLY (x) != PROPERTY_READONLY (property_decl))
978 error ("property %qD %<readonly%> attribute conflicts with its"
979 " interface version", decl);
981 /* copies must also match. */
982 if (PROPERTY_COPIES (x) != PROPERTY_COPIES (property_decl))
984 error ("property %qD %<copies%> attribute conflicts with its"
985 " interface version", decl);
987 /* Cannot have readonly and setter attribute for the same property. */
988 if (PROPERTY_READONLY (property_decl) == boolean_true_node &&
989 PROPERTY_SETTER_NAME (property_decl))
991 warning (0, "a %<readonly%> property cannot have a setter (ignored)");
992 PROPERTY_SETTER_NAME (property_decl) = NULL_TREE;
994 /* Add the property to the list of properties for current implementation. */
995 TREE_CHAIN (property_decl) = IMPL_PROPERTY_DECL (objc_implementation_context);
996 IMPL_PROPERTY_DECL (objc_implementation_context) = property_decl;
1000 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
1001 PROTOCOL.
1003 static tree
1004 lookup_property_in_list (tree chain, tree property)
1006 tree x;
1007 for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
1008 if (PROPERTY_NAME (x) == property)
1009 return x;
1010 return NULL_TREE;
1013 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
1015 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
1017 tree rproto, x;
1018 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
1020 tree p = TREE_VALUE (rproto);
1021 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
1023 if ((x = lookup_property_in_list (p, property)))
1024 return x;
1025 if (PROTOCOL_LIST (p))
1026 return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
1028 else
1030 ; /* An identifier...if we could not find a protocol. */
1033 return NULL_TREE;
1036 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
1037 chain of interface hierarchy.
1039 static tree
1040 lookup_property (tree interface_type, tree property)
1042 tree inter = interface_type;
1043 while (inter)
1045 tree x, category;
1046 if ((x = lookup_property_in_list (inter, property)))
1047 return x;
1048 /* Failing that, look for the property in each category of the class. */
1049 category = inter;
1050 while ((category = CLASS_CATEGORY_LIST (category)))
1051 if ((x = lookup_property_in_list (category, property)))
1052 return x;
1054 /* Failing to find in categories, look for property in protocol list. */
1055 if (CLASS_PROTOCOL_LIST (inter)
1056 && (x = lookup_property_in_protocol_list (
1057 CLASS_PROTOCOL_LIST (inter), property)))
1058 return x;
1060 /* Failing that, climb up the inheritance hierarchy. */
1061 inter = lookup_interface (CLASS_SUPER_NAME (inter));
1063 return inter;
1066 /* This routine recognizes a dot-notation for a propery reference and generates a call to
1067 the getter function for this property. In all other cases, it returns a NULL_TREE.
1070 tree
1071 objc_build_getter_call (tree receiver, tree component)
1073 tree x = NULL_TREE;
1074 tree rtype;
1076 if (receiver == NULL_TREE
1077 || receiver == error_mark_node
1078 || (rtype = TREE_TYPE (receiver)) == NULL_TREE)
1079 return NULL_TREE;
1081 if (component == NULL_TREE
1082 || component == error_mark_node
1083 || TREE_CODE (component) != IDENTIFIER_NODE)
1084 return NULL_TREE;
1086 if (objc_is_id (rtype))
1088 tree rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
1089 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
1090 : NULL_TREE);
1091 if (rprotos)
1092 x = lookup_property_in_protocol_list (rprotos, component);
1094 else
1096 tree basetype = TYPE_MAIN_VARIANT (rtype);
1098 if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1099 basetype = TREE_TYPE (basetype);
1100 else
1101 return NULL_TREE;
1103 while (basetype != NULL_TREE
1104 && TREE_CODE (basetype) == RECORD_TYPE
1105 && OBJC_TYPE_NAME (basetype)
1106 && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1107 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1108 basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1110 if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1112 tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1113 if (!interface_type)
1114 return NULL_TREE;
1115 x = lookup_property (interface_type, component);
1119 if (x)
1121 tree call_exp, getter;
1122 /* Get the getter name. */
1123 gcc_assert (PROPERTY_NAME (x));
1124 getter = objc_finish_message_expr (receiver, PROPERTY_NAME (x),
1125 NULL_TREE);
1126 call_exp = getter;
1127 #ifdef OBJCPLUS
1128 /* In C++, a getter which returns an aggregate value results in a
1129 target_expr which initializes a temporary to the call expression. */
1130 if (TREE_CODE (getter) == TARGET_EXPR)
1132 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
1133 gcc_assert (TREE_CODE (TREE_OPERAND (getter,0)) == VAR_DECL);
1134 call_exp = TREE_OPERAND (getter,1);
1136 #endif
1137 gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
1139 CALL_EXPR_OBJC_PROPERTY_GETTER (call_exp) = 1;
1140 return getter;
1142 return NULL_TREE;
1145 /* This routine builds a call to property's 'setter' function. RECEIVER is the
1146 receiving object for 'setter'. PROPERTY_IDENT is name of the property and
1147 RHS is the argument passed to the 'setter' function. */
1149 static tree
1150 objc_setter_func_call (tree receiver, tree property_ident, tree rhs)
1152 tree setter_argument = build_tree_list (NULL_TREE, rhs);
1153 char *setter_name = objc_build_property_setter_name (property_ident, true);
1154 tree setter;
1155 in_objc_property_setter_name_context = true;
1156 setter = objc_finish_message_expr (receiver, get_identifier (setter_name),
1157 setter_argument);
1158 in_objc_property_setter_name_context = false;
1159 return setter;
1162 /* Find the selector identifier from a reference. A somewhat tortuous way of
1163 obtaining the information to allow a setter to be written, given an
1164 existing getter. */
1166 static tree
1167 get_selector_from_reference (tree selref)
1169 tree chain;
1171 if (flag_next_runtime)
1173 /* Run through the selectors until we find the one we're looking for. */
1174 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1175 if (TREE_PURPOSE (chain) == selref)
1176 return TREE_VALUE (chain);
1178 else
1180 /* To find our way back to the selector for the GNU runtime is harder
1181 work, we need to decompose the representation of SELECTOR_TABLE[n]
1182 to find 'n'. This representation is in several forms. */
1183 if (TREE_CODE (selref) == POINTER_PLUS_EXPR)
1185 /* We need the element size to decode the array offset expression
1186 into an index. */
1187 unsigned size = (unsigned) TREE_INT_CST_LOW
1188 (TYPE_SIZE_UNIT
1189 (TREE_TYPE
1190 (TREE_TYPE
1191 (TREE_OPERAND
1192 (TREE_OPERAND
1193 (TREE_OPERAND (selref, 0), 0), 0)))));
1194 unsigned index =
1195 (unsigned) TREE_INT_CST_LOW (TREE_OPERAND (selref, 1))
1196 / size;
1197 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1198 if (!index--)
1199 return TREE_VALUE (chain);
1201 else if (TREE_CODE (selref) == NOP_EXPR)
1203 /* Either we have a base an index, or we have just a base (when the
1204 index is 0. */
1205 if (TREE_CODE (TREE_OPERAND (selref, 0)) == ADDR_EXPR
1206 && TREE_CODE
1207 (TREE_OPERAND
1208 (TREE_OPERAND (selref, 0), 0)) == ARRAY_REF)
1210 /* The Nth. */
1211 unsigned index = (unsigned) TREE_INT_CST_LOW
1212 (TREE_OPERAND
1213 (TREE_OPERAND
1214 (TREE_OPERAND (selref, 0), 0), 1));
1215 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1216 if (!index--)
1217 return TREE_VALUE (chain);
1219 else
1220 return TREE_VALUE (sel_ref_chain);
1221 } /* Else we don't know how to figure this out - which will produce a
1222 parse error - saying that the LHS is not writeable. */
1224 return NULL_TREE;
1227 /* This routine converts a previously synthesized 'getter' function call for
1228 a property and converts it to a 'setter' function call for the same
1229 property. */
1231 tree
1232 objc_build_setter_call (tree lhs, tree rhs)
1234 if (lhs
1235 && TREE_CODE (lhs) == CALL_EXPR
1236 && CALL_EXPR_OBJC_PROPERTY_GETTER (lhs))
1238 tree selector;
1239 /* Get the Object. */
1240 tree receiver = TREE_OPERAND (lhs, 3);
1241 /* Get the selector reference. */
1242 tree selector_reference = TREE_OPERAND (lhs, 4);
1243 gcc_assert (receiver && selector_reference);
1244 /* The style of the selector reference is different for GNU & NeXT. */
1245 selector = get_selector_from_reference (selector_reference);
1246 if (selector)
1247 return objc_setter_func_call (receiver, selector, rhs);
1249 return NULL_TREE;
1252 /* This routine checks to see if ID is a property name. If so, it
1253 returns property declaration. */
1255 static tree
1256 is_property (tree klass, tree id)
1258 tree x;
1260 for (x = CLASS_PROPERTY_DECL (klass); x; x = TREE_CHAIN (x))
1261 if (PROPERTY_NAME (x) == id)
1262 return x;
1263 return NULL_TREE;
1266 /* This routine returns call to property's getter when a property is
1267 used stand-alone (without self. notation). */
1269 static tree
1270 build_property_reference (tree property, tree id)
1272 tree getter;
1273 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
1275 error ("property %qs accessed in class method",
1276 IDENTIFIER_POINTER (id));
1277 return error_mark_node;
1280 getter = objc_finish_message_expr (self_decl, PROPERTY_NAME (property), NULL_TREE);
1281 CALL_EXPR_OBJC_PROPERTY_GETTER (getter) = 1;
1282 return getter;
1285 tree
1286 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
1287 tree optparms, bool ellipsis)
1289 if (is_class_method)
1290 return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
1291 optparms, ellipsis);
1292 else
1293 return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
1294 optparms, ellipsis);
1297 void
1298 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
1300 if (!objc_interface_context)
1302 /* PS: At the moment, due to how the parser works, it should be
1303 impossible to get here. But it's good to have the check in
1304 case the parser changes.
1306 fatal_error ("method declaration not in @interface context");
1309 objc_decl_method_attributes (&decl, attributes, 0);
1310 objc_add_method (objc_interface_context,
1311 decl,
1312 is_class_method,
1313 objc_method_optional_flag);
1316 /* Return 'true' if the method definition could be started, and
1317 'false' if not (because we are outside an @implementation context).
1319 bool
1320 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
1322 if (!objc_implementation_context)
1324 error ("method definition not in @implementation context");
1325 return false;
1328 if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node)
1329 return false;
1331 #ifndef OBJCPLUS
1332 /* Indicate no valid break/continue context by setting these variables
1333 to some non-null, non-label value. We'll notice and emit the proper
1334 error message in c_finish_bc_stmt. */
1335 c_break_label = c_cont_label = size_zero_node;
1336 #endif
1338 objc_decl_method_attributes (&decl, attributes, 0);
1339 objc_add_method (objc_implementation_context,
1340 decl,
1341 is_class_method,
1342 /* is optional */ false);
1343 start_method_def (decl);
1344 return true;
1347 void
1348 objc_add_instance_variable (tree decl)
1350 (void) add_instance_variable (objc_ivar_context,
1351 objc_ivar_visibility,
1352 decl);
1355 /* Return true if TYPE is 'id'. */
1357 static bool
1358 objc_is_object_id (tree type)
1360 return OBJC_TYPE_NAME (type) == objc_object_id;
1363 static bool
1364 objc_is_class_id (tree type)
1366 return OBJC_TYPE_NAME (type) == objc_class_id;
1369 /* Construct a C struct with same name as KLASS, a base struct with tag
1370 SUPER_NAME (if any), and FIELDS indicated. */
1372 static tree
1373 objc_build_struct (tree klass, tree fields, tree super_name)
1375 tree name = CLASS_NAME (klass);
1376 tree s = objc_start_struct (name);
1377 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
1378 tree t;
1379 VEC(tree,heap) *objc_info = NULL;
1380 int i;
1382 if (super)
1384 /* Prepend a packed variant of the base class into the layout. This
1385 is necessary to preserve ObjC ABI compatibility. */
1386 tree base = build_decl (input_location,
1387 FIELD_DECL, NULL_TREE, super);
1388 tree field = TYPE_FIELDS (super);
1390 while (field && DECL_CHAIN (field)
1391 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
1392 field = DECL_CHAIN (field);
1394 /* For ObjC ABI purposes, the "packed" size of a base class is
1395 the sum of the offset and the size (in bits) of the last field
1396 in the class. */
1397 DECL_SIZE (base)
1398 = (field && TREE_CODE (field) == FIELD_DECL
1399 ? size_binop (PLUS_EXPR,
1400 size_binop (PLUS_EXPR,
1401 size_binop
1402 (MULT_EXPR,
1403 convert (bitsizetype,
1404 DECL_FIELD_OFFSET (field)),
1405 bitsize_int (BITS_PER_UNIT)),
1406 DECL_FIELD_BIT_OFFSET (field)),
1407 DECL_SIZE (field))
1408 : bitsize_zero_node);
1409 DECL_SIZE_UNIT (base)
1410 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
1411 size_int (BITS_PER_UNIT));
1412 DECL_ARTIFICIAL (base) = 1;
1413 DECL_ALIGN (base) = 1;
1414 DECL_FIELD_CONTEXT (base) = s;
1415 #ifdef OBJCPLUS
1416 DECL_FIELD_IS_BASE (base) = 1;
1418 if (fields)
1419 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
1420 #endif /* are following the ObjC ABI here. */
1421 DECL_CHAIN (base) = fields;
1422 fields = base;
1425 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
1426 in all variants of this RECORD_TYPE to be clobbered, but it is therein
1427 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
1428 Hence, we must squirrel away the ObjC-specific information before calling
1429 finish_struct(), and then reinstate it afterwards. */
1431 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
1433 if (!TYPE_HAS_OBJC_INFO (t))
1435 INIT_TYPE_OBJC_INFO (t);
1436 TYPE_OBJC_INTERFACE (t) = klass;
1438 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
1441 /* Point the struct at its related Objective-C class. */
1442 INIT_TYPE_OBJC_INFO (s);
1443 TYPE_OBJC_INTERFACE (s) = klass;
1445 s = objc_finish_struct (s, fields);
1447 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
1449 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
1450 /* Replace the IDENTIFIER_NODE with an actual @interface. */
1451 TYPE_OBJC_INTERFACE (t) = klass;
1453 VEC_free (tree, heap, objc_info);
1455 /* Use TYPE_BINFO structures to point at the super class, if any. */
1456 objc_xref_basetypes (s, super);
1458 /* Mark this struct as a class template. */
1459 CLASS_STATIC_TEMPLATE (klass) = s;
1461 return s;
1464 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
1465 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
1466 process. */
1467 static tree
1468 objc_build_volatilized_type (tree type)
1470 tree t;
1472 /* Check if we have not constructed the desired variant already. */
1473 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
1475 /* The type qualifiers must (obviously) match up. */
1476 if (!TYPE_VOLATILE (t)
1477 || (TYPE_READONLY (t) != TYPE_READONLY (type))
1478 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
1479 continue;
1481 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
1482 info, if any) must match up. */
1483 if (POINTER_TYPE_P (t)
1484 && (TREE_TYPE (t) != TREE_TYPE (type)))
1485 continue;
1487 /* Only match up the types which were previously volatilized in similar fashion and not
1488 because they were declared as such. */
1489 if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t)))
1490 continue;
1492 /* Everything matches up! */
1493 return t;
1496 /* Ok, we could not re-use any of the pre-existing variants. Create
1497 a new one. */
1498 t = build_variant_type_copy (type);
1499 TYPE_VOLATILE (t) = 1;
1501 TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type),
1502 tree_cons (get_identifier ("objc_volatilized"),
1503 NULL_TREE,
1504 NULL_TREE));
1505 if (TREE_CODE (t) == ARRAY_TYPE)
1506 TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t));
1508 /* Set up the canonical type information. */
1509 if (TYPE_STRUCTURAL_EQUALITY_P (type))
1510 SET_TYPE_STRUCTURAL_EQUALITY (t);
1511 else if (TYPE_CANONICAL (type) != type)
1512 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
1513 else
1514 TYPE_CANONICAL (t) = t;
1516 return t;
1519 /* Mark DECL as being 'volatile' for purposes of Darwin
1520 _setjmp()/_longjmp() exception handling. Called from
1521 objc_mark_locals_volatile(). */
1522 void
1523 objc_volatilize_decl (tree decl)
1525 /* Do not mess with variables that are 'static' or (already)
1526 'volatile'. */
1527 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
1528 && (TREE_CODE (decl) == VAR_DECL
1529 || TREE_CODE (decl) == PARM_DECL))
1531 tree t = TREE_TYPE (decl);
1533 t = objc_build_volatilized_type (t);
1535 TREE_TYPE (decl) = t;
1536 TREE_THIS_VOLATILE (decl) = 1;
1537 TREE_SIDE_EFFECTS (decl) = 1;
1538 DECL_REGISTER (decl) = 0;
1539 #ifndef OBJCPLUS
1540 C_DECL_REGISTER (decl) = 0;
1541 #endif
1545 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1546 (including its categories and superclasses) or by object type TYP.
1547 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1549 static bool
1550 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
1552 bool class_type = (cls != NULL_TREE);
1554 while (cls)
1556 tree c;
1558 /* Check protocols adopted by the class and its categories. */
1559 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1561 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1562 return true;
1565 /* Repeat for superclasses. */
1566 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1569 /* Check for any protocols attached directly to the object type. */
1570 if (TYPE_HAS_OBJC_INFO (typ))
1572 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1573 return true;
1576 if (warn)
1578 *errbuf = 0;
1579 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1580 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1581 "implementing" a given protocol, since they do not have an
1582 implementation. */
1583 if (class_type)
1584 warning (0, "class %qs does not implement the %qE protocol",
1585 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1586 else
1587 warning (0, "type %qs does not conform to the %qE protocol",
1588 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1591 return false;
1594 /* Check if class RCLS and instance struct type RTYP conform to at least the
1595 same protocols that LCLS and LTYP conform to. */
1597 static bool
1598 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1600 tree p;
1601 bool have_lproto = false;
1603 while (lcls)
1605 /* NB: We do _not_ look at categories defined for LCLS; these may or
1606 may not get loaded in, and therefore it is unreasonable to require
1607 that RCLS/RTYP must implement any of their protocols. */
1608 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1610 have_lproto = true;
1612 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1613 return warn;
1616 /* Repeat for superclasses. */
1617 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1620 /* Check for any protocols attached directly to the object type. */
1621 if (TYPE_HAS_OBJC_INFO (ltyp))
1623 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1625 have_lproto = true;
1627 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1628 return warn;
1632 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1633 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1634 away with simply checking for 'id' or 'Class' (!RCLS), since this
1635 routine will not get called in other cases. */
1636 return have_lproto || (rcls != NULL_TREE);
1639 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1640 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1641 compatible by objc_compare_types() below. */
1643 tree
1644 objc_common_type (tree type1, tree type2)
1646 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
1648 while (POINTER_TYPE_P (inner1))
1650 inner1 = TREE_TYPE (inner1);
1651 inner2 = TREE_TYPE (inner2);
1654 /* If one type is derived from another, return the base type. */
1655 if (DERIVED_FROM_P (inner1, inner2))
1656 return type1;
1657 else if (DERIVED_FROM_P (inner2, inner1))
1658 return type2;
1660 /* If both types are 'Class', return 'Class'. */
1661 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
1662 return objc_class_type;
1664 /* Otherwise, return 'id'. */
1665 return objc_object_type;
1668 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1669 an instance of RTYP to an instance of LTYP or to compare the two
1670 (if ARGNO is equal to -3), per ObjC type system rules. Before
1671 returning 'true', this routine may issue warnings related to, e.g.,
1672 protocol conformance. When returning 'false', the routine must
1673 produce absolutely no warnings; the C or C++ front-end will do so
1674 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1675 the routine must return 'false'.
1677 The ARGNO parameter is encoded as follows:
1678 >= 1 Parameter number (CALLEE contains function being called);
1679 0 Return value;
1680 -1 Assignment;
1681 -2 Initialization;
1682 -3 Comparison (LTYP and RTYP may match in either direction);
1683 -4 Silent comparison (for C++ overload resolution).
1686 bool
1687 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1689 tree lcls, rcls, lproto, rproto;
1690 bool pointers_compatible;
1692 /* We must be dealing with pointer types */
1693 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1694 return false;
1698 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1699 rtyp = TREE_TYPE (rtyp);
1701 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1703 /* We must also handle function pointers, since ObjC is a bit more
1704 lenient than C or C++ on this. */
1705 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
1707 /* Return types must be covariant. */
1708 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
1709 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
1710 argno, callee))
1711 return false;
1713 /* Argument types must be contravariant. */
1714 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
1715 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
1717 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
1718 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
1719 argno, callee))
1720 return false;
1723 return (ltyp == rtyp);
1726 /* Past this point, we are only interested in ObjC class instances,
1727 or 'id' or 'Class'. */
1728 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1729 return false;
1731 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1732 && !TYPE_HAS_OBJC_INFO (ltyp))
1733 return false;
1735 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1736 && !TYPE_HAS_OBJC_INFO (rtyp))
1737 return false;
1739 /* Past this point, we are committed to returning 'true' to the caller
1740 (unless performing a silent comparison; see below). However, we can
1741 still warn about type and/or protocol mismatches. */
1743 if (TYPE_HAS_OBJC_INFO (ltyp))
1745 lcls = TYPE_OBJC_INTERFACE (ltyp);
1746 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1748 else
1749 lcls = lproto = NULL_TREE;
1751 if (TYPE_HAS_OBJC_INFO (rtyp))
1753 rcls = TYPE_OBJC_INTERFACE (rtyp);
1754 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1756 else
1757 rcls = rproto = NULL_TREE;
1759 /* If we could not find an @interface declaration, we must have
1760 only seen a @class declaration; for purposes of type comparison,
1761 treat it as a stand-alone (root) class. */
1763 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1764 lcls = NULL_TREE;
1766 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1767 rcls = NULL_TREE;
1769 /* If either type is an unqualified 'id', we're done. */
1770 if ((!lproto && objc_is_object_id (ltyp))
1771 || (!rproto && objc_is_object_id (rtyp)))
1772 return true;
1774 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1776 /* If the underlying types are the same, and at most one of them has
1777 a protocol list, we do not need to issue any diagnostics. */
1778 if (pointers_compatible && (!lproto || !rproto))
1779 return true;
1781 /* If exactly one of the types is 'Class', issue a diagnostic; any
1782 exceptions of this rule have already been handled. */
1783 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1784 pointers_compatible = false;
1785 /* Otherwise, check for inheritance relations. */
1786 else
1788 if (!pointers_compatible)
1789 pointers_compatible
1790 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1792 if (!pointers_compatible)
1793 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1795 if (!pointers_compatible && argno <= -3)
1796 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1799 /* If the pointers match modulo protocols, check for protocol conformance
1800 mismatches. */
1801 if (pointers_compatible)
1803 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1804 argno != -3);
1806 if (!pointers_compatible && argno == -3)
1807 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1808 argno != -3);
1811 if (!pointers_compatible)
1813 /* The two pointers are not exactly compatible. Issue a warning, unless
1814 we are performing a silent comparison, in which case return 'false'
1815 instead. */
1816 /* NB: For the time being, we shall make our warnings look like their
1817 C counterparts. In the future, we may wish to make them more
1818 ObjC-specific. */
1819 switch (argno)
1821 case -4:
1822 return false;
1824 case -3:
1825 warning (0, "comparison of distinct Objective-C types lacks a cast");
1826 break;
1828 case -2:
1829 warning (0, "initialization from distinct Objective-C type");
1830 break;
1832 case -1:
1833 warning (0, "assignment from distinct Objective-C type");
1834 break;
1836 case 0:
1837 warning (0, "distinct Objective-C type in return");
1838 break;
1840 default:
1841 warning (0, "passing argument %d of %qE from distinct "
1842 "Objective-C type", argno, callee);
1843 break;
1847 return true;
1850 /* This routine is similar to objc_compare_types except that function-pointers are
1851 excluded. This is because, caller assumes that common types are of (id, Object*)
1852 variety and calls objc_common_type to obtain a common type. There is no commonolty
1853 between two function-pointers in this regard. */
1855 bool
1856 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
1858 if (objc_compare_types (ltyp, rtyp, argno, callee))
1860 /* exclude function-pointer types. */
1863 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1864 rtyp = TREE_TYPE (rtyp);
1866 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1867 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
1869 return false;
1872 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1873 lives in the volatilized hash table, ignore the 'volatile' bit when
1874 making the comparison. */
1876 bool
1877 objc_type_quals_match (tree ltyp, tree rtyp)
1879 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1881 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp)))
1882 lquals &= ~TYPE_QUAL_VOLATILE;
1884 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp)))
1885 rquals &= ~TYPE_QUAL_VOLATILE;
1887 return (lquals == rquals);
1890 #ifndef OBJCPLUS
1891 /* Determine if CHILD is derived from PARENT. The routine assumes that
1892 both parameters are RECORD_TYPEs, and is non-reflexive. */
1894 static bool
1895 objc_derived_from_p (tree parent, tree child)
1897 parent = TYPE_MAIN_VARIANT (parent);
1899 for (child = TYPE_MAIN_VARIANT (child);
1900 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1902 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1903 (TYPE_BINFO (child),
1904 0)));
1906 if (child == parent)
1907 return true;
1910 return false;
1912 #endif
1914 static tree
1915 objc_build_component_ref (tree datum, tree component)
1917 /* If COMPONENT is NULL, the caller is referring to the anonymous
1918 base class field. */
1919 if (!component)
1921 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1923 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1926 /* The 'build_component_ref' routine has been removed from the C++
1927 front-end, but 'finish_class_member_access_expr' seems to be
1928 a worthy substitute. */
1929 #ifdef OBJCPLUS
1930 return finish_class_member_access_expr (datum, component, false,
1931 tf_warning_or_error);
1932 #else
1933 return build_component_ref (input_location, datum, component);
1934 #endif
1937 /* Recursively copy inheritance information rooted at BINFO. To do this,
1938 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1940 static tree
1941 objc_copy_binfo (tree binfo)
1943 tree btype = BINFO_TYPE (binfo);
1944 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1945 tree base_binfo;
1946 int ix;
1948 BINFO_TYPE (binfo2) = btype;
1949 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1950 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1952 /* Recursively copy base binfos of BINFO. */
1953 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1955 tree base_binfo2 = objc_copy_binfo (base_binfo);
1957 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1958 BINFO_BASE_APPEND (binfo2, base_binfo2);
1961 return binfo2;
1964 /* Record superclass information provided in BASETYPE for ObjC class REF.
1965 This is loosely based on cp/decl.c:xref_basetypes(). */
1967 static void
1968 objc_xref_basetypes (tree ref, tree basetype)
1970 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1972 TYPE_BINFO (ref) = binfo;
1973 BINFO_OFFSET (binfo) = size_zero_node;
1974 BINFO_TYPE (binfo) = ref;
1976 if (basetype)
1978 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1980 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1981 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1982 BINFO_BASE_APPEND (binfo, base_binfo);
1983 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1987 /* Called from finish_decl. */
1989 void
1990 objc_check_decl (tree decl)
1992 tree type = TREE_TYPE (decl);
1994 if (TREE_CODE (type) != RECORD_TYPE)
1995 return;
1996 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1997 error ("statically allocated instance of Objective-C class %qE",
1998 type);
2001 void
2002 objc_check_global_decl (tree decl)
2004 tree id = DECL_NAME (decl);
2005 if (objc_is_class_name (id) && global_bindings_p())
2006 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2009 /* Return a non-volatalized version of TYPE. */
2011 tree
2012 objc_non_volatilized_type (tree type)
2014 if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type)))
2015 type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE));
2016 return type;
2019 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
2020 either name an Objective-C class, or refer to the special 'id' or 'Class'
2021 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
2023 tree
2024 objc_get_protocol_qualified_type (tree interface, tree protocols)
2026 /* If INTERFACE is not provided, default to 'id'. */
2027 tree type = (interface ? objc_is_id (interface) : objc_object_type);
2028 bool is_ptr = (type != NULL_TREE);
2030 if (!is_ptr)
2032 type = objc_is_class_name (interface);
2034 if (type)
2036 /* If looking at a typedef, retrieve the precise type it
2037 describes. */
2038 if (TREE_CODE (interface) == IDENTIFIER_NODE)
2039 interface = identifier_global_value (interface);
2041 type = ((interface && TREE_CODE (interface) == TYPE_DECL
2042 && DECL_ORIGINAL_TYPE (interface))
2043 ? DECL_ORIGINAL_TYPE (interface)
2044 : xref_tag (RECORD_TYPE, type));
2046 else
2047 return interface;
2050 if (protocols)
2052 type = build_variant_type_copy (type);
2054 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2055 to the pointee. */
2056 if (is_ptr)
2058 tree orig_pointee_type = TREE_TYPE (type);
2059 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2061 /* Set up the canonical type information. */
2062 TYPE_CANONICAL (type)
2063 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2065 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2066 type = TREE_TYPE (type);
2069 /* Look up protocols and install in lang specific list. */
2070 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2071 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2073 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2074 return the pointer to the new pointee variant. */
2075 if (is_ptr)
2076 type = TYPE_POINTER_TO (type);
2077 else
2078 TYPE_OBJC_INTERFACE (type)
2079 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2082 return type;
2085 /* Check for circular dependencies in protocols. The arguments are
2086 PROTO, the protocol to check, and LIST, a list of protocol it
2087 conforms to. */
2089 static void
2090 check_protocol_recursively (tree proto, tree list)
2092 tree p;
2094 for (p = list; p; p = TREE_CHAIN (p))
2096 tree pp = TREE_VALUE (p);
2098 if (TREE_CODE (pp) == IDENTIFIER_NODE)
2099 pp = lookup_protocol (pp);
2101 if (pp == proto)
2102 fatal_error ("protocol %qE has circular dependency",
2103 PROTOCOL_NAME (pp));
2104 if (pp)
2105 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2109 /* Look up PROTOCOLS, and return a list of those that are found.
2110 If none are found, return NULL. */
2112 static tree
2113 lookup_and_install_protocols (tree protocols)
2115 tree proto;
2116 tree return_value = NULL_TREE;
2118 if (protocols == error_mark_node)
2119 return NULL;
2121 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2123 tree ident = TREE_VALUE (proto);
2124 tree p = lookup_protocol (ident);
2126 if (p)
2127 return_value = chainon (return_value,
2128 build_tree_list (NULL_TREE, p));
2129 else if (ident != error_mark_node)
2130 error ("cannot find protocol declaration for %qE",
2131 ident);
2134 return return_value;
2137 /* Create a declaration for field NAME of a given TYPE. */
2139 static tree
2140 create_field_decl (tree type, const char *name)
2142 return build_decl (input_location,
2143 FIELD_DECL, get_identifier (name), type);
2146 /* Create a global, static declaration for variable NAME of a given TYPE. The
2147 finish_var_decl() routine will need to be called on it afterwards. */
2149 static tree
2150 start_var_decl (tree type, const char *name)
2152 tree var = build_decl (input_location,
2153 VAR_DECL, get_identifier (name), type);
2155 TREE_STATIC (var) = 1;
2156 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
2157 DECL_IGNORED_P (var) = 1;
2158 DECL_ARTIFICIAL (var) = 1;
2159 DECL_CONTEXT (var) = NULL_TREE;
2160 #ifdef OBJCPLUS
2161 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2162 #endif
2164 return var;
2167 /* Finish off the variable declaration created by start_var_decl(). */
2169 static void
2170 finish_var_decl (tree var, tree initializer)
2172 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
2175 /* Find the decl for the constant string class reference. This is only
2176 used for the NeXT runtime. */
2178 static tree
2179 setup_string_decl (void)
2181 char *name;
2182 size_t length;
2184 /* %s in format will provide room for terminating null */
2185 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
2186 + strlen (constant_string_class_name);
2187 name = XNEWVEC (char, length);
2188 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
2189 constant_string_class_name);
2190 constant_string_global_id = get_identifier (name);
2191 string_class_decl = lookup_name (constant_string_global_id);
2193 return string_class_decl;
2196 /* Purpose: "play" parser, creating/installing representations
2197 of the declarations that are required by Objective-C.
2199 Model:
2201 type_spec--------->sc_spec
2202 (tree_list) (tree_list)
2205 identifier_node identifier_node */
2207 static void
2208 synth_module_prologue (void)
2210 tree type;
2211 enum debug_info_type save_write_symbols = write_symbols;
2212 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
2214 /* Suppress outputting debug symbols, because
2215 dbxout_init hasn't been called yet. */
2216 write_symbols = NO_DEBUG;
2217 debug_hooks = &do_nothing_debug_hooks;
2219 #ifdef OBJCPLUS
2220 push_lang_context (lang_name_c); /* extern "C" */
2221 #endif
2223 /* The following are also defined in <objc/objc.h> and friends. */
2225 objc_object_id = get_identifier (TAG_OBJECT);
2226 objc_class_id = get_identifier (TAG_CLASS);
2228 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
2229 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
2231 objc_object_type = build_pointer_type (objc_object_reference);
2232 objc_class_type = build_pointer_type (objc_class_reference);
2234 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
2235 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
2237 /* Declare the 'id' and 'Class' typedefs. */
2239 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2240 TYPE_DECL,
2241 objc_object_name,
2242 objc_object_type));
2243 TREE_NO_WARNING (type) = 1;
2244 type = lang_hooks.decls.pushdecl (build_decl (input_location,
2245 TYPE_DECL,
2246 objc_class_name,
2247 objc_class_type));
2248 TREE_NO_WARNING (type) = 1;
2250 /* Forward-declare '@interface Protocol'. */
2252 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
2253 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
2254 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
2255 type));
2257 /* Declare type of selector-objects that represent an operation name. */
2259 if (flag_next_runtime)
2260 /* `struct objc_selector *' */
2261 objc_selector_type
2262 = build_pointer_type (xref_tag (RECORD_TYPE,
2263 get_identifier (TAG_SELECTOR)));
2264 else
2265 /* `const struct objc_selector *' */
2266 objc_selector_type
2267 = build_pointer_type
2268 (build_qualified_type (xref_tag (RECORD_TYPE,
2269 get_identifier (TAG_SELECTOR)),
2270 TYPE_QUAL_CONST));
2272 /* Declare receiver type used for dispatching messages to 'super'. */
2274 /* `struct objc_super *' */
2275 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
2276 get_identifier (TAG_SUPER)));
2278 /* Declare pointers to method and ivar lists. */
2279 objc_method_list_ptr = build_pointer_type
2280 (xref_tag (RECORD_TYPE,
2281 get_identifier (UTAG_METHOD_LIST)));
2282 objc_method_proto_list_ptr
2283 = build_pointer_type (xref_tag (RECORD_TYPE,
2284 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
2285 objc_ivar_list_ptr = build_pointer_type
2286 (xref_tag (RECORD_TYPE,
2287 get_identifier (UTAG_IVAR_LIST)));
2289 /* TREE_NOTHROW is cleared for the message-sending functions,
2290 because the function that gets called can throw in Obj-C++, or
2291 could itself call something that can throw even in Obj-C. */
2293 if (flag_next_runtime)
2295 /* NB: In order to call one of the ..._stret (struct-returning)
2296 functions, the function *MUST* first be cast to a signature that
2297 corresponds to the actual ObjC method being invoked. This is
2298 what is done by the build_objc_method_call() routine below. */
2300 /* id objc_msgSend (id, SEL, ...); */
2301 /* id objc_msgSendNonNil (id, SEL, ...); */
2302 /* id objc_msgSend_stret (id, SEL, ...); */
2303 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
2304 type
2305 = build_varargs_function_type_list (objc_object_type,
2306 objc_object_type,
2307 objc_selector_type,
2308 NULL_TREE);
2309 umsg_decl = add_builtin_function (TAG_MSGSEND,
2310 type, 0, NOT_BUILT_IN,
2311 NULL, NULL_TREE);
2312 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
2313 type, 0, NOT_BUILT_IN,
2314 NULL, NULL_TREE);
2315 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
2316 type, 0, NOT_BUILT_IN,
2317 NULL, NULL_TREE);
2318 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
2319 type, 0, NOT_BUILT_IN,
2320 NULL, NULL_TREE);
2322 /* These can throw, because the function that gets called can throw
2323 in Obj-C++, or could itself call something that can throw even
2324 in Obj-C. */
2325 TREE_NOTHROW (umsg_decl) = 0;
2326 TREE_NOTHROW (umsg_nonnil_decl) = 0;
2327 TREE_NOTHROW (umsg_stret_decl) = 0;
2328 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
2330 /* id objc_msgSend_Fast (id, SEL, ...)
2331 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
2332 #ifdef OFFS_MSGSEND_FAST
2333 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
2334 type, 0, NOT_BUILT_IN,
2335 NULL, NULL_TREE);
2336 TREE_NOTHROW (umsg_fast_decl) = 0;
2337 DECL_ATTRIBUTES (umsg_fast_decl)
2338 = tree_cons (get_identifier ("hard_coded_address"),
2339 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
2340 NULL_TREE);
2341 #else
2342 /* No direct dispatch available. */
2343 umsg_fast_decl = umsg_decl;
2344 #endif
2346 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
2347 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
2348 type
2349 = build_varargs_function_type_list (objc_object_type,
2350 objc_super_type,
2351 objc_selector_type,
2352 NULL_TREE);
2353 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2354 type, 0, NOT_BUILT_IN,
2355 NULL, NULL_TREE);
2356 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
2357 type, 0, NOT_BUILT_IN, 0,
2358 NULL_TREE);
2359 TREE_NOTHROW (umsg_super_decl) = 0;
2360 TREE_NOTHROW (umsg_super_stret_decl) = 0;
2362 else
2364 /* GNU runtime messenger entry points. */
2366 /* typedef id (*IMP)(id, SEL, ...); */
2367 tree ftype =
2368 build_varargs_function_type_list (objc_object_type,
2369 objc_object_type,
2370 objc_selector_type,
2371 NULL_TREE);
2372 tree IMP_type = build_pointer_type (ftype);
2374 /* IMP objc_msg_lookup (id, SEL); */
2375 type = build_function_type_list (IMP_type,
2376 objc_object_type,
2377 objc_selector_type,
2378 NULL_TREE);
2379 umsg_decl = add_builtin_function (TAG_MSGSEND,
2380 type, 0, NOT_BUILT_IN,
2381 NULL, NULL_TREE);
2382 TREE_NOTHROW (umsg_decl) = 0;
2384 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
2385 type
2386 = build_function_type_list (IMP_type,
2387 objc_super_type,
2388 objc_selector_type,
2389 NULL_TREE);
2390 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
2391 type, 0, NOT_BUILT_IN,
2392 NULL, NULL_TREE);
2393 TREE_NOTHROW (umsg_super_decl) = 0;
2395 /* The following GNU runtime entry point is called to initialize
2396 each module:
2398 __objc_exec_class (void *); */
2399 type
2400 = build_function_type_list (void_type_node,
2401 ptr_type_node,
2402 NULL_TREE);
2403 execclass_decl = add_builtin_function (TAG_EXECCLASS,
2404 type, 0, NOT_BUILT_IN,
2405 NULL, NULL_TREE);
2408 /* id objc_getClass (const char *); */
2410 type = build_function_type_list (objc_object_type,
2411 const_string_type_node,
2412 NULL_TREE);
2414 objc_get_class_decl
2415 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
2416 NULL, NULL_TREE);
2418 /* id objc_getMetaClass (const char *); */
2420 objc_get_meta_class_decl
2421 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
2423 build_class_template ();
2424 build_super_template ();
2425 build_protocol_template ();
2426 build_category_template ();
2427 build_objc_exception_stuff ();
2429 if (flag_next_runtime)
2430 build_next_objc_exception_stuff ();
2432 /* static SEL _OBJC_SELECTOR_TABLE[]; */
2434 if (! flag_next_runtime)
2435 build_selector_table_decl ();
2437 /* Forward declare constant_string_id and constant_string_type. */
2438 if (!constant_string_class_name)
2439 constant_string_class_name = default_constant_string_class_name;
2441 constant_string_id = get_identifier (constant_string_class_name);
2442 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
2444 /* Pre-build the following entities - for speed/convenience. */
2445 self_id = get_identifier ("self");
2446 ucmd_id = get_identifier ("_cmd");
2448 /* Declare struct _objc_fast_enumeration_state { ... }; */
2449 build_fast_enumeration_state_template ();
2451 /* void objc_enumeration_mutation (id) */
2452 type = build_function_type (void_type_node,
2453 tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
2454 objc_enumeration_mutation_decl
2455 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
2456 NULL, NULL_TREE);
2457 TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
2459 #ifdef OBJCPLUS
2460 pop_lang_context ();
2461 #endif
2463 write_symbols = save_write_symbols;
2464 debug_hooks = save_hooks;
2467 /* Ensure that the ivar list for NSConstantString/NXConstantString
2468 (or whatever was specified via `-fconstant-string-class')
2469 contains fields at least as large as the following three, so that
2470 the runtime can stomp on them with confidence:
2472 struct STRING_OBJECT_CLASS_NAME
2474 Object isa;
2475 char *cString;
2476 unsigned int length;
2477 }; */
2479 static int
2480 check_string_class_template (void)
2482 tree field_decl = objc_get_class_ivars (constant_string_id);
2484 #define AT_LEAST_AS_LARGE_AS(F, T) \
2485 (F && TREE_CODE (F) == FIELD_DECL \
2486 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
2487 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
2489 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2490 return 0;
2492 field_decl = DECL_CHAIN (field_decl);
2493 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
2494 return 0;
2496 field_decl = DECL_CHAIN (field_decl);
2497 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
2499 #undef AT_LEAST_AS_LARGE_AS
2502 /* Avoid calling `check_string_class_template ()' more than once. */
2503 static GTY(()) int string_layout_checked;
2505 /* Construct an internal string layout to be used as a template for
2506 creating NSConstantString/NXConstantString instances. */
2508 static tree
2509 objc_build_internal_const_str_type (void)
2511 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
2512 tree fields = build_decl (input_location,
2513 FIELD_DECL, NULL_TREE, ptr_type_node);
2514 tree field = build_decl (input_location,
2515 FIELD_DECL, NULL_TREE, ptr_type_node);
2517 DECL_CHAIN (field) = fields; fields = field;
2518 field = build_decl (input_location,
2519 FIELD_DECL, NULL_TREE, unsigned_type_node);
2520 DECL_CHAIN (field) = fields; fields = field;
2521 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
2522 reverse order! */
2523 finish_builtin_struct (type, "__builtin_ObjCString",
2524 fields, NULL_TREE);
2526 return type;
2529 /* Custom build_string which sets TREE_TYPE! */
2531 static tree
2532 my_build_string (int len, const char *str)
2534 return fix_string_type (build_string (len, str));
2537 /* Build a string with contents STR and length LEN and convert it to a
2538 pointer. */
2540 static tree
2541 my_build_string_pointer (int len, const char *str)
2543 tree string = my_build_string (len, str);
2544 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
2545 return build1 (ADDR_EXPR, ptrtype, string);
2548 static hashval_t
2549 string_hash (const void *ptr)
2551 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
2552 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
2553 int i, len = TREE_STRING_LENGTH (str);
2554 hashval_t h = len;
2556 for (i = 0; i < len; i++)
2557 h = ((h * 613) + p[i]);
2559 return h;
2562 static int
2563 string_eq (const void *ptr1, const void *ptr2)
2565 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
2566 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
2567 int len1 = TREE_STRING_LENGTH (str1);
2569 return (len1 == TREE_STRING_LENGTH (str2)
2570 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
2571 len1));
2574 /* Given a chain of STRING_CST's, build a static instance of
2575 NXConstantString which points at the concatenation of those
2576 strings. We place the string object in the __string_objects
2577 section of the __OBJC segment. The Objective-C runtime will
2578 initialize the isa pointers of the string objects to point at the
2579 NXConstantString class object. */
2581 tree
2582 objc_build_string_object (tree string)
2584 tree constant_string_class;
2585 int length;
2586 tree fields, addr;
2587 struct string_descriptor *desc, key;
2588 void **loc;
2590 /* Prep the string argument. */
2591 string = fix_string_type (string);
2592 TREE_SET_CODE (string, STRING_CST);
2593 length = TREE_STRING_LENGTH (string) - 1;
2595 /* The target may have different ideas on how to construct an ObjC string
2596 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
2597 constant CFString reference instead.
2598 At present, this is only supported for the NeXT runtime. */
2599 if (flag_next_runtime && targetcm.objc_construct_string)
2601 tree constructor = (*targetcm.objc_construct_string) (string);
2602 if (constructor)
2603 return build1 (NOP_EXPR, objc_object_type, constructor);
2606 /* Check whether the string class being used actually exists and has the
2607 correct ivar layout. */
2608 if (!string_layout_checked)
2610 string_layout_checked = -1;
2611 constant_string_class = lookup_interface (constant_string_id);
2612 internal_const_str_type = objc_build_internal_const_str_type ();
2614 if (!constant_string_class
2615 || !(constant_string_type
2616 = CLASS_STATIC_TEMPLATE (constant_string_class)))
2617 error ("cannot find interface declaration for %qE",
2618 constant_string_id);
2619 /* The NSConstantString/NXConstantString ivar layout is now known. */
2620 else if (!check_string_class_template ())
2621 error ("interface %qE does not have valid constant string layout",
2622 constant_string_id);
2623 /* For the NeXT runtime, we can generate a literal reference
2624 to the string class, don't need to run a constructor. */
2625 else if (flag_next_runtime && !setup_string_decl ())
2626 error ("cannot find reference tag for class %qE",
2627 constant_string_id);
2628 else
2630 string_layout_checked = 1; /* Success! */
2631 add_class_reference (constant_string_id);
2635 if (string_layout_checked == -1)
2636 return error_mark_node;
2638 /* Perhaps we already constructed a constant string just like this one? */
2639 key.literal = string;
2640 loc = htab_find_slot (string_htab, &key, INSERT);
2641 desc = (struct string_descriptor *) *loc;
2643 if (!desc)
2645 tree var, constructor;
2646 VEC(constructor_elt,gc) *v = NULL;
2647 *loc = desc = ggc_alloc_string_descriptor ();
2648 desc->literal = string;
2650 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2651 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2652 fields = TYPE_FIELDS (internal_const_str_type);
2653 CONSTRUCTOR_APPEND_ELT (v, fields,
2654 flag_next_runtime
2655 ? build_unary_op (input_location,
2656 ADDR_EXPR, string_class_decl, 0)
2657 : build_int_cst (NULL_TREE, 0));
2658 fields = DECL_CHAIN (fields);
2659 CONSTRUCTOR_APPEND_ELT (v, fields,
2660 build_unary_op (input_location,
2661 ADDR_EXPR, string, 1));
2662 fields = DECL_CHAIN (fields);
2663 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
2664 constructor = objc_build_constructor (internal_const_str_type, v);
2666 if (!flag_next_runtime)
2667 constructor
2668 = objc_add_static_instance (constructor, constant_string_type);
2669 else
2671 var = build_decl (input_location,
2672 CONST_DECL, NULL, TREE_TYPE (constructor));
2673 DECL_INITIAL (var) = constructor;
2674 TREE_STATIC (var) = 1;
2675 pushdecl_top_level (var);
2676 constructor = var;
2678 desc->constructor = constructor;
2681 addr = convert (build_pointer_type (constant_string_type),
2682 build_unary_op (input_location,
2683 ADDR_EXPR, desc->constructor, 1));
2685 return addr;
2688 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2690 static GTY(()) int num_static_inst;
2692 static tree
2693 objc_add_static_instance (tree constructor, tree class_decl)
2695 tree *chain, decl;
2696 char buf[256];
2698 /* Find the list of static instances for the CLASS_DECL. Create one if
2699 not found. */
2700 for (chain = &objc_static_instances;
2701 *chain && TREE_VALUE (*chain) != class_decl;
2702 chain = &TREE_CHAIN (*chain));
2703 if (!*chain)
2705 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2706 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2709 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2710 decl = build_decl (input_location,
2711 VAR_DECL, get_identifier (buf), class_decl);
2712 TREE_STATIC (decl) = 1;
2713 DECL_ARTIFICIAL (decl) = 1;
2714 TREE_USED (decl) = 1;
2715 DECL_INITIAL (decl) = constructor;
2717 /* We may be writing something else just now.
2718 Postpone till end of input. */
2719 DECL_DEFER_OUTPUT (decl) = 1;
2720 pushdecl_top_level (decl);
2721 rest_of_decl_compilation (decl, 1, 0);
2723 /* Add the DECL to the head of this CLASS' list. */
2724 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2726 return decl;
2729 /* Build a static constant CONSTRUCTOR
2730 with type TYPE and elements ELTS. */
2732 static tree
2733 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
2735 tree constructor = build_constructor (type, elts);
2737 TREE_CONSTANT (constructor) = 1;
2738 TREE_STATIC (constructor) = 1;
2739 TREE_READONLY (constructor) = 1;
2741 #ifdef OBJCPLUS
2742 /* Adjust for impedance mismatch. We should figure out how to build
2743 CONSTRUCTORs that consistently please both the C and C++ gods. */
2744 if (!VEC_index (constructor_elt, elts, 0)->index)
2745 TREE_TYPE (constructor) = init_list_type_node;
2746 #endif
2748 return constructor;
2751 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2753 /* Predefine the following data type:
2755 struct _objc_symtab
2757 long sel_ref_cnt;
2758 SEL *refs;
2759 short cls_def_cnt;
2760 short cat_def_cnt;
2761 void *defs[cls_def_cnt + cat_def_cnt];
2762 }; */
2764 static void
2765 build_objc_symtab_template (void)
2767 tree fields, *chain = NULL;
2769 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2771 /* long sel_ref_cnt; */
2772 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
2774 /* SEL *refs; */
2775 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
2777 /* short cls_def_cnt; */
2778 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
2780 /* short cat_def_cnt; */
2781 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2783 if (imp_count || cat_count || !flag_next_runtime)
2785 /* void *defs[imp_count + cat_count (+ 1)]; */
2786 /* NB: The index is one less than the size of the array. */
2787 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
2788 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
2789 add_field_decl (array_type, "defs", &chain);
2792 objc_finish_struct (objc_symtab_template, fields);
2795 /* Create the initial value for the `defs' field of _objc_symtab.
2796 This is a CONSTRUCTOR. */
2798 static tree
2799 init_def_list (tree type)
2801 tree expr;
2802 struct imp_entry *impent;
2803 VEC(constructor_elt,gc) *v = NULL;
2805 if (imp_count)
2806 for (impent = imp_list; impent; impent = impent->next)
2808 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2810 expr = build_unary_op (input_location,
2811 ADDR_EXPR, impent->class_decl, 0);
2812 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2816 if (cat_count)
2817 for (impent = imp_list; impent; impent = impent->next)
2819 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2821 expr = build_unary_op (input_location,
2822 ADDR_EXPR, impent->class_decl, 0);
2823 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2827 if (!flag_next_runtime)
2829 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2830 if (static_instances_decl)
2831 expr = build_unary_op (input_location,
2832 ADDR_EXPR, static_instances_decl, 0);
2833 else
2834 expr = integer_zero_node;
2836 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2839 return objc_build_constructor (type, v);
2842 /* Construct the initial value for all of _objc_symtab. */
2844 static tree
2845 init_objc_symtab (tree type)
2847 VEC(constructor_elt,gc) *v = NULL;
2849 /* sel_ref_cnt = { ..., 5, ... } */
2851 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2852 build_int_cst (long_integer_type_node, 0));
2854 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2856 if (flag_next_runtime || ! sel_ref_chain)
2857 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
2858 build_pointer_type (objc_selector_type),
2859 integer_zero_node));
2860 else
2862 tree expr = build_unary_op (input_location, ADDR_EXPR,
2863 UOBJC_SELECTOR_TABLE_decl, 1);
2865 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2866 convert (build_pointer_type (objc_selector_type),
2867 expr));
2870 /* cls_def_cnt = { ..., 5, ... } */
2872 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2873 build_int_cst (short_integer_type_node, imp_count));
2875 /* cat_def_cnt = { ..., 5, ... } */
2877 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2878 build_int_cst (short_integer_type_node, cat_count));
2880 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2882 if (imp_count || cat_count || !flag_next_runtime)
2885 tree field = TYPE_FIELDS (type);
2886 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2888 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2891 return objc_build_constructor (type, v);
2894 /* Generate forward declarations for metadata such as
2895 'OBJC_CLASS_...'. */
2897 static tree
2898 build_metadata_decl (const char *name, tree type)
2900 tree decl;
2902 /* struct TYPE NAME_<name>; */
2903 decl = start_var_decl (type, synth_id_with_class_suffix
2904 (name,
2905 objc_implementation_context));
2907 return decl;
2910 /* Push forward-declarations of all the categories so that
2911 init_def_list can use them in a CONSTRUCTOR. */
2913 static void
2914 forward_declare_categories (void)
2916 struct imp_entry *impent;
2917 tree sav = objc_implementation_context;
2919 for (impent = imp_list; impent; impent = impent->next)
2921 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2923 /* Set an invisible arg to synth_id_with_class_suffix. */
2924 objc_implementation_context = impent->imp_context;
2925 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2926 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2927 objc_category_template);
2930 objc_implementation_context = sav;
2933 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2934 and initialized appropriately. */
2936 static void
2937 generate_objc_symtab_decl (void)
2940 build_objc_symtab_template ();
2941 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2942 finish_var_decl (UOBJC_SYMBOLS_decl,
2943 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2946 static tree
2947 init_module_descriptor (tree type)
2949 tree expr;
2950 VEC(constructor_elt,gc) *v = NULL;
2952 /* version = { 1, ... } */
2954 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2955 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2957 /* size = { ..., sizeof (struct _objc_module), ... } */
2959 expr = convert (long_integer_type_node,
2960 size_in_bytes (objc_module_template));
2961 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2963 /* Don't provide any file name for security reasons. */
2964 /* name = { ..., "", ... } */
2966 expr = add_objc_string (get_identifier (""), class_names);
2967 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2969 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2971 if (UOBJC_SYMBOLS_decl)
2972 expr = build_unary_op (input_location,
2973 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2974 else
2975 expr = null_pointer_node;
2976 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2978 return objc_build_constructor (type, v);
2981 /* Write out the data structures to describe Objective C classes defined.
2983 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2985 static void
2986 build_module_descriptor (void)
2988 tree decls, *chain = NULL;
2990 #ifdef OBJCPLUS
2991 push_lang_context (lang_name_c); /* extern "C" */
2992 #endif
2994 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2996 /* long version; */
2997 decls = add_field_decl (long_integer_type_node, "version", &chain);
2999 /* long size; */
3000 add_field_decl (long_integer_type_node, "size", &chain);
3002 /* char *name; */
3003 add_field_decl (string_type_node, "name", &chain);
3005 /* struct _objc_symtab *symtab; */
3006 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3007 get_identifier (UTAG_SYMTAB))),
3008 "symtab", &chain);
3010 objc_finish_struct (objc_module_template, decls);
3012 /* Create an instance of "_objc_module". */
3013 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3014 /* This is the root of the metadata for defined classes and categories, it
3015 is referenced by the runtime and, therefore, needed. */
3016 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3017 finish_var_decl (UOBJC_MODULES_decl,
3018 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3020 #ifdef OBJCPLUS
3021 pop_lang_context ();
3022 #endif
3025 /* The GNU runtime requires us to provide a static initializer function
3026 for each module:
3028 static void __objc_gnu_init (void) {
3029 __objc_exec_class (&L_OBJC_MODULES);
3030 } */
3032 static void
3033 build_module_initializer_routine (void)
3035 tree body;
3037 #ifdef OBJCPLUS
3038 push_lang_context (lang_name_c); /* extern "C" */
3039 #endif
3041 objc_push_parm (build_decl (input_location,
3042 PARM_DECL, NULL_TREE, void_type_node));
3043 #ifdef OBJCPLUS
3044 objc_start_function (get_identifier (TAG_GNUINIT),
3045 build_function_type_list (void_type_node, NULL_TREE),
3046 NULL_TREE, NULL_TREE);
3047 #else
3048 objc_start_function (get_identifier (TAG_GNUINIT),
3049 build_function_type_list (void_type_node, NULL_TREE),
3050 NULL_TREE, objc_get_parm_info (0));
3051 #endif
3052 body = c_begin_compound_stmt (true);
3053 add_stmt (build_function_call
3054 (input_location,
3055 execclass_decl,
3056 build_tree_list
3057 (NULL_TREE,
3058 build_unary_op (input_location, ADDR_EXPR,
3059 UOBJC_MODULES_decl, 0))));
3060 add_stmt (c_end_compound_stmt (input_location, body, true));
3062 TREE_PUBLIC (current_function_decl) = 0;
3064 #ifndef OBJCPLUS
3065 /* For Objective-C++, we will need to call __objc_gnu_init
3066 from objc_generate_static_init_call() below. */
3067 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3068 #endif
3070 GNU_INIT_decl = current_function_decl;
3071 finish_function ();
3073 #ifdef OBJCPLUS
3074 pop_lang_context ();
3075 #endif
3078 #ifdef OBJCPLUS
3079 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3080 to be called by the module initializer routine. */
3083 objc_static_init_needed_p (void)
3085 return (GNU_INIT_decl != NULL_TREE);
3088 /* Generate a call to the __objc_gnu_init initializer function. */
3090 tree
3091 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3093 add_stmt (build_stmt (input_location, EXPR_STMT,
3094 build_function_call (input_location,
3095 GNU_INIT_decl, NULL_TREE)));
3097 return ctors;
3099 #endif /* OBJCPLUS */
3101 /* Return the DECL of the string IDENT in the SECTION. */
3103 static tree
3104 get_objc_string_decl (tree ident, enum string_section section)
3106 tree chain;
3108 switch (section)
3110 case class_names:
3111 chain = class_names_chain;
3112 break;
3113 case meth_var_names:
3114 chain = meth_var_names_chain;
3115 break;
3116 case meth_var_types:
3117 chain = meth_var_types_chain;
3118 break;
3119 default:
3120 gcc_unreachable ();
3123 for (; chain != 0; chain = TREE_CHAIN (chain))
3124 if (TREE_VALUE (chain) == ident)
3125 return (TREE_PURPOSE (chain));
3127 gcc_unreachable ();
3128 return NULL_TREE;
3131 /* Output references to all statically allocated objects. Return the DECL
3132 for the array built. */
3134 static void
3135 generate_static_references (void)
3137 tree expr = NULL_TREE;
3138 tree class_name, klass, decl;
3139 tree cl_chain, in_chain, type
3140 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3141 int num_inst, num_class;
3142 char buf[256];
3143 VEC(constructor_elt,gc) *decls = NULL;
3145 if (flag_next_runtime)
3146 gcc_unreachable ();
3148 for (cl_chain = objc_static_instances, num_class = 0;
3149 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3151 VEC(constructor_elt,gc) *v = NULL;
3153 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3154 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3156 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3157 decl = start_var_decl (type, buf);
3159 /* Output {class_name, ...}. */
3160 klass = TREE_VALUE (cl_chain);
3161 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
3162 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3163 build_unary_op (input_location,
3164 ADDR_EXPR, class_name, 1));
3166 /* Output {..., instance, ...}. */
3167 for (in_chain = TREE_PURPOSE (cl_chain);
3168 in_chain; in_chain = TREE_CHAIN (in_chain))
3170 expr = build_unary_op (input_location,
3171 ADDR_EXPR, TREE_VALUE (in_chain), 1);
3172 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3175 /* Output {..., NULL}. */
3176 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
3178 expr = objc_build_constructor (TREE_TYPE (decl), v);
3179 finish_var_decl (decl, expr);
3180 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
3181 build_unary_op (input_location,
3182 ADDR_EXPR, decl, 1));
3185 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
3186 expr = objc_build_constructor (type, decls);
3187 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
3188 finish_var_decl (static_instances_decl, expr);
3191 static GTY(()) int selector_reference_idx;
3193 static tree
3194 build_selector_reference_decl (void)
3196 tree decl;
3197 char buf[256];
3199 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
3200 decl = start_var_decl (objc_selector_type, buf);
3202 return decl;
3205 static void
3206 build_selector_table_decl (void)
3208 tree temp;
3210 if (flag_typed_selectors)
3212 build_selector_template ();
3213 temp = build_array_type (objc_selector_template, NULL_TREE);
3215 else
3216 temp = build_array_type (objc_selector_type, NULL_TREE);
3218 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
3221 /* Just a handy wrapper for add_objc_string. */
3223 static tree
3224 build_selector (tree ident)
3226 return convert (objc_selector_type,
3227 add_objc_string (ident, meth_var_names));
3230 /* Used only by build_*_selector_translation_table (). */
3231 static void
3232 diagnose_missing_method (tree meth, location_t here)
3234 tree method_chain;
3235 bool found = false;
3236 for (method_chain = meth_var_names_chain;
3237 method_chain;
3238 method_chain = TREE_CHAIN (method_chain))
3240 if (TREE_VALUE (method_chain) == meth)
3242 found = true;
3243 break;
3247 if (!found)
3248 warning_at (here, 0, "creating selector for nonexistent method %qE",
3249 meth);
3252 static void
3253 build_next_selector_translation_table (void)
3255 tree chain;
3256 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3258 tree expr;
3259 tree decl = TREE_PURPOSE (chain);
3260 if (warn_selector && objc_implementation_context)
3262 location_t loc;
3263 if (decl)
3264 loc = DECL_SOURCE_LOCATION (decl);
3265 else
3266 loc = input_location;
3267 diagnose_missing_method (TREE_VALUE (chain), loc);
3270 expr = build_selector (TREE_VALUE (chain));
3272 if (decl)
3274 /* Entries of this form are used for references to methods.
3275 The runtime re-writes these on start-up, but the compiler can't see
3276 that and optimizes it away unless we force it. */
3277 DECL_PRESERVE_P (decl) = 1;
3278 finish_var_decl (decl, expr);
3283 static void
3284 build_gnu_selector_translation_table (void)
3286 tree chain;
3287 /* int offset = 0;
3288 tree decl = NULL_TREE;*/
3289 VEC(constructor_elt,gc) *inits = NULL;
3291 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
3293 tree expr;
3295 if (warn_selector && objc_implementation_context)
3296 diagnose_missing_method (TREE_VALUE (chain), input_location);
3298 expr = build_selector (TREE_VALUE (chain));
3299 /* add one for the '\0' character
3300 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
3303 if (flag_typed_selectors)
3305 VEC(constructor_elt,gc) *v = NULL;
3306 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
3307 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3308 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
3309 expr = objc_build_constructor (objc_selector_template, v);
3312 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3314 } /* each element in the chain */
3317 /* Cause the selector table (previously forward-declared)
3318 to be actually output. */
3319 tree expr;
3321 if (flag_typed_selectors)
3323 VEC(constructor_elt,gc) *v = NULL;
3324 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3325 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
3326 expr = objc_build_constructor (objc_selector_template, v);
3328 else
3329 expr = integer_zero_node;
3331 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
3332 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
3333 inits);
3334 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
3338 static tree
3339 get_proto_encoding (tree proto)
3341 tree encoding;
3342 if (proto)
3344 if (! METHOD_ENCODING (proto))
3346 encoding = encode_method_prototype (proto);
3347 METHOD_ENCODING (proto) = encoding;
3349 else
3350 encoding = METHOD_ENCODING (proto);
3352 return add_objc_string (encoding, meth_var_types);
3354 else
3355 return build_int_cst (NULL_TREE, 0);
3358 /* sel_ref_chain is a list whose "value" fields will be instances of
3359 identifier_node that represent the selector. LOC is the location of
3360 the @selector. */
3362 static tree
3363 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
3365 tree *chain = &sel_ref_chain;
3366 tree expr;
3367 int index = 0;
3369 while (*chain)
3371 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
3372 goto return_at_index;
3374 index++;
3375 chain = &TREE_CHAIN (*chain);
3378 *chain = tree_cons (prototype, ident, NULL_TREE);
3380 return_at_index:
3381 expr = build_unary_op (loc, ADDR_EXPR,
3382 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3383 build_int_cst (NULL_TREE, index)),
3385 return convert (objc_selector_type, expr);
3388 static tree
3389 build_selector_reference (location_t loc, tree ident)
3391 tree *chain = &sel_ref_chain;
3392 tree expr;
3393 int index = 0;
3395 while (*chain)
3397 if (TREE_VALUE (*chain) == ident)
3398 return (flag_next_runtime
3399 ? TREE_PURPOSE (*chain)
3400 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3401 build_int_cst (NULL_TREE, index)));
3403 index++;
3404 chain = &TREE_CHAIN (*chain);
3407 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
3409 *chain = tree_cons (expr, ident, NULL_TREE);
3411 return (flag_next_runtime
3412 ? expr
3413 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
3414 build_int_cst (NULL_TREE, index)));
3417 static GTY(()) int class_reference_idx;
3419 static tree
3420 build_class_reference_decl (void)
3422 tree decl;
3423 char buf[256];
3425 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
3426 decl = start_var_decl (objc_class_type, buf);
3428 return decl;
3431 /* Create a class reference, but don't create a variable to reference
3432 it. */
3434 static void
3435 add_class_reference (tree ident)
3437 tree chain;
3439 if ((chain = cls_ref_chain))
3441 tree tail;
3444 if (ident == TREE_VALUE (chain))
3445 return;
3447 tail = chain;
3448 chain = TREE_CHAIN (chain);
3450 while (chain);
3452 /* Append to the end of the list */
3453 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
3455 else
3456 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
3459 /* Get a class reference, creating it if necessary. Also create the
3460 reference variable. */
3462 tree
3463 objc_get_class_reference (tree ident)
3465 tree orig_ident = (DECL_P (ident)
3466 ? DECL_NAME (ident)
3467 : TYPE_P (ident)
3468 ? OBJC_TYPE_NAME (ident)
3469 : ident);
3470 bool local_scope = false;
3472 #ifdef OBJCPLUS
3473 if (processing_template_decl)
3474 /* Must wait until template instantiation time. */
3475 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
3476 #endif
3478 if (TREE_CODE (ident) == TYPE_DECL)
3479 ident = (DECL_ORIGINAL_TYPE (ident)
3480 ? DECL_ORIGINAL_TYPE (ident)
3481 : TREE_TYPE (ident));
3483 #ifdef OBJCPLUS
3484 if (TYPE_P (ident)
3485 && CP_TYPE_CONTEXT (ident) != global_namespace)
3486 local_scope = true;
3487 #endif
3489 if (local_scope || !(ident = objc_is_class_name (ident)))
3491 error ("%qE is not an Objective-C class name or alias",
3492 orig_ident);
3493 return error_mark_node;
3496 if (flag_next_runtime && !flag_zero_link)
3498 tree *chain;
3499 tree decl;
3501 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
3502 if (TREE_VALUE (*chain) == ident)
3504 if (! TREE_PURPOSE (*chain))
3505 TREE_PURPOSE (*chain) = build_class_reference_decl ();
3507 return TREE_PURPOSE (*chain);
3510 decl = build_class_reference_decl ();
3511 *chain = tree_cons (decl, ident, NULL_TREE);
3512 return decl;
3514 else
3516 tree params;
3518 add_class_reference (ident);
3520 params = build_tree_list (NULL_TREE,
3521 my_build_string_pointer
3522 (IDENTIFIER_LENGTH (ident) + 1,
3523 IDENTIFIER_POINTER (ident)));
3525 assemble_external (objc_get_class_decl);
3526 return build_function_call (input_location, objc_get_class_decl, params);
3530 /* For each string section we have a chain which maps identifier nodes
3531 to decls for the strings. */
3533 static GTY(()) int class_names_idx;
3534 static GTY(()) int meth_var_names_idx;
3535 static GTY(()) int meth_var_types_idx;
3537 static tree
3538 add_objc_string (tree ident, enum string_section section)
3540 tree *chain, decl, type, string_expr;
3541 char buf[256];
3543 buf[0] = 0;
3544 switch (section)
3546 case class_names:
3547 chain = &class_names_chain;
3548 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
3549 break;
3550 case meth_var_names:
3551 chain = &meth_var_names_chain;
3552 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
3553 break;
3554 case meth_var_types:
3555 chain = &meth_var_types_chain;
3556 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
3557 break;
3558 default:
3559 gcc_unreachable ();
3562 while (*chain)
3564 if (TREE_VALUE (*chain) == ident)
3565 return convert (string_type_node,
3566 build_unary_op (input_location,
3567 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
3569 chain = &TREE_CHAIN (*chain);
3572 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
3573 decl = start_var_decl (type, buf);
3574 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
3575 IDENTIFIER_POINTER (ident));
3576 TREE_CONSTANT (decl) = 1;
3577 finish_var_decl (decl, string_expr);
3579 *chain = tree_cons (decl, ident, NULL_TREE);
3581 return convert (string_type_node, build_unary_op (input_location,
3582 ADDR_EXPR, decl, 1));
3585 void
3586 objc_declare_alias (tree alias_ident, tree class_ident)
3588 tree underlying_class;
3590 #ifdef OBJCPLUS
3591 if (current_namespace != global_namespace) {
3592 error ("Objective-C declarations may only appear in global scope");
3594 #endif /* OBJCPLUS */
3596 if (!(underlying_class = objc_is_class_name (class_ident)))
3597 warning (0, "cannot find class %qE", class_ident);
3598 else if (objc_is_class_name (alias_ident))
3599 warning (0, "class %qE already exists", alias_ident);
3600 else
3602 /* Implement @compatibility_alias as a typedef. */
3603 #ifdef OBJCPLUS
3604 push_lang_context (lang_name_c); /* extern "C" */
3605 #endif
3606 lang_hooks.decls.pushdecl (build_decl
3607 (input_location,
3608 TYPE_DECL,
3609 alias_ident,
3610 xref_tag (RECORD_TYPE, underlying_class)));
3611 #ifdef OBJCPLUS
3612 pop_lang_context ();
3613 #endif
3614 hash_class_name_enter (als_name_hash_list, alias_ident,
3615 underlying_class);
3619 void
3620 objc_declare_class (tree ident_list)
3622 tree list;
3623 #ifdef OBJCPLUS
3624 if (current_namespace != global_namespace) {
3625 error ("Objective-C declarations may only appear in global scope");
3627 #endif /* OBJCPLUS */
3629 for (list = ident_list; list; list = TREE_CHAIN (list))
3631 tree ident = TREE_VALUE (list);
3633 if (! objc_is_class_name (ident))
3635 tree record = lookup_name (ident), type = record;
3637 if (record)
3639 if (TREE_CODE (record) == TYPE_DECL)
3640 type = DECL_ORIGINAL_TYPE (record) ?
3641 DECL_ORIGINAL_TYPE (record) :
3642 TREE_TYPE (record);
3644 if (!TYPE_HAS_OBJC_INFO (type)
3645 || !TYPE_OBJC_INTERFACE (type))
3647 error ("%qE redeclared as different kind of symbol",
3648 ident);
3649 error ("previous declaration of %q+D",
3650 record);
3654 record = xref_tag (RECORD_TYPE, ident);
3655 INIT_TYPE_OBJC_INFO (record);
3656 TYPE_OBJC_INTERFACE (record) = ident;
3657 hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
3662 tree
3663 objc_is_class_name (tree ident)
3665 hash target;
3667 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3668 && identifier_global_value (ident))
3669 ident = identifier_global_value (ident);
3670 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3671 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3673 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3674 ident = OBJC_TYPE_NAME (ident);
3675 #ifdef OBJCPLUS
3676 if (ident && TREE_CODE (ident) == TYPE_DECL)
3678 tree type = TREE_TYPE (ident);
3679 if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
3680 return NULL_TREE;
3681 ident = DECL_NAME (ident);
3683 #endif
3684 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3685 return NULL_TREE;
3687 if (lookup_interface (ident))
3688 return ident;
3690 target = hash_class_name_lookup (cls_name_hash_list, ident);
3691 if (target)
3692 return target->key;
3694 target = hash_class_name_lookup (als_name_hash_list, ident);
3695 if (target)
3697 gcc_assert (target->list && target->list->value);
3698 return target->list->value;
3701 return 0;
3704 /* Check whether TYPE is either 'id' or 'Class'. */
3706 tree
3707 objc_is_id (tree type)
3709 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3710 && identifier_global_value (type))
3711 type = identifier_global_value (type);
3713 if (type && TREE_CODE (type) == TYPE_DECL)
3714 type = TREE_TYPE (type);
3716 /* NB: This function may be called before the ObjC front-end has
3717 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3718 return (objc_object_type && type
3719 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3720 ? type
3721 : NULL_TREE);
3724 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3725 class instance. This is needed by other parts of the compiler to
3726 handle ObjC types gracefully. */
3728 tree
3729 objc_is_object_ptr (tree type)
3731 tree ret;
3733 type = TYPE_MAIN_VARIANT (type);
3734 if (!POINTER_TYPE_P (type))
3735 return 0;
3737 ret = objc_is_id (type);
3738 if (!ret)
3739 ret = objc_is_class_name (TREE_TYPE (type));
3741 return ret;
3744 static int
3745 objc_is_gcable_type (tree type, int or_strong_p)
3747 tree name;
3749 if (!TYPE_P (type))
3750 return 0;
3751 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3752 return 1;
3753 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3754 return 1;
3755 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3756 return 0;
3757 type = TREE_TYPE (type);
3758 if (TREE_CODE (type) != RECORD_TYPE)
3759 return 0;
3760 name = TYPE_NAME (type);
3761 return (objc_is_class_name (name) != NULL_TREE);
3764 static tree
3765 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3767 if (expr == oldexpr)
3768 return newexpr;
3770 switch (TREE_CODE (expr))
3772 case COMPONENT_REF:
3773 return objc_build_component_ref
3774 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3775 oldexpr,
3776 newexpr),
3777 DECL_NAME (TREE_OPERAND (expr, 1)));
3778 case ARRAY_REF:
3779 return build_array_ref (input_location,
3780 objc_substitute_decl (TREE_OPERAND (expr, 0),
3781 oldexpr,
3782 newexpr),
3783 TREE_OPERAND (expr, 1));
3784 case INDIRECT_REF:
3785 return build_indirect_ref (input_location,
3786 objc_substitute_decl (TREE_OPERAND (expr, 0),
3787 oldexpr,
3788 newexpr), RO_ARROW);
3789 default:
3790 return expr;
3794 static tree
3795 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3797 tree func_params;
3798 /* The LHS parameter contains the expression 'outervar->memberspec';
3799 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3800 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3802 tree offs
3803 = objc_substitute_decl
3804 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3805 tree func
3806 = (flag_objc_direct_dispatch
3807 ? objc_assign_ivar_fast_decl
3808 : objc_assign_ivar_decl);
3810 offs = convert (integer_type_node, build_unary_op (input_location,
3811 ADDR_EXPR, offs, 0));
3812 offs = fold (offs);
3813 func_params = tree_cons (NULL_TREE,
3814 convert (objc_object_type, rhs),
3815 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3816 tree_cons (NULL_TREE, offs,
3817 NULL_TREE)));
3819 assemble_external (func);
3820 return build_function_call (input_location, func, func_params);
3823 static tree
3824 objc_build_global_assignment (tree lhs, tree rhs)
3826 tree func_params = tree_cons (NULL_TREE,
3827 convert (objc_object_type, rhs),
3828 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3829 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3830 NULL_TREE));
3832 assemble_external (objc_assign_global_decl);
3833 return build_function_call (input_location,
3834 objc_assign_global_decl, func_params);
3837 static tree
3838 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3840 tree func_params = tree_cons (NULL_TREE,
3841 convert (objc_object_type, rhs),
3842 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3843 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3844 NULL_TREE));
3846 assemble_external (objc_assign_strong_cast_decl);
3847 return build_function_call (input_location,
3848 objc_assign_strong_cast_decl, func_params);
3851 static int
3852 objc_is_gcable_p (tree expr)
3854 return (TREE_CODE (expr) == COMPONENT_REF
3855 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3856 : TREE_CODE (expr) == ARRAY_REF
3857 ? (objc_is_gcable_p (TREE_TYPE (expr))
3858 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3859 : TREE_CODE (expr) == ARRAY_TYPE
3860 ? objc_is_gcable_p (TREE_TYPE (expr))
3861 : TYPE_P (expr)
3862 ? objc_is_gcable_type (expr, 1)
3863 : (objc_is_gcable_p (TREE_TYPE (expr))
3864 || (DECL_P (expr)
3865 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3868 static int
3869 objc_is_ivar_reference_p (tree expr)
3871 return (TREE_CODE (expr) == ARRAY_REF
3872 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3873 : TREE_CODE (expr) == COMPONENT_REF
3874 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3875 : 0);
3878 static int
3879 objc_is_global_reference_p (tree expr)
3881 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3882 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3883 : DECL_P (expr)
3884 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
3885 : 0);
3888 tree
3889 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3891 tree result = NULL_TREE, outer;
3892 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3894 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3895 will have been transformed to the form '*(type *)&expr'. */
3896 if (TREE_CODE (lhs) == INDIRECT_REF)
3898 outer = TREE_OPERAND (lhs, 0);
3900 while (!strong_cast_p
3901 && (CONVERT_EXPR_P (outer)
3902 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3904 tree lhstype = TREE_TYPE (outer);
3906 /* Descend down the cast chain, and record the first objc_gc
3907 attribute found. */
3908 if (POINTER_TYPE_P (lhstype))
3910 tree attr
3911 = lookup_attribute ("objc_gc",
3912 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3914 if (attr)
3915 strong_cast_p = 1;
3918 outer = TREE_OPERAND (outer, 0);
3922 /* If we have a __strong cast, it trumps all else. */
3923 if (strong_cast_p)
3925 if (modifycode != NOP_EXPR)
3926 goto invalid_pointer_arithmetic;
3928 if (warn_assign_intercept)
3929 warning (0, "strong-cast assignment has been intercepted");
3931 result = objc_build_strong_cast_assignment (lhs, rhs);
3933 goto exit_point;
3936 /* the lhs must be of a suitable type, regardless of its underlying
3937 structure. */
3938 if (!objc_is_gcable_p (lhs))
3939 goto exit_point;
3941 outer = lhs;
3943 while (outer
3944 && (TREE_CODE (outer) == COMPONENT_REF
3945 || TREE_CODE (outer) == ARRAY_REF))
3946 outer = TREE_OPERAND (outer, 0);
3948 if (TREE_CODE (outer) == INDIRECT_REF)
3950 outer = TREE_OPERAND (outer, 0);
3951 indirect_p = 1;
3954 outer_gc_p = objc_is_gcable_p (outer);
3956 /* Handle ivar assignments. */
3957 if (objc_is_ivar_reference_p (lhs))
3959 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3960 doesn't cut it here), the best we can do here is suggest a cast. */
3961 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3963 /* We may still be able to use the global write barrier... */
3964 if (!indirect_p && objc_is_global_reference_p (outer))
3965 goto global_reference;
3967 suggest_cast:
3968 if (modifycode == NOP_EXPR)
3970 if (warn_assign_intercept)
3971 warning (0, "strong-cast may possibly be needed");
3974 goto exit_point;
3977 if (modifycode != NOP_EXPR)
3978 goto invalid_pointer_arithmetic;
3980 if (warn_assign_intercept)
3981 warning (0, "instance variable assignment has been intercepted");
3983 result = objc_build_ivar_assignment (outer, lhs, rhs);
3985 goto exit_point;
3988 /* Likewise, intercept assignment to global/static variables if their type is
3989 GC-marked. */
3990 if (objc_is_global_reference_p (outer))
3992 if (indirect_p)
3993 goto suggest_cast;
3995 global_reference:
3996 if (modifycode != NOP_EXPR)
3998 invalid_pointer_arithmetic:
3999 if (outer_gc_p)
4000 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4002 goto exit_point;
4005 if (warn_assign_intercept)
4006 warning (0, "global/static variable assignment has been intercepted");
4008 result = objc_build_global_assignment (lhs, rhs);
4011 /* In all other cases, fall back to the normal mechanism. */
4012 exit_point:
4013 return result;
4016 struct GTY(()) interface_tuple {
4017 tree id;
4018 tree class_name;
4021 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4023 static hashval_t
4024 hash_interface (const void *p)
4026 const struct interface_tuple *d = (const struct interface_tuple *) p;
4027 return IDENTIFIER_HASH_VALUE (d->id);
4030 static int
4031 eq_interface (const void *p1, const void *p2)
4033 const struct interface_tuple *d = (const struct interface_tuple *) p1;
4034 return d->id == p2;
4037 static tree
4038 lookup_interface (tree ident)
4040 #ifdef OBJCPLUS
4041 if (ident && TREE_CODE (ident) == TYPE_DECL)
4042 ident = DECL_NAME (ident);
4043 #endif
4045 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4046 return NULL_TREE;
4049 struct interface_tuple **slot;
4050 tree i = NULL_TREE;
4052 if (interface_htab)
4054 slot = (struct interface_tuple **)
4055 htab_find_slot_with_hash (interface_htab, ident,
4056 IDENTIFIER_HASH_VALUE (ident),
4057 NO_INSERT);
4058 if (slot && *slot)
4059 i = (*slot)->class_name;
4061 return i;
4065 /* Implement @defs (<classname>) within struct bodies. */
4067 tree
4068 objc_get_class_ivars (tree class_name)
4070 tree interface = lookup_interface (class_name);
4072 if (interface)
4073 return get_class_ivars (interface, true);
4075 error ("cannot find interface declaration for %qE",
4076 class_name);
4078 return error_mark_node;
4081 /* Called when checking the variables in a struct. If we are not
4082 doing the ivars list inside an @interface context, then returns
4083 fieldlist unchanged. Else, returns the list of class ivars.
4085 tree
4086 objc_get_interface_ivars (tree fieldlist)
4088 if (!objc_collecting_ivars || !objc_interface_context
4089 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4090 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4091 return fieldlist;
4093 return get_class_ivars (objc_interface_context, true);
4096 /* Used by: build_private_template, continue_class,
4097 and for @defs constructs. */
4099 static tree
4100 get_class_ivars (tree interface, bool inherited)
4102 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4104 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4105 by the current class (i.e., they do not include super-class ivars).
4106 However, the CLASS_IVARS list will be side-effected by a call to
4107 finish_struct(), which will fill in field offsets. */
4108 if (!CLASS_IVARS (interface))
4109 CLASS_IVARS (interface) = ivar_chain;
4111 if (!inherited)
4112 return ivar_chain;
4114 while (CLASS_SUPER_NAME (interface))
4116 /* Prepend super-class ivars. */
4117 interface = lookup_interface (CLASS_SUPER_NAME (interface));
4118 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4119 ivar_chain);
4122 return ivar_chain;
4125 /* Create a temporary variable of type 'type'. If 'name' is set, uses
4126 the specified name, else use no name. Returns the declaration of
4127 the type. The 'name' is mostly useful for debugging.
4129 static tree
4130 objc_create_temporary_var (tree type, const char *name)
4132 tree decl;
4134 if (name != NULL)
4136 decl = build_decl (input_location,
4137 VAR_DECL, get_identifier (name), type);
4139 else
4141 decl = build_decl (input_location,
4142 VAR_DECL, NULL_TREE, type);
4144 TREE_USED (decl) = 1;
4145 DECL_ARTIFICIAL (decl) = 1;
4146 DECL_IGNORED_P (decl) = 1;
4147 DECL_CONTEXT (decl) = current_function_decl;
4149 return decl;
4152 /* Exception handling constructs. We begin by having the parser do most
4153 of the work and passing us blocks. What we do next depends on whether
4154 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4155 We abstract all of this in a handful of appropriately named routines. */
4157 /* Stack of open try blocks. */
4159 struct objc_try_context
4161 struct objc_try_context *outer;
4163 /* Statements (or statement lists) as processed by the parser. */
4164 tree try_body;
4165 tree finally_body;
4167 /* Some file position locations. */
4168 location_t try_locus;
4169 location_t end_try_locus;
4170 location_t end_catch_locus;
4171 location_t finally_locus;
4172 location_t end_finally_locus;
4174 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4175 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4176 tree catch_list;
4178 /* The CATCH_EXPR of an open @catch clause. */
4179 tree current_catch;
4181 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
4182 tree caught_decl;
4183 tree stack_decl;
4184 tree rethrow_decl;
4187 static struct objc_try_context *cur_try_context;
4189 static GTY(()) tree objc_eh_personality_decl;
4191 /* This hook, called via lang_eh_runtime_type, generates a runtime object
4192 that represents TYPE. For Objective-C, this is just the class name. */
4193 /* ??? Isn't there a class object or some such? Is it easy to get? */
4195 #ifndef OBJCPLUS
4196 tree
4197 objc_eh_runtime_type (tree type)
4199 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
4202 tree
4203 objc_eh_personality (void)
4205 if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
4206 objc_eh_personality_decl = build_personality_function ("gnu_objc");
4207 return objc_eh_personality_decl;
4209 #endif
4211 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
4212 of Darwin, we'll arrange for it to be initialized (and associated
4213 with a binding) later. */
4215 static tree
4216 objc_build_exc_ptr (void)
4218 if (flag_objc_sjlj_exceptions)
4220 tree var = cur_try_context->caught_decl;
4221 if (!var)
4223 var = objc_create_temporary_var (objc_object_type, NULL);
4224 cur_try_context->caught_decl = var;
4226 return var;
4228 else
4230 tree t;
4231 t = built_in_decls[BUILT_IN_EH_POINTER];
4232 t = build_call_expr (t, 1, integer_zero_node);
4233 return fold_convert (objc_object_type, t);
4237 /* Build "objc_exception_try_exit(&_stack)". */
4239 static tree
4240 next_sjlj_build_try_exit (void)
4242 tree t;
4243 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4244 t = tree_cons (NULL, t, NULL);
4245 t = build_function_call (input_location,
4246 objc_exception_try_exit_decl, t);
4247 return t;
4250 /* Build
4251 objc_exception_try_enter (&_stack);
4252 if (_setjmp(&_stack.buf))
4254 else
4256 Return the COND_EXPR. Note that the THEN and ELSE fields are left
4257 empty, ready for the caller to fill them in. */
4259 static tree
4260 next_sjlj_build_enter_and_setjmp (void)
4262 tree t, enter, sj, cond;
4264 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4265 t = tree_cons (NULL, t, NULL);
4266 enter = build_function_call (input_location,
4267 objc_exception_try_enter_decl, t);
4269 t = objc_build_component_ref (cur_try_context->stack_decl,
4270 get_identifier ("buf"));
4271 t = build_fold_addr_expr_loc (input_location, t);
4272 #ifdef OBJCPLUS
4273 /* Convert _setjmp argument to type that is expected. */
4274 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
4275 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
4276 else
4277 t = convert (ptr_type_node, t);
4278 #else
4279 t = convert (ptr_type_node, t);
4280 #endif
4281 t = tree_cons (NULL, t, NULL);
4282 sj = build_function_call (input_location,
4283 objc_setjmp_decl, t);
4285 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
4286 cond = c_common_truthvalue_conversion (input_location, cond);
4288 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
4291 /* Build:
4293 DECL = objc_exception_extract(&_stack); */
4295 static tree
4296 next_sjlj_build_exc_extract (tree decl)
4298 tree t;
4300 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
4301 t = tree_cons (NULL, t, NULL);
4302 t = build_function_call (input_location,
4303 objc_exception_extract_decl, t);
4304 t = convert (TREE_TYPE (decl), t);
4305 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4307 return t;
4310 /* Build
4311 if (objc_exception_match(obj_get_class(TYPE), _caught)
4312 BODY
4313 else if (...)
4315 else
4317 _rethrow = _caught;
4318 objc_exception_try_exit(&_stack);
4320 from the sequence of CATCH_EXPRs in the current try context. */
4322 static tree
4323 next_sjlj_build_catch_list (void)
4325 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4326 tree catch_seq, t;
4327 tree *last = &catch_seq;
4328 bool saw_id = false;
4330 for (; !tsi_end_p (i); tsi_next (&i))
4332 tree stmt = tsi_stmt (i);
4333 tree type = CATCH_TYPES (stmt);
4334 tree body = CATCH_BODY (stmt);
4336 if (type == NULL)
4338 *last = body;
4339 saw_id = true;
4340 break;
4342 else
4344 tree args, cond;
4346 if (type == error_mark_node)
4347 cond = error_mark_node;
4348 else
4350 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
4351 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
4352 args = tree_cons (NULL, t, args);
4353 t = build_function_call (input_location,
4354 objc_exception_match_decl, args);
4355 cond = c_common_truthvalue_conversion (input_location, t);
4357 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
4358 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
4360 *last = t;
4361 last = &COND_EXPR_ELSE (t);
4365 if (!saw_id)
4367 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
4368 cur_try_context->caught_decl);
4369 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4370 append_to_statement_list (t, last);
4372 t = next_sjlj_build_try_exit ();
4373 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
4374 append_to_statement_list (t, last);
4377 return catch_seq;
4380 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
4381 exception handling. We aim to build:
4384 struct _objc_exception_data _stack;
4385 id _rethrow = 0;
4388 objc_exception_try_enter (&_stack);
4389 if (_setjmp(&_stack.buf))
4391 id _caught = objc_exception_extract(&_stack);
4392 objc_exception_try_enter (&_stack);
4393 if (_setjmp(&_stack.buf))
4394 _rethrow = objc_exception_extract(&_stack);
4395 else
4396 CATCH-LIST
4398 else
4399 TRY-BLOCK
4401 finally
4403 if (!_rethrow)
4404 objc_exception_try_exit(&_stack);
4405 FINALLY-BLOCK
4406 if (_rethrow)
4407 objc_exception_throw(_rethrow);
4411 If CATCH-LIST is empty, we can omit all of the block containing
4412 "_caught" except for the setting of _rethrow. Note the use of
4413 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
4414 but handles goto and other exits from the block. */
4416 static tree
4417 next_sjlj_build_try_catch_finally (void)
4419 tree rethrow_decl, stack_decl, t;
4420 tree catch_seq, try_fin, bind;
4422 /* Create the declarations involved. */
4423 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
4424 stack_decl = objc_create_temporary_var (t, NULL);
4425 cur_try_context->stack_decl = stack_decl;
4427 rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
4428 cur_try_context->rethrow_decl = rethrow_decl;
4429 TREE_CHAIN (rethrow_decl) = stack_decl;
4431 /* Build the outermost variable binding level. */
4432 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
4433 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
4434 TREE_SIDE_EFFECTS (bind) = 1;
4436 /* Initialize rethrow_decl. */
4437 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
4438 convert (objc_object_type, null_pointer_node));
4439 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4440 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
4442 /* Build the outermost TRY_FINALLY_EXPR. */
4443 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
4444 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
4445 TREE_SIDE_EFFECTS (try_fin) = 1;
4446 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
4448 /* Create the complete catch sequence. */
4449 if (cur_try_context->catch_list)
4451 tree caught_decl = objc_build_exc_ptr ();
4452 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
4453 TREE_SIDE_EFFECTS (catch_seq) = 1;
4455 t = next_sjlj_build_exc_extract (caught_decl);
4456 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4458 t = next_sjlj_build_enter_and_setjmp ();
4459 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
4460 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
4461 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
4463 else
4464 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
4465 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
4467 /* Build the main register-and-try if statement. */
4468 t = next_sjlj_build_enter_and_setjmp ();
4469 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
4470 COND_EXPR_THEN (t) = catch_seq;
4471 COND_EXPR_ELSE (t) = cur_try_context->try_body;
4472 TREE_OPERAND (try_fin, 0) = t;
4474 /* Build the complete FINALLY statement list. */
4475 t = next_sjlj_build_try_exit ();
4476 t = build_stmt (input_location, COND_EXPR,
4477 c_common_truthvalue_conversion
4478 (input_location, rethrow_decl),
4479 NULL, t);
4480 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
4481 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4483 append_to_statement_list (cur_try_context->finally_body,
4484 &TREE_OPERAND (try_fin, 1));
4486 t = tree_cons (NULL, rethrow_decl, NULL);
4487 t = build_function_call (input_location,
4488 objc_exception_throw_decl, t);
4489 t = build_stmt (input_location, COND_EXPR,
4490 c_common_truthvalue_conversion (input_location,
4491 rethrow_decl),
4492 t, NULL);
4493 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
4494 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
4496 return bind;
4499 /* Called just after parsing the @try and its associated BODY. We now
4500 must prepare for the tricky bits -- handling the catches and finally. */
4502 void
4503 objc_begin_try_stmt (location_t try_locus, tree body)
4505 struct objc_try_context *c = XCNEW (struct objc_try_context);
4506 c->outer = cur_try_context;
4507 c->try_body = body;
4508 c->try_locus = try_locus;
4509 c->end_try_locus = input_location;
4510 cur_try_context = c;
4512 /* -fobjc-exceptions is required to enable Objective-C exceptions.
4513 For example, on Darwin, ObjC exceptions require a sufficiently
4514 recent version of the runtime, so the user must ask for them
4515 explicitly. On other platforms, at the moment -fobjc-exceptions
4516 triggers -fexceptions which again is required for exceptions to
4517 work.
4519 if (!flag_objc_exceptions)
4521 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4524 if (flag_objc_sjlj_exceptions)
4525 objc_mark_locals_volatile (NULL);
4528 /* Called just after parsing "@catch (parm)". Open a binding level,
4529 enter DECL into the binding level, and initialize it. Leave the
4530 binding level open while the body of the compound statement is parsed. */
4532 void
4533 objc_begin_catch_clause (tree decl)
4535 tree compound, type, t;
4537 /* Begin a new scope that the entire catch clause will live in. */
4538 compound = c_begin_compound_stmt (true);
4540 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
4541 decl = build_decl (input_location,
4542 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
4543 lang_hooks.decls.pushdecl (decl);
4545 /* Since a decl is required here by syntax, don't warn if its unused. */
4546 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
4547 be what the previous objc implementation did. */
4548 TREE_USED (decl) = 1;
4549 DECL_READ_P (decl) = 1;
4551 /* Verify that the type of the catch is valid. It must be a pointer
4552 to an Objective-C class, or "id" (which is catch-all). */
4553 type = TREE_TYPE (decl);
4555 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
4556 type = NULL;
4557 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
4559 error ("@catch parameter is not a known Objective-C class type");
4560 type = error_mark_node;
4562 else if (cur_try_context->catch_list)
4564 /* Examine previous @catch clauses and see if we've already
4565 caught the type in question. */
4566 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
4567 for (; !tsi_end_p (i); tsi_next (&i))
4569 tree stmt = tsi_stmt (i);
4570 t = CATCH_TYPES (stmt);
4571 if (t == error_mark_node)
4572 continue;
4573 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
4575 warning (0, "exception of type %<%T%> will be caught",
4576 TREE_TYPE (type));
4577 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
4578 TREE_TYPE (t ? t : objc_object_type));
4579 break;
4584 /* Record the data for the catch in the try context so that we can
4585 finalize it later. */
4586 t = build_stmt (input_location, CATCH_EXPR, type, compound);
4587 cur_try_context->current_catch = t;
4589 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4590 t = objc_build_exc_ptr ();
4591 t = convert (TREE_TYPE (decl), t);
4592 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4593 add_stmt (t);
4596 /* Called just after parsing the closing brace of a @catch clause. Close
4597 the open binding level, and record a CATCH_EXPR for it. */
4599 void
4600 objc_finish_catch_clause (void)
4602 tree c = cur_try_context->current_catch;
4603 cur_try_context->current_catch = NULL;
4604 cur_try_context->end_catch_locus = input_location;
4606 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
4607 append_to_statement_list (c, &cur_try_context->catch_list);
4610 /* Called after parsing a @finally clause and its associated BODY.
4611 Record the body for later placement. */
4613 void
4614 objc_build_finally_clause (location_t finally_locus, tree body)
4616 cur_try_context->finally_body = body;
4617 cur_try_context->finally_locus = finally_locus;
4618 cur_try_context->end_finally_locus = input_location;
4621 /* Called to finalize a @try construct. */
4623 tree
4624 objc_finish_try_stmt (void)
4626 struct objc_try_context *c = cur_try_context;
4627 tree stmt;
4629 if (c->catch_list == NULL && c->finally_body == NULL)
4630 error ("%<@try%> without %<@catch%> or %<@finally%>");
4632 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4633 if (flag_objc_sjlj_exceptions)
4635 bool save = in_late_binary_op;
4636 in_late_binary_op = true;
4637 if (!cur_try_context->finally_body)
4639 cur_try_context->finally_locus = input_location;
4640 cur_try_context->end_finally_locus = input_location;
4642 stmt = next_sjlj_build_try_catch_finally ();
4643 in_late_binary_op = save;
4645 else
4647 /* Otherwise, nest the CATCH inside a FINALLY. */
4648 stmt = c->try_body;
4649 if (c->catch_list)
4651 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
4652 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4654 if (c->finally_body)
4656 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
4657 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4660 add_stmt (stmt);
4662 cur_try_context = c->outer;
4663 free (c);
4664 return stmt;
4667 tree
4668 objc_build_throw_stmt (location_t loc, tree throw_expr)
4670 tree args;
4672 if (!flag_objc_exceptions)
4674 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4677 if (throw_expr == NULL)
4679 /* If we're not inside a @catch block, there is no "current
4680 exception" to be rethrown. */
4681 if (cur_try_context == NULL
4682 || cur_try_context->current_catch == NULL)
4684 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
4685 return NULL_TREE;
4688 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4689 value that we get from the runtime. */
4690 throw_expr = objc_build_exc_ptr ();
4693 /* A throw is just a call to the runtime throw function with the
4694 object as a parameter. */
4695 args = tree_cons (NULL, throw_expr, NULL);
4696 return add_stmt (build_function_call (loc,
4697 objc_exception_throw_decl, args));
4700 tree
4701 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4703 tree args, call;
4705 /* First lock the mutex. */
4706 mutex = save_expr (mutex);
4707 args = tree_cons (NULL, mutex, NULL);
4708 call = build_function_call (input_location,
4709 objc_sync_enter_decl, args);
4710 SET_EXPR_LOCATION (call, start_locus);
4711 add_stmt (call);
4713 /* Build the mutex unlock. */
4714 args = tree_cons (NULL, mutex, NULL);
4715 call = build_function_call (input_location,
4716 objc_sync_exit_decl, args);
4717 SET_EXPR_LOCATION (call, input_location);
4719 /* Put the that and the body in a TRY_FINALLY. */
4720 objc_begin_try_stmt (start_locus, body);
4721 objc_build_finally_clause (input_location, call);
4722 return objc_finish_try_stmt ();
4726 /* Predefine the following data type:
4728 struct _objc_exception_data
4730 int buf[OBJC_JBLEN];
4731 void *pointers[4];
4732 }; */
4734 /* The following yuckiness should prevent users from having to #include
4735 <setjmp.h> in their code... */
4737 /* Define to a harmless positive value so the below code doesn't die. */
4738 #ifndef OBJC_JBLEN
4739 #define OBJC_JBLEN 18
4740 #endif
4742 static void
4743 build_next_objc_exception_stuff (void)
4745 tree decls, temp_type, *chain = NULL;
4747 objc_exception_data_template
4748 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4750 /* int buf[OBJC_JBLEN]; */
4752 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
4753 decls = add_field_decl (temp_type, "buf", &chain);
4755 /* void *pointers[4]; */
4757 temp_type = build_sized_array_type (ptr_type_node, 4);
4758 add_field_decl (temp_type, "pointers", &chain);
4760 objc_finish_struct (objc_exception_data_template, decls);
4762 /* int _setjmp(...); */
4763 /* If the user includes <setjmp.h>, this shall be superseded by
4764 'int _setjmp(jmp_buf);' */
4765 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
4766 objc_setjmp_decl
4767 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4769 /* id objc_exception_extract(struct _objc_exception_data *); */
4770 temp_type
4771 = build_function_type_list (objc_object_type,
4772 build_pointer_type (objc_exception_data_template),
4773 NULL_TREE);
4774 objc_exception_extract_decl
4775 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4776 NULL_TREE);
4777 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4778 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4779 temp_type
4780 = build_function_type_list (void_type_node,
4781 build_pointer_type (objc_exception_data_template),
4782 NULL_TREE);
4783 objc_exception_try_enter_decl
4784 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4785 NULL_TREE);
4786 objc_exception_try_exit_decl
4787 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4788 NULL_TREE);
4790 /* int objc_exception_match(id, id); */
4791 temp_type
4792 = build_function_type_list (integer_type_node,
4793 objc_object_type, objc_object_type, NULL_TREE);
4794 objc_exception_match_decl
4795 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4796 NULL_TREE);
4798 /* id objc_assign_ivar (id, id, unsigned int); */
4799 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4800 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4801 temp_type
4802 = build_function_type_list (objc_object_type,
4803 objc_object_type,
4804 objc_object_type,
4805 unsigned_type_node,
4806 NULL_TREE);
4807 objc_assign_ivar_decl
4808 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4809 NULL, NULL_TREE);
4810 #ifdef OFFS_ASSIGNIVAR_FAST
4811 objc_assign_ivar_fast_decl
4812 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4813 NOT_BUILT_IN, NULL, NULL_TREE);
4814 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4815 = tree_cons (get_identifier ("hard_coded_address"),
4816 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4817 NULL_TREE);
4818 #else
4819 /* Default to slower ivar method. */
4820 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4821 #endif
4823 /* id objc_assign_global (id, id *); */
4824 /* id objc_assign_strongCast (id, id *); */
4825 temp_type = build_function_type_list (objc_object_type,
4826 objc_object_type,
4827 build_pointer_type (objc_object_type),
4828 NULL_TREE);
4829 objc_assign_global_decl
4830 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4831 NULL_TREE);
4832 objc_assign_strong_cast_decl
4833 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4834 NULL_TREE);
4837 static void
4838 build_objc_exception_stuff (void)
4840 tree noreturn_list, nothrow_list, temp_type;
4842 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4843 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4845 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4846 /* void objc_sync_enter(id); */
4847 /* void objc_sync_exit(id); */
4848 temp_type = build_function_type_list (void_type_node,
4849 objc_object_type,
4850 NULL_TREE);
4851 objc_exception_throw_decl
4852 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4853 noreturn_list);
4854 objc_sync_enter_decl
4855 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4856 NULL, nothrow_list);
4857 objc_sync_exit_decl
4858 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4859 NULL, nothrow_list);
4862 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4863 name as the class:
4865 struct <classname> {
4866 struct _objc_class *isa;
4868 }; */
4870 static void
4871 build_private_template (tree klass)
4873 if (!CLASS_STATIC_TEMPLATE (klass))
4875 tree record = objc_build_struct (klass,
4876 get_class_ivars (klass, false),
4877 CLASS_SUPER_NAME (klass));
4879 /* Set the TREE_USED bit for this struct, so that stab generator
4880 can emit stabs for this struct type. */
4881 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4882 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4886 /* Begin code generation for protocols... */
4888 /* struct _objc_protocol {
4889 struct _objc_class *isa;
4890 char *protocol_name;
4891 struct _objc_protocol **protocol_list;
4892 struct _objc__method_prototype_list *instance_methods;
4893 struct _objc__method_prototype_list *class_methods;
4894 }; */
4896 static void
4897 build_protocol_template (void)
4899 tree ptype, decls, *chain = NULL;
4901 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4903 /* struct _objc_class *isa; */
4904 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4905 get_identifier (UTAG_CLASS)));
4906 decls = add_field_decl (ptype, "isa", &chain);
4908 /* char *protocol_name; */
4909 add_field_decl (string_type_node, "protocol_name", &chain);
4911 /* struct _objc_protocol **protocol_list; */
4912 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4913 add_field_decl (ptype, "protocol_list", &chain);
4915 /* struct _objc__method_prototype_list *instance_methods; */
4916 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
4918 /* struct _objc__method_prototype_list *class_methods; */
4919 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
4921 objc_finish_struct (objc_protocol_template, decls);
4924 static tree
4925 build_descriptor_table_initializer (tree type, tree entries)
4927 VEC(constructor_elt,gc) *inits = NULL;
4931 VEC(constructor_elt,gc) *elts = NULL;
4933 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4934 build_selector (METHOD_SEL_NAME (entries)));
4935 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4936 add_objc_string (METHOD_ENCODING (entries),
4937 meth_var_types));
4939 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
4940 objc_build_constructor (type, elts));
4942 entries = DECL_CHAIN (entries);
4944 while (entries);
4946 return objc_build_constructor (build_array_type (type, 0), inits);
4949 /* struct objc_method_prototype_list {
4950 int count;
4951 struct objc_method_prototype {
4952 SEL name;
4953 char *types;
4954 } list[1];
4955 }; */
4957 static tree
4958 build_method_prototype_list_template (tree list_type, int size)
4960 tree objc_ivar_list_record;
4961 tree array_type, decls, *chain = NULL;
4963 /* Generate an unnamed struct definition. */
4965 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4967 /* int method_count; */
4968 decls = add_field_decl (integer_type_node, "method_count", &chain);
4970 /* struct objc_method method_list[]; */
4971 array_type = build_sized_array_type (list_type, size);
4972 add_field_decl (array_type, "method_list", &chain);
4974 objc_finish_struct (objc_ivar_list_record, decls);
4976 return objc_ivar_list_record;
4979 static tree
4980 build_method_prototype_template (void)
4982 tree proto_record;
4983 tree decls, *chain = NULL;
4985 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4987 /* SEL _cmd; */
4988 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
4990 /* char *method_types; */
4991 add_field_decl (string_type_node, "method_types", &chain);
4993 objc_finish_struct (proto_record, decls);
4995 return proto_record;
4998 static tree
4999 objc_method_parm_type (tree type)
5001 type = TREE_VALUE (TREE_TYPE (type));
5002 if (TREE_CODE (type) == TYPE_DECL)
5003 type = TREE_TYPE (type);
5004 return type;
5007 static int
5008 objc_encoded_type_size (tree type)
5010 int sz = int_size_in_bytes (type);
5012 /* Make all integer and enum types at least as large
5013 as an int. */
5014 if (sz > 0 && INTEGRAL_TYPE_P (type))
5015 sz = MAX (sz, int_size_in_bytes (integer_type_node));
5016 /* Treat arrays as pointers, since that's how they're
5017 passed in. */
5018 else if (TREE_CODE (type) == ARRAY_TYPE)
5019 sz = int_size_in_bytes (ptr_type_node);
5020 return sz;
5023 /* Encode a method prototype.
5025 The format is described in gcc/doc/objc.texi, section 'Method
5026 signatures'.
5028 static tree
5029 encode_method_prototype (tree method_decl)
5031 tree parms;
5032 int parm_offset, i;
5033 char buf[40];
5034 tree result;
5036 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5037 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5039 /* Encode return type. */
5040 encode_type (objc_method_parm_type (method_decl),
5041 obstack_object_size (&util_obstack),
5042 OBJC_ENCODE_INLINE_DEFS);
5044 /* Stack size. */
5045 /* The first two arguments (self and _cmd) are pointers; account for
5046 their size. */
5047 i = int_size_in_bytes (ptr_type_node);
5048 parm_offset = 2 * i;
5049 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5050 parms = DECL_CHAIN (parms))
5052 tree type = objc_method_parm_type (parms);
5053 int sz = objc_encoded_type_size (type);
5055 /* If a type size is not known, bail out. */
5056 if (sz < 0)
5058 error ("type %q+D does not have a known size",
5059 type);
5060 /* Pretend that the encoding succeeded; the compilation will
5061 fail nevertheless. */
5062 goto finish_encoding;
5064 parm_offset += sz;
5067 sprintf (buf, "%d@0:%d", parm_offset, i);
5068 obstack_grow (&util_obstack, buf, strlen (buf));
5070 /* Argument types. */
5071 parm_offset = 2 * i;
5072 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5073 parms = DECL_CHAIN (parms))
5075 tree type = objc_method_parm_type (parms);
5077 /* Process argument qualifiers for user supplied arguments. */
5078 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5080 /* Type. */
5081 encode_type (type, obstack_object_size (&util_obstack),
5082 OBJC_ENCODE_INLINE_DEFS);
5084 /* Compute offset. */
5085 sprintf (buf, "%d", parm_offset);
5086 parm_offset += objc_encoded_type_size (type);
5088 obstack_grow (&util_obstack, buf, strlen (buf));
5091 finish_encoding:
5092 obstack_1grow (&util_obstack, '\0');
5093 result = get_identifier (XOBFINISH (&util_obstack, char *));
5094 obstack_free (&util_obstack, util_firstobj);
5095 return result;
5098 static tree
5099 generate_descriptor_table (tree type, const char *name, int size, tree list,
5100 tree proto)
5102 tree decl;
5103 VEC(constructor_elt,gc) *v = NULL;
5105 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
5107 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
5108 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5110 finish_var_decl (decl, objc_build_constructor (type, v));
5112 return decl;
5115 static void
5116 generate_method_descriptors (tree protocol)
5118 tree initlist, chain, method_list_template;
5119 int size;
5121 if (!objc_method_prototype_template)
5122 objc_method_prototype_template = build_method_prototype_template ();
5124 chain = PROTOCOL_CLS_METHODS (protocol);
5125 if (chain)
5127 size = list_length (chain);
5129 method_list_template
5130 = build_method_prototype_list_template (objc_method_prototype_template,
5131 size);
5133 initlist
5134 = build_descriptor_table_initializer (objc_method_prototype_template,
5135 chain);
5137 UOBJC_CLASS_METHODS_decl
5138 = generate_descriptor_table (method_list_template,
5139 "_OBJC_PROTOCOL_CLASS_METHODS",
5140 size, initlist, protocol);
5142 else
5143 UOBJC_CLASS_METHODS_decl = 0;
5145 chain = PROTOCOL_NST_METHODS (protocol);
5146 if (chain)
5148 size = list_length (chain);
5150 method_list_template
5151 = build_method_prototype_list_template (objc_method_prototype_template,
5152 size);
5153 initlist
5154 = build_descriptor_table_initializer (objc_method_prototype_template,
5155 chain);
5157 UOBJC_INSTANCE_METHODS_decl
5158 = generate_descriptor_table (method_list_template,
5159 "_OBJC_PROTOCOL_INSTANCE_METHODS",
5160 size, initlist, protocol);
5162 else
5163 UOBJC_INSTANCE_METHODS_decl = 0;
5166 static void
5167 generate_protocol_references (tree plist)
5169 tree lproto;
5171 /* Forward declare protocols referenced. */
5172 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5174 tree proto = TREE_VALUE (lproto);
5176 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
5177 && PROTOCOL_NAME (proto))
5179 if (! PROTOCOL_FORWARD_DECL (proto))
5180 build_protocol_reference (proto);
5182 if (PROTOCOL_LIST (proto))
5183 generate_protocol_references (PROTOCOL_LIST (proto));
5188 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
5189 current class. */
5190 #ifdef OBJCPLUS
5191 static void
5192 objc_generate_cxx_ctor_or_dtor (bool dtor)
5194 tree fn, body, compound_stmt, ivar;
5196 /* - (id) .cxx_construct { ... return self; } */
5197 /* - (void) .cxx_construct { ... } */
5199 objc_start_method_definition
5200 (false /* is_class_method */,
5201 objc_build_method_signature (false /* is_class_method */,
5202 build_tree_list (NULL_TREE,
5203 dtor
5204 ? void_type_node
5205 : objc_object_type),
5206 get_identifier (dtor
5207 ? TAG_CXX_DESTRUCT
5208 : TAG_CXX_CONSTRUCT),
5209 make_node (TREE_LIST),
5210 false), NULL);
5211 body = begin_function_body ();
5212 compound_stmt = begin_compound_stmt (0);
5214 ivar = CLASS_IVARS (implementation_template);
5215 /* Destroy ivars in reverse order. */
5216 if (dtor)
5217 ivar = nreverse (copy_list (ivar));
5219 for (; ivar; ivar = TREE_CHAIN (ivar))
5221 if (TREE_CODE (ivar) == FIELD_DECL)
5223 tree type = TREE_TYPE (ivar);
5225 /* Call the ivar's default constructor or destructor. Do not
5226 call the destructor unless a corresponding constructor call
5227 has also been made (or is not needed). */
5228 if (MAYBE_CLASS_TYPE_P (type)
5229 && (dtor
5230 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5231 && (!TYPE_NEEDS_CONSTRUCTING (type)
5232 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5233 : (TYPE_NEEDS_CONSTRUCTING (type)
5234 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
5235 finish_expr_stmt
5236 (build_special_member_call
5237 (build_ivar_reference (DECL_NAME (ivar)),
5238 dtor ? complete_dtor_identifier : complete_ctor_identifier,
5239 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
5243 /* The constructor returns 'self'. */
5244 if (!dtor)
5245 finish_return_stmt (self_decl);
5247 finish_compound_stmt (compound_stmt);
5248 finish_function_body (body);
5249 fn = current_function_decl;
5250 finish_function ();
5251 objc_finish_method_definition (fn);
5254 /* The following routine will examine the current @interface for any
5255 non-POD C++ ivars requiring non-trivial construction and/or
5256 destruction, and then synthesize special '- .cxx_construct' and/or
5257 '- .cxx_destruct' methods which will run the appropriate
5258 construction or destruction code. Note that ivars inherited from
5259 super-classes are _not_ considered. */
5260 static void
5261 objc_generate_cxx_cdtors (void)
5263 bool need_ctor = false, need_dtor = false;
5264 tree ivar;
5266 /* Error case, due to possibly an extra @end. */
5267 if (!objc_implementation_context)
5268 return;
5270 /* We do not want to do this for categories, since they do not have
5271 their own ivars. */
5273 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
5274 return;
5276 /* First, determine if we even need a constructor and/or destructor. */
5278 for (ivar = CLASS_IVARS (implementation_template); ivar;
5279 ivar = TREE_CHAIN (ivar))
5281 if (TREE_CODE (ivar) == FIELD_DECL)
5283 tree type = TREE_TYPE (ivar);
5285 if (MAYBE_CLASS_TYPE_P (type))
5287 if (TYPE_NEEDS_CONSTRUCTING (type)
5288 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
5289 /* NB: If a default constructor is not available, we will not
5290 be able to initialize this ivar; the add_instance_variable()
5291 routine will already have warned about this. */
5292 need_ctor = true;
5294 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
5295 && (!TYPE_NEEDS_CONSTRUCTING (type)
5296 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
5297 /* NB: If a default constructor is not available, we will not
5298 call the destructor either, for symmetry. */
5299 need_dtor = true;
5304 /* Generate '- .cxx_construct' if needed. */
5306 if (need_ctor)
5307 objc_generate_cxx_ctor_or_dtor (false);
5309 /* Generate '- .cxx_destruct' if needed. */
5311 if (need_dtor)
5312 objc_generate_cxx_ctor_or_dtor (true);
5314 /* The 'imp_list' variable points at an imp_entry record for the current
5315 @implementation. Record the existence of '- .cxx_construct' and/or
5316 '- .cxx_destruct' methods therein; it will be included in the
5317 metadata for the class. */
5318 if (flag_next_runtime)
5319 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
5321 #endif
5323 /* For each protocol which was referenced either from a @protocol()
5324 expression, or because a class/category implements it (then a
5325 pointer to the protocol is stored in the struct describing the
5326 class/category), we create a statically allocated instance of the
5327 Protocol class. The code is written in such a way as to generate
5328 as few Protocol objects as possible; we generate a unique Protocol
5329 instance for each protocol, and we don't generate a Protocol
5330 instance if the protocol is never referenced (either from a
5331 @protocol() or from a class/category implementation). These
5332 statically allocated objects can be referred to via the static
5333 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
5335 The statically allocated Protocol objects that we generate here
5336 need to be fixed up at runtime in order to be used: the 'isa'
5337 pointer of the objects need to be set up to point to the 'Protocol'
5338 class, as known at runtime.
5340 The NeXT runtime fixes up all protocols at program startup time,
5341 before main() is entered. It uses a low-level trick to look up all
5342 those symbols, then loops on them and fixes them up.
5344 The GNU runtime as well fixes up all protocols before user code
5345 from the module is executed; it requires pointers to those symbols
5346 to be put in the objc_symtab (which is then passed as argument to
5347 the function __objc_exec_class() which the compiler sets up to be
5348 executed automatically when the module is loaded); setup of those
5349 Protocol objects happen in two ways in the GNU runtime: all
5350 Protocol objects referred to by a class or category implementation
5351 are fixed up when the class/category is loaded; all Protocol
5352 objects referred to by a @protocol() expression are added by the
5353 compiler to the list of statically allocated instances to fixup
5354 (the same list holding the statically allocated constant string
5355 objects). Because, as explained above, the compiler generates as
5356 few Protocol objects as possible, some Protocol object might end up
5357 being referenced multiple times when compiled with the GNU runtime,
5358 and end up being fixed up multiple times at runtime initialization.
5359 But that doesn't hurt, it's just a little inefficient. */
5361 static void
5362 generate_protocols (void)
5364 tree p, encoding;
5365 tree decl;
5366 tree initlist, protocol_name_expr, refs_decl, refs_expr;
5368 /* If a protocol was directly referenced, pull in indirect references. */
5369 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5370 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
5371 generate_protocol_references (PROTOCOL_LIST (p));
5373 for (p = protocol_chain; p; p = TREE_CHAIN (p))
5375 tree nst_methods = PROTOCOL_NST_METHODS (p);
5376 tree cls_methods = PROTOCOL_CLS_METHODS (p);
5378 /* If protocol wasn't referenced, don't generate any code. */
5379 decl = PROTOCOL_FORWARD_DECL (p);
5381 if (!decl)
5382 continue;
5384 /* Make sure we link in the Protocol class. */
5385 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5387 while (nst_methods)
5389 if (! METHOD_ENCODING (nst_methods))
5391 encoding = encode_method_prototype (nst_methods);
5392 METHOD_ENCODING (nst_methods) = encoding;
5394 nst_methods = DECL_CHAIN (nst_methods);
5397 while (cls_methods)
5399 if (! METHOD_ENCODING (cls_methods))
5401 encoding = encode_method_prototype (cls_methods);
5402 METHOD_ENCODING (cls_methods) = encoding;
5405 cls_methods = DECL_CHAIN (cls_methods);
5407 generate_method_descriptors (p);
5409 if (PROTOCOL_LIST (p))
5410 refs_decl = generate_protocol_list (p);
5411 else
5412 refs_decl = 0;
5414 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5415 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
5417 if (refs_decl)
5418 refs_expr = convert (build_pointer_type (build_pointer_type
5419 (objc_protocol_template)),
5420 build_unary_op (input_location,
5421 ADDR_EXPR, refs_decl, 0));
5422 else
5423 refs_expr = build_int_cst (NULL_TREE, 0);
5425 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
5426 by generate_method_descriptors, which is called above. */
5427 initlist = build_protocol_initializer (TREE_TYPE (decl),
5428 protocol_name_expr, refs_expr,
5429 UOBJC_INSTANCE_METHODS_decl,
5430 UOBJC_CLASS_METHODS_decl);
5431 finish_var_decl (decl, initlist);
5435 static tree
5436 build_protocol_initializer (tree type, tree protocol_name,
5437 tree protocol_list, tree instance_methods,
5438 tree class_methods)
5440 tree expr;
5441 tree cast_type = build_pointer_type
5442 (xref_tag (RECORD_TYPE,
5443 get_identifier (UTAG_CLASS)));
5444 VEC(constructor_elt,gc) *inits = NULL;
5446 /* Filling the "isa" in with one allows the runtime system to
5447 detect that the version change...should remove before final release. */
5449 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
5450 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5451 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
5452 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
5454 if (!instance_methods)
5455 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5456 else
5458 expr = convert (objc_method_proto_list_ptr,
5459 build_unary_op (input_location,
5460 ADDR_EXPR, instance_methods, 0));
5461 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5464 if (!class_methods)
5465 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
5466 else
5468 expr = convert (objc_method_proto_list_ptr,
5469 build_unary_op (input_location,
5470 ADDR_EXPR, class_methods, 0));
5471 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
5474 return objc_build_constructor (type, inits);
5477 /* struct _objc_category {
5478 char *category_name;
5479 char *class_name;
5480 struct _objc_method_list *instance_methods;
5481 struct _objc_method_list *class_methods;
5482 struct _objc_protocol_list *protocols;
5483 }; */
5485 static void
5486 build_category_template (void)
5488 tree ptype, decls, *chain = NULL;
5490 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
5492 /* char *category_name; */
5493 decls = add_field_decl (string_type_node, "category_name", &chain);
5495 /* char *class_name; */
5496 add_field_decl (string_type_node, "class_name", &chain);
5498 /* struct _objc_method_list *instance_methods; */
5499 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
5501 /* struct _objc_method_list *class_methods; */
5502 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
5504 /* struct _objc_protocol **protocol_list; */
5505 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5506 add_field_decl (ptype, "protocol_list", &chain);
5508 objc_finish_struct (objc_category_template, decls);
5511 /* struct _objc_selector {
5512 SEL sel_id;
5513 char *sel_type;
5514 }; */
5516 static void
5517 build_selector_template (void)
5519 tree decls, *chain = NULL;
5521 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
5523 /* SEL sel_id; */
5524 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
5526 /* char *sel_type; */
5527 add_field_decl (string_type_node, "sel_type", &chain);
5529 objc_finish_struct (objc_selector_template, decls);
5532 /* struct _objc_class {
5533 struct _objc_class *isa;
5534 struct _objc_class *super_class;
5535 char *name;
5536 long version;
5537 long info;
5538 long instance_size;
5539 struct _objc_ivar_list *ivars;
5540 struct _objc_method_list *methods;
5541 #ifdef __NEXT_RUNTIME__
5542 struct objc_cache *cache;
5543 #else
5544 struct sarray *dtable;
5545 struct _objc_class *subclass_list;
5546 struct _objc_class *sibling_class;
5547 #endif
5548 struct _objc_protocol_list *protocols;
5549 #ifdef __NEXT_RUNTIME__
5550 void *sel_id;
5551 #endif
5552 void *gc_object_type;
5553 }; */
5555 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
5556 the NeXT/Apple runtime; still, the compiler must generate them to
5557 maintain backward binary compatibility (and to allow for future
5558 expansion). */
5560 static void
5561 build_class_template (void)
5563 tree ptype, decls, *chain = NULL;
5565 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
5567 /* struct _objc_class *isa; */
5568 decls = add_field_decl (build_pointer_type (objc_class_template),
5569 "isa", &chain);
5571 /* struct _objc_class *super_class; */
5572 add_field_decl (build_pointer_type (objc_class_template),
5573 "super_class", &chain);
5575 /* char *name; */
5576 add_field_decl (string_type_node, "name", &chain);
5578 /* long version; */
5579 add_field_decl (long_integer_type_node, "version", &chain);
5581 /* long info; */
5582 add_field_decl (long_integer_type_node, "info", &chain);
5584 /* long instance_size; */
5585 add_field_decl (long_integer_type_node, "instance_size", &chain);
5587 /* struct _objc_ivar_list *ivars; */
5588 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
5590 /* struct _objc_method_list *methods; */
5591 add_field_decl (objc_method_list_ptr, "methods", &chain);
5593 if (flag_next_runtime)
5595 /* struct objc_cache *cache; */
5596 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5597 get_identifier ("objc_cache")));
5598 add_field_decl (ptype, "cache", &chain);
5600 else
5602 /* struct sarray *dtable; */
5603 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
5604 get_identifier ("sarray")));
5605 add_field_decl (ptype, "dtable", &chain);
5607 /* struct objc_class *subclass_list; */
5608 ptype = build_pointer_type (objc_class_template);
5609 add_field_decl (ptype, "subclass_list", &chain);
5611 /* struct objc_class *sibling_class; */
5612 ptype = build_pointer_type (objc_class_template);
5613 add_field_decl (ptype, "sibling_class", &chain);
5616 /* struct _objc_protocol **protocol_list; */
5617 ptype = build_pointer_type (build_pointer_type
5618 (xref_tag (RECORD_TYPE,
5619 get_identifier (UTAG_PROTOCOL))));
5620 add_field_decl (ptype, "protocol_list", &chain);
5622 if (flag_next_runtime)
5624 /* void *sel_id; */
5625 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
5628 /* void *gc_object_type; */
5629 add_field_decl (build_pointer_type (void_type_node),
5630 "gc_object_type", &chain);
5632 objc_finish_struct (objc_class_template, decls);
5635 /* Generate appropriate forward declarations for an implementation. */
5637 static void
5638 synth_forward_declarations (void)
5640 tree an_id;
5642 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5643 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5644 objc_class_template);
5646 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5647 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5648 objc_class_template);
5650 /* Pre-build the following entities - for speed/convenience. */
5652 an_id = get_identifier ("super_class");
5653 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5654 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5657 static void
5658 error_with_ivar (const char *message, tree decl)
5660 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5661 message, identifier_to_locale (gen_declaration (decl)));
5665 static void
5666 check_ivars (tree inter, tree imp)
5668 tree intdecls = CLASS_RAW_IVARS (inter);
5669 tree impdecls = CLASS_RAW_IVARS (imp);
5671 while (1)
5673 tree t1, t2;
5675 #ifdef OBJCPLUS
5676 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5677 intdecls = TREE_CHAIN (intdecls);
5678 #endif
5679 if (intdecls == 0 && impdecls == 0)
5680 break;
5681 if (intdecls == 0 || impdecls == 0)
5683 error ("inconsistent instance variable specification");
5684 break;
5687 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5689 if (!comptypes (t1, t2)
5690 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5691 DECL_INITIAL (impdecls)))
5693 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5695 error_with_ivar ("conflicting instance variable type",
5696 impdecls);
5697 error_with_ivar ("previous declaration of",
5698 intdecls);
5700 else /* both the type and the name don't match */
5702 error ("inconsistent instance variable specification");
5703 break;
5707 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5709 error_with_ivar ("conflicting instance variable name",
5710 impdecls);
5711 error_with_ivar ("previous declaration of",
5712 intdecls);
5715 intdecls = DECL_CHAIN (intdecls);
5716 impdecls = DECL_CHAIN (impdecls);
5720 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5721 This needs to be done just once per compilation. */
5723 /* struct _objc_super {
5724 struct _objc_object *self;
5725 struct _objc_class *super_class;
5726 }; */
5728 static void
5729 build_super_template (void)
5731 tree decls, *chain = NULL;
5733 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5735 /* struct _objc_object *self; */
5736 decls = add_field_decl (objc_object_type, "self", &chain);
5738 /* struct _objc_class *super_class; */
5739 add_field_decl (build_pointer_type (objc_class_template),
5740 "super_class", &chain);
5742 objc_finish_struct (objc_super_template, decls);
5745 /* struct _objc_ivar {
5746 char *ivar_name;
5747 char *ivar_type;
5748 int ivar_offset;
5749 }; */
5751 static tree
5752 build_ivar_template (void)
5754 tree objc_ivar_id, objc_ivar_record;
5755 tree decls, *chain = NULL;
5757 objc_ivar_id = get_identifier (UTAG_IVAR);
5758 objc_ivar_record = objc_start_struct (objc_ivar_id);
5760 /* char *ivar_name; */
5761 decls = add_field_decl (string_type_node, "ivar_name", &chain);
5763 /* char *ivar_type; */
5764 add_field_decl (string_type_node, "ivar_type", &chain);
5766 /* int ivar_offset; */
5767 add_field_decl (integer_type_node, "ivar_offset", &chain);
5769 objc_finish_struct (objc_ivar_record, decls);
5771 return objc_ivar_record;
5774 /* struct {
5775 int ivar_count;
5776 struct objc_ivar ivar_list[ivar_count];
5777 }; */
5779 static tree
5780 build_ivar_list_template (tree list_type, int size)
5782 tree objc_ivar_list_record;
5783 tree array_type, decls, *chain = NULL;
5785 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5787 /* int ivar_count; */
5788 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
5790 /* struct objc_ivar ivar_list[]; */
5791 array_type = build_sized_array_type (list_type, size);
5792 add_field_decl (array_type, "ivar_list", &chain);
5794 objc_finish_struct (objc_ivar_list_record, decls);
5796 return objc_ivar_list_record;
5799 /* struct {
5800 struct _objc__method_prototype_list *method_next;
5801 int method_count;
5802 struct objc_method method_list[method_count];
5803 }; */
5805 static tree
5806 build_method_list_template (tree list_type, int size)
5808 tree objc_ivar_list_record;
5809 tree array_type, decls, *chain = NULL;
5811 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5813 /* struct _objc__method_prototype_list *method_next; */
5814 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
5816 /* int method_count; */
5817 add_field_decl (integer_type_node, "method_count", &chain);
5819 /* struct objc_method method_list[]; */
5820 array_type = build_sized_array_type (list_type, size);
5821 add_field_decl (array_type, "method_list", &chain);
5823 objc_finish_struct (objc_ivar_list_record, decls);
5825 return objc_ivar_list_record;
5828 static tree
5829 build_ivar_list_initializer (tree type, tree field_decl)
5831 VEC(constructor_elt,gc) *inits = NULL;
5835 VEC(constructor_elt,gc) *ivar = NULL;
5836 tree id;
5838 /* Set name. */
5839 if (DECL_NAME (field_decl))
5840 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
5841 add_objc_string (DECL_NAME (field_decl),
5842 meth_var_names));
5843 else
5844 /* Unnamed bit-field ivar (yuck). */
5845 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
5847 /* Set type. */
5848 encode_field_decl (field_decl,
5849 obstack_object_size (&util_obstack),
5850 OBJC_ENCODE_DONT_INLINE_DEFS);
5852 /* Null terminate string. */
5853 obstack_1grow (&util_obstack, 0);
5854 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5855 meth_var_types);
5856 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
5857 obstack_free (&util_obstack, util_firstobj);
5859 /* Set offset. */
5860 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
5861 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5862 objc_build_constructor (type, ivar));
5864 field_decl = DECL_CHAIN (field_decl);
5865 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5867 while (field_decl);
5869 return objc_build_constructor (build_array_type (type, 0), inits);
5872 static tree
5873 generate_ivars_list (tree type, const char *name, int size, tree list)
5875 tree decl;
5876 VEC(constructor_elt,gc) *inits = NULL;
5878 decl = start_var_decl (type, synth_id_with_class_suffix
5879 (name, objc_implementation_context));
5881 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
5882 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
5884 finish_var_decl (decl,
5885 objc_build_constructor (TREE_TYPE (decl), inits));
5887 return decl;
5890 /* Count only the fields occurring in T. */
5892 static int
5893 ivar_list_length (tree t)
5895 int count = 0;
5897 for (; t; t = DECL_CHAIN (t))
5898 if (TREE_CODE (t) == FIELD_DECL)
5899 ++count;
5901 return count;
5904 static void
5905 generate_ivar_lists (void)
5907 tree initlist, ivar_list_template, chain;
5908 int size;
5910 generating_instance_variables = 1;
5912 if (!objc_ivar_template)
5913 objc_ivar_template = build_ivar_template ();
5915 /* Only generate class variables for the root of the inheritance
5916 hierarchy since these will be the same for every class. */
5918 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5919 && (chain = TYPE_FIELDS (objc_class_template)))
5921 size = ivar_list_length (chain);
5923 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5924 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5926 UOBJC_CLASS_VARIABLES_decl
5927 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5928 size, initlist);
5930 else
5931 UOBJC_CLASS_VARIABLES_decl = 0;
5933 chain = CLASS_IVARS (implementation_template);
5934 if (chain)
5936 size = ivar_list_length (chain);
5937 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5938 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5940 UOBJC_INSTANCE_VARIABLES_decl
5941 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5942 size, initlist);
5944 else
5945 UOBJC_INSTANCE_VARIABLES_decl = 0;
5947 generating_instance_variables = 0;
5950 static tree
5951 build_dispatch_table_initializer (tree type, tree entries)
5953 VEC(constructor_elt,gc) *inits = NULL;
5957 VEC(constructor_elt,gc) *elems = NULL;
5958 tree expr;
5960 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5961 build_selector (METHOD_SEL_NAME (entries)));
5963 /* Generate the method encoding if we don't have one already. */
5964 if (! METHOD_ENCODING (entries))
5965 METHOD_ENCODING (entries) =
5966 encode_method_prototype (entries);
5968 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5969 add_objc_string (METHOD_ENCODING (entries),
5970 meth_var_types));
5972 expr = convert (ptr_type_node,
5973 build_unary_op (input_location, ADDR_EXPR,
5974 METHOD_DEFINITION (entries), 1));
5975 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
5977 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5978 objc_build_constructor (type, elems));
5980 entries = DECL_CHAIN (entries);
5982 while (entries);
5984 return objc_build_constructor (build_array_type (type, 0), inits);
5987 /* To accomplish method prototyping without generating all kinds of
5988 inane warnings, the definition of the dispatch table entries were
5989 changed from:
5991 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5993 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5995 static tree
5996 build_method_template (void)
5998 tree _SLT_record;
5999 tree decls, *chain = NULL;
6001 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
6003 /* SEL _cmd; */
6004 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6006 /* char *method_types; */
6007 add_field_decl (string_type_node, "method_types", &chain);
6009 /* void *_imp; */
6010 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6012 objc_finish_struct (_SLT_record, decls);
6014 return _SLT_record;
6018 static tree
6019 generate_dispatch_table (tree type, const char *name, int size, tree list)
6021 tree decl;
6022 VEC(constructor_elt,gc) *v = NULL;
6024 decl = start_var_decl (type, synth_id_with_class_suffix
6025 (name, objc_implementation_context));
6027 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6028 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6029 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6031 finish_var_decl (decl,
6032 objc_build_constructor (TREE_TYPE (decl), v));
6034 return decl;
6037 static void
6038 mark_referenced_methods (void)
6040 struct imp_entry *impent;
6041 tree chain;
6043 for (impent = imp_list; impent; impent = impent->next)
6045 chain = CLASS_CLS_METHODS (impent->imp_context);
6046 while (chain)
6048 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6049 chain = DECL_CHAIN (chain);
6052 chain = CLASS_NST_METHODS (impent->imp_context);
6053 while (chain)
6055 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6056 chain = DECL_CHAIN (chain);
6061 static void
6062 generate_dispatch_tables (void)
6064 tree initlist, chain, method_list_template;
6065 int size;
6067 if (!objc_method_template)
6068 objc_method_template = build_method_template ();
6070 chain = CLASS_CLS_METHODS (objc_implementation_context);
6071 if (chain)
6073 size = list_length (chain);
6075 method_list_template
6076 = build_method_list_template (objc_method_template, size);
6077 initlist
6078 = build_dispatch_table_initializer (objc_method_template, chain);
6080 UOBJC_CLASS_METHODS_decl
6081 = generate_dispatch_table (method_list_template,
6082 ((TREE_CODE (objc_implementation_context)
6083 == CLASS_IMPLEMENTATION_TYPE)
6084 ? "_OBJC_CLASS_METHODS"
6085 : "_OBJC_CATEGORY_CLASS_METHODS"),
6086 size, initlist);
6088 else
6089 UOBJC_CLASS_METHODS_decl = 0;
6091 chain = CLASS_NST_METHODS (objc_implementation_context);
6092 if (chain)
6094 size = list_length (chain);
6096 method_list_template
6097 = build_method_list_template (objc_method_template, size);
6098 initlist
6099 = build_dispatch_table_initializer (objc_method_template, chain);
6101 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6102 UOBJC_INSTANCE_METHODS_decl
6103 = generate_dispatch_table (method_list_template,
6104 "_OBJC_INSTANCE_METHODS",
6105 size, initlist);
6106 else
6107 /* We have a category. */
6108 UOBJC_INSTANCE_METHODS_decl
6109 = generate_dispatch_table (method_list_template,
6110 "_OBJC_CATEGORY_INSTANCE_METHODS",
6111 size, initlist);
6113 else
6114 UOBJC_INSTANCE_METHODS_decl = 0;
6117 static tree
6118 generate_protocol_list (tree i_or_p)
6120 tree array_type, ptype, refs_decl, lproto, e, plist;
6121 int size = 0;
6122 const char *ref_name;
6123 VEC(constructor_elt,gc) *v = NULL;
6125 switch (TREE_CODE (i_or_p))
6127 case CLASS_INTERFACE_TYPE:
6128 case CATEGORY_INTERFACE_TYPE:
6129 plist = CLASS_PROTOCOL_LIST (i_or_p);
6130 break;
6131 case PROTOCOL_INTERFACE_TYPE:
6132 plist = PROTOCOL_LIST (i_or_p);
6133 break;
6134 default:
6135 gcc_unreachable ();
6138 /* Compute size. */
6139 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6140 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
6141 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
6142 size++;
6144 /* Build initializer. */
6145 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6146 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
6147 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6149 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6151 tree pval = TREE_VALUE (lproto);
6153 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
6154 && PROTOCOL_FORWARD_DECL (pval))
6156 e = build_unary_op (input_location, ADDR_EXPR,
6157 PROTOCOL_FORWARD_DECL (pval), 0);
6158 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
6162 /* static struct objc_protocol *refs[n]; */
6164 switch (TREE_CODE (i_or_p))
6166 case PROTOCOL_INTERFACE_TYPE:
6167 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
6168 break;
6169 case CLASS_INTERFACE_TYPE:
6170 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
6171 break;
6172 case CATEGORY_INTERFACE_TYPE:
6173 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
6174 break;
6175 default:
6176 gcc_unreachable ();
6179 ptype = build_pointer_type (objc_protocol_template);
6180 array_type = build_sized_array_type (ptype, size + 3);
6181 refs_decl = start_var_decl (array_type, ref_name);
6183 finish_var_decl (refs_decl,
6184 objc_build_constructor (TREE_TYPE (refs_decl), v));
6186 return refs_decl;
6189 static tree
6190 build_category_initializer (tree type, tree cat_name, tree class_name,
6191 tree instance_methods, tree class_methods,
6192 tree protocol_list)
6194 tree expr;
6195 VEC(constructor_elt,gc) *v = NULL;
6197 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
6198 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
6200 if (!instance_methods)
6201 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6202 else
6204 expr = convert (objc_method_list_ptr,
6205 build_unary_op (input_location, ADDR_EXPR,
6206 instance_methods, 0));
6207 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6209 if (!class_methods)
6210 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6211 else
6213 expr = convert (objc_method_list_ptr,
6214 build_unary_op (input_location, ADDR_EXPR,
6215 class_methods, 0));
6216 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6219 /* protocol_list = */
6220 if (!protocol_list)
6221 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6222 else
6224 expr = convert (build_pointer_type
6225 (build_pointer_type
6226 (objc_protocol_template)),
6227 build_unary_op (input_location, ADDR_EXPR,
6228 protocol_list, 0));
6229 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6232 return objc_build_constructor (type, v);
6235 /* struct _objc_class {
6236 struct objc_class *isa;
6237 struct objc_class *super_class;
6238 char *name;
6239 long version;
6240 long info;
6241 long instance_size;
6242 struct objc_ivar_list *ivars;
6243 struct objc_method_list *methods;
6244 if (flag_next_runtime)
6245 struct objc_cache *cache;
6246 else {
6247 struct sarray *dtable;
6248 struct objc_class *subclass_list;
6249 struct objc_class *sibling_class;
6251 struct objc_protocol_list *protocols;
6252 if (flag_next_runtime)
6253 void *sel_id;
6254 void *gc_object_type;
6255 }; */
6257 static tree
6258 build_shared_structure_initializer (tree type, tree isa, tree super,
6259 tree name, tree size, int status,
6260 tree dispatch_table, tree ivar_list,
6261 tree protocol_list)
6263 tree expr;
6264 VEC(constructor_elt,gc) *v = NULL;
6266 /* isa = */
6267 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
6269 /* super_class = */
6270 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
6272 /* name = */
6273 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
6275 /* version = */
6276 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6277 build_int_cst (long_integer_type_node, 0));
6279 /* info = */
6280 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6281 build_int_cst (long_integer_type_node, status));
6283 /* instance_size = */
6284 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6285 convert (long_integer_type_node, size));
6287 /* objc_ivar_list = */
6288 if (!ivar_list)
6289 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6290 else
6292 expr = convert (objc_ivar_list_ptr,
6293 build_unary_op (input_location, ADDR_EXPR,
6294 ivar_list, 0));
6295 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6298 /* objc_method_list = */
6299 if (!dispatch_table)
6300 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6301 else
6303 expr = convert (objc_method_list_ptr,
6304 build_unary_op (input_location, ADDR_EXPR,
6305 dispatch_table, 0));
6306 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6309 if (flag_next_runtime)
6310 /* method_cache = */
6311 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6312 else
6314 /* dtable = */
6315 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6317 /* subclass_list = */
6318 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6320 /* sibling_class = */
6321 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6324 /* protocol_list = */
6325 if (! protocol_list)
6326 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6327 else
6329 expr = convert (build_pointer_type
6330 (build_pointer_type
6331 (objc_protocol_template)),
6332 build_unary_op (input_location, ADDR_EXPR,
6333 protocol_list, 0));
6334 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
6337 if (flag_next_runtime)
6338 /* sel_id = NULL */
6339 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6341 /* gc_object_type = NULL */
6342 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
6344 return objc_build_constructor (type, v);
6347 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
6349 static inline tree
6350 lookup_category (tree klass, tree cat_name)
6352 tree category = CLASS_CATEGORY_LIST (klass);
6354 while (category && CLASS_SUPER_NAME (category) != cat_name)
6355 category = CLASS_CATEGORY_LIST (category);
6356 return category;
6359 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
6361 static void
6362 generate_category (struct imp_entry *impent)
6364 tree initlist, cat_name_expr, class_name_expr;
6365 tree protocol_decl, category;
6366 tree cat = impent->imp_context;
6368 implementation_template = impent->imp_template;
6369 UOBJC_CLASS_decl = impent->class_decl;
6370 UOBJC_METACLASS_decl = impent->meta_decl;
6372 add_class_reference (CLASS_NAME (cat));
6373 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
6375 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
6377 category = lookup_category (implementation_template,
6378 CLASS_SUPER_NAME (cat));
6380 if (category && CLASS_PROTOCOL_LIST (category))
6382 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
6383 protocol_decl = generate_protocol_list (category);
6385 else
6386 protocol_decl = 0;
6388 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
6389 cat_name_expr, class_name_expr,
6390 UOBJC_INSTANCE_METHODS_decl,
6391 UOBJC_CLASS_METHODS_decl,
6392 protocol_decl);
6393 /* Finish and initialize the forward decl. */
6394 finish_var_decl (UOBJC_CLASS_decl, initlist);
6397 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
6398 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6400 static void
6401 generate_shared_structures (struct imp_entry *impent)
6403 tree name_expr, super_expr, root_expr;
6404 tree my_root_id, my_super_id;
6405 tree cast_type, initlist, protocol_decl;
6406 int cls_flags;
6408 objc_implementation_context = impent->imp_context;
6409 implementation_template = impent->imp_template;
6410 UOBJC_CLASS_decl = impent->class_decl;
6411 UOBJC_METACLASS_decl = impent->meta_decl;
6412 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
6414 my_super_id = CLASS_SUPER_NAME (implementation_template);
6415 if (my_super_id)
6417 add_class_reference (my_super_id);
6419 /* Compute "my_root_id" - this is required for code generation.
6420 the "isa" for all meta class structures points to the root of
6421 the inheritance hierarchy (e.g. "__Object")... */
6422 my_root_id = my_super_id;
6425 tree my_root_int = lookup_interface (my_root_id);
6427 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
6428 my_root_id = CLASS_SUPER_NAME (my_root_int);
6429 else
6430 break;
6432 while (1);
6434 else
6435 /* No super class. */
6436 my_root_id = CLASS_NAME (implementation_template);
6438 cast_type = build_pointer_type (objc_class_template);
6439 name_expr = add_objc_string (CLASS_NAME (implementation_template),
6440 class_names);
6442 /* Install class `isa' and `super' pointers at runtime. */
6443 if (my_super_id)
6444 super_expr = add_objc_string (my_super_id, class_names);
6445 else
6446 super_expr = integer_zero_node;
6448 super_expr = build_c_cast (input_location,
6449 cast_type, super_expr); /* cast! */
6451 root_expr = add_objc_string (my_root_id, class_names);
6452 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
6454 if (CLASS_PROTOCOL_LIST (implementation_template))
6456 generate_protocol_references
6457 (CLASS_PROTOCOL_LIST (implementation_template));
6458 protocol_decl = generate_protocol_list (implementation_template);
6460 else
6461 protocol_decl = 0;
6463 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
6465 initlist
6466 = build_shared_structure_initializer
6467 (TREE_TYPE (UOBJC_METACLASS_decl),
6468 root_expr, super_expr, name_expr,
6469 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
6470 2 /*CLS_META*/,
6471 UOBJC_CLASS_METHODS_decl,
6472 UOBJC_CLASS_VARIABLES_decl,
6473 protocol_decl);
6475 finish_var_decl (UOBJC_METACLASS_decl, initlist);
6477 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
6479 initlist
6480 = build_shared_structure_initializer
6481 (TREE_TYPE (UOBJC_CLASS_decl),
6482 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
6483 super_expr, name_expr,
6484 convert (integer_type_node,
6485 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
6486 (implementation_template))),
6487 1 /*CLS_FACTORY*/ | cls_flags,
6488 UOBJC_INSTANCE_METHODS_decl,
6489 UOBJC_INSTANCE_VARIABLES_decl,
6490 protocol_decl);
6492 finish_var_decl (UOBJC_CLASS_decl, initlist);
6496 static const char *
6497 synth_id_with_class_suffix (const char *preamble, tree ctxt)
6499 static char string[BUFSIZE];
6501 switch (TREE_CODE (ctxt))
6503 case CLASS_IMPLEMENTATION_TYPE:
6504 case CLASS_INTERFACE_TYPE:
6505 sprintf (string, "%s_%s", preamble,
6506 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
6507 break;
6508 case CATEGORY_IMPLEMENTATION_TYPE:
6509 case CATEGORY_INTERFACE_TYPE:
6511 /* We have a category. */
6512 const char *const class_name
6513 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
6514 const char *const class_super_name
6515 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
6516 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
6517 break;
6519 case PROTOCOL_INTERFACE_TYPE:
6521 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
6522 sprintf (string, "%s_%s", preamble, protocol_name);
6523 break;
6525 default:
6526 gcc_unreachable ();
6529 return string;
6532 /* If type is empty or only type qualifiers are present, add default
6533 type of id (otherwise grokdeclarator will default to int). */
6534 static inline tree
6535 adjust_type_for_id_default (tree type)
6537 if (!type)
6538 type = make_node (TREE_LIST);
6540 if (!TREE_VALUE (type))
6541 TREE_VALUE (type) = objc_object_type;
6542 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
6543 && TYPED_OBJECT (TREE_VALUE (type)))
6544 error ("can not use an object as parameter to a method");
6546 return type;
6549 /* Usage:
6550 keyworddecl:
6551 selector ':' '(' typename ')' identifier
6553 Purpose:
6554 Transform an Objective-C keyword argument into
6555 the C equivalent parameter declarator.
6557 In: key_name, an "identifier_node" (optional).
6558 arg_type, a "tree_list" (optional).
6559 arg_name, an "identifier_node".
6560 attributes, a optional tree containing param attributes.
6562 Note: It would be really nice to strongly type the preceding
6563 arguments in the function prototype; however, then I
6564 could not use the "accessor" macros defined in "tree.h".
6566 Out: an instance of "keyword_decl". */
6568 tree
6569 objc_build_keyword_decl (tree key_name, tree arg_type,
6570 tree arg_name, tree attributes)
6572 tree keyword_decl;
6574 if (attributes)
6575 warning_at (input_location, OPT_Wattributes,
6576 "method parameter attributes are not available in this "
6577 "version of the compiler, (ignored)");
6579 /* If no type is specified, default to "id". */
6580 arg_type = adjust_type_for_id_default (arg_type);
6582 keyword_decl = make_node (KEYWORD_DECL);
6584 TREE_TYPE (keyword_decl) = arg_type;
6585 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
6586 KEYWORD_KEY_NAME (keyword_decl) = key_name;
6588 return keyword_decl;
6591 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
6592 static tree
6593 build_keyword_selector (tree selector)
6595 int len = 0;
6596 tree key_chain, key_name;
6597 char *buf;
6599 /* Scan the selector to see how much space we'll need. */
6600 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6602 switch (TREE_CODE (selector))
6604 case KEYWORD_DECL:
6605 key_name = KEYWORD_KEY_NAME (key_chain);
6606 break;
6607 case TREE_LIST:
6608 key_name = TREE_PURPOSE (key_chain);
6609 break;
6610 default:
6611 gcc_unreachable ();
6614 if (key_name)
6615 len += IDENTIFIER_LENGTH (key_name) + 1;
6616 else
6617 /* Just a ':' arg. */
6618 len++;
6621 buf = (char *) alloca (len + 1);
6622 /* Start the buffer out as an empty string. */
6623 buf[0] = '\0';
6625 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6627 switch (TREE_CODE (selector))
6629 case KEYWORD_DECL:
6630 key_name = KEYWORD_KEY_NAME (key_chain);
6631 break;
6632 case TREE_LIST:
6633 key_name = TREE_PURPOSE (key_chain);
6634 /* The keyword decl chain will later be used as a function
6635 argument chain. Unhook the selector itself so as to not
6636 confuse other parts of the compiler. */
6637 TREE_PURPOSE (key_chain) = NULL_TREE;
6638 break;
6639 default:
6640 gcc_unreachable ();
6643 if (key_name)
6644 strcat (buf, IDENTIFIER_POINTER (key_name));
6645 strcat (buf, ":");
6648 return get_identifier (buf);
6651 /* Used for declarations and definitions. */
6653 static tree
6654 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6655 tree add_args, bool ellipsis)
6657 tree method_decl;
6659 /* If no type is specified, default to "id". */
6660 ret_type = adjust_type_for_id_default (ret_type);
6662 method_decl = make_node (code);
6663 TREE_TYPE (method_decl) = ret_type;
6665 /* If we have a keyword selector, create an identifier_node that
6666 represents the full selector name (`:' included)... */
6667 if (TREE_CODE (selector) == KEYWORD_DECL)
6669 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6670 METHOD_SEL_ARGS (method_decl) = selector;
6671 METHOD_ADD_ARGS (method_decl) = add_args;
6672 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6674 else
6676 METHOD_SEL_NAME (method_decl) = selector;
6677 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6678 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6681 return method_decl;
6684 #define METHOD_DEF 0
6685 #define METHOD_REF 1
6687 /* This routine processes objective-c method attributes. */
6689 static void
6690 objc_decl_method_attributes (tree *node, tree attributes, int flags)
6692 tree sentinel_attr = lookup_attribute ("sentinel", attributes);
6693 if (sentinel_attr)
6695 /* hackery to make an obj method look like a function type. */
6696 tree rettype = TREE_TYPE (*node);
6697 TREE_TYPE (*node) = build_function_type (TREE_VALUE (rettype),
6698 get_arg_type_list (*node, METHOD_REF, 0));
6699 decl_attributes (node, attributes, flags);
6700 METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
6701 TREE_TYPE (*node) = rettype;
6703 else
6704 decl_attributes (node, attributes, flags);
6707 bool
6708 objc_method_decl (enum tree_code opcode)
6710 return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
6713 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6714 an argument list for method METH. CONTEXT is either METHOD_DEF or
6715 METHOD_REF, saying whether we are trying to define a method or call
6716 one. SUPERFLAG says this is for a send to super; this makes a
6717 difference for the NeXT calling sequence in which the lookup and
6718 the method call are done together. If METH is null, user-defined
6719 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6721 static tree
6722 get_arg_type_list (tree meth, int context, int superflag)
6724 tree arglist, akey;
6726 /* Receiver type. */
6727 if (flag_next_runtime && superflag)
6728 arglist = build_tree_list (NULL_TREE, objc_super_type);
6729 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6730 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6731 else
6732 arglist = build_tree_list (NULL_TREE, objc_object_type);
6734 /* Selector type - will eventually change to `int'. */
6735 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6737 /* No actual method prototype given -- assume that remaining arguments
6738 are `...'. */
6739 if (!meth)
6740 return arglist;
6742 /* Build a list of argument types. */
6743 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
6745 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6747 /* Decay argument types for the underlying C function as appropriate. */
6748 arg_type = objc_decay_parm_type (arg_type);
6750 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6753 if (METHOD_ADD_ARGS (meth))
6755 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6756 akey; akey = TREE_CHAIN (akey))
6758 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6760 arg_type = objc_decay_parm_type (arg_type);
6762 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6765 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6766 goto lack_of_ellipsis;
6768 else
6770 lack_of_ellipsis:
6771 chainon (arglist, OBJC_VOID_AT_END);
6774 return arglist;
6777 static tree
6778 check_duplicates (hash hsh, int methods, int is_class)
6780 tree meth = NULL_TREE;
6782 if (hsh)
6784 meth = hsh->key;
6786 if (hsh->list)
6788 /* We have two or more methods with the same name but
6789 different types. */
6790 attr loop;
6792 /* But just how different are those types? If
6793 -Wno-strict-selector-match is specified, we shall not
6794 complain if the differences are solely among types with
6795 identical size and alignment. */
6796 if (!warn_strict_selector_match)
6798 for (loop = hsh->list; loop; loop = loop->next)
6799 if (!comp_proto_with_proto (meth, loop->value, 0))
6800 goto issue_warning;
6802 return meth;
6805 issue_warning:
6806 if (methods)
6808 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6810 warning_at (input_location, 0,
6811 "multiple methods named %<%c%E%> found",
6812 (is_class ? '+' : '-'),
6813 METHOD_SEL_NAME (meth));
6814 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6815 (type ? '-' : '+'),
6816 identifier_to_locale (gen_method_decl (meth)));
6818 else
6820 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6822 warning_at (input_location, 0,
6823 "multiple selectors named %<%c%E%> found",
6824 (is_class ? '+' : '-'),
6825 METHOD_SEL_NAME (meth));
6826 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6827 (type ? '-' : '+'),
6828 identifier_to_locale (gen_method_decl (meth)));
6831 for (loop = hsh->list; loop; loop = loop->next)
6833 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6835 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6836 (type ? '-' : '+'),
6837 identifier_to_locale (gen_method_decl (loop->value)));
6841 return meth;
6844 /* If RECEIVER is a class reference, return the identifier node for
6845 the referenced class. RECEIVER is created by objc_get_class_reference,
6846 so we check the exact form created depending on which runtimes are
6847 used. */
6849 static tree
6850 receiver_is_class_object (tree receiver, int self, int super)
6852 tree chain, exp, arg;
6854 /* The receiver is 'self' or 'super' in the context of a class method. */
6855 if (objc_method_context
6856 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6857 && (self || super))
6858 return (super
6859 ? CLASS_SUPER_NAME (implementation_template)
6860 : CLASS_NAME (implementation_template));
6862 if (flag_next_runtime)
6864 /* The receiver is a variable created by
6865 build_class_reference_decl. */
6866 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6867 /* Look up the identifier. */
6868 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6869 if (TREE_PURPOSE (chain) == receiver)
6870 return TREE_VALUE (chain);
6873 /* The receiver is a function call that returns an id. Check if
6874 it is a call to objc_getClass, if so, pick up the class name. */
6875 if (TREE_CODE (receiver) == CALL_EXPR
6876 && (exp = CALL_EXPR_FN (receiver))
6877 && TREE_CODE (exp) == ADDR_EXPR
6878 && (exp = TREE_OPERAND (exp, 0))
6879 && TREE_CODE (exp) == FUNCTION_DECL
6880 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6881 prototypes for objc_get_class(). Thankfully, they seem to share the
6882 same function type. */
6883 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6884 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6885 /* We have a call to objc_get_class/objc_getClass! */
6886 && (arg = CALL_EXPR_ARG (receiver, 0)))
6888 STRIP_NOPS (arg);
6889 if (TREE_CODE (arg) == ADDR_EXPR
6890 && (arg = TREE_OPERAND (arg, 0))
6891 && TREE_CODE (arg) == STRING_CST)
6892 /* Finally, we have the class name. */
6893 return get_identifier (TREE_STRING_POINTER (arg));
6895 return 0;
6898 /* If we are currently building a message expr, this holds
6899 the identifier of the selector of the message. This is
6900 used when printing warnings about argument mismatches. */
6902 static tree current_objc_message_selector = 0;
6904 tree
6905 objc_message_selector (void)
6907 return current_objc_message_selector;
6910 /* Construct an expression for sending a message.
6911 MESS has the object to send to in TREE_PURPOSE
6912 and the argument list (including selector) in TREE_VALUE.
6914 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6915 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6917 tree
6918 objc_build_message_expr (tree mess)
6920 tree receiver = TREE_PURPOSE (mess);
6921 tree sel_name;
6922 #ifdef OBJCPLUS
6923 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6924 #else
6925 tree args = TREE_VALUE (mess);
6926 #endif
6927 tree method_params = NULL_TREE;
6929 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6930 return error_mark_node;
6932 /* Obtain the full selector name. */
6933 switch (TREE_CODE (args))
6935 case IDENTIFIER_NODE:
6936 /* A unary selector. */
6937 sel_name = args;
6938 break;
6939 case TREE_LIST:
6940 sel_name = build_keyword_selector (args);
6941 break;
6942 default:
6943 gcc_unreachable ();
6946 /* Build the parameter list to give to the method. */
6947 if (TREE_CODE (args) == TREE_LIST)
6948 #ifdef OBJCPLUS
6949 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6950 #else
6952 tree chain = args, prev = NULL_TREE;
6954 /* We have a keyword selector--check for comma expressions. */
6955 while (chain)
6957 tree element = TREE_VALUE (chain);
6959 /* We have a comma expression, must collapse... */
6960 if (TREE_CODE (element) == TREE_LIST)
6962 if (prev)
6963 TREE_CHAIN (prev) = element;
6964 else
6965 args = element;
6967 prev = chain;
6968 chain = TREE_CHAIN (chain);
6970 method_params = args;
6972 #endif
6974 #ifdef OBJCPLUS
6975 if (processing_template_decl)
6976 /* Must wait until template instantiation time. */
6977 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6978 method_params);
6979 #endif
6981 return objc_finish_message_expr (receiver, sel_name, method_params);
6984 /* Look up method SEL_NAME that would be suitable for receiver
6985 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6986 nonzero), and report on any duplicates. */
6988 static tree
6989 lookup_method_in_hash_lists (tree sel_name, int is_class)
6991 hash method_prototype = NULL;
6993 if (!is_class)
6994 method_prototype = hash_lookup (nst_method_hash_list,
6995 sel_name);
6997 if (!method_prototype)
6999 method_prototype = hash_lookup (cls_method_hash_list,
7000 sel_name);
7001 is_class = 1;
7004 return check_duplicates (method_prototype, 1, is_class);
7007 /* The 'objc_finish_message_expr' routine is called from within
7008 'objc_build_message_expr' for non-template functions. In the case of
7009 C++ template functions, it is called from 'build_expr_from_tree'
7010 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
7012 tree
7013 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
7015 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
7016 tree selector, retval, class_tree;
7017 int self, super, have_cast;
7019 /* We have used the receiver, so mark it as read. */
7020 mark_exp_read (receiver);
7022 /* Extract the receiver of the message, as well as its type
7023 (where the latter may take the form of a cast or be inferred
7024 from the implementation context). */
7025 rtype = receiver;
7026 while (TREE_CODE (rtype) == COMPOUND_EXPR
7027 || TREE_CODE (rtype) == MODIFY_EXPR
7028 || CONVERT_EXPR_P (rtype)
7029 || TREE_CODE (rtype) == COMPONENT_REF)
7030 rtype = TREE_OPERAND (rtype, 0);
7032 self = (rtype == self_decl);
7033 super = (rtype == UOBJC_SUPER_decl);
7034 rtype = TREE_TYPE (receiver);
7036 have_cast = (TREE_CODE (receiver) == NOP_EXPR
7037 || (TREE_CODE (receiver) == COMPOUND_EXPR
7038 && !IS_SUPER (rtype)));
7040 /* If we are calling [super dealloc], reset our warning flag. */
7041 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
7042 should_call_super_dealloc = 0;
7044 /* If the receiver is a class object, retrieve the corresponding
7045 @interface, if one exists. */
7046 class_tree = receiver_is_class_object (receiver, self, super);
7048 /* Now determine the receiver type (if an explicit cast has not been
7049 provided). */
7050 if (!have_cast)
7052 if (class_tree)
7053 rtype = lookup_interface (class_tree);
7054 /* Handle `self' and `super'. */
7055 else if (super)
7057 if (!CLASS_SUPER_NAME (implementation_template))
7059 error ("no super class declared in @interface for %qE",
7060 CLASS_NAME (implementation_template));
7061 return error_mark_node;
7063 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
7065 else if (self)
7066 rtype = lookup_interface (CLASS_NAME (implementation_template));
7069 /* If receiver is of type `id' or `Class' (or if the @interface for a
7070 class is not visible), we shall be satisfied with the existence of
7071 any instance or class method. */
7072 if (objc_is_id (rtype))
7074 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
7075 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
7076 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
7077 : NULL_TREE);
7078 rtype = NULL_TREE;
7080 if (rprotos)
7082 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
7083 in protocols themselves for the method prototype. */
7084 method_prototype
7085 = lookup_method_in_protocol_list (rprotos, sel_name,
7086 class_tree != NULL_TREE);
7088 /* If messaging 'Class <Proto>' but did not find a class method
7089 prototype, search for an instance method instead, and warn
7090 about having done so. */
7091 if (!method_prototype && !rtype && class_tree != NULL_TREE)
7093 method_prototype
7094 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7096 if (method_prototype)
7097 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
7098 sel_name, sel_name);
7102 else if (rtype)
7104 tree orig_rtype = rtype;
7106 if (TREE_CODE (rtype) == POINTER_TYPE)
7107 rtype = TREE_TYPE (rtype);
7108 /* Traverse typedef aliases */
7109 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
7110 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
7111 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
7112 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
7113 if (TYPED_OBJECT (rtype))
7115 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
7116 rtype = TYPE_OBJC_INTERFACE (rtype);
7118 /* If we could not find an @interface declaration, we must have
7119 only seen a @class declaration; so, we cannot say anything
7120 more intelligent about which methods the receiver will
7121 understand. */
7122 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
7124 rtype = NULL_TREE;
7125 /* We could not find an @interface declaration, yet Message maybe in a
7126 @class's protocol. */
7127 if (!method_prototype && rprotos)
7128 method_prototype
7129 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
7131 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
7132 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
7134 /* We have a valid ObjC class name. Look up the method name
7135 in the published @interface for the class (and its
7136 superclasses). */
7137 method_prototype
7138 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
7140 /* If the method was not found in the @interface, it may still
7141 exist locally as part of the @implementation. */
7142 if (!method_prototype && objc_implementation_context
7143 && CLASS_NAME (objc_implementation_context)
7144 == OBJC_TYPE_NAME (rtype))
7145 method_prototype
7146 = lookup_method
7147 ((class_tree
7148 ? CLASS_CLS_METHODS (objc_implementation_context)
7149 : CLASS_NST_METHODS (objc_implementation_context)),
7150 sel_name);
7152 /* If we haven't found a candidate method by now, try looking for
7153 it in the protocol list. */
7154 if (!method_prototype && rprotos)
7155 method_prototype
7156 = lookup_method_in_protocol_list (rprotos, sel_name,
7157 class_tree != NULL_TREE);
7159 else
7161 warning (0, "invalid receiver type %qs",
7162 identifier_to_locale (gen_type_name (orig_rtype)));
7163 /* After issuing the "invalid receiver" warning, perform method
7164 lookup as if we were messaging 'id'. */
7165 rtype = rprotos = NULL_TREE;
7170 /* For 'id' or 'Class' receivers, search in the global hash table
7171 as a last resort. For all receivers, warn if protocol searches
7172 have failed. */
7173 if (!method_prototype)
7175 if (rprotos)
7176 warning (0, "%<%c%E%> not found in protocol(s)",
7177 (class_tree ? '+' : '-'),
7178 sel_name);
7180 if (!rtype)
7181 method_prototype
7182 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
7185 if (!method_prototype && in_objc_property_setter_name_context)
7186 error ("readonly property can not be set");
7187 else if (!method_prototype)
7189 static bool warn_missing_methods = false;
7191 if (rtype)
7192 warning (0, "%qE may not respond to %<%c%E%>",
7193 OBJC_TYPE_NAME (rtype),
7194 (class_tree ? '+' : '-'),
7195 sel_name);
7196 /* If we are messaging an 'id' or 'Class' object and made it here,
7197 then we have failed to find _any_ instance or class method,
7198 respectively. */
7199 else
7200 warning (0, "no %<%c%E%> method found",
7201 (class_tree ? '+' : '-'),
7202 sel_name);
7204 if (!warn_missing_methods)
7206 warning_at (input_location,
7207 0, "(Messages without a matching method signature");
7208 warning_at (input_location,
7209 0, "will be assumed to return %<id%> and accept");
7210 warning_at (input_location,
7211 0, "%<...%> as arguments.)");
7212 warn_missing_methods = true;
7216 /* Save the selector name for printing error messages. */
7217 current_objc_message_selector = sel_name;
7219 /* Build the parameters list for looking up the method.
7220 These are the object itself and the selector. */
7222 if (flag_typed_selectors)
7223 selector = build_typed_selector_reference (input_location,
7224 sel_name, method_prototype);
7225 else
7226 selector = build_selector_reference (input_location, sel_name);
7228 retval = build_objc_method_call (input_location, super, method_prototype,
7229 receiver,
7230 selector, method_params);
7232 current_objc_message_selector = 0;
7234 return retval;
7237 /* Build a tree expression to send OBJECT the operation SELECTOR,
7238 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
7239 assuming the method has prototype METHOD_PROTOTYPE.
7240 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
7241 LOC is the location of the expression to build.
7242 Use METHOD_PARAMS as list of args to pass to the method.
7243 If SUPER_FLAG is nonzero, we look up the superclass's method. */
7245 static tree
7246 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
7247 tree lookup_object, tree selector,
7248 tree method_params)
7250 tree sender = (super_flag ? umsg_super_decl :
7251 (!flag_next_runtime || flag_nil_receivers
7252 ? (flag_objc_direct_dispatch
7253 ? umsg_fast_decl
7254 : umsg_decl)
7255 : umsg_nonnil_decl));
7256 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
7257 VEC(tree, gc) *parms = NULL;
7258 unsigned nparm = (method_params ? list_length (method_params) : 0);
7260 /* If a prototype for the method to be called exists, then cast
7261 the sender's return type and arguments to match that of the method.
7262 Otherwise, leave sender as is. */
7263 tree ret_type
7264 = (method_prototype
7265 ? TREE_VALUE (TREE_TYPE (method_prototype))
7266 : objc_object_type);
7268 tree method_param_types =
7269 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
7270 tree ftype = build_function_type (ret_type, method_param_types);
7271 tree sender_cast;
7272 tree method, t;
7274 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
7275 ftype = build_type_attribute_variant (
7276 ftype, METHOD_TYPE_ATTRIBUTES (method_prototype));
7278 sender_cast = build_pointer_type (ftype);
7280 if (method_prototype && TREE_DEPRECATED (method_prototype))
7281 objc_warn_deprecated_use (method_prototype, NULL_TREE);
7283 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
7285 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
7286 lookup_object = save_expr (lookup_object);
7288 /* Param list + 2 slots for object and selector. */
7289 parms = VEC_alloc (tree, gc, nparm + 2);
7291 if (flag_next_runtime)
7293 /* If we are returning a struct in memory, and the address
7294 of that memory location is passed as a hidden first
7295 argument, then change which messenger entry point this
7296 expr will call. NB: Note that sender_cast remains
7297 unchanged (it already has a struct return type). */
7298 if (!targetm.calls.struct_value_rtx (0, 0)
7299 && (TREE_CODE (ret_type) == RECORD_TYPE
7300 || TREE_CODE (ret_type) == UNION_TYPE)
7301 && targetm.calls.return_in_memory (ret_type, 0))
7302 sender = (super_flag ? umsg_super_stret_decl :
7303 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
7305 method = build_fold_addr_expr_loc (input_location, sender);
7306 /* Pass the object to the method. */
7307 VEC_quick_push (tree, parms, lookup_object);
7309 else
7311 /* This is the portable (GNU) way. */
7312 /* First, call the lookup function to get a pointer to the method,
7313 then cast the pointer, then call it with the method arguments. */
7314 VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
7315 VEC_quick_push (tree, tv, lookup_object);
7316 VEC_quick_push (tree, tv, selector);
7317 method = build_function_call_vec (loc, sender, tv, NULL);
7318 VEC_free (tree, gc, tv);
7320 /* Pass the appropriate object to the method. */
7321 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
7324 /* Pass the selector to the method. */
7325 VEC_quick_push (tree, parms, selector);
7326 /* Now append the remainder of the parms. */
7327 if (nparm)
7328 for (; method_params; method_params = TREE_CHAIN (method_params))
7329 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
7331 /* Build an obj_type_ref, with the correct cast for the method call. */
7332 t = build3 (OBJ_TYPE_REF, sender_cast, method,
7333 lookup_object, size_zero_node);
7334 t = build_function_call_vec (loc, t, parms, NULL);\
7335 VEC_free (tree, gc, parms);
7336 return t;
7339 static void
7340 build_protocol_reference (tree p)
7342 tree decl;
7343 const char *proto_name;
7345 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
7347 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
7348 decl = start_var_decl (objc_protocol_template, proto_name);
7350 PROTOCOL_FORWARD_DECL (p) = decl;
7353 /* This function is called by the parser when (and only when) a
7354 @protocol() expression is found, in order to compile it. */
7355 tree
7356 objc_build_protocol_expr (tree protoname)
7358 tree expr;
7359 tree p = lookup_protocol (protoname);
7361 if (!p)
7363 error ("cannot find protocol declaration for %qE",
7364 protoname);
7365 return error_mark_node;
7368 if (!PROTOCOL_FORWARD_DECL (p))
7369 build_protocol_reference (p);
7371 expr = build_unary_op (input_location,
7372 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
7374 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
7375 if we have it, rather than converting it here. */
7376 expr = convert (objc_protocol_type, expr);
7378 /* The @protocol() expression is being compiled into a pointer to a
7379 statically allocated instance of the Protocol class. To become
7380 usable at runtime, the 'isa' pointer of the instance need to be
7381 fixed up at runtime by the runtime library, to point to the
7382 actual 'Protocol' class. */
7384 /* For the GNU runtime, put the static Protocol instance in the list
7385 of statically allocated instances, so that we make sure that its
7386 'isa' pointer is fixed up at runtime by the GNU runtime library
7387 to point to the Protocol class (at runtime, when loading the
7388 module, the GNU runtime library loops on the statically allocated
7389 instances (as found in the defs field in objc_symtab) and fixups
7390 all the 'isa' pointers of those objects). */
7391 if (! flag_next_runtime)
7393 /* This type is a struct containing the fields of a Protocol
7394 object. (Cfr. objc_protocol_type instead is the type of a pointer
7395 to such a struct). */
7396 tree protocol_struct_type = xref_tag
7397 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
7398 tree *chain;
7400 /* Look for the list of Protocol statically allocated instances
7401 to fixup at runtime. Create a new list to hold Protocol
7402 statically allocated instances, if the list is not found. At
7403 present there is only another list, holding NSConstantString
7404 static instances to be fixed up at runtime. */
7405 for (chain = &objc_static_instances;
7406 *chain && TREE_VALUE (*chain) != protocol_struct_type;
7407 chain = &TREE_CHAIN (*chain));
7408 if (!*chain)
7410 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
7411 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
7412 class_names);
7415 /* Add this statically allocated instance to the Protocol list. */
7416 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
7417 PROTOCOL_FORWARD_DECL (p),
7418 TREE_PURPOSE (*chain));
7422 return expr;
7425 /* This function is called by the parser when a @selector() expression
7426 is found, in order to compile it. It is only called by the parser
7427 and only to compile a @selector(). LOC is the location of the
7428 @selector. */
7429 tree
7430 objc_build_selector_expr (location_t loc, tree selnamelist)
7432 tree selname;
7434 /* Obtain the full selector name. */
7435 switch (TREE_CODE (selnamelist))
7437 case IDENTIFIER_NODE:
7438 /* A unary selector. */
7439 selname = selnamelist;
7440 break;
7441 case TREE_LIST:
7442 selname = build_keyword_selector (selnamelist);
7443 break;
7444 default:
7445 gcc_unreachable ();
7448 /* If we are required to check @selector() expressions as they
7449 are found, check that the selector has been declared. */
7450 if (warn_undeclared_selector)
7452 /* Look the selector up in the list of all known class and
7453 instance methods (up to this line) to check that the selector
7454 exists. */
7455 hash hsh;
7457 /* First try with instance methods. */
7458 hsh = hash_lookup (nst_method_hash_list, selname);
7460 /* If not found, try with class methods. */
7461 if (!hsh)
7463 hsh = hash_lookup (cls_method_hash_list, selname);
7466 /* If still not found, print out a warning. */
7467 if (!hsh)
7469 warning (0, "undeclared selector %qE", selname);
7474 if (flag_typed_selectors)
7475 return build_typed_selector_reference (loc, selname, 0);
7476 else
7477 return build_selector_reference (loc, selname);
7480 /* This is used to implement @encode(). See gcc/doc/objc.texi,
7481 section '@encode'. */
7482 tree
7483 objc_build_encode_expr (tree type)
7485 tree result;
7486 const char *string;
7488 encode_type (type, obstack_object_size (&util_obstack),
7489 OBJC_ENCODE_INLINE_DEFS);
7490 obstack_1grow (&util_obstack, 0); /* null terminate string */
7491 string = XOBFINISH (&util_obstack, const char *);
7493 /* Synthesize a string that represents the encoded struct/union. */
7494 result = my_build_string (strlen (string) + 1, string);
7495 obstack_free (&util_obstack, util_firstobj);
7496 return result;
7499 static tree
7500 build_ivar_reference (tree id)
7502 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7504 /* Historically, a class method that produced objects (factory
7505 method) would assign `self' to the instance that it
7506 allocated. This would effectively turn the class method into
7507 an instance method. Following this assignment, the instance
7508 variables could be accessed. That practice, while safe,
7509 violates the simple rule that a class method should not refer
7510 to an instance variable. It's better to catch the cases
7511 where this is done unknowingly than to support the above
7512 paradigm. */
7513 warning (0, "instance variable %qE accessed in class method",
7514 id);
7515 self_decl = convert (objc_instance_type, self_decl); /* cast */
7518 return objc_build_component_ref (build_indirect_ref (input_location,
7519 self_decl, RO_ARROW),
7520 id);
7523 /* Compute a hash value for a given method SEL_NAME. */
7525 static size_t
7526 hash_func (tree sel_name)
7528 const unsigned char *s
7529 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
7530 size_t h = 0;
7532 while (*s)
7533 h = h * 67 + *s++ - 113;
7534 return h;
7537 static void
7538 hash_init (void)
7540 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7541 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7543 cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7544 als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
7546 /* Initialize the hash table used to hold the constant string objects. */
7547 string_htab = htab_create_ggc (31, string_hash,
7548 string_eq, NULL);
7551 /* This routine adds sel_name to the hash list. sel_name is a class or alias
7552 name for the class. If alias name, then value is its underlying class.
7553 If class, the value is NULL_TREE. */
7555 static void
7556 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
7558 hash obj;
7559 int slot = hash_func (sel_name) % SIZEHASHTABLE;
7561 obj = ggc_alloc_hashed_entry ();
7562 if (value != NULL_TREE)
7564 /* Save the underlying class for the 'alias' in the hash table */
7565 attr obj_attr = ggc_alloc_hashed_attribute ();
7566 obj_attr->value = value;
7567 obj->list = obj_attr;
7569 else
7570 obj->list = 0;
7571 obj->next = hashlist[slot];
7572 obj->key = sel_name;
7574 hashlist[slot] = obj; /* append to front */
7579 Searches in the hash table looking for a match for class or alias name.
7582 static hash
7583 hash_class_name_lookup (hash *hashlist, tree sel_name)
7585 hash target;
7587 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7589 while (target)
7591 if (sel_name == target->key)
7592 return target;
7594 target = target->next;
7596 return 0;
7599 /* WARNING!!!! hash_enter is called with a method, and will peek
7600 inside to find its selector! But hash_lookup is given a selector
7601 directly, and looks for the selector that's inside the found
7602 entry's key (method) for comparison. */
7604 static void
7605 hash_enter (hash *hashlist, tree method)
7607 hash obj;
7608 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
7610 obj = ggc_alloc_hashed_entry ();
7611 obj->list = 0;
7612 obj->next = hashlist[slot];
7613 obj->key = method;
7615 hashlist[slot] = obj; /* append to front */
7618 static hash
7619 hash_lookup (hash *hashlist, tree sel_name)
7621 hash target;
7623 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
7625 while (target)
7627 if (sel_name == METHOD_SEL_NAME (target->key))
7628 return target;
7630 target = target->next;
7632 return 0;
7635 static void
7636 hash_add_attr (hash entry, tree value)
7638 attr obj;
7640 obj = ggc_alloc_hashed_attribute ();
7641 obj->next = entry->list;
7642 obj->value = value;
7644 entry->list = obj; /* append to front */
7647 static tree
7648 lookup_method (tree mchain, tree method)
7650 tree key;
7652 if (TREE_CODE (method) == IDENTIFIER_NODE)
7653 key = method;
7654 else
7655 key = METHOD_SEL_NAME (method);
7657 while (mchain)
7659 if (METHOD_SEL_NAME (mchain) == key)
7660 return mchain;
7662 mchain = DECL_CHAIN (mchain);
7664 return NULL_TREE;
7667 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
7668 in INTERFACE, along with any categories and protocols attached thereto.
7669 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
7670 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
7671 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
7672 be found in INTERFACE or any of its superclasses, look for an _instance_
7673 method of the same name in the root class as a last resort.
7675 If a suitable method cannot be found, return NULL_TREE. */
7677 static tree
7678 lookup_method_static (tree interface, tree ident, int flags)
7680 tree meth = NULL_TREE, root_inter = NULL_TREE;
7681 tree inter = interface;
7682 int is_class = (flags & OBJC_LOOKUP_CLASS);
7683 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
7685 while (inter)
7687 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
7688 tree category = inter;
7690 /* First, look up the method in the class itself. */
7691 if ((meth = lookup_method (chain, ident)))
7692 return meth;
7694 /* Failing that, look for the method in each category of the class. */
7695 while ((category = CLASS_CATEGORY_LIST (category)))
7697 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
7699 /* Check directly in each category. */
7700 if ((meth = lookup_method (chain, ident)))
7701 return meth;
7703 /* Failing that, check in each category's protocols. */
7704 if (CLASS_PROTOCOL_LIST (category))
7706 if ((meth = (lookup_method_in_protocol_list
7707 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
7708 return meth;
7712 /* If not found in categories, check in protocols of the main class. */
7713 if (CLASS_PROTOCOL_LIST (inter))
7715 if ((meth = (lookup_method_in_protocol_list
7716 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
7717 return meth;
7720 /* If we were instructed not to look in superclasses, don't. */
7721 if (no_superclasses)
7722 return NULL_TREE;
7724 /* Failing that, climb up the inheritance hierarchy. */
7725 root_inter = inter;
7726 inter = lookup_interface (CLASS_SUPER_NAME (inter));
7728 while (inter);
7730 /* If no class (factory) method was found, check if an _instance_
7731 method of the same name exists in the root class. This is what
7732 the Objective-C runtime will do. If an instance method was not
7733 found, return 0. */
7734 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
7737 /* Add the method to the hash list if it doesn't contain an identical
7738 method already. */
7740 static void
7741 add_method_to_hash_list (hash *hash_list, tree method)
7743 hash hsh;
7745 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7747 /* Install on a global chain. */
7748 hash_enter (hash_list, method);
7750 else
7752 /* Check types against those; if different, add to a list. */
7753 attr loop;
7754 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7755 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7756 already_there |= comp_proto_with_proto (method, loop->value, 1);
7757 if (!already_there)
7758 hash_add_attr (hsh, method);
7762 static tree
7763 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
7765 tree mth;
7767 /* @optional methods are added to protocol's OPTIONAL list */
7768 if (is_optional)
7770 gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
7771 if (!(mth = lookup_method (is_class
7772 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
7773 : PROTOCOL_OPTIONAL_NST_METHODS (klass),
7774 method)))
7776 if (is_class)
7778 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
7779 PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
7781 else
7783 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
7784 PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
7788 else if (!(mth = lookup_method (is_class
7789 ? CLASS_CLS_METHODS (klass)
7790 : CLASS_NST_METHODS (klass), method)))
7792 /* put method on list in reverse order */
7793 if (is_class)
7795 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
7796 CLASS_CLS_METHODS (klass) = method;
7798 else
7800 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
7801 CLASS_NST_METHODS (klass) = method;
7804 else
7806 /* When processing an @interface for a class or category, give hard
7807 errors on methods with identical selectors but differing argument
7808 and/or return types. We do not do this for @implementations, because
7809 C/C++ will do it for us (i.e., there will be duplicate function
7810 definition errors). */
7811 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7812 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7813 && !comp_proto_with_proto (method, mth, 1))
7814 error ("duplicate declaration of method %<%c%E%>",
7815 is_class ? '+' : '-',
7816 METHOD_SEL_NAME (mth));
7819 if (is_class)
7820 add_method_to_hash_list (cls_method_hash_list, method);
7821 else
7823 add_method_to_hash_list (nst_method_hash_list, method);
7825 /* Instance methods in root classes (and categories thereof)
7826 may act as class methods as a last resort. We also add
7827 instance methods listed in @protocol declarations to
7828 the class hash table, on the assumption that @protocols
7829 may be adopted by root classes or categories. */
7830 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7831 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7832 klass = lookup_interface (CLASS_NAME (klass));
7834 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7835 || !CLASS_SUPER_NAME (klass))
7836 add_method_to_hash_list (cls_method_hash_list, method);
7839 return method;
7842 static tree
7843 add_class (tree class_name, tree name)
7845 struct interface_tuple **slot;
7847 /* Put interfaces on list in reverse order. */
7848 TREE_CHAIN (class_name) = interface_chain;
7849 interface_chain = class_name;
7851 if (interface_htab == NULL)
7852 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7853 slot = (struct interface_tuple **)
7854 htab_find_slot_with_hash (interface_htab, name,
7855 IDENTIFIER_HASH_VALUE (name),
7856 INSERT);
7857 if (!*slot)
7859 *slot = ggc_alloc_cleared_interface_tuple ();
7860 (*slot)->id = name;
7862 (*slot)->class_name = class_name;
7864 return interface_chain;
7867 static void
7868 add_category (tree klass, tree category)
7870 /* Put categories on list in reverse order. */
7871 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7873 if (cat)
7875 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7876 CLASS_NAME (klass),
7877 CLASS_SUPER_NAME (category));
7879 else
7881 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7882 CLASS_CATEGORY_LIST (klass) = category;
7886 /* Called after parsing each instance variable declaration. Necessary to
7887 preserve typedefs and implement public/private...
7889 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7891 static tree
7892 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
7893 tree field_decl)
7895 tree field_type = TREE_TYPE (field_decl);
7896 const char *ivar_name = DECL_NAME (field_decl)
7897 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7898 : _("<unnamed>");
7900 #ifdef OBJCPLUS
7901 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7903 error ("illegal reference type specified for instance variable %qs",
7904 ivar_name);
7905 /* Return class as is without adding this ivar. */
7906 return klass;
7908 #endif
7910 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7911 || TYPE_SIZE (field_type) == error_mark_node)
7912 /* 'type[0]' is allowed, but 'type[]' is not! */
7914 error ("instance variable %qs has unknown size", ivar_name);
7915 /* Return class as is without adding this ivar. */
7916 return klass;
7919 #ifdef OBJCPLUS
7920 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7921 need to either (1) warn the user about it or (2) generate suitable
7922 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7923 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7924 if (MAYBE_CLASS_TYPE_P (field_type)
7925 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7926 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7927 || TYPE_POLYMORPHIC_P (field_type)))
7929 tree type_name = OBJC_TYPE_NAME (field_type);
7931 if (flag_objc_call_cxx_cdtors)
7933 /* Since the ObjC runtime will be calling the constructors and
7934 destructors for us, the only thing we can't handle is the lack
7935 of a default constructor. */
7936 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7937 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7939 warning (0, "type %qE has no default constructor to call",
7940 type_name);
7942 /* If we cannot call a constructor, we should also avoid
7943 calling the destructor, for symmetry. */
7944 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7945 warning (0, "destructor for %qE shall not be run either",
7946 type_name);
7949 else
7951 static bool warn_cxx_ivars = false;
7953 if (TYPE_POLYMORPHIC_P (field_type))
7955 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7956 initialize them. */
7957 error ("type %qE has virtual member functions", type_name);
7958 error ("illegal aggregate type %qE specified "
7959 "for instance variable %qs",
7960 type_name, ivar_name);
7961 /* Return class as is without adding this ivar. */
7962 return klass;
7965 /* User-defined constructors and destructors are not known to Obj-C
7966 and hence will not be called. This may or may not be a problem. */
7967 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7968 warning (0, "type %qE has a user-defined constructor", type_name);
7969 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7970 warning (0, "type %qE has a user-defined destructor", type_name);
7972 if (!warn_cxx_ivars)
7974 warning (0, "C++ constructors and destructors will not "
7975 "be invoked for Objective-C fields");
7976 warn_cxx_ivars = true;
7980 #endif
7982 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7983 switch (visibility)
7985 case OBJC_IVAR_VIS_PROTECTED:
7986 TREE_PUBLIC (field_decl) = 0;
7987 TREE_PRIVATE (field_decl) = 0;
7988 TREE_PROTECTED (field_decl) = 1;
7989 break;
7991 case OBJC_IVAR_VIS_PACKAGE:
7992 /* TODO: Implement the package variant. */
7993 case OBJC_IVAR_VIS_PUBLIC:
7994 TREE_PUBLIC (field_decl) = 1;
7995 TREE_PRIVATE (field_decl) = 0;
7996 TREE_PROTECTED (field_decl) = 0;
7997 break;
7999 case OBJC_IVAR_VIS_PRIVATE:
8000 TREE_PUBLIC (field_decl) = 0;
8001 TREE_PRIVATE (field_decl) = 1;
8002 TREE_PROTECTED (field_decl) = 0;
8003 break;
8007 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
8009 return klass;
8012 static tree
8013 is_ivar (tree decl_chain, tree ident)
8015 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
8016 if (DECL_NAME (decl_chain) == ident)
8017 return decl_chain;
8018 return NULL_TREE;
8021 /* True if the ivar is private and we are not in its implementation. */
8023 static int
8024 is_private (tree decl)
8026 return (TREE_PRIVATE (decl)
8027 && ! is_ivar (CLASS_IVARS (implementation_template),
8028 DECL_NAME (decl)));
8031 /* We have an instance variable reference;, check to see if it is public. */
8034 objc_is_public (tree expr, tree identifier)
8036 tree basetype, decl;
8038 #ifdef OBJCPLUS
8039 if (processing_template_decl)
8040 return 1;
8041 #endif
8043 if (TREE_TYPE (expr) == error_mark_node)
8044 return 1;
8046 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
8048 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
8050 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
8052 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
8054 if (!klass)
8056 error ("cannot find interface declaration for %qE",
8057 OBJC_TYPE_NAME (basetype));
8058 return 0;
8061 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
8063 if (TREE_PUBLIC (decl))
8064 return 1;
8066 /* Important difference between the Stepstone translator:
8067 all instance variables should be public within the context
8068 of the implementation. */
8069 if (objc_implementation_context
8070 && ((TREE_CODE (objc_implementation_context)
8071 == CLASS_IMPLEMENTATION_TYPE)
8072 || (TREE_CODE (objc_implementation_context)
8073 == CATEGORY_IMPLEMENTATION_TYPE)))
8075 tree curtype = TYPE_MAIN_VARIANT
8076 (CLASS_STATIC_TEMPLATE
8077 (implementation_template));
8079 if (basetype == curtype
8080 || DERIVED_FROM_P (basetype, curtype))
8082 int priv = is_private (decl);
8084 if (priv)
8085 error ("instance variable %qE is declared private",
8086 DECL_NAME (decl));
8088 return !priv;
8092 /* The 2.95.2 compiler sometimes allowed C functions to access
8093 non-@public ivars. We will let this slide for now... */
8094 if (!objc_method_context)
8096 warning (0, "instance variable %qE is %s; "
8097 "this will be a hard error in the future",
8098 identifier,
8099 TREE_PRIVATE (decl) ? "@private" : "@protected");
8100 return 1;
8103 error ("instance variable %qE is declared %s",
8104 identifier,
8105 TREE_PRIVATE (decl) ? "private" : "protected");
8106 return 0;
8111 return 1;
8114 /* Make sure all entries in CHAIN are also in LIST. */
8116 static int
8117 check_methods (tree chain, tree list, int mtype)
8119 int first = 1;
8121 while (chain)
8123 if (!lookup_method (list, chain))
8125 if (first)
8127 switch (TREE_CODE (objc_implementation_context))
8129 case CLASS_IMPLEMENTATION_TYPE:
8130 warning (0, "incomplete implementation of class %qE",
8131 CLASS_NAME (objc_implementation_context));
8132 break;
8133 case CATEGORY_IMPLEMENTATION_TYPE:
8134 warning (0, "incomplete implementation of category %qE",
8135 CLASS_SUPER_NAME (objc_implementation_context));
8136 break;
8137 default:
8138 gcc_unreachable ();
8140 first = 0;
8143 warning (0, "method definition for %<%c%E%> not found",
8144 mtype, METHOD_SEL_NAME (chain));
8147 chain = DECL_CHAIN (chain);
8150 return first;
8153 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
8155 static int
8156 conforms_to_protocol (tree klass, tree protocol)
8158 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
8160 tree p = CLASS_PROTOCOL_LIST (klass);
8161 while (p && TREE_VALUE (p) != protocol)
8162 p = TREE_CHAIN (p);
8164 if (!p)
8166 tree super = (CLASS_SUPER_NAME (klass)
8167 ? lookup_interface (CLASS_SUPER_NAME (klass))
8168 : NULL_TREE);
8169 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
8170 if (!tmp)
8171 return 0;
8175 return 1;
8178 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
8179 CONTEXT. This is one of two mechanisms to check protocol integrity. */
8181 static int
8182 check_methods_accessible (tree chain, tree context, int mtype)
8184 int first = 1;
8185 tree list;
8186 tree base_context = context;
8188 while (chain)
8190 context = base_context;
8191 while (context)
8193 if (mtype == '+')
8194 list = CLASS_CLS_METHODS (context);
8195 else
8196 list = CLASS_NST_METHODS (context);
8198 if (lookup_method (list, chain))
8199 break;
8201 switch (TREE_CODE (context))
8203 case CLASS_IMPLEMENTATION_TYPE:
8204 case CLASS_INTERFACE_TYPE:
8205 context = (CLASS_SUPER_NAME (context)
8206 ? lookup_interface (CLASS_SUPER_NAME (context))
8207 : NULL_TREE);
8208 break;
8209 case CATEGORY_IMPLEMENTATION_TYPE:
8210 case CATEGORY_INTERFACE_TYPE:
8211 context = (CLASS_NAME (context)
8212 ? lookup_interface (CLASS_NAME (context))
8213 : NULL_TREE);
8214 break;
8215 default:
8216 gcc_unreachable ();
8220 if (context == NULL_TREE)
8222 if (first)
8224 switch (TREE_CODE (objc_implementation_context))
8226 case CLASS_IMPLEMENTATION_TYPE:
8227 warning (0, "incomplete implementation of class %qE",
8228 CLASS_NAME (objc_implementation_context));
8229 break;
8230 case CATEGORY_IMPLEMENTATION_TYPE:
8231 warning (0, "incomplete implementation of category %qE",
8232 CLASS_SUPER_NAME (objc_implementation_context));
8233 break;
8234 default:
8235 gcc_unreachable ();
8237 first = 0;
8239 warning (0, "method definition for %<%c%E%> not found",
8240 mtype, METHOD_SEL_NAME (chain));
8243 chain = TREE_CHAIN (chain); /* next method... */
8245 return first;
8248 /* Check whether the current interface (accessible via
8249 'objc_implementation_context') actually implements protocol P, along
8250 with any protocols that P inherits. */
8252 static void
8253 check_protocol (tree p, const char *type, tree name)
8255 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
8257 int f1, f2;
8259 /* Ensure that all protocols have bodies! */
8260 if (warn_protocol)
8262 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
8263 CLASS_CLS_METHODS (objc_implementation_context),
8264 '+');
8265 f2 = check_methods (PROTOCOL_NST_METHODS (p),
8266 CLASS_NST_METHODS (objc_implementation_context),
8267 '-');
8269 else
8271 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
8272 objc_implementation_context,
8273 '+');
8274 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
8275 objc_implementation_context,
8276 '-');
8279 if (!f1 || !f2)
8280 warning (0, "%s %qE does not fully implement the %qE protocol",
8281 type, name, PROTOCOL_NAME (p));
8284 /* Check protocols recursively. */
8285 if (PROTOCOL_LIST (p))
8287 tree subs = PROTOCOL_LIST (p);
8288 tree super_class =
8289 lookup_interface (CLASS_SUPER_NAME (implementation_template));
8291 while (subs)
8293 tree sub = TREE_VALUE (subs);
8295 /* If the superclass does not conform to the protocols
8296 inherited by P, then we must! */
8297 if (!super_class || !conforms_to_protocol (super_class, sub))
8298 check_protocol (sub, type, name);
8299 subs = TREE_CHAIN (subs);
8304 /* Check whether the current interface (accessible via
8305 'objc_implementation_context') actually implements the protocols listed
8306 in PROTO_LIST. */
8308 static void
8309 check_protocols (tree proto_list, const char *type, tree name)
8311 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
8313 tree p = TREE_VALUE (proto_list);
8315 check_protocol (p, type, name);
8319 /* Make sure that the class CLASS_NAME is defined
8320 CODE says which kind of thing CLASS_NAME ought to be.
8321 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
8322 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
8324 static tree
8325 start_class (enum tree_code code, tree class_name, tree super_name,
8326 tree protocol_list)
8328 tree klass, decl;
8330 #ifdef OBJCPLUS
8331 if (current_namespace != global_namespace) {
8332 error ("Objective-C declarations may only appear in global scope");
8334 #endif /* OBJCPLUS */
8336 if (objc_implementation_context)
8338 warning (0, "%<@end%> missing in implementation context");
8339 finish_class (objc_implementation_context);
8340 objc_ivar_chain = NULL_TREE;
8341 objc_implementation_context = NULL_TREE;
8344 klass = make_node (code);
8345 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
8347 /* Check for existence of the super class, if one was specified. Note
8348 that we must have seen an @interface, not just a @class. If we
8349 are looking at a @compatibility_alias, traverse it first. */
8350 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
8351 && super_name)
8353 tree super = objc_is_class_name (super_name);
8355 if (!super || !lookup_interface (super))
8357 error ("cannot find interface declaration for %qE, superclass of %qE",
8358 super ? super : super_name,
8359 class_name);
8360 super_name = NULL_TREE;
8362 else
8363 super_name = super;
8366 CLASS_NAME (klass) = class_name;
8367 CLASS_SUPER_NAME (klass) = super_name;
8368 CLASS_CLS_METHODS (klass) = NULL_TREE;
8370 if (! objc_is_class_name (class_name)
8371 && (decl = lookup_name (class_name)))
8373 error ("%qE redeclared as different kind of symbol",
8374 class_name);
8375 error ("previous declaration of %q+D",
8376 decl);
8379 switch (code)
8381 case CLASS_IMPLEMENTATION_TYPE:
8383 tree chain;
8385 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
8386 if (TREE_VALUE (chain) == class_name)
8388 error ("reimplementation of class %qE",
8389 class_name);
8390 return error_mark_node;
8392 implemented_classes = tree_cons (NULL_TREE, class_name,
8393 implemented_classes);
8396 /* Reset for multiple classes per file. */
8397 method_slot = 0;
8399 objc_implementation_context = klass;
8401 /* Lookup the interface for this implementation. */
8403 if (!(implementation_template = lookup_interface (class_name)))
8405 warning (0, "cannot find interface declaration for %qE",
8406 class_name);
8407 add_class (implementation_template = objc_implementation_context,
8408 class_name);
8411 /* If a super class has been specified in the implementation,
8412 insure it conforms to the one specified in the interface. */
8414 if (super_name
8415 && (super_name != CLASS_SUPER_NAME (implementation_template)))
8417 tree previous_name = CLASS_SUPER_NAME (implementation_template);
8418 error ("conflicting super class name %qE",
8419 super_name);
8420 if (previous_name)
8421 error ("previous declaration of %qE", previous_name);
8422 else
8423 error ("previous declaration");
8426 else if (! super_name)
8428 CLASS_SUPER_NAME (objc_implementation_context)
8429 = CLASS_SUPER_NAME (implementation_template);
8431 break;
8433 case CLASS_INTERFACE_TYPE:
8434 if (lookup_interface (class_name))
8435 #ifdef OBJCPLUS
8436 error ("duplicate interface declaration for class %qE", class_name);
8437 #else
8438 warning (0, "duplicate interface declaration for class %qE", class_name);
8439 #endif
8440 else
8441 add_class (klass, class_name);
8443 if (protocol_list)
8444 CLASS_PROTOCOL_LIST (klass)
8445 = lookup_and_install_protocols (protocol_list);
8446 break;
8448 case CATEGORY_INTERFACE_TYPE:
8450 tree class_category_is_assoc_with;
8452 /* For a category, class_name is really the name of the class that
8453 the following set of methods will be associated with. We must
8454 find the interface so that can derive the objects template. */
8455 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
8457 error ("cannot find interface declaration for %qE",
8458 class_name);
8459 exit (FATAL_EXIT_CODE);
8461 else
8462 add_category (class_category_is_assoc_with, klass);
8464 if (protocol_list)
8465 CLASS_PROTOCOL_LIST (klass)
8466 = lookup_and_install_protocols (protocol_list);
8468 break;
8470 case CATEGORY_IMPLEMENTATION_TYPE:
8471 /* Reset for multiple classes per file. */
8472 method_slot = 0;
8474 objc_implementation_context = klass;
8476 /* For a category, class_name is really the name of the class that
8477 the following set of methods will be associated with. We must
8478 find the interface so that can derive the objects template. */
8480 if (!(implementation_template = lookup_interface (class_name)))
8482 error ("cannot find interface declaration for %qE",
8483 class_name);
8484 exit (FATAL_EXIT_CODE);
8486 break;
8487 default:
8488 gcc_unreachable ();
8490 return klass;
8493 static tree
8494 continue_class (tree klass)
8496 switch (TREE_CODE (klass))
8498 case CLASS_IMPLEMENTATION_TYPE:
8499 case CATEGORY_IMPLEMENTATION_TYPE:
8501 struct imp_entry *imp_entry;
8503 /* Check consistency of the instance variables. */
8505 if (CLASS_RAW_IVARS (klass))
8506 check_ivars (implementation_template, klass);
8508 /* code generation */
8509 #ifdef OBJCPLUS
8510 push_lang_context (lang_name_c);
8511 #endif
8512 build_private_template (implementation_template);
8513 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
8514 objc_instance_type = build_pointer_type (uprivate_record);
8516 imp_entry = ggc_alloc_imp_entry ();
8518 imp_entry->next = imp_list;
8519 imp_entry->imp_context = klass;
8520 imp_entry->imp_template = implementation_template;
8522 synth_forward_declarations ();
8523 imp_entry->class_decl = UOBJC_CLASS_decl;
8524 imp_entry->meta_decl = UOBJC_METACLASS_decl;
8525 imp_entry->has_cxx_cdtors = 0;
8527 /* Append to front and increment count. */
8528 imp_list = imp_entry;
8529 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
8530 imp_count++;
8531 else
8532 cat_count++;
8533 #ifdef OBJCPLUS
8534 pop_lang_context ();
8535 #endif /* OBJCPLUS */
8537 return get_class_ivars (implementation_template, true);
8538 break;
8540 case CLASS_INTERFACE_TYPE:
8542 #ifdef OBJCPLUS
8543 push_lang_context (lang_name_c);
8544 #endif /* OBJCPLUS */
8545 objc_collecting_ivars = 1;
8546 build_private_template (klass);
8547 objc_collecting_ivars = 0;
8548 #ifdef OBJCPLUS
8549 pop_lang_context ();
8550 #endif /* OBJCPLUS */
8551 return NULL_TREE;
8552 break;
8554 default:
8555 return error_mark_node;
8559 /* This routine builds a property ivar name. */
8561 static char *
8562 objc_build_property_ivar_name (tree property_decl)
8564 static char string[BUFSIZE];
8565 sprintf (string, "_%s", IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
8566 return string;
8569 /* This routine builds name of the setter synthesized function. */
8571 static char *
8572 objc_build_property_setter_name (tree ident, bool delimit_colon)
8574 static char string[BUFSIZE];
8575 if (delimit_colon)
8576 sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
8577 else
8578 sprintf (string, "set%s", IDENTIFIER_POINTER (ident));
8579 string[3] = TOUPPER (string[3]);
8580 return string;
8583 /* This routine does all the work for generating data and code per each
8584 property declared in current implementation. */
8586 static void
8587 objc_gen_one_property_datum (tree klass, tree property, tree class_methods, bool *ivar_added)
8589 tree mth;
8591 /* If getter, check that it is already declared in user code. */
8592 if (PROPERTY_GETTER_NAME (property))
8594 mth = lookup_method (CLASS_NST_METHODS (class_methods),
8595 PROPERTY_GETTER_NAME (property));
8596 if (!mth)
8597 error ("property getter %qs not declared in class %qs",
8598 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property)),
8599 IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
8601 /* If setter, check that it is already declared in user code. */
8602 if (PROPERTY_SETTER_NAME (property))
8604 mth = lookup_method (CLASS_NST_METHODS (class_methods),
8605 PROPERTY_SETTER_NAME (property));
8606 if (!mth)
8607 error ("property setter %qs not declared in class %qs",
8608 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property)),
8609 IDENTIFIER_POINTER (CLASS_NAME (class_methods)));
8611 /* If ivar attribute specified, check that it is already declared. */
8612 if (PROPERTY_IVAR_NAME (property))
8614 if (!is_ivar (CLASS_IVARS (klass),
8615 PROPERTY_IVAR_NAME (property)))
8616 error ("ivar %qs in property declaration must be an existing ivar",
8617 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property)));
8619 else if (!PROPERTY_GETTER_NAME (property)
8620 || (PROPERTY_READONLY (property) == boolean_false_node
8621 && !PROPERTY_SETTER_NAME (property)))
8623 /* Setter and/or getter must be synthesize and there was no user-specified
8624 ivar. Must create an ivar and add to to current class's ivar list. */
8625 tree record = CLASS_STATIC_TEMPLATE (klass);
8626 tree type = TREE_TYPE (property);
8627 tree field_decl, field;
8628 field_decl = create_field_decl (type,
8629 objc_build_property_ivar_name (property));
8630 DECL_CONTEXT (field_decl) = record;
8631 (void) add_instance_variable (klass,
8632 OBJC_IVAR_VIS_PUBLIC, field_decl);
8633 /* Unfortunately, CLASS_IVARS is completed when interface is completed.
8634 Must add the new ivar by hand to its list here. */
8636 CLASS_IVARS (klass) =
8637 chainon (CLASS_IVARS (klass),
8638 copy_node (field_decl));
8639 gcc_assert (record);
8640 /* Must also add this ivar to the end of list of fields for this class. */
8641 field = TYPE_FIELDS (record);
8642 if (field && field != CLASS_IVARS (klass))
8643 /* class has a hidden field, attach ivar list after the hiddent field. */
8644 TREE_CHAIN (field) = CLASS_IVARS (klass);
8645 else
8646 TYPE_FIELDS (record) = CLASS_IVARS (klass);
8647 *ivar_added = true;
8651 /* This routine processes an existing getter or setter attribute.
8652 It aliases internal property getter or setter to the user implemented
8653 getter or setter.
8656 static void
8657 objc_process_getter_setter (tree klass, tree property, bool getter)
8659 tree prop_mth_decl;
8660 tree prop_getter_mth_decl;
8661 tree name_ident;
8663 if (getter)
8664 /* getter name is same as property name. */
8665 name_ident = PROPERTY_NAME (property);
8666 else
8667 /* Must synthesize setter name from property name. */
8668 name_ident = get_identifier (objc_build_property_setter_name (
8669 PROPERTY_NAME (property), true));
8671 /* Find declaration of instance method for the property in its class. */
8672 prop_mth_decl = lookup_method (CLASS_NST_METHODS (klass), name_ident);
8674 if (!prop_mth_decl)
8675 return;
8677 prop_getter_mth_decl = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8678 getter ? PROPERTY_GETTER_NAME (property)
8679 : PROPERTY_SETTER_NAME (property));
8681 if (!prop_getter_mth_decl)
8682 return;
8684 if (!match_proto_with_proto (prop_getter_mth_decl, prop_mth_decl, 1))
8686 error ("User %s %qs does not match property %qs type",
8687 getter ? "getter" : "setter",
8688 IDENTIFIER_POINTER (DECL_NAME (prop_getter_mth_decl)),
8689 IDENTIFIER_POINTER (PROPERTY_NAME (property)));
8690 return;
8692 /* We alias internal property getter to the user implemented getter by copying relevant
8693 entries from user's implementation to the internal one. */
8694 prop_mth_decl = copy_node (prop_mth_decl);
8695 METHOD_ENCODING (prop_mth_decl) = METHOD_ENCODING (prop_getter_mth_decl);
8696 METHOD_DEFINITION (prop_mth_decl) = METHOD_DEFINITION (prop_getter_mth_decl);
8697 objc_add_method (objc_implementation_context, prop_mth_decl, 0, 0);
8700 /* This routine synthesizes a 'getter' method. */
8702 static void
8703 objc_synthesize_getter (tree klass, tree class_method, tree property)
8705 tree fn, decl;
8706 tree body;
8707 tree ret_val;
8708 tree ivar_ident;
8710 /* If user has implemented a getter with same name then do nothing. */
8711 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8712 PROPERTY_NAME (property)))
8713 return;
8715 /* Find declaration of the property in the interface. There must be one. */
8716 decl = lookup_method (CLASS_NST_METHODS (class_method),
8717 PROPERTY_NAME (property));
8719 /* If one not declared in the interface, this condition has already been reported
8720 as user error (because property was not declared in the interface). */
8721 if (!decl)
8722 return;
8724 /* For now no attributes. */
8725 objc_start_method_definition (false /* is_class_method */, copy_node (decl), NULL_TREE);
8727 body = c_begin_compound_stmt (true);
8728 /* return self->_property_name; */
8729 /* If user specified an ivar, use it in generation of the getter. */
8730 ivar_ident = PROPERTY_IVAR_NAME (property)
8731 ? PROPERTY_IVAR_NAME (property)
8732 : get_identifier (objc_build_property_ivar_name (property));
8734 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8735 is added *after* user ivar is parsed and objc_continue_implementation
8736 has already been called. */
8737 objc_ivar_chain = CLASS_IVARS (klass);
8738 ret_val = objc_lookup_ivar (NULL_TREE, ivar_ident);
8739 /* If ivar attribute is not a user declared attribute, this condition has
8740 already been repored as error. */
8741 gcc_assert (ret_val || PROPERTY_IVAR_NAME (property));
8743 if (ret_val)
8745 #ifdef OBJCPLUS
8746 finish_return_stmt (ret_val);
8747 #else
8748 (void)c_finish_return (input_location, ret_val, NULL);
8749 #endif
8751 add_stmt (c_end_compound_stmt (input_location, body, true));
8752 fn = current_function_decl;
8753 #ifdef OBJCPLUS
8754 finish_function ();
8755 #endif
8756 objc_finish_method_definition (fn);
8759 /* This routine synthesizes a 'setter' method. */
8761 static void
8762 objc_synthesize_setter (tree klass, tree class_method, tree property)
8764 tree fn, decl, ivar_ident, lhs, rhs;
8765 tree body;
8766 char *setter_name = objc_build_property_setter_name (
8767 PROPERTY_NAME (property), true);
8768 tree setter_ident = get_identifier (setter_name);
8770 /* If user has implemented a setter with same name then do nothing. */
8771 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
8772 setter_ident))
8773 return;
8775 /* Find declaration of the property in the interface. There must be one. */
8776 decl = lookup_method (CLASS_NST_METHODS (class_method), setter_ident);
8778 /* If one not declared in the inerface, this condition has already been reported
8779 as user error (because property was not declared in the interface. */
8780 if (!decl)
8781 return;
8783 /* For now, no attributes. */
8784 objc_start_method_definition (false /* is_class_method */, copy_node (decl), NULL_TREE);
8786 body = c_begin_compound_stmt (true);
8787 /* _property_name = _value; */
8788 /* If user specified an ivar, use it in generation of the setter. */
8789 ivar_ident = PROPERTY_IVAR_NAME (property)
8790 ? PROPERTY_IVAR_NAME (property)
8791 : get_identifier (objc_build_property_ivar_name (property));
8793 /* objc_ivar_chain might not be up to date in the case that property 'ivar'
8794 is added *after* user ivar is parsed and objc_continue_implementation
8795 has already been called. */
8796 objc_ivar_chain = CLASS_IVARS (klass);
8797 lhs = objc_lookup_ivar (NULL_TREE, ivar_ident);
8798 /* If ivar attribute is not a user declared attribute, this condition has
8799 already been repored as error. */
8800 gcc_assert (lhs || PROPERTY_IVAR_NAME (property));
8801 if (lhs)
8803 rhs = lookup_name (get_identifier ("_value"));
8804 gcc_assert (rhs);
8805 /* FIXME: NULL types to get compile. */
8806 add_stmt (build_modify_expr (input_location,
8807 lhs, NULL_TREE, NOP_EXPR,
8808 input_location, rhs, NULL_TREE));
8810 add_stmt (c_end_compound_stmt (input_location, body, true));
8811 fn = current_function_decl;
8812 #ifdef OBJCPLUS
8813 finish_function ();
8814 #endif
8815 objc_finish_method_definition (fn);
8818 /* This function is called by the parser after a @synthesize
8819 expression is parsed. 'start_locus' is the location of the
8820 @synthesize expression, and 'property_and_ivar_list' is a chained
8821 list of the property and ivar names.
8823 void
8824 objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_and_ivar_list ATTRIBUTE_UNUSED)
8826 if (property_and_ivar_list == error_mark_node)
8827 return;
8829 if (!objc_implementation_context)
8831 /* We can get here only in Objective-C; the Objective-C++ parser
8832 detects the problem while parsing, outputs the error
8833 "misplaced '@synthesize' Objective-C++ construct" and skips
8834 the declaration. */
8835 error ("%<@synthesize%> not in @implementation context");
8836 return;
8839 /* TODO */
8840 error ("%<@synthesize%> is not supported in this version of the compiler");
8843 /* This function is called by the parser after a @dynamic expression
8844 is parsed. 'start_locus' is the location of the @dynamic
8845 expression, and 'property_list' is a chained list of all the
8846 property names. */
8847 void
8848 objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_list ATTRIBUTE_UNUSED)
8850 if (property_list == error_mark_node)
8851 return;
8853 if (!objc_implementation_context)
8855 /* We can get here only in Objective-C; the Objective-C++ parser
8856 detects the problem while parsing, outputs the error
8857 "misplaced '@dynamic' Objective-C++ construct" and skips the
8858 declaration. */
8859 error ("%<@dynamic%> not in @implementation context");
8860 return;
8863 /* TODO */
8864 error ("%<@dynamic%> is not supported in this version of the compiler");
8867 /* Main routine to generate code/data for all the property information for
8868 current implementation (class or category). CLASS is the interface where
8869 ivars are declared. CLASS_METHODS is where methods are found which
8870 could be a class or a category depending on whether we are implementing
8871 property of a class or a category. */
8873 static void
8874 objc_gen_property_data (tree klass, tree class_methods)
8876 tree x;
8877 bool ivar_added = false;
8878 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
8879 objc_gen_one_property_datum (klass, x, class_methods, &ivar_added);
8881 if (ivar_added)
8883 tree record = CLASS_STATIC_TEMPLATE (klass);
8884 /* Ugh, must recalculate struct layout since at least one ivar was added. */
8885 TYPE_SIZE (record) = 0;
8886 layout_type (record);
8889 /* Synthesize all getters for properties. */
8890 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
8892 /* Property has a getter attribute, no need to synthesize one. */
8893 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
8894 objc_synthesize_getter (klass, class_methods, x);
8895 else
8896 objc_process_getter_setter (class_methods, x, true);
8898 if (PROPERTY_READONLY (x) == boolean_false_node)
8900 /* not a readonly property. */
8901 if (PROPERTY_SETTER_NAME (x) == NULL_TREE)
8902 objc_synthesize_setter (klass, class_methods, x);
8903 else
8904 objc_process_getter_setter (class_methods, x, false);
8909 /* This is called once we see the "@end" in an interface/implementation. */
8911 static void
8912 finish_class (tree klass)
8914 switch (TREE_CODE (klass))
8916 case CLASS_IMPLEMENTATION_TYPE:
8918 /* All code generation is done in finish_objc. */
8920 /* Generate what needed for property; setters, getters, etc. */
8921 objc_gen_property_data (implementation_template, implementation_template);
8923 if (implementation_template != objc_implementation_context)
8925 /* Ensure that all method listed in the interface contain bodies. */
8926 check_methods (CLASS_CLS_METHODS (implementation_template),
8927 CLASS_CLS_METHODS (objc_implementation_context), '+');
8928 check_methods (CLASS_NST_METHODS (implementation_template),
8929 CLASS_NST_METHODS (objc_implementation_context), '-');
8931 if (CLASS_PROTOCOL_LIST (implementation_template))
8932 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
8933 "class",
8934 CLASS_NAME (objc_implementation_context));
8936 break;
8938 case CATEGORY_IMPLEMENTATION_TYPE:
8940 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
8942 if (category)
8944 /* Generate what needed for property; setters, getters, etc. */
8945 objc_gen_property_data (implementation_template, category);
8947 /* Ensure all method listed in the interface contain bodies. */
8948 check_methods (CLASS_CLS_METHODS (category),
8949 CLASS_CLS_METHODS (objc_implementation_context), '+');
8950 check_methods (CLASS_NST_METHODS (category),
8951 CLASS_NST_METHODS (objc_implementation_context), '-');
8953 if (CLASS_PROTOCOL_LIST (category))
8954 check_protocols (CLASS_PROTOCOL_LIST (category),
8955 "category",
8956 CLASS_SUPER_NAME (objc_implementation_context));
8958 break;
8960 default:
8962 /* Process properties of the class. */
8963 tree x;
8964 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
8966 tree type = TREE_TYPE (x);
8967 tree prop_name = PROPERTY_NAME (x);
8968 /* Build an instance method declaration: - (type) prop_name; */
8969 if (PROPERTY_GETTER_NAME (x) == NULL_TREE)
8971 /* No getter attribute specified. Generate an instance method for the
8972 getter. */
8973 tree rettype = build_tree_list (NULL_TREE, type);
8974 tree getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
8975 rettype, prop_name,
8976 NULL_TREE, false);
8977 objc_add_method (objc_interface_context, getter_decl, false, false);
8978 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
8980 else
8981 warning (0, "getter = %qs may not be specified in an interface",
8982 IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (x)));
8984 /* Build an instance method declaration: - (void) setName: (type)value; */
8985 if (PROPERTY_SETTER_NAME (x) == NULL_TREE
8986 && PROPERTY_READONLY (x) == boolean_false_node)
8988 /* Declare a setter instance method in the interface. */
8989 tree key_name, arg_type, arg_name;
8990 tree setter_decl, selector;
8991 tree ret_type = build_tree_list (NULL_TREE, void_type_node);
8992 /* setter name. */
8993 key_name = get_identifier (objc_build_property_setter_name
8994 (PROPERTY_NAME (x), false));
8995 arg_type = build_tree_list (NULL_TREE, type);
8996 arg_name = get_identifier ("_value");
8997 /* For now, no attributes. */
8998 selector = objc_build_keyword_decl (key_name, arg_type, arg_name, NULL);
8999 setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
9000 ret_type, selector,
9001 build_tree_list (NULL_TREE, NULL_TREE),
9002 false);
9003 objc_add_method (objc_interface_context, setter_decl, false, false);
9004 METHOD_PROPERTY_CONTEXT (setter_decl) = x;
9006 else if (PROPERTY_SETTER_NAME (x))
9007 warning (0, "setter = %qs may not be specified in an interface",
9008 IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x)));
9009 if (PROPERTY_IVAR_NAME (x))
9010 warning (0, "ivar = %qs attribute may not be specified in an interface",
9011 IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (x)));
9017 static tree
9018 add_protocol (tree protocol)
9020 /* Put protocol on list in reverse order. */
9021 TREE_CHAIN (protocol) = protocol_chain;
9022 protocol_chain = protocol;
9023 return protocol_chain;
9026 static tree
9027 lookup_protocol (tree ident)
9029 tree chain;
9031 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
9032 if (ident == PROTOCOL_NAME (chain))
9033 return chain;
9035 return NULL_TREE;
9038 /* This function forward declares the protocols named by NAMES. If
9039 they are already declared or defined, the function has no effect. */
9041 void
9042 objc_declare_protocols (tree names)
9044 tree list;
9046 #ifdef OBJCPLUS
9047 if (current_namespace != global_namespace) {
9048 error ("Objective-C declarations may only appear in global scope");
9050 #endif /* OBJCPLUS */
9052 for (list = names; list; list = TREE_CHAIN (list))
9054 tree name = TREE_VALUE (list);
9056 if (lookup_protocol (name) == NULL_TREE)
9058 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
9060 TYPE_LANG_SLOT_1 (protocol)
9061 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9062 PROTOCOL_NAME (protocol) = name;
9063 PROTOCOL_LIST (protocol) = NULL_TREE;
9064 add_protocol (protocol);
9065 PROTOCOL_DEFINED (protocol) = 0;
9066 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9071 static tree
9072 start_protocol (enum tree_code code, tree name, tree list)
9074 tree protocol;
9076 #ifdef OBJCPLUS
9077 if (current_namespace != global_namespace) {
9078 error ("Objective-C declarations may only appear in global scope");
9080 #endif /* OBJCPLUS */
9082 protocol = lookup_protocol (name);
9084 if (!protocol)
9086 protocol = make_node (code);
9087 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
9089 PROTOCOL_NAME (protocol) = name;
9090 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9091 add_protocol (protocol);
9092 PROTOCOL_DEFINED (protocol) = 1;
9093 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
9095 check_protocol_recursively (protocol, list);
9097 else if (! PROTOCOL_DEFINED (protocol))
9099 PROTOCOL_DEFINED (protocol) = 1;
9100 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
9102 check_protocol_recursively (protocol, list);
9104 else
9106 warning (0, "duplicate declaration for protocol %qE",
9107 name);
9109 return protocol;
9113 /* "Encode" a data type into a string, which grows in util_obstack.
9115 The format is described in gcc/doc/objc.texi, section 'Type
9116 encoding'.
9118 Most of the encode_xxx functions have a 'type' argument, which is
9119 the type to encode, and an integer 'curtype' argument, which is the
9120 index in the encoding string of the beginning of the encoding of
9121 the current type, and allows you to find what characters have
9122 already been written for the current type (they are the ones in the
9123 current encoding string starting from 'curtype').
9125 For example, if we are encoding a method which returns 'int' and
9126 takes a 'char **' argument, then when we get to the point of
9127 encoding the 'char **' argument, the encoded string already
9128 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
9129 'curtype' will be set to 7 when starting to encode 'char **'.
9130 During the whole of the encoding of 'char **', 'curtype' will be
9131 fixed at 7, so the routine encoding the second pointer can find out
9132 that it's actually encoding a pointer to a pointer by looking
9133 backwards at what has already been encoded for the current type,
9134 and seeing there is a "^" (meaning a pointer) in there.
9138 /* Encode type qualifiers encodes one of the "PQ" Objective-C
9139 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
9140 'const', instead, is encoded directly as part of the type.
9143 static void
9144 encode_type_qualifiers (tree declspecs)
9146 tree spec;
9148 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
9150 /* FIXME: Shouldn't we use token->keyword here ? */
9151 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
9152 obstack_1grow (&util_obstack, 'n');
9153 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
9154 obstack_1grow (&util_obstack, 'N');
9155 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
9156 obstack_1grow (&util_obstack, 'o');
9157 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
9158 obstack_1grow (&util_obstack, 'O');
9159 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
9160 obstack_1grow (&util_obstack, 'R');
9161 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
9162 obstack_1grow (&util_obstack, 'V');
9163 else
9164 gcc_unreachable ();
9168 /* Determine if a pointee is marked read-only. Only used by the NeXT
9169 runtime to be compatible with gcc-3.3. */
9171 static bool
9172 pointee_is_readonly (tree pointee)
9174 while (POINTER_TYPE_P (pointee))
9175 pointee = TREE_TYPE (pointee);
9177 return TYPE_READONLY (pointee);
9180 /* Encode a pointer type. */
9182 static void
9183 encode_pointer (tree type, int curtype, int format)
9185 tree pointer_to = TREE_TYPE (type);
9187 if (flag_next_runtime)
9189 /* This code is used to be compatible with gcc-3.3. */
9190 /* For historical/compatibility reasons, the read-only qualifier
9191 of the pointee gets emitted _before_ the '^'. The read-only
9192 qualifier of the pointer itself gets ignored, _unless_ we are
9193 looking at a typedef! Also, do not emit the 'r' for anything
9194 but the outermost type! */
9195 if (!generating_instance_variables
9196 && (obstack_object_size (&util_obstack) - curtype <= 1)
9197 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
9198 ? TYPE_READONLY (type)
9199 : pointee_is_readonly (pointer_to)))
9200 obstack_1grow (&util_obstack, 'r');
9203 if (TREE_CODE (pointer_to) == RECORD_TYPE)
9205 if (OBJC_TYPE_NAME (pointer_to)
9206 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
9208 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
9210 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
9212 obstack_1grow (&util_obstack, '@');
9213 return;
9215 else if (TYPE_HAS_OBJC_INFO (pointer_to)
9216 && TYPE_OBJC_INTERFACE (pointer_to))
9218 if (generating_instance_variables)
9220 obstack_1grow (&util_obstack, '@');
9221 obstack_1grow (&util_obstack, '"');
9222 obstack_grow (&util_obstack, name, strlen (name));
9223 obstack_1grow (&util_obstack, '"');
9224 return;
9226 else
9228 obstack_1grow (&util_obstack, '@');
9229 return;
9232 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
9234 obstack_1grow (&util_obstack, '#');
9235 return;
9237 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
9239 obstack_1grow (&util_obstack, ':');
9240 return;
9244 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
9245 && TYPE_MODE (pointer_to) == QImode)
9247 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
9248 ? OBJC_TYPE_NAME (pointer_to)
9249 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
9251 /* (BOOL *) are an exception and are encoded as ^c, while all
9252 other pointers to char are encoded as *. */
9253 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
9255 if (!flag_next_runtime)
9257 /* The NeXT runtime adds the 'r' before getting here. */
9259 /* It appears that "r*" means "const char *" rather than
9260 "char *const". "char *const" is encoded as "*",
9261 which is identical to "char *", so the "const" is
9262 unfortunately lost. */
9263 if (TYPE_READONLY (pointer_to))
9264 obstack_1grow (&util_obstack, 'r');
9267 obstack_1grow (&util_obstack, '*');
9268 return;
9272 /* We have a normal pointer type that does not get special treatment. */
9273 obstack_1grow (&util_obstack, '^');
9274 encode_type (pointer_to, curtype, format);
9277 static void
9278 encode_array (tree type, int curtype, int format)
9280 tree an_int_cst = TYPE_SIZE (type);
9281 tree array_of = TREE_TYPE (type);
9282 char buffer[40];
9284 if (an_int_cst == NULL)
9286 /* We are trying to encode an incomplete array. An incomplete
9287 array is forbidden as part of an instance variable. */
9288 if (generating_instance_variables)
9290 /* TODO: Detect this error earlier. */
9291 error ("instance variable has unknown size");
9292 return;
9295 /* So the only case in which an incomplete array could occur is
9296 if we are encoding the arguments or return value of a method.
9297 In that case, an incomplete array argument or return value
9298 (eg, -(void)display: (char[])string) is treated like a
9299 pointer because that is how the compiler does the function
9300 call. A special, more complicated case, is when the
9301 incomplete array is the last member of a struct (eg, if we
9302 are encoding "struct { unsigned long int a;double b[];}"),
9303 which is again part of a method argument/return value. In
9304 that case, we really need to communicate to the runtime that
9305 there is an incomplete array (not a pointer!) there. So, we
9306 detect that special case and encode it as a zero-length
9307 array.
9309 Try to detect that we are part of a struct. We do this by
9310 searching for '=' in the type encoding for the current type.
9311 NB: This hack assumes that you can't use '=' as part of a C
9312 identifier.
9315 char *enc = obstack_base (&util_obstack) + curtype;
9316 if (memchr (enc, '=',
9317 obstack_object_size (&util_obstack) - curtype) == NULL)
9319 /* We are not inside a struct. Encode the array as a
9320 pointer. */
9321 encode_pointer (type, curtype, format);
9322 return;
9326 /* Else, we are in a struct, and we encode it as a zero-length
9327 array. */
9328 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
9330 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
9331 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
9332 else
9333 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
9334 TREE_INT_CST_LOW (an_int_cst)
9335 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
9337 obstack_grow (&util_obstack, buffer, strlen (buffer));
9338 encode_type (array_of, curtype, format);
9339 obstack_1grow (&util_obstack, ']');
9340 return;
9343 /* Encode a vector. The vector type is a GCC extension to C. */
9344 static void
9345 encode_vector (tree type, int curtype, int format)
9347 tree vector_of = TREE_TYPE (type);
9348 char buffer[40];
9350 /* Vectors are like simple fixed-size arrays. */
9352 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
9353 alignment of the vector, and <code> is the base type. Eg, int
9354 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
9355 assuming that the alignment is 32 bytes. We include size and
9356 alignment in bytes so that the runtime does not have to have any
9357 knowledge of the actual types.
9359 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
9360 /* We want to compute the equivalent of sizeof (<vector>).
9361 Code inspired by c_sizeof_or_alignof_type. */
9362 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
9363 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
9364 /* We want to compute the equivalent of __alignof__
9365 (<vector>). Code inspired by
9366 c_sizeof_or_alignof_type. */
9367 TYPE_ALIGN_UNIT (type));
9368 obstack_grow (&util_obstack, buffer, strlen (buffer));
9369 encode_type (vector_of, curtype, format);
9370 obstack_1grow (&util_obstack, ']');
9371 return;
9374 static void
9375 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
9377 tree field = TYPE_FIELDS (type);
9379 for (; field; field = DECL_CHAIN (field))
9381 #ifdef OBJCPLUS
9382 /* C++ static members, and things that are not field at all,
9383 should not appear in the encoding. */
9384 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
9385 continue;
9386 #endif
9388 /* Recursively encode fields of embedded base classes. */
9389 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
9390 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
9392 encode_aggregate_fields (TREE_TYPE (field),
9393 pointed_to, curtype, format);
9394 continue;
9397 if (generating_instance_variables && !pointed_to)
9399 tree fname = DECL_NAME (field);
9401 obstack_1grow (&util_obstack, '"');
9403 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
9404 obstack_grow (&util_obstack,
9405 IDENTIFIER_POINTER (fname),
9406 strlen (IDENTIFIER_POINTER (fname)));
9408 obstack_1grow (&util_obstack, '"');
9411 encode_field_decl (field, curtype, format);
9415 static void
9416 encode_aggregate_within (tree type, int curtype, int format, int left,
9417 int right)
9419 tree name;
9420 /* NB: aggregates that are pointed to have slightly different encoding
9421 rules in that you never encode the names of instance variables. */
9422 int ob_size = obstack_object_size (&util_obstack);
9423 bool inline_contents = false;
9424 bool pointed_to = false;
9426 if (flag_next_runtime)
9428 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
9429 pointed_to = true;
9431 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
9432 && (!pointed_to || ob_size - curtype == 1
9433 || (ob_size - curtype == 2
9434 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
9435 inline_contents = true;
9437 else
9439 /* c0 and c1 are the last two characters in the encoding of the
9440 current type; if the last two characters were '^' or '^r',
9441 then we are encoding an aggregate that is "pointed to". The
9442 comment above applies: in that case we should avoid encoding
9443 the names of instance variables.
9445 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
9446 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
9448 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
9449 pointed_to = true;
9451 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
9453 if (!pointed_to)
9454 inline_contents = true;
9455 else
9457 /* Note that the check (ob_size - curtype < 2) prevents
9458 infinite recursion when encoding a structure which is
9459 a linked list (eg, struct node { struct node *next;
9460 }). Each time we follow a pointer, we add one
9461 character to ob_size, and curtype is fixed, so after
9462 at most two pointers we stop inlining contents and
9463 break the loop.
9465 The other case where we don't inline is "^r", which
9466 is a pointer to a constant struct.
9468 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
9469 inline_contents = true;
9474 /* Traverse struct aliases; it is important to get the
9475 original struct and its tag name (if any). */
9476 type = TYPE_MAIN_VARIANT (type);
9477 name = OBJC_TYPE_NAME (type);
9478 /* Open parenth/bracket. */
9479 obstack_1grow (&util_obstack, left);
9481 /* Encode the struct/union tag name, or '?' if a tag was
9482 not provided. Typedef aliases do not qualify. */
9483 #ifdef OBJCPLUS
9484 /* For compatibility with the NeXT runtime, ObjC++ encodes template
9485 args as a composite struct tag name. */
9486 if (name && TREE_CODE (name) == IDENTIFIER_NODE
9487 /* Did this struct have a tag? */
9488 && !TYPE_WAS_ANONYMOUS (type))
9489 obstack_grow (&util_obstack,
9490 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
9491 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
9492 #else
9493 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
9494 obstack_grow (&util_obstack,
9495 IDENTIFIER_POINTER (name),
9496 strlen (IDENTIFIER_POINTER (name)));
9497 #endif
9498 else
9499 obstack_1grow (&util_obstack, '?');
9501 /* Encode the types (and possibly names) of the inner fields,
9502 if required. */
9503 if (inline_contents)
9505 obstack_1grow (&util_obstack, '=');
9506 encode_aggregate_fields (type, pointed_to, curtype, format);
9508 /* Close parenth/bracket. */
9509 obstack_1grow (&util_obstack, right);
9512 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
9513 field type. */
9515 static void
9516 encode_next_bitfield (int width)
9518 char buffer[40];
9519 sprintf (buffer, "b%d", width);
9520 obstack_grow (&util_obstack, buffer, strlen (buffer));
9524 /* Encodes 'type', ignoring type qualifiers (which you should encode
9525 beforehand if needed) with the exception of 'const', which is
9526 encoded by encode_type. See above for the explanation of
9527 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
9528 OBJC_ENCODE_DONT_INLINE_DEFS.
9530 static void
9531 encode_type (tree type, int curtype, int format)
9533 enum tree_code code = TREE_CODE (type);
9535 /* Ignore type qualifiers other than 'const' when encoding a
9536 type. */
9538 if (type == error_mark_node)
9539 return;
9541 if (!flag_next_runtime)
9543 if (TYPE_READONLY (type))
9544 obstack_1grow (&util_obstack, 'r');
9547 switch (code)
9549 case ENUMERAL_TYPE:
9550 if (flag_next_runtime)
9552 /* Kludge for backwards-compatibility with gcc-3.3: enums
9553 are always encoded as 'i' no matter what type they
9554 actually are (!). */
9555 obstack_1grow (&util_obstack, 'i');
9556 break;
9558 /* Else, they are encoded exactly like the integer type that is
9559 used by the compiler to store them. */
9560 case INTEGER_TYPE:
9562 char c;
9563 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
9565 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
9566 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
9567 case 32:
9569 tree int_type = type;
9570 if (flag_next_runtime)
9572 /* Another legacy kludge for compatiblity with
9573 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
9574 but not always. For typedefs, we need to use 'i'
9575 or 'I' instead if encoding a struct field, or a
9576 pointer! */
9577 int_type = ((!generating_instance_variables
9578 && (obstack_object_size (&util_obstack)
9579 == (unsigned) curtype))
9580 ? TYPE_MAIN_VARIANT (type)
9581 : type);
9583 if (int_type == long_unsigned_type_node
9584 || int_type == long_integer_type_node)
9585 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
9586 else
9587 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
9589 break;
9590 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
9591 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
9592 default: gcc_unreachable ();
9594 obstack_1grow (&util_obstack, c);
9595 break;
9597 case REAL_TYPE:
9599 char c;
9600 /* Floating point types. */
9601 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
9603 case 32: c = 'f'; break;
9604 case 64: c = 'd'; break;
9605 case 96:
9606 case 128: c = 'D'; break;
9607 default: gcc_unreachable ();
9609 obstack_1grow (&util_obstack, c);
9610 break;
9612 case VOID_TYPE:
9613 obstack_1grow (&util_obstack, 'v');
9614 break;
9616 case BOOLEAN_TYPE:
9617 obstack_1grow (&util_obstack, 'B');
9618 break;
9620 case ARRAY_TYPE:
9621 encode_array (type, curtype, format);
9622 break;
9624 case POINTER_TYPE:
9625 #ifdef OBJCPLUS
9626 case REFERENCE_TYPE:
9627 #endif
9628 encode_pointer (type, curtype, format);
9629 break;
9631 case RECORD_TYPE:
9632 encode_aggregate_within (type, curtype, format, '{', '}');
9633 break;
9635 case UNION_TYPE:
9636 encode_aggregate_within (type, curtype, format, '(', ')');
9637 break;
9639 case FUNCTION_TYPE: /* '?' means an unknown type. */
9640 obstack_1grow (&util_obstack, '?');
9641 break;
9643 case COMPLEX_TYPE:
9644 /* A complex is encoded as 'j' followed by the inner type (eg,
9645 "_Complex int" is encoded as 'ji'). */
9646 obstack_1grow (&util_obstack, 'j');
9647 encode_type (TREE_TYPE (type), curtype, format);
9648 break;
9650 case VECTOR_TYPE:
9651 encode_vector (type, curtype, format);
9652 break;
9654 default:
9655 warning (0, "unknown type %s found during Objective-C encoding",
9656 gen_type_name (type));
9657 obstack_1grow (&util_obstack, '?');
9658 break;
9661 if (flag_next_runtime)
9663 /* Super-kludge. Some ObjC qualifier and type combinations need
9664 to be rearranged for compatibility with gcc-3.3. */
9665 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
9667 char *enc = obstack_base (&util_obstack) + curtype;
9669 /* Rewrite "in const" from "nr" to "rn". */
9670 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
9671 strncpy (enc - 1, "rn", 2);
9676 static void
9677 encode_gnu_bitfield (int position, tree type, int size)
9679 enum tree_code code = TREE_CODE (type);
9680 char buffer[40];
9681 char charType = '?';
9683 /* This code is only executed for the GNU runtime, so we can ignore
9684 the NeXT runtime kludge of always encoding enums as 'i' no matter
9685 what integers they actually are. */
9686 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
9688 if (integer_zerop (TYPE_MIN_VALUE (type)))
9689 /* Unsigned integer types. */
9691 switch (TYPE_MODE (type))
9693 case QImode:
9694 charType = 'C'; break;
9695 case HImode:
9696 charType = 'S'; break;
9697 case SImode:
9699 if (type == long_unsigned_type_node)
9700 charType = 'L';
9701 else
9702 charType = 'I';
9703 break;
9705 case DImode:
9706 charType = 'Q'; break;
9707 default:
9708 gcc_unreachable ();
9711 else
9712 /* Signed integer types. */
9714 switch (TYPE_MODE (type))
9716 case QImode:
9717 charType = 'c'; break;
9718 case HImode:
9719 charType = 's'; break;
9720 case SImode:
9722 if (type == long_integer_type_node)
9723 charType = 'l';
9724 else
9725 charType = 'i';
9726 break;
9728 case DImode:
9729 charType = 'q'; break;
9730 default:
9731 gcc_unreachable ();
9735 else
9737 /* Do not do any encoding, produce an error and keep going. */
9738 error ("trying to encode non-integer type as a bitfield");
9739 return;
9742 sprintf (buffer, "b%d%c%d", position, charType, size);
9743 obstack_grow (&util_obstack, buffer, strlen (buffer));
9746 static void
9747 encode_field_decl (tree field_decl, int curtype, int format)
9749 #ifdef OBJCPLUS
9750 /* C++ static members, and things that are not fields at all,
9751 should not appear in the encoding. */
9752 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
9753 return;
9754 #endif
9756 /* Generate the bitfield typing information, if needed. Note the difference
9757 between GNU and NeXT runtimes. */
9758 if (DECL_BIT_FIELD_TYPE (field_decl))
9760 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
9762 if (flag_next_runtime)
9763 encode_next_bitfield (size);
9764 else
9765 encode_gnu_bitfield (int_bit_position (field_decl),
9766 DECL_BIT_FIELD_TYPE (field_decl), size);
9768 else
9769 encode_type (TREE_TYPE (field_decl), curtype, format);
9772 /* Decay array and function parameters into pointers. */
9774 static tree
9775 objc_decay_parm_type (tree type)
9777 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
9778 type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
9779 ? TREE_TYPE (type)
9780 : type);
9782 return type;
9785 static GTY(()) tree objc_parmlist = NULL_TREE;
9787 /* Append PARM to a list of formal parameters of a method, making a necessary
9788 array-to-pointer adjustment along the way. */
9790 static void
9791 objc_push_parm (tree parm)
9793 tree type;
9795 if (TREE_TYPE (parm) == error_mark_node)
9797 objc_parmlist = chainon (objc_parmlist, parm);
9798 return;
9801 /* Decay arrays and functions into pointers. */
9802 type = objc_decay_parm_type (TREE_TYPE (parm));
9804 /* If the parameter type has been decayed, a new PARM_DECL needs to be
9805 built as well. */
9806 if (type != TREE_TYPE (parm))
9807 parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
9809 DECL_ARG_TYPE (parm)
9810 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
9812 /* Record constancy and volatility. */
9813 c_apply_type_quals_to_decl
9814 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
9815 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
9816 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
9818 objc_parmlist = chainon (objc_parmlist, parm);
9821 /* Retrieve the formal parameter list constructed via preceding calls to
9822 objc_push_parm(). */
9824 #ifdef OBJCPLUS
9825 static tree
9826 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
9827 #else
9828 static struct c_arg_info *
9829 objc_get_parm_info (int have_ellipsis)
9830 #endif
9832 #ifdef OBJCPLUS
9833 tree parm_info = objc_parmlist;
9834 objc_parmlist = NULL_TREE;
9836 return parm_info;
9837 #else
9838 tree parm_info = objc_parmlist;
9839 struct c_arg_info *arg_info;
9840 /* The C front-end requires an elaborate song and dance at
9841 this point. */
9842 push_scope ();
9843 declare_parm_level ();
9844 while (parm_info)
9846 tree next = DECL_CHAIN (parm_info);
9848 DECL_CHAIN (parm_info) = NULL_TREE;
9849 parm_info = pushdecl (parm_info);
9850 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
9851 parm_info = next;
9853 arg_info = get_parm_info (have_ellipsis);
9854 pop_scope ();
9855 objc_parmlist = NULL_TREE;
9856 return arg_info;
9857 #endif
9860 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
9861 method definitions. In the case of instance methods, we can be more
9862 specific as to the type of 'self'. */
9864 static void
9865 synth_self_and_ucmd_args (void)
9867 tree self_type;
9869 if (objc_method_context
9870 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
9871 self_type = objc_instance_type;
9872 else
9873 /* Really a `struct objc_class *'. However, we allow people to
9874 assign to self, which changes its type midstream. */
9875 self_type = objc_object_type;
9877 /* id self; */
9878 objc_push_parm (build_decl (input_location,
9879 PARM_DECL, self_id, self_type));
9881 /* SEL _cmd; */
9882 objc_push_parm (build_decl (input_location,
9883 PARM_DECL, ucmd_id, objc_selector_type));
9886 /* Transform an Objective-C method definition into a static C function
9887 definition, synthesizing the first two arguments, "self" and "_cmd",
9888 in the process. */
9890 static void
9891 start_method_def (tree method)
9893 tree parmlist;
9894 #ifdef OBJCPLUS
9895 tree parm_info;
9896 #else
9897 struct c_arg_info *parm_info;
9898 #endif
9899 int have_ellipsis = 0;
9901 /* If we are defining a "dealloc" method in a non-root class, we
9902 will need to check if a [super dealloc] is missing, and warn if
9903 it is. */
9904 if(CLASS_SUPER_NAME (objc_implementation_context)
9905 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
9906 should_call_super_dealloc = 1;
9907 else
9908 should_call_super_dealloc = 0;
9910 /* Required to implement _msgSuper. */
9911 objc_method_context = method;
9912 UOBJC_SUPER_decl = NULL_TREE;
9914 /* Generate prototype declarations for arguments..."new-style". */
9915 synth_self_and_ucmd_args ();
9917 /* Generate argument declarations if a keyword_decl. */
9918 parmlist = METHOD_SEL_ARGS (method);
9919 while (parmlist)
9921 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
9923 parm = build_decl (input_location,
9924 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
9925 objc_push_parm (parm);
9926 parmlist = DECL_CHAIN (parmlist);
9929 if (METHOD_ADD_ARGS (method))
9931 tree akey;
9933 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
9934 akey; akey = TREE_CHAIN (akey))
9936 objc_push_parm (TREE_VALUE (akey));
9939 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9940 have_ellipsis = 1;
9943 parm_info = objc_get_parm_info (have_ellipsis);
9945 really_start_method (objc_method_context, parm_info);
9948 /* Return 1 if TYPE1 is equivalent to TYPE2
9949 for purposes of method overloading. */
9951 static int
9952 objc_types_are_equivalent (tree type1, tree type2)
9954 if (type1 == type2)
9955 return 1;
9957 /* Strip away indirections. */
9958 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
9959 && (TREE_CODE (type1) == TREE_CODE (type2)))
9960 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
9961 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
9962 return 0;
9964 type1 = (TYPE_HAS_OBJC_INFO (type1)
9965 ? TYPE_OBJC_PROTOCOL_LIST (type1)
9966 : NULL_TREE);
9967 type2 = (TYPE_HAS_OBJC_INFO (type2)
9968 ? TYPE_OBJC_PROTOCOL_LIST (type2)
9969 : NULL_TREE);
9971 if (list_length (type1) == list_length (type2))
9973 for (; type2; type2 = TREE_CHAIN (type2))
9974 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
9975 return 0;
9976 return 1;
9978 return 0;
9981 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
9983 static int
9984 objc_types_share_size_and_alignment (tree type1, tree type2)
9986 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
9987 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
9990 /* Return 1 if PROTO1 is equivalent to PROTO2
9991 for purposes of method overloading. Ordinarily, the type signatures
9992 should match up exactly, unless STRICT is zero, in which case we
9993 shall allow differences in which the size and alignment of a type
9994 is the same. */
9996 static int
9997 comp_proto_with_proto (tree proto1, tree proto2, int strict)
9999 /* The following test is needed in case there are hashing
10000 collisions. */
10001 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
10002 return 0;
10004 return match_proto_with_proto (proto1, proto2, strict);
10007 static int
10008 match_proto_with_proto (tree proto1, tree proto2, int strict)
10010 tree type1, type2;
10012 /* Compare return types. */
10013 type1 = TREE_VALUE (TREE_TYPE (proto1));
10014 type2 = TREE_VALUE (TREE_TYPE (proto2));
10016 if (!objc_types_are_equivalent (type1, type2)
10017 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
10018 return 0;
10020 /* Compare argument types. */
10021 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
10022 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
10023 type1 && type2;
10024 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
10026 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
10027 && (strict
10028 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
10029 TREE_VALUE (type2))))
10030 return 0;
10033 return (!type1 && !type2);
10036 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
10037 this occurs. ObjC method dispatches are _not_ like C++ virtual
10038 member function dispatches, and we account for the difference here. */
10039 tree
10040 #ifdef OBJCPLUS
10041 objc_fold_obj_type_ref (tree ref, tree known_type)
10042 #else
10043 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
10044 tree known_type ATTRIBUTE_UNUSED)
10045 #endif
10047 #ifdef OBJCPLUS
10048 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
10050 /* If the receiver does not have virtual member functions, there
10051 is nothing we can (or need to) do here. */
10052 if (!v)
10053 return NULL_TREE;
10055 /* Let C++ handle C++ virtual functions. */
10056 return cp_fold_obj_type_ref (ref, known_type);
10057 #else
10058 /* For plain ObjC, we currently do not need to do anything. */
10059 return NULL_TREE;
10060 #endif
10063 static void
10064 objc_start_function (tree name, tree type, tree attrs,
10065 #ifdef OBJCPLUS
10066 tree params
10067 #else
10068 struct c_arg_info *params
10069 #endif
10072 tree fndecl = build_decl (input_location,
10073 FUNCTION_DECL, name, type);
10075 #ifdef OBJCPLUS
10076 DECL_ARGUMENTS (fndecl) = params;
10077 DECL_INITIAL (fndecl) = error_mark_node;
10078 DECL_EXTERNAL (fndecl) = 0;
10079 TREE_STATIC (fndecl) = 1;
10080 retrofit_lang_decl (fndecl);
10081 cplus_decl_attributes (&fndecl, attrs, 0);
10082 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
10083 #else
10084 current_function_returns_value = 0; /* Assume, until we see it does. */
10085 current_function_returns_null = 0;
10087 decl_attributes (&fndecl, attrs, 0);
10088 announce_function (fndecl);
10089 DECL_INITIAL (fndecl) = error_mark_node;
10090 DECL_EXTERNAL (fndecl) = 0;
10091 TREE_STATIC (fndecl) = 1;
10092 current_function_decl = pushdecl (fndecl);
10093 push_scope ();
10094 declare_parm_level ();
10095 DECL_RESULT (current_function_decl)
10096 = build_decl (input_location,
10097 RESULT_DECL, NULL_TREE,
10098 TREE_TYPE (TREE_TYPE (current_function_decl)));
10099 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
10100 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
10101 start_fname_decls ();
10102 store_parm_decls_from (params);
10103 #endif
10105 TREE_USED (current_function_decl) = 1;
10108 /* - Generate an identifier for the function. the format is "_n_cls",
10109 where 1 <= n <= nMethods, and cls is the name the implementation we
10110 are processing.
10111 - Install the return type from the method declaration.
10112 - If we have a prototype, check for type consistency. */
10114 static void
10115 really_start_method (tree method,
10116 #ifdef OBJCPLUS
10117 tree parmlist
10118 #else
10119 struct c_arg_info *parmlist
10120 #endif
10123 tree ret_type, meth_type;
10124 tree method_id;
10125 const char *sel_name, *class_name, *cat_name;
10126 char *buf;
10128 /* Synth the storage class & assemble the return type. */
10129 ret_type = TREE_VALUE (TREE_TYPE (method));
10131 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
10132 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
10133 cat_name = ((TREE_CODE (objc_implementation_context)
10134 == CLASS_IMPLEMENTATION_TYPE)
10135 ? NULL
10136 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
10137 method_slot++;
10139 /* Make sure this is big enough for any plausible method label. */
10140 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
10141 + (cat_name ? strlen (cat_name) : 0));
10143 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
10144 class_name, cat_name, sel_name, method_slot);
10146 method_id = get_identifier (buf);
10148 #ifdef OBJCPLUS
10149 /* Objective-C methods cannot be overloaded, so we don't need
10150 the type encoding appended. It looks bad anyway... */
10151 push_lang_context (lang_name_c);
10152 #endif
10154 meth_type
10155 = build_function_type (ret_type,
10156 get_arg_type_list (method, METHOD_DEF, 0));
10157 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
10159 /* Set self_decl from the first argument. */
10160 self_decl = DECL_ARGUMENTS (current_function_decl);
10162 /* Suppress unused warnings. */
10163 TREE_USED (self_decl) = 1;
10164 DECL_READ_P (self_decl) = 1;
10165 TREE_USED (DECL_CHAIN (self_decl)) = 1;
10166 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
10167 #ifdef OBJCPLUS
10168 pop_lang_context ();
10169 #endif
10171 METHOD_DEFINITION (method) = current_function_decl;
10173 /* Check consistency...start_function, pushdecl, duplicate_decls. */
10175 if (implementation_template != objc_implementation_context)
10177 tree proto
10178 = lookup_method_static (implementation_template,
10179 METHOD_SEL_NAME (method),
10180 ((TREE_CODE (method) == CLASS_METHOD_DECL)
10181 | OBJC_LOOKUP_NO_SUPER));
10183 if (proto)
10185 if (!comp_proto_with_proto (method, proto, 1))
10187 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
10189 warning_at (DECL_SOURCE_LOCATION (method), 0,
10190 "conflicting types for %<%c%s%>",
10191 (type ? '-' : '+'),
10192 identifier_to_locale (gen_method_decl (method)));
10193 inform (DECL_SOURCE_LOCATION (proto),
10194 "previous declaration of %<%c%s%>",
10195 (type ? '-' : '+'),
10196 identifier_to_locale (gen_method_decl (proto)));
10199 else
10201 /* We have a method @implementation even though we did not
10202 see a corresponding @interface declaration (which is allowed
10203 by Objective-C rules). Go ahead and place the method in
10204 the @interface anyway, so that message dispatch lookups
10205 will see it. */
10206 tree interface = implementation_template;
10208 if (TREE_CODE (objc_implementation_context)
10209 == CATEGORY_IMPLEMENTATION_TYPE)
10210 interface = lookup_category
10211 (interface,
10212 CLASS_SUPER_NAME (objc_implementation_context));
10214 if (interface)
10215 objc_add_method (interface, copy_node (method),
10216 TREE_CODE (method) == CLASS_METHOD_DECL,
10217 /* is_optional= */ false);
10222 static void *UOBJC_SUPER_scope = 0;
10224 /* _n_Method (id self, SEL sel, ...)
10226 struct objc_super _S;
10227 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
10228 } */
10230 static tree
10231 get_super_receiver (void)
10233 if (objc_method_context)
10235 tree super_expr, super_expr_list;
10237 if (!UOBJC_SUPER_decl)
10239 UOBJC_SUPER_decl = build_decl (input_location,
10240 VAR_DECL, get_identifier (TAG_SUPER),
10241 objc_super_template);
10242 /* This prevents `unused variable' warnings when compiling with -Wall. */
10243 TREE_USED (UOBJC_SUPER_decl) = 1;
10244 DECL_READ_P (UOBJC_SUPER_decl) = 1;
10245 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
10246 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
10247 NULL_TREE);
10248 UOBJC_SUPER_scope = objc_get_current_scope ();
10251 /* Set receiver to self. */
10252 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
10253 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
10254 NOP_EXPR, input_location, self_decl,
10255 NULL_TREE);
10256 super_expr_list = super_expr;
10258 /* Set class to begin searching. */
10259 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
10260 get_identifier ("super_class"));
10262 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
10264 /* [_cls, __cls]Super are "pre-built" in
10265 synth_forward_declarations. */
10267 super_expr = build_modify_expr (input_location, super_expr,
10268 NULL_TREE, NOP_EXPR,
10269 input_location,
10270 ((TREE_CODE (objc_method_context)
10271 == INSTANCE_METHOD_DECL)
10272 ? ucls_super_ref
10273 : uucls_super_ref),
10274 NULL_TREE);
10277 else
10278 /* We have a category. */
10280 tree super_name = CLASS_SUPER_NAME (implementation_template);
10281 tree super_class;
10283 /* Barf if super used in a category of Object. */
10284 if (!super_name)
10286 error ("no super class declared in interface for %qE",
10287 CLASS_NAME (implementation_template));
10288 return error_mark_node;
10291 if (flag_next_runtime && !flag_zero_link)
10293 super_class = objc_get_class_reference (super_name);
10294 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
10295 /* If we are in a class method, we must retrieve the
10296 _metaclass_ for the current class, pointed at by
10297 the class's "isa" pointer. The following assumes that
10298 "isa" is the first ivar in a class (which it must be). */
10299 super_class
10300 = build_indirect_ref
10301 (input_location,
10302 build_c_cast (input_location,
10303 build_pointer_type (objc_class_type),
10304 super_class), RO_UNARY_STAR);
10306 else
10308 add_class_reference (super_name);
10309 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
10310 ? objc_get_class_decl : objc_get_meta_class_decl);
10311 assemble_external (super_class);
10312 super_class
10313 = build_function_call
10314 (input_location,
10315 super_class,
10316 build_tree_list
10317 (NULL_TREE,
10318 my_build_string_pointer
10319 (IDENTIFIER_LENGTH (super_name) + 1,
10320 IDENTIFIER_POINTER (super_name))));
10323 super_expr
10324 = build_modify_expr (input_location, super_expr, NULL_TREE,
10325 NOP_EXPR,
10326 input_location,
10327 build_c_cast (input_location,
10328 TREE_TYPE (super_expr),
10329 super_class),
10330 NULL_TREE);
10333 super_expr_list = build_compound_expr (input_location,
10334 super_expr_list, super_expr);
10336 super_expr = build_unary_op (input_location,
10337 ADDR_EXPR, UOBJC_SUPER_decl, 0);
10338 super_expr_list = build_compound_expr (input_location,
10339 super_expr_list, super_expr);
10341 return super_expr_list;
10343 else
10345 error ("[super ...] must appear in a method context");
10346 return error_mark_node;
10350 /* When exiting a scope, sever links to a 'super' declaration (if any)
10351 therein contained. */
10353 void
10354 objc_clear_super_receiver (void)
10356 if (objc_method_context
10357 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
10358 UOBJC_SUPER_decl = 0;
10359 UOBJC_SUPER_scope = 0;
10363 void
10364 objc_finish_method_definition (tree fndecl)
10366 /* We cannot validly inline ObjC methods, at least not without a language
10367 extension to declare that a method need not be dynamically
10368 dispatched, so suppress all thoughts of doing so. */
10369 DECL_UNINLINABLE (fndecl) = 1;
10371 #ifndef OBJCPLUS
10372 /* The C++ front-end will have called finish_function() for us. */
10373 finish_function ();
10374 #endif
10376 METHOD_ENCODING (objc_method_context)
10377 = encode_method_prototype (objc_method_context);
10379 /* Required to implement _msgSuper. This must be done AFTER finish_function,
10380 since the optimizer may find "may be used before set" errors. */
10381 objc_method_context = NULL_TREE;
10383 if (should_call_super_dealloc)
10384 warning (0, "method possibly missing a [super dealloc] call");
10387 /* Given a tree DECL node, produce a printable description of it in the given
10388 buffer, overwriting the buffer. */
10390 static char *
10391 gen_declaration (tree decl)
10393 errbuf[0] = '\0';
10395 if (DECL_P (decl))
10397 gen_type_name_0 (TREE_TYPE (decl));
10399 if (DECL_NAME (decl))
10401 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
10402 strcat (errbuf, " ");
10404 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
10407 if (DECL_INITIAL (decl)
10408 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
10409 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
10410 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
10413 return errbuf;
10416 /* Given a tree TYPE node, produce a printable description of it in the given
10417 buffer, overwriting the buffer. */
10419 static char *
10420 gen_type_name_0 (tree type)
10422 tree orig = type, proto;
10424 if (TYPE_P (type) && TYPE_NAME (type))
10425 type = TYPE_NAME (type);
10426 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
10428 tree inner = TREE_TYPE (type);
10430 while (TREE_CODE (inner) == ARRAY_TYPE)
10431 inner = TREE_TYPE (inner);
10433 gen_type_name_0 (inner);
10435 if (!POINTER_TYPE_P (inner))
10436 strcat (errbuf, " ");
10438 if (POINTER_TYPE_P (type))
10439 strcat (errbuf, "*");
10440 else
10441 while (type != inner)
10443 strcat (errbuf, "[");
10445 if (TYPE_DOMAIN (type))
10447 char sz[20];
10449 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
10450 (TREE_INT_CST_LOW
10451 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
10452 strcat (errbuf, sz);
10455 strcat (errbuf, "]");
10456 type = TREE_TYPE (type);
10459 goto exit_function;
10462 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
10463 type = DECL_NAME (type);
10465 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
10466 ? IDENTIFIER_POINTER (type)
10467 : "");
10469 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
10470 if (objc_is_id (orig))
10471 orig = TREE_TYPE (orig);
10473 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
10475 if (proto)
10477 strcat (errbuf, " <");
10479 while (proto) {
10480 strcat (errbuf,
10481 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
10482 proto = TREE_CHAIN (proto);
10483 strcat (errbuf, proto ? ", " : ">");
10487 exit_function:
10488 return errbuf;
10491 static char *
10492 gen_type_name (tree type)
10494 errbuf[0] = '\0';
10496 return gen_type_name_0 (type);
10499 /* Given a method tree, put a printable description into the given
10500 buffer (overwriting) and return a pointer to the buffer. */
10502 static char *
10503 gen_method_decl (tree method)
10505 tree chain;
10507 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
10508 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
10509 strcat (errbuf, ")");
10510 chain = METHOD_SEL_ARGS (method);
10512 if (chain)
10514 /* We have a chain of keyword_decls. */
10517 if (KEYWORD_KEY_NAME (chain))
10518 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
10520 strcat (errbuf, ":(");
10521 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
10522 strcat (errbuf, ")");
10524 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
10525 if ((chain = DECL_CHAIN (chain)))
10526 strcat (errbuf, " ");
10528 while (chain);
10530 if (METHOD_ADD_ARGS (method))
10532 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
10534 /* Know we have a chain of parm_decls. */
10535 while (chain)
10537 strcat (errbuf, ", ");
10538 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
10539 chain = TREE_CHAIN (chain);
10542 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
10543 strcat (errbuf, ", ...");
10547 else
10548 /* We have a unary selector. */
10549 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
10551 return errbuf;
10554 /* Debug info. */
10557 /* Dump an @interface declaration of the supplied class CHAIN to the
10558 supplied file FP. Used to implement the -gen-decls option (which
10559 prints out an @interface declaration of all classes compiled in
10560 this run); potentially useful for debugging the compiler too. */
10561 static void
10562 dump_interface (FILE *fp, tree chain)
10564 /* FIXME: A heap overflow here whenever a method (or ivar)
10565 declaration is so long that it doesn't fit in the buffer. The
10566 code and all the related functions should be rewritten to avoid
10567 using fixed size buffers. */
10568 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
10569 tree ivar_decls = CLASS_RAW_IVARS (chain);
10570 tree nst_methods = CLASS_NST_METHODS (chain);
10571 tree cls_methods = CLASS_CLS_METHODS (chain);
10573 fprintf (fp, "\n@interface %s", my_name);
10575 /* CLASS_SUPER_NAME is used to store the superclass name for
10576 classes, and the category name for categories. */
10577 if (CLASS_SUPER_NAME (chain))
10579 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
10581 switch (TREE_CODE (chain))
10583 case CATEGORY_IMPLEMENTATION_TYPE:
10584 case CATEGORY_INTERFACE_TYPE:
10585 fprintf (fp, " (%s)\n", name);
10586 break;
10587 default:
10588 fprintf (fp, " : %s\n", name);
10589 break;
10592 else
10593 fprintf (fp, "\n");
10595 /* FIXME - the following doesn't seem to work at the moment. */
10596 if (ivar_decls)
10598 fprintf (fp, "{\n");
10601 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
10602 ivar_decls = TREE_CHAIN (ivar_decls);
10604 while (ivar_decls);
10605 fprintf (fp, "}\n");
10608 while (nst_methods)
10610 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
10611 nst_methods = TREE_CHAIN (nst_methods);
10614 while (cls_methods)
10616 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
10617 cls_methods = TREE_CHAIN (cls_methods);
10620 fprintf (fp, "@end\n");
10623 #if 0
10624 /* Produce the pretty printing for an Objective-C method. This is
10625 currently unused, but could be handy while reorganizing the pretty
10626 printing to be more robust. */
10627 static const char *
10628 objc_pretty_print_method (bool is_class_method,
10629 const char *class_name,
10630 const char *category_name,
10631 const char *selector)
10633 if (category_name)
10635 char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
10636 + strlen (selector) + 7);
10638 if (is_class_method)
10639 sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
10640 else
10641 sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
10643 return result;
10645 else
10647 char *result = XNEWVEC (char, strlen (class_name)
10648 + strlen (selector) + 5);
10650 if (is_class_method)
10651 sprintf (result, "+[%s %s]", class_name, selector);
10652 else
10653 sprintf (result, "-[%s %s]", class_name, selector);
10655 return result;
10658 #endif
10660 /* Demangle function for Objective-C. Attempt to demangle the
10661 function name associated with a method (eg, going from
10662 "_i_NSObject__class" to "-[NSObject class]"); usually for the
10663 purpose of pretty printing or error messages. Return the demangled
10664 name, or NULL if the string is not an Objective-C mangled method
10665 name.
10667 Because of how the mangling is done, any method that has a '_' in
10668 its original name is at risk of being demangled incorrectly. In
10669 some cases there are multiple valid ways to demangle a method name
10670 and there is no way we can decide.
10672 TODO: objc_demangle() can't always get it right; the right way to
10673 get this correct for all method names would be to store the
10674 Objective-C method name somewhere in the function decl. Then,
10675 there is no demangling to do; we'd just pull the method name out of
10676 the decl. As an additional bonus, when printing error messages we
10677 could check for such a method name, and if we find it, we know the
10678 function is actually an Objective-C method and we could print error
10679 messages saying "In method '+[NSObject class]" instead of "In
10680 function '+[NSObject class]" as we do now. */
10681 static const char *
10682 objc_demangle (const char *mangled)
10684 char *demangled, *cp;
10686 if (mangled[0] == '_' &&
10687 (mangled[1] == 'i' || mangled[1] == 'c') &&
10688 mangled[2] == '_')
10690 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
10691 if (mangled[1] == 'i')
10692 *cp++ = '-'; /* for instance method */
10693 else
10694 *cp++ = '+'; /* for class method */
10695 *cp++ = '['; /* opening left brace */
10696 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
10697 while (*cp && *cp == '_')
10698 cp++; /* skip any initial underbars in class name */
10699 cp = strchr(cp, '_'); /* find first non-initial underbar */
10700 if (cp == NULL)
10702 free(demangled); /* not mangled name */
10703 return NULL;
10705 if (cp[1] == '_') /* easy case: no category name */
10707 *cp++ = ' '; /* replace two '_' with one ' ' */
10708 strcpy(cp, mangled + (cp - demangled) + 2);
10710 else
10712 *cp++ = '('; /* less easy case: category name */
10713 cp = strchr(cp, '_');
10714 if (cp == 0)
10716 free(demangled); /* not mangled name */
10717 return NULL;
10719 *cp++ = ')';
10720 *cp++ = ' '; /* overwriting 1st char of method name... */
10721 strcpy(cp, mangled + (cp - demangled)); /* get it back */
10723 /* Now we have the method name. We need to generally replace
10724 '_' with ':' but trying to preserve '_' if it could only have
10725 been in the mangled string because it was already in the
10726 original name. In cases where it's ambiguous, we assume that
10727 any '_' originated from a ':'. */
10729 /* Initial '_'s in method name can't have been generating by
10730 converting ':'s. Skip them. */
10731 while (*cp && *cp == '_')
10732 cp++;
10734 /* If the method name does not end with '_', then it has no
10735 arguments and there was no replacement of ':'s with '_'s
10736 during mangling. Check for that case, and skip any
10737 replacement if so. This at least guarantees that methods
10738 with no arguments are always demangled correctly (unless the
10739 original name ends with '_'). */
10740 if (*(mangled + strlen (mangled) - 1) != '_')
10742 /* Skip to the end. */
10743 for (; *cp; cp++)
10746 else
10748 /* Replace remaining '_' with ':'. This may get it wrong if
10749 there were '_'s in the original name. In most cases it
10750 is impossible to disambiguate. */
10751 for (; *cp; cp++)
10752 if (*cp == '_')
10753 *cp = ':';
10755 *cp++ = ']'; /* closing right brace */
10756 *cp++ = 0; /* string terminator */
10757 return demangled;
10759 else
10760 return NULL; /* not an objc mangled name */
10763 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
10764 specific decl, return the printable name for it. If not, return
10765 NULL. */
10766 const char *
10767 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
10769 const char *decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
10771 switch (TREE_CODE (decl))
10773 case FUNCTION_DECL:
10774 return objc_demangle (decl_name);
10775 break;
10776 /* This unusual case (INSTANCE_METHOD_DECL and
10777 CLASS_METHOD_DECL) seems to happen only in ObjC++ and to be a
10778 by-product of the method attribute changes. It would be nice
10779 to be able to print "-[NSObject autorelease] is deprecated",
10780 but to do that, we'd need to store the class and method name
10781 in the method decl, which we currently don't do. For now,
10782 just return the name of the method. We don't return NULL,
10783 because that may trigger further attempts to pretty-print the
10784 decl in C/C++, but they wouldn't know how to pretty-print
10785 it. */
10786 case INSTANCE_METHOD_DECL:
10787 case CLASS_METHOD_DECL:
10788 return decl_name;
10789 break;
10790 default:
10791 return NULL;
10792 break;
10796 /* Return a printable name for 'decl'. This first tries
10797 objc_maybe_printable_name(), and if that fails, it hands it back to
10798 C/C++. 'v' is the verbosity level, as this is a
10799 LANG_HOOKS_DECL_PRINTABLE_NAME. */
10800 const char *
10801 objc_printable_name (tree decl, int v)
10803 const char *demangled_name = objc_maybe_printable_name (decl, v);
10805 if (demangled_name != NULL)
10806 return demangled_name;
10807 else
10809 #ifdef OBJCPLUS
10810 return cxx_printable_name (decl, v);
10811 #else
10812 return IDENTIFIER_POINTER (DECL_NAME (decl));
10813 #endif
10817 static void
10818 init_objc (void)
10820 gcc_obstack_init (&util_obstack);
10821 util_firstobj = (char *) obstack_finish (&util_obstack);
10823 errbuf = XNEWVEC (char, 1024 * 10);
10824 hash_init ();
10825 synth_module_prologue ();
10828 static void
10829 finish_objc (void)
10831 struct imp_entry *impent;
10832 tree chain;
10833 /* The internally generated initializers appear to have missing braces.
10834 Don't warn about this. */
10835 int save_warn_missing_braces = warn_missing_braces;
10836 warn_missing_braces = 0;
10838 /* A missing @end may not be detected by the parser. */
10839 if (objc_implementation_context)
10841 warning (0, "%<@end%> missing in implementation context");
10842 finish_class (objc_implementation_context);
10843 objc_ivar_chain = NULL_TREE;
10844 objc_implementation_context = NULL_TREE;
10847 /* Process the static instances here because initialization of objc_symtab
10848 depends on them. */
10849 if (objc_static_instances)
10850 generate_static_references ();
10852 /* forward declare categories */
10853 if (cat_count)
10854 forward_declare_categories ();
10856 for (impent = imp_list; impent; impent = impent->next)
10858 objc_implementation_context = impent->imp_context;
10859 implementation_template = impent->imp_template;
10861 /* FIXME: This needs reworking to be more obvious. */
10863 UOBJC_CLASS_decl = impent->class_decl;
10864 UOBJC_METACLASS_decl = impent->meta_decl;
10866 /* Dump the @interface of each class as we compile it, if the
10867 -gen-decls option is in use. TODO: Dump the classes in the
10868 order they were found, rather than in reverse order as we
10869 are doing now. */
10870 if (flag_gen_declaration)
10872 dump_interface (gen_declaration_file, objc_implementation_context);
10875 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
10877 /* all of the following reference the string pool... */
10878 generate_ivar_lists ();
10879 generate_dispatch_tables ();
10880 generate_shared_structures (impent);
10882 else
10884 generate_dispatch_tables ();
10885 generate_category (impent);
10888 impent->class_decl = UOBJC_CLASS_decl;
10889 impent->meta_decl = UOBJC_METACLASS_decl;
10892 /* If we are using an array of selectors, we must always
10893 finish up the array decl even if no selectors were used. */
10894 if (flag_next_runtime)
10895 build_next_selector_translation_table ();
10896 else
10897 build_gnu_selector_translation_table ();
10899 if (protocol_chain)
10900 generate_protocols ();
10902 if (flag_next_runtime)
10903 generate_objc_image_info ();
10905 if (imp_list || class_names_chain
10906 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
10907 generate_objc_symtab_decl ();
10909 /* Arrange for ObjC data structures to be initialized at run time. */
10910 if (objc_implementation_context || class_names_chain || objc_static_instances
10911 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
10913 build_module_descriptor ();
10915 if (!flag_next_runtime)
10916 build_module_initializer_routine ();
10919 /* Dump the class references. This forces the appropriate classes
10920 to be linked into the executable image, preserving unix archive
10921 semantics. This can be removed when we move to a more dynamically
10922 linked environment. */
10924 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
10926 handle_class_ref (chain);
10927 if (TREE_PURPOSE (chain))
10928 generate_classref_translation_entry (chain);
10931 for (impent = imp_list; impent; impent = impent->next)
10932 handle_impent (impent);
10934 if (warn_selector)
10936 int slot;
10937 hash hsh;
10939 /* Run through the selector hash tables and print a warning for any
10940 selector which has multiple methods. */
10942 for (slot = 0; slot < SIZEHASHTABLE; slot++)
10944 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
10945 check_duplicates (hsh, 0, 1);
10946 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
10947 check_duplicates (hsh, 0, 1);
10951 warn_missing_braces = save_warn_missing_braces;
10954 /* Subroutines of finish_objc. */
10956 static void
10957 generate_classref_translation_entry (tree chain)
10959 tree expr, decl, type;
10961 decl = TREE_PURPOSE (chain);
10962 type = TREE_TYPE (decl);
10964 expr = add_objc_string (TREE_VALUE (chain), class_names);
10965 expr = convert (type, expr); /* cast! */
10967 /* This is a class reference. It is re-written by the runtime,
10968 but will be optimized away unless we force it. */
10969 DECL_PRESERVE_P (decl) = 1;
10970 finish_var_decl (decl, expr);
10971 return;
10974 static void
10975 handle_class_ref (tree chain)
10977 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
10978 char *string = (char *) alloca (strlen (name) + 30);
10979 tree decl;
10980 tree exp;
10982 sprintf (string, "%sobjc_class_name_%s",
10983 (flag_next_runtime ? "." : "__"), name);
10985 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
10986 if (flag_next_runtime)
10988 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
10989 return;
10991 #endif
10993 /* Make a decl for this name, so we can use its address in a tree. */
10994 decl = build_decl (input_location,
10995 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
10996 DECL_EXTERNAL (decl) = 1;
10997 TREE_PUBLIC (decl) = 1;
10998 pushdecl (decl);
10999 finish_var_decl (decl, 0);
11001 /* Make a decl for the address. */
11002 sprintf (string, "%sobjc_class_ref_%s",
11003 (flag_next_runtime ? "." : "__"), name);
11004 exp = build1 (ADDR_EXPR, string_type_node, decl);
11005 decl = build_decl (input_location,
11006 VAR_DECL, get_identifier (string), string_type_node);
11007 TREE_STATIC (decl) = 1;
11008 TREE_USED (decl) = 1;
11009 DECL_READ_P (decl) = 1;
11010 DECL_ARTIFICIAL (decl) = 1;
11011 DECL_INITIAL (decl) = error_mark_node;
11013 /* We must force the reference. */
11014 DECL_PRESERVE_P (decl) = 1;
11016 pushdecl (decl);
11017 finish_var_decl (decl, exp);
11020 static void
11021 handle_impent (struct imp_entry *impent)
11023 char *string;
11025 objc_implementation_context = impent->imp_context;
11026 implementation_template = impent->imp_template;
11028 switch (TREE_CODE (impent->imp_context))
11030 case CLASS_IMPLEMENTATION_TYPE:
11032 const char *const class_name =
11033 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
11035 string = (char *) alloca (strlen (class_name) + 30);
11037 sprintf (string, "%sobjc_class_name_%s",
11038 (flag_next_runtime ? "." : "__"), class_name);
11039 break;
11041 case CATEGORY_IMPLEMENTATION_TYPE:
11043 const char *const class_name =
11044 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
11045 const char *const class_super_name =
11046 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
11048 string = (char *) alloca (strlen (class_name)
11049 + strlen (class_super_name) + 30);
11051 /* Do the same for categories. Even though no references to
11052 these symbols are generated automatically by the compiler,
11053 it gives you a handle to pull them into an archive by
11054 hand. */
11055 sprintf (string, "*%sobjc_category_name_%s_%s",
11056 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
11057 break;
11059 default:
11060 return;
11063 #ifdef ASM_DECLARE_CLASS_REFERENCE
11064 if (flag_next_runtime)
11066 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
11067 return;
11069 else
11070 #endif
11072 tree decl, init;
11074 init = integer_zero_node;
11075 decl = build_decl (input_location,
11076 VAR_DECL, get_identifier (string), TREE_TYPE (init));
11077 TREE_PUBLIC (decl) = 1;
11078 TREE_READONLY (decl) = 1;
11079 TREE_USED (decl) = 1;
11080 TREE_CONSTANT (decl) = 1;
11081 DECL_CONTEXT (decl) = NULL_TREE;
11082 DECL_ARTIFICIAL (decl) = 1;
11083 TREE_STATIC (decl) = 1;
11084 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
11085 /* We must force the reference. */
11086 DECL_PRESERVE_P (decl) = 1;
11088 finish_var_decl(decl, init) ;
11092 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
11093 later requires that ObjC translation units participating in F&C be
11094 specially marked. The following routine accomplishes this. */
11096 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
11098 static void
11099 generate_objc_image_info (void)
11101 tree decl;
11102 int flags
11103 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
11104 | (flag_objc_gc ? 2 : 0));
11105 VEC(constructor_elt,gc) *v = NULL;
11106 tree array_type;
11108 if (!flags)
11109 return; /* No need for an image_info entry. */
11111 array_type = build_sized_array_type (integer_type_node, 2);
11113 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
11115 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
11116 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
11117 /* If we need this (determined above) it is because the runtime wants to
11118 refer to it in a manner hidden from the compiler. So we must force the
11119 output. */
11120 DECL_PRESERVE_P (decl) = 1;
11121 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
11124 /* Routine is called to issue diagnostic when reference to a private
11125 ivar is made and no other variable with same name is found in
11126 current scope. */
11127 bool
11128 objc_diagnose_private_ivar (tree id)
11130 tree ivar;
11131 if (!objc_method_context)
11132 return false;
11133 ivar = is_ivar (objc_ivar_chain, id);
11134 if (ivar && is_private (ivar))
11136 error ("instance variable %qs is declared private",
11137 IDENTIFIER_POINTER (id));
11138 return true;
11140 return false;
11143 /* Look up ID as an instance variable. OTHER contains the result of
11144 the C or C++ lookup, which we may want to use instead. */
11145 /* Also handle use of property as setter/getter. */
11146 tree
11147 objc_lookup_ivar (tree other, tree id)
11149 tree ivar, property;
11151 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
11152 if (!objc_method_context)
11153 return other;
11155 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
11156 /* We have a message to super. */
11157 return get_super_receiver ();
11159 /* In a class method, look up an instance variable only as a last
11160 resort. */
11161 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
11162 && other && other != error_mark_node)
11163 return other;
11165 property = NULL_TREE;
11166 if (objc_implementation_context)
11167 property = is_property (objc_implementation_context, id);
11169 if (!property)
11171 /* Look up the ivar, but do not use it if it is not accessible. */
11172 ivar = is_ivar (objc_ivar_chain, id);
11174 if (!ivar || is_private (ivar))
11175 return other;
11178 /* In an instance method, a local variable (or parameter) may hide the
11179 instance variable. */
11180 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
11181 && other && other != error_mark_node
11182 #ifdef OBJCPLUS
11183 && CP_DECL_CONTEXT (other) != global_namespace)
11184 #else
11185 && !DECL_FILE_SCOPE_P (other))
11186 #endif
11188 if (property)
11189 warning (0, "local declaration of %qE hides property", id);
11190 else
11191 warning (0, "local declaration of %qE hides instance variable", id);
11193 return other;
11196 if (property)
11197 return build_property_reference (property, id);
11199 /* At this point, we are either in an instance method with no obscuring
11200 local definitions, or in a class method with no alternate definitions
11201 at all. */
11202 return build_ivar_reference (id);
11205 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
11206 needs to be done if we are calling a function through a cast. */
11208 tree
11209 objc_rewrite_function_call (tree function, tree first_param)
11211 if (TREE_CODE (function) == NOP_EXPR
11212 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
11213 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
11214 == FUNCTION_DECL)
11216 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
11217 TREE_OPERAND (function, 0),
11218 first_param, size_zero_node);
11221 return function;
11224 /* Look for the special case of OBJC_TYPE_REF with the address of
11225 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
11226 of its cousins). */
11229 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
11231 enum gimplify_status r0, r1;
11232 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
11233 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
11234 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
11235 == FUNCTION_DECL)
11237 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
11238 value of the OBJ_TYPE_REF, so force them to be emitted
11239 during subexpression evaluation rather than after the
11240 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
11241 C to use direct rather than indirect calls when the
11242 object expression has a postincrement. */
11243 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
11244 is_gimple_val, fb_rvalue);
11245 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
11246 is_gimple_val, fb_rvalue);
11248 return MIN (r0, r1);
11251 #ifdef OBJCPLUS
11252 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
11253 #else
11254 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
11255 #endif
11258 /* This routine returns true if TYP is a valid objc object type,
11259 suitable for messaging; false otherwise.
11262 static bool
11263 objc_type_valid_for_messaging (tree typ)
11265 if (!POINTER_TYPE_P (typ))
11266 return false;
11269 typ = TREE_TYPE (typ); /* Remove indirections. */
11270 while (POINTER_TYPE_P (typ));
11272 if (TREE_CODE (typ) != RECORD_TYPE)
11273 return false;
11275 return objc_is_object_id (typ) || TYPE_HAS_OBJC_INFO (typ);
11278 /* Begin code generation for fast enumeration (foreach) ... */
11280 /* Defines
11282 struct __objcFastEnumerationState
11284 unsigned long state;
11285 id *itemsPtr;
11286 unsigned long *mutationsPtr;
11287 unsigned long extra[5];
11290 Confusingly enough, NSFastEnumeration is then defined by libraries
11291 to be the same structure.
11294 static void
11295 build_fast_enumeration_state_template (void)
11297 tree decls, *chain = NULL;
11299 /* { */
11300 objc_fast_enumeration_state_template = objc_start_struct (get_identifier
11301 (TAG_FAST_ENUMERATION_STATE));
11303 /* unsigned long state; */
11304 decls = add_field_decl (long_unsigned_type_node, "state", &chain);
11306 /* id *itemsPtr; */
11307 add_field_decl (build_pointer_type (objc_object_type),
11308 "itemsPtr", &chain);
11310 /* unsigned long *mutationsPtr; */
11311 add_field_decl (build_pointer_type (long_unsigned_type_node),
11312 "mutationsPtr", &chain);
11314 /* unsigned long extra[5]; */
11315 add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
11316 "extra", &chain);
11318 /* } */
11319 objc_finish_struct (objc_fast_enumeration_state_template, decls);
11323 'objc_finish_foreach_loop()' generates the code for an Objective-C
11324 foreach loop. The 'location' argument is the location of the 'for'
11325 that starts the loop. The 'object_expression' is the expression of
11326 the 'object' that iterates; the 'collection_expression' is the
11327 expression of the collection that we iterate over (we need to make
11328 sure we evaluate this only once); the 'for_body' is the set of
11329 statements to be executed in each iteration; 'break_label' and
11330 'continue_label' are the break and continue labels which we need to
11331 emit since the <statements> may be jumping to 'break_label' (if they
11332 contain 'break') or to 'continue_label' (if they contain
11333 'continue').
11335 The syntax is
11337 for (<object expression> in <collection expression>)
11338 <statements>
11340 which is compiled into the following blurb:
11343 id __objc_foreach_collection;
11344 __objc_fast_enumeration_state __objc_foreach_enum_state;
11345 unsigned long __objc_foreach_batchsize;
11346 id __objc_foreach_items[16];
11347 __objc_foreach_collection = <collection expression>;
11348 __objc_foreach_enum_state = { 0 };
11349 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11351 if (__objc_foreach_batchsize == 0)
11352 <object expression> = nil;
11353 else
11355 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
11356 next_batch:
11358 unsigned long __objc_foreach_index;
11359 __objc_foreach_index = 0;
11361 next_object:
11362 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
11363 <object expression> = enumState.itemsPtr[__objc_foreach_index];
11364 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
11366 continue_label:
11367 __objc_foreach_index++;
11368 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
11369 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
11371 if (__objc_foreach_batchsize != 0) goto next_batch;
11372 <object expression> = nil;
11373 break_label:
11377 'statements' may contain a 'continue' or 'break' instruction, which
11378 the user expects to 'continue' or 'break' the entire foreach loop.
11379 We are provided the labels that 'break' and 'continue' jump to, so
11380 we place them where we want them to jump to when they pick them.
11382 Optimization TODO: we could cache the IMP of
11383 countByEnumeratingWithState:objects:count:.
11386 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
11387 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
11389 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11390 #include "tree-pretty-print.h"
11391 #endif
11393 void
11394 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
11395 tree break_label, tree continue_label)
11397 /* A tree representing the __objcFastEnumerationState struct type,
11398 or NSFastEnumerationState struct, whatever we are using. */
11399 tree objc_fast_enumeration_state_type;
11401 /* The trees representing the declarations of each of the local variables. */
11402 tree objc_foreach_collection_decl;
11403 tree objc_foreach_enum_state_decl;
11404 tree objc_foreach_items_decl;
11405 tree objc_foreach_batchsize_decl;
11406 tree objc_foreach_mutations_pointer_decl;
11407 tree objc_foreach_index_decl;
11409 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
11410 tree selector_name;
11412 /* A tree representing the local bind. */
11413 tree bind;
11415 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
11416 tree first_if;
11418 /* A tree representing the 'else' part of 'first_if' */
11419 tree first_else;
11421 /* A tree representing the 'next_batch' label. */
11422 tree next_batch_label_decl;
11424 /* A tree representing the binding after the 'next_batch' label. */
11425 tree next_batch_bind;
11427 /* A tree representing the 'next_object' label. */
11428 tree next_object_label_decl;
11430 /* Temporary variables. */
11431 tree t;
11432 int i;
11434 if (object_expression == error_mark_node)
11435 return;
11437 if (collection_expression == error_mark_node)
11438 return;
11440 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression)))
11442 error ("iterating variable in fast enumeration is not an object");
11443 return;
11446 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression)))
11448 error ("collection in fast enumeration is not an object");
11449 return;
11452 /* TODO: Check that object_expression is either a variable
11453 declaration, or an lvalue. */
11455 /* This kludge is an idea from apple. We use the
11456 __objcFastEnumerationState struct implicitly defined by the
11457 compiler, unless a NSFastEnumerationState struct has been defined
11458 (by a Foundation library such as GNUstep Base) in which case, we
11459 use that one.
11461 objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
11463 tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
11465 if (objc_NSFastEnumeration_type)
11467 /* TODO: We really need to check that
11468 objc_NSFastEnumeration_type is the same as ours! */
11469 if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
11471 /* If it's a typedef, use the original type. */
11472 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
11473 objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
11474 else
11475 objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
11480 /* { */
11481 /* Done by c-parser.c. */
11483 /* type object; */
11484 /* Done by c-parser.c. */
11486 /* id __objc_foreach_collection */
11487 objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
11489 /* __objcFastEnumerationState __objc_foreach_enum_state; */
11490 objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
11491 TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
11493 /* id __objc_foreach_items[16]; */
11494 objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
11495 TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
11497 /* unsigned long __objc_foreach_batchsize; */
11498 objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
11499 TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
11501 /* Generate the local variable binding. */
11502 bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
11503 SET_EXPR_LOCATION (bind, location);
11504 TREE_SIDE_EFFECTS (bind) = 1;
11506 /* __objc_foreach_collection = <collection expression>; */
11507 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
11508 SET_EXPR_LOCATION (t, location);
11509 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11511 /* __objc_foreach_enum_state.state = 0; */
11512 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11513 get_identifier ("state")),
11514 build_int_cst (long_unsigned_type_node, 0));
11515 SET_EXPR_LOCATION (t, location);
11516 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11518 /* __objc_foreach_enum_state.itemsPtr = NULL; */
11519 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11520 get_identifier ("itemsPtr")),
11521 null_pointer_node);
11522 SET_EXPR_LOCATION (t, location);
11523 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11525 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
11526 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
11527 get_identifier ("mutationsPtr")),
11528 null_pointer_node);
11529 SET_EXPR_LOCATION (t, location);
11530 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11532 /* __objc_foreach_enum_state.extra[0] = 0; */
11533 /* __objc_foreach_enum_state.extra[1] = 0; */
11534 /* __objc_foreach_enum_state.extra[2] = 0; */
11535 /* __objc_foreach_enum_state.extra[3] = 0; */
11536 /* __objc_foreach_enum_state.extra[4] = 0; */
11537 for (i = 0; i < 5 ; i++)
11539 t = build2 (MODIFY_EXPR, void_type_node,
11540 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11541 get_identifier ("extra")),
11542 build_int_cst (NULL_TREE, i)),
11543 build_int_cst (long_unsigned_type_node, 0));
11544 SET_EXPR_LOCATION (t, location);
11545 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11548 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11549 selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
11550 #ifdef OBJCPLUS
11551 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11552 /* Parameters. */
11553 tree_cons /* &__objc_foreach_enum_state */
11554 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11555 tree_cons /* __objc_foreach_items */
11556 (NULL_TREE, objc_foreach_items_decl,
11557 tree_cons /* 16 */
11558 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11559 #else
11560 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11562 struct c_expr array;
11563 array.value = objc_foreach_items_decl;
11564 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11565 /* Parameters. */
11566 tree_cons /* &__objc_foreach_enum_state */
11567 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11568 tree_cons /* __objc_foreach_items */
11569 (NULL_TREE, default_function_array_conversion (location, array).value,
11570 tree_cons /* 16 */
11571 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11573 #endif
11574 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
11575 convert (long_unsigned_type_node, t));
11576 SET_EXPR_LOCATION (t, location);
11577 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
11579 /* if (__objc_foreach_batchsize == 0) */
11580 first_if = build3 (COND_EXPR, void_type_node,
11581 /* Condition. */
11582 c_fully_fold
11583 (c_common_truthvalue_conversion
11584 (location,
11585 build_binary_op (location,
11586 EQ_EXPR,
11587 objc_foreach_batchsize_decl,
11588 build_int_cst (long_unsigned_type_node, 0), 1)),
11589 false, NULL),
11590 /* Then block (we fill it in later). */
11591 NULL_TREE,
11592 /* Else block (we fill it in later). */
11593 NULL_TREE);
11594 SET_EXPR_LOCATION (first_if, location);
11595 append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
11597 /* then <object expression> = nil; */
11598 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
11599 SET_EXPR_LOCATION (t, location);
11600 COND_EXPR_THEN (first_if) = t;
11602 /* Now we build the 'else' part of the if; once we finish building
11603 it, we attach it to first_if as the 'else' part. */
11605 /* else */
11606 /* { */
11608 /* unsigned long __objc_foreach_mutations_pointer; */
11609 objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
11611 /* Generate the local variable binding. */
11612 first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
11613 SET_EXPR_LOCATION (first_else, location);
11614 TREE_SIDE_EFFECTS (first_else) = 1;
11616 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
11617 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
11618 build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11619 get_identifier ("mutationsPtr")),
11620 RO_UNARY_STAR));
11621 SET_EXPR_LOCATION (t, location);
11622 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11624 /* next_batch: */
11625 next_batch_label_decl = create_artificial_label (location);
11626 t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
11627 SET_EXPR_LOCATION (t, location);
11628 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11630 /* { */
11632 /* unsigned long __objc_foreach_index; */
11633 objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
11635 /* Generate the local variable binding. */
11636 next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
11637 SET_EXPR_LOCATION (next_batch_bind, location);
11638 TREE_SIDE_EFFECTS (next_batch_bind) = 1;
11639 append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
11641 /* __objc_foreach_index = 0; */
11642 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
11643 build_int_cst (long_unsigned_type_node, 0));
11644 SET_EXPR_LOCATION (t, location);
11645 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11647 /* next_object: */
11648 next_object_label_decl = create_artificial_label (location);
11649 t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
11650 SET_EXPR_LOCATION (t, location);
11651 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11653 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
11654 t = build3 (COND_EXPR, void_type_node,
11655 /* Condition. */
11656 c_fully_fold
11657 (c_common_truthvalue_conversion
11658 (location,
11659 build_binary_op
11660 (location,
11661 NE_EXPR,
11662 objc_foreach_mutations_pointer_decl,
11663 build_indirect_ref (location,
11664 objc_build_component_ref (objc_foreach_enum_state_decl,
11665 get_identifier ("mutationsPtr")),
11666 RO_UNARY_STAR), 1)),
11667 false, NULL),
11668 /* Then block. */
11669 build_function_call (input_location,
11670 objc_enumeration_mutation_decl,
11671 tree_cons (NULL, collection_expression, NULL)),
11672 /* Else block. */
11673 NULL_TREE);
11674 SET_EXPR_LOCATION (t, location);
11675 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11677 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
11678 t = build2 (MODIFY_EXPR, void_type_node, object_expression,
11679 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
11680 get_identifier ("itemsPtr")),
11681 objc_foreach_index_decl));
11682 SET_EXPR_LOCATION (t, location);
11683 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11685 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
11686 append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
11688 /* continue_label: */
11689 if (continue_label)
11691 t = build1 (LABEL_EXPR, void_type_node, continue_label);
11692 SET_EXPR_LOCATION (t, location);
11693 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11696 /* __objc_foreach_index++; */
11697 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
11698 build_binary_op (location,
11699 PLUS_EXPR,
11700 objc_foreach_index_decl,
11701 build_int_cst (long_unsigned_type_node, 1), 1));
11702 SET_EXPR_LOCATION (t, location);
11703 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11705 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
11706 t = build3 (COND_EXPR, void_type_node,
11707 /* Condition. */
11708 c_fully_fold
11709 (c_common_truthvalue_conversion
11710 (location,
11711 build_binary_op (location,
11712 LT_EXPR,
11713 objc_foreach_index_decl,
11714 objc_foreach_batchsize_decl, 1)),
11715 false, NULL),
11716 /* Then block. */
11717 build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
11718 /* Else block. */
11719 NULL_TREE);
11720 SET_EXPR_LOCATION (t, location);
11721 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11723 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
11724 #ifdef OBJCPLUS
11725 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11726 /* Parameters. */
11727 tree_cons /* &__objc_foreach_enum_state */
11728 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11729 tree_cons /* __objc_foreach_items */
11730 (NULL_TREE, objc_foreach_items_decl,
11731 tree_cons /* 16 */
11732 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11733 #else
11734 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
11736 struct c_expr array;
11737 array.value = objc_foreach_items_decl;
11738 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
11739 /* Parameters. */
11740 tree_cons /* &__objc_foreach_enum_state */
11741 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
11742 tree_cons /* __objc_foreach_items */
11743 (NULL_TREE, default_function_array_conversion (location, array).value,
11744 tree_cons /* 16 */
11745 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
11747 #endif
11748 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
11749 convert (long_unsigned_type_node, t));
11750 SET_EXPR_LOCATION (t, location);
11751 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
11753 /* } */
11755 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
11756 t = build3 (COND_EXPR, void_type_node,
11757 /* Condition. */
11758 c_fully_fold
11759 (c_common_truthvalue_conversion
11760 (location,
11761 build_binary_op (location,
11762 NE_EXPR,
11763 objc_foreach_batchsize_decl,
11764 build_int_cst (long_unsigned_type_node, 0), 1)),
11765 false, NULL),
11766 /* Then block. */
11767 build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
11768 /* Else block. */
11769 NULL_TREE);
11770 SET_EXPR_LOCATION (t, location);
11771 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11773 /* <object expression> = nil; */
11774 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
11775 SET_EXPR_LOCATION (t, location);
11776 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11778 /* break_label: */
11779 if (break_label)
11781 t = build1 (LABEL_EXPR, void_type_node, break_label);
11782 SET_EXPR_LOCATION (t, location);
11783 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
11786 /* } */
11787 COND_EXPR_ELSE (first_if) = first_else;
11789 /* Do the whole thing. */
11790 add_stmt (bind);
11792 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
11793 /* This will print to stderr the whole blurb generated by the
11794 compiler while compiling (assuming the compiler doesn't crash
11795 before getting here).
11797 debug_generic_stmt (bind);
11798 #endif
11800 /* } */
11801 /* Done by c-parser.c */
11804 #include "gt-objc-objc-act.h"