Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / gcc / objc / objc-act.c
blob131ce5524e4c306a45a38562d4b243577b4aa7c2
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-objc.h"
38 #include "c-family/c-pragma.h"
39 #include "c-family/c-format.h"
40 #include "flags.h"
41 #include "langhooks.h"
42 #include "objc-act.h"
43 #include "input.h"
44 #include "function.h"
45 #include "output.h"
46 #include "toplev.h"
47 #include "ggc.h"
48 #include "debug.h"
49 #include "target.h"
50 #include "diagnostic-core.h"
51 #include "intl.h"
52 #include "cgraph.h"
53 #include "tree-iterator.h"
54 #include "hashtab.h"
55 #include "langhooks-def.h"
57 /* For default_tree_printer (). */
58 #include "tree-pretty-print.h"
60 /* For enum gimplify_status */
61 #include "gimple.h"
63 #define OBJC_VOID_AT_END void_list_node
65 static unsigned int should_call_super_dealloc = 0;
67 /* When building Objective-C++, we are not linking against the C front-end
68 and so need to replicate the C tree-construction functions in some way. */
69 #ifdef OBJCPLUS
70 #define OBJCP_REMAP_FUNCTIONS
71 #include "objcp-decl.h"
72 #endif /* OBJCPLUS */
74 /* This is the default way of generating a method name. */
75 /* This has the problem that "test_method:argument:" and
76 "test:method_argument:" will generate the same name
77 ("_i_Test__test_method_argument_" for an instance method of the
78 class "Test"), so you can't have them both in the same class!
79 Moreover, the demangling (going from
80 "_i_Test__test_method_argument" back to the original name) is
81 undefined because there are two correct ways of demangling the
82 name. */
83 #ifndef OBJC_GEN_METHOD_LABEL
84 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
85 do { \
86 char *temp; \
87 sprintf ((BUF), "_%s_%s_%s_%s", \
88 ((IS_INST) ? "i" : "c"), \
89 (CLASS_NAME), \
90 ((CAT_NAME)? (CAT_NAME) : ""), \
91 (SEL_NAME)); \
92 for (temp = (BUF); *temp; temp++) \
93 if (*temp == ':') *temp = '_'; \
94 } while (0)
95 #endif
97 /* These need specifying. */
98 #ifndef OBJC_FORWARDING_STACK_OFFSET
99 #define OBJC_FORWARDING_STACK_OFFSET 0
100 #endif
102 #ifndef OBJC_FORWARDING_MIN_OFFSET
103 #define OBJC_FORWARDING_MIN_OFFSET 0
104 #endif
106 /* Set up for use of obstacks. */
108 #include "obstack.h"
110 /* This obstack is used to accumulate the encoding of a data type. */
111 static struct obstack util_obstack;
113 /* This points to the beginning of obstack contents, so we can free
114 the whole contents. */
115 char *util_firstobj;
117 /* The version identifies which language generation and runtime
118 the module (file) was compiled for, and is recorded in the
119 module descriptor. */
121 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
122 #define PROTOCOL_VERSION 2
124 /* (Decide if these can ever be validly changed.) */
125 #define OBJC_ENCODE_INLINE_DEFS 0
126 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
128 /*** Private Interface (procedures) ***/
130 /* Used by compile_file. */
132 static void init_objc (void);
133 static void finish_objc (void);
135 /* Code generation. */
137 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
138 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
139 static tree get_proto_encoding (tree);
140 static tree lookup_interface (tree);
141 static tree objc_add_static_instance (tree, tree);
143 static tree start_class (enum tree_code, tree, tree, tree, tree);
144 static tree continue_class (tree);
145 static void finish_class (tree);
146 static void start_method_def (tree);
147 #ifdef OBJCPLUS
148 static void objc_start_function (tree, tree, tree, tree);
149 #else
150 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
151 #endif
152 static tree start_protocol (enum tree_code, tree, tree, tree);
153 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
154 static tree objc_add_method (tree, tree, int, bool);
155 static tree add_instance_variable (tree, objc_ivar_visibility_kind, tree);
156 static tree build_ivar_reference (tree);
157 static tree is_ivar (tree, tree);
159 static void build_objc_exception_stuff (void);
160 static void build_next_objc_exception_stuff (void);
162 /* We only need the following for ObjC; ObjC++ will use C++'s definition
163 of DERIVED_FROM_P. */
164 #ifndef OBJCPLUS
165 static bool objc_derived_from_p (tree, tree);
166 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
167 #endif
169 /* Property. */
170 static void objc_gen_property_data (tree, tree);
171 static void objc_synthesize_getter (tree, tree, tree);
172 static void objc_synthesize_setter (tree, tree, tree);
173 static char *objc_build_property_setter_name (tree);
174 static int match_proto_with_proto (tree, tree, int);
175 static tree lookup_property (tree, tree);
176 static tree lookup_property_in_list (tree, tree);
177 static tree lookup_property_in_protocol_list (tree, tree);
178 static void build_objc_property_accessor_helpers (void);
180 static void objc_xref_basetypes (tree, tree);
182 static void build_class_template (void);
183 static void build_selector_template (void);
184 static void build_category_template (void);
185 static void build_super_template (void);
186 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
187 static tree get_class_ivars (tree, bool);
188 static tree generate_protocol_list (tree);
189 static void build_protocol_reference (tree);
191 static void build_fast_enumeration_state_template (void);
193 #ifdef OBJCPLUS
194 static void objc_generate_cxx_cdtors (void);
195 #endif
197 /* objc attribute */
198 static void objc_decl_method_attributes (tree*, tree, int);
199 static tree build_keyword_selector (tree);
200 static const char *synth_id_with_class_suffix (const char *, tree);
202 /* Hash tables to manage the global pool of method prototypes. */
204 hash *nst_method_hash_list = 0;
205 hash *cls_method_hash_list = 0;
207 /* Hash tables to manage the global pool of class names. */
209 hash *cls_name_hash_list = 0;
210 hash *als_name_hash_list = 0;
212 static void hash_class_name_enter (hash *, tree, tree);
213 static hash hash_class_name_lookup (hash *, tree);
215 static hash hash_lookup (hash *, tree);
216 static tree lookup_method (tree, tree);
217 static tree lookup_method_static (tree, tree, int);
219 static tree add_class (tree, tree);
220 static void add_category (tree, tree);
221 static inline tree lookup_category (tree, tree);
223 enum string_section
225 class_names, /* class, category, protocol, module names */
226 meth_var_names, /* method and variable names */
227 meth_var_types /* method and variable type descriptors */
230 static tree add_objc_string (tree, enum string_section);
231 static void build_selector_table_decl (void);
233 /* Protocols. */
235 static tree lookup_protocol (tree, bool);
236 static tree lookup_and_install_protocols (tree);
238 /* Type encoding. */
240 static void encode_type_qualifiers (tree);
241 static void encode_type (tree, int, int);
242 static void encode_field_decl (tree, int, int);
244 #ifdef OBJCPLUS
245 static void really_start_method (tree, tree);
246 #else
247 static void really_start_method (tree, struct c_arg_info *);
248 #endif
249 static int comp_proto_with_proto (tree, tree, int);
250 static tree get_arg_type_list (tree, int, int);
251 static tree objc_decay_parm_type (tree);
252 static void objc_push_parm (tree);
253 #ifdef OBJCPLUS
254 static tree objc_get_parm_info (int);
255 #else
256 static struct c_arg_info *objc_get_parm_info (int);
257 #endif
259 /* Utilities for debugging and error diagnostics. */
261 static char *gen_type_name (tree);
262 static char *gen_type_name_0 (tree);
263 static char *gen_method_decl (tree);
264 static char *gen_declaration (tree);
266 /* Everything else. */
268 static tree create_field_decl (tree, const char *);
269 static void add_class_reference (tree);
270 static void build_protocol_template (void);
271 static tree encode_method_prototype (tree);
272 static void generate_classref_translation_entry (tree);
273 static void handle_class_ref (tree);
274 static void generate_struct_by_value_array (void)
275 ATTRIBUTE_NORETURN;
276 static void mark_referenced_methods (void);
277 static void generate_objc_image_info (void);
278 static bool objc_type_valid_for_messaging (tree type, bool allow_classes);
280 /*** Private Interface (data) ***/
282 /* Reserved tag definitions. */
284 #define OBJECT_TYPEDEF_NAME "id"
285 #define CLASS_TYPEDEF_NAME "Class"
287 #define TAG_OBJECT "objc_object"
288 #define TAG_CLASS "objc_class"
289 #define TAG_SUPER "objc_super"
290 #define TAG_SELECTOR "objc_selector"
292 #define UTAG_CLASS "_objc_class"
293 #define UTAG_IVAR "_objc_ivar"
294 #define UTAG_IVAR_LIST "_objc_ivar_list"
295 #define UTAG_METHOD "_objc_method"
296 #define UTAG_METHOD_LIST "_objc_method_list"
297 #define UTAG_CATEGORY "_objc_category"
298 #define UTAG_MODULE "_objc_module"
299 #define UTAG_SYMTAB "_objc_symtab"
300 #define UTAG_SUPER "_objc_super"
301 #define UTAG_SELECTOR "_objc_selector"
303 #define UTAG_PROTOCOL "_objc_protocol"
304 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
305 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
307 /* Note that the string object global name is only needed for the
308 NeXT runtime. */
309 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
311 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
313 #define TAG_ENUMERATION_MUTATION "objc_enumerationMutation"
314 #define TAG_FAST_ENUMERATION_STATE "__objcFastEnumerationState"
316 static const char *TAG_GETCLASS;
317 static const char *TAG_GETMETACLASS;
318 static const char *TAG_MSGSEND;
319 static const char *TAG_MSGSENDSUPER;
320 /* The NeXT Objective-C messenger may have two extra entry points, for use
321 when returning a structure. */
322 static const char *TAG_MSGSEND_STRET;
323 static const char *TAG_MSGSENDSUPER_STRET;
324 static const char *default_constant_string_class_name;
326 /* Runtime metadata flags. */
327 #define CLS_FACTORY 0x0001L
328 #define CLS_META 0x0002L
329 #define CLS_HAS_CXX_STRUCTORS 0x2000L
331 #define OBJC_MODIFIER_STATIC 0x00000001
332 #define OBJC_MODIFIER_FINAL 0x00000002
333 #define OBJC_MODIFIER_PUBLIC 0x00000004
334 #define OBJC_MODIFIER_PRIVATE 0x00000008
335 #define OBJC_MODIFIER_PROTECTED 0x00000010
336 #define OBJC_MODIFIER_NATIVE 0x00000020
337 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
338 #define OBJC_MODIFIER_ABSTRACT 0x00000080
339 #define OBJC_MODIFIER_VOLATILE 0x00000100
340 #define OBJC_MODIFIER_TRANSIENT 0x00000200
341 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
343 /* NeXT-specific tags. */
345 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
346 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
347 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
348 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
349 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
350 #define TAG_EXCEPTIONMATCH "objc_exception_match"
351 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
352 #define TAG_SYNCENTER "objc_sync_enter"
353 #define TAG_SYNCEXIT "objc_sync_exit"
354 #define TAG_SETJMP "_setjmp"
355 #define UTAG_EXCDATA "_objc_exception_data"
357 #define TAG_ASSIGNIVAR "objc_assign_ivar"
358 #define TAG_ASSIGNGLOBAL "objc_assign_global"
359 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
361 /* Branch entry points. All that matters here are the addresses;
362 functions with these names do not really exist in libobjc. */
364 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
365 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
367 #define TAG_CXX_CONSTRUCT ".cxx_construct"
368 #define TAG_CXX_DESTRUCT ".cxx_destruct"
370 /* GNU-specific tags. */
372 #define TAG_EXECCLASS "__objc_exec_class"
373 #define TAG_GNUINIT "__objc_gnu_init"
375 /* Flags for lookup_method_static(). */
377 /* Look for class methods. */
378 #define OBJC_LOOKUP_CLASS 1
379 /* Do not examine superclasses. */
380 #define OBJC_LOOKUP_NO_SUPER 2
381 /* Disable returning an instance method of a root class when a class
382 method can't be found. */
383 #define OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS 4
385 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
386 tree objc_global_trees[OCTI_MAX];
388 static void handle_impent (struct imp_entry *);
390 struct imp_entry *imp_list = 0;
391 int imp_count = 0; /* `@implementation' */
392 int cat_count = 0; /* `@category' */
394 objc_ivar_visibility_kind objc_ivar_visibility;
396 /* Use to generate method labels. */
397 static int method_slot = 0;
399 /* Flag to say whether methods in a protocol are optional or
400 required. */
401 static bool objc_method_optional_flag = false;
403 static int objc_collecting_ivars = 0;
405 /* Flag that is set to 'true' while we are processing a class
406 extension. Since a class extension just "reopens" the main
407 @interface, this can be used to determine if we are in the main
408 @interface, or in a class extension. */
409 static bool objc_in_class_extension = false;
411 #define BUFSIZE 1024
413 static char *errbuf; /* Buffer for error diagnostics */
415 /* An array of all the local variables in the current function that
416 need to be marked as volatile. */
417 VEC(tree,gc) *local_variables_to_volatilize = NULL;
420 static int flag_typed_selectors;
422 /* Store all constructed constant strings in a hash table so that
423 they get uniqued properly. */
425 struct GTY(()) string_descriptor {
426 /* The literal argument . */
427 tree literal;
429 /* The resulting constant string. */
430 tree constructor;
433 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
435 FILE *gen_declaration_file;
437 /* Tells "encode_pointer/encode_aggregate" whether we are generating
438 type descriptors for instance variables (as opposed to methods).
439 Type descriptors for instance variables contain more information
440 than methods (for static typing and embedded structures). */
442 static int generating_instance_variables = 0;
444 /* For building an objc struct. These may not be used when this file
445 is compiled as part of obj-c++. */
447 static bool objc_building_struct;
448 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
450 /* Start building a struct for objc. */
452 static tree
453 objc_start_struct (tree name)
455 gcc_assert (!objc_building_struct);
456 objc_building_struct = true;
457 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
460 /* Finish building a struct for objc. */
462 static tree
463 objc_finish_struct (tree type, tree fieldlist)
465 gcc_assert (objc_building_struct);
466 objc_building_struct = false;
467 return finish_struct (input_location, type, fieldlist, NULL_TREE,
468 objc_struct_info);
471 static tree
472 build_sized_array_type (tree base_type, int size)
474 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
475 return build_array_type (base_type, index_type);
478 static tree
479 add_field_decl (tree type, const char *name, tree **chain)
481 tree field = create_field_decl (type, name);
483 if (*chain != NULL)
484 **chain = field;
485 *chain = &DECL_CHAIN (field);
487 return field;
490 /* Create a temporary variable of type 'type'. If 'name' is set, uses
491 the specified name, else use no name. Returns the declaration of
492 the type. The 'name' is mostly useful for debugging.
494 static tree
495 objc_create_temporary_var (tree type, const char *name)
497 tree decl;
499 if (name != NULL)
501 decl = build_decl (input_location,
502 VAR_DECL, get_identifier (name), type);
504 else
506 decl = build_decl (input_location,
507 VAR_DECL, NULL_TREE, type);
509 TREE_USED (decl) = 1;
510 DECL_ARTIFICIAL (decl) = 1;
511 DECL_IGNORED_P (decl) = 1;
512 DECL_CONTEXT (decl) = current_function_decl;
514 return decl;
517 /* Some platforms pass small structures through registers versus
518 through an invisible pointer. Determine at what size structure is
519 the transition point between the two possibilities. */
521 static void
522 generate_struct_by_value_array (void)
524 tree type;
525 tree decls;
526 int i, j;
527 int aggregate_in_mem[32];
528 int found = 0;
530 /* Presumably no platform passes 32 byte structures in a register. */
531 for (i = 1; i < 32; i++)
533 char buffer[5];
534 tree *chain = NULL;
536 /* Create an unnamed struct that has `i' character components */
537 type = objc_start_struct (NULL_TREE);
539 strcpy (buffer, "c1");
540 decls = add_field_decl (char_type_node, buffer, &chain);
542 for (j = 1; j < i; j++)
544 sprintf (buffer, "c%d", j + 1);
545 add_field_decl (char_type_node, buffer, &chain);
547 objc_finish_struct (type, decls);
549 aggregate_in_mem[i] = aggregate_value_p (type, 0);
550 if (!aggregate_in_mem[i])
551 found = 1;
554 /* We found some structures that are returned in registers instead of memory
555 so output the necessary data. */
556 if (found)
558 for (i = 31; i >= 0; i--)
559 if (!aggregate_in_mem[i])
560 break;
561 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
563 /* The first member of the structure is always 0 because we don't handle
564 structures with 0 members */
565 printf ("static int struct_forward_array[] = {\n 0");
567 for (j = 1; j <= i; j++)
568 printf (", %d", aggregate_in_mem[j]);
569 printf ("\n};\n");
572 exit (0);
575 bool
576 objc_init (void)
578 #ifdef OBJCPLUS
579 if (cxx_init () == false)
580 #else
581 if (c_objc_common_init () == false)
582 #endif
583 return false;
585 /* If gen_declaration desired, open the output file. */
586 if (flag_gen_declaration)
588 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
589 gen_declaration_file = fopen (dumpname, "w");
590 if (gen_declaration_file == 0)
591 fatal_error ("can%'t open %s: %m", dumpname);
592 free (dumpname);
595 if (flag_next_runtime)
597 TAG_GETCLASS = "objc_getClass";
598 TAG_GETMETACLASS = "objc_getMetaClass";
599 TAG_MSGSEND = "objc_msgSend";
600 TAG_MSGSENDSUPER = "objc_msgSendSuper";
601 TAG_MSGSEND_STRET = "objc_msgSend_stret";
602 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
603 default_constant_string_class_name = "NSConstantString";
605 else
607 TAG_GETCLASS = "objc_get_class";
608 TAG_GETMETACLASS = "objc_get_meta_class";
609 TAG_MSGSEND = "objc_msg_lookup";
610 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
611 /* GNU runtime does not provide special functions to support
612 structure-returning methods. */
613 default_constant_string_class_name = "NXConstantString";
614 flag_typed_selectors = 1;
615 /* GNU runtime does not need the compiler to change code
616 in order to do GC. */
617 if (flag_objc_gc)
619 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
620 flag_objc_gc=0;
624 init_objc ();
626 if (print_struct_values && !flag_compare_debug)
627 generate_struct_by_value_array ();
629 return true;
632 /* This is called automatically (at the very end of compilation) by
633 c_write_global_declarations and cp_write_global_declarations. */
634 void
635 objc_write_global_declarations (void)
637 mark_referenced_methods ();
639 /* Finalize Objective-C runtime data. */
640 finish_objc ();
642 if (gen_declaration_file)
643 fclose (gen_declaration_file);
646 /* Return the first occurrence of a method declaration corresponding
647 to sel_name in rproto_list. Search rproto_list recursively.
648 If is_class is 0, search for instance methods, otherwise for class
649 methods. */
650 static tree
651 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
652 int is_class)
654 tree rproto, p, m;
656 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
658 p = TREE_VALUE (rproto);
659 m = NULL_TREE;
661 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
663 /* First, search the @required protocol methods. */
664 if (is_class)
665 m = lookup_method (PROTOCOL_CLS_METHODS (p), sel_name);
666 else
667 m = lookup_method (PROTOCOL_NST_METHODS (p), sel_name);
669 if (m)
670 return m;
672 /* If still not found, search the @optional protocol methods. */
673 if (is_class)
674 m = lookup_method (PROTOCOL_OPTIONAL_CLS_METHODS (p), sel_name);
675 else
676 m = lookup_method (PROTOCOL_OPTIONAL_NST_METHODS (p), sel_name);
678 if (m)
679 return m;
681 /* If still not found, search the attached protocols. */
682 if (PROTOCOL_LIST (p))
683 m = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
684 sel_name, is_class);
685 if (m)
686 return m;
688 else
690 ; /* An identifier...if we could not find a protocol. */
694 return 0;
697 static tree
698 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
700 tree rproto, p;
702 /* Make sure the protocol is supported by the object on the rhs. */
703 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
705 tree fnd = 0;
706 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
708 p = TREE_VALUE (rproto);
710 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
712 if (lproto == p)
713 fnd = lproto;
715 else if (PROTOCOL_LIST (p))
716 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
719 if (fnd)
720 return fnd;
723 else
725 ; /* An identifier...if we could not find a protocol. */
728 return 0;
731 void
732 objc_start_class_interface (tree klass, tree super_class,
733 tree protos, tree attributes)
735 if (flag_objc1_only && attributes)
736 error_at (input_location, "class attributes are not available in Objective-C 1.0");
738 objc_interface_context
739 = objc_ivar_context
740 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos, attributes);
741 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
744 void
745 objc_start_category_interface (tree klass, tree categ,
746 tree protos, tree attributes)
748 if (attributes)
750 if (flag_objc1_only)
751 error_at (input_location, "category attributes are not available in Objective-C 1.0");
752 else
753 warning_at (input_location, OPT_Wattributes,
754 "category attributes are not available in this version"
755 " of the compiler, (ignored)");
757 if (categ == NULL_TREE)
759 if (flag_objc1_only)
760 error_at (input_location, "class extensions are not available in Objective-C 1.0");
762 objc_interface_context
763 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos, NULL_TREE);
764 objc_ivar_chain
765 = continue_class (objc_interface_context);
768 void
769 objc_start_protocol (tree name, tree protos, tree attributes)
771 if (flag_objc1_only && attributes)
772 error_at (input_location, "protocol attributes are not available in Objective-C 1.0");
774 objc_interface_context
775 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos, attributes);
776 objc_method_optional_flag = false;
779 void
780 objc_continue_interface (void)
782 objc_ivar_chain
783 = continue_class (objc_interface_context);
786 void
787 objc_finish_interface (void)
789 finish_class (objc_interface_context);
790 objc_interface_context = NULL_TREE;
791 objc_method_optional_flag = false;
792 objc_in_class_extension = false;
795 void
796 objc_start_class_implementation (tree klass, tree super_class)
798 objc_implementation_context
799 = objc_ivar_context
800 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE,
801 NULL_TREE);
802 objc_ivar_visibility = OBJC_IVAR_VIS_PROTECTED;
805 void
806 objc_start_category_implementation (tree klass, tree categ)
808 objc_implementation_context
809 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE,
810 NULL_TREE);
811 objc_ivar_chain
812 = continue_class (objc_implementation_context);
815 void
816 objc_continue_implementation (void)
818 objc_ivar_chain
819 = continue_class (objc_implementation_context);
822 void
823 objc_finish_implementation (void)
825 #ifdef OBJCPLUS
826 if (flag_objc_call_cxx_cdtors)
827 objc_generate_cxx_cdtors ();
828 #endif
830 if (objc_implementation_context)
832 finish_class (objc_implementation_context);
833 objc_ivar_chain = NULL_TREE;
834 objc_implementation_context = NULL_TREE;
836 else
837 warning (0, "%<@end%> must appear in an @implementation context");
840 void
841 objc_set_visibility (objc_ivar_visibility_kind visibility)
843 if (visibility == OBJC_IVAR_VIS_PACKAGE)
845 if (flag_objc1_only)
846 error ("%<@package%> is not available in Objective-C 1.0");
847 else
848 warning (0, "%<@package%> presently has the same effect as %<@public%>");
850 objc_ivar_visibility = visibility;
853 void
854 objc_set_method_opt (bool optional)
856 if (flag_objc1_only)
857 error_at (input_location, "@optional/@required are not available in Objective-C 1.0");
859 objc_method_optional_flag = optional;
860 if (!objc_interface_context
861 || TREE_CODE (objc_interface_context) != PROTOCOL_INTERFACE_TYPE)
863 error ("@optional/@required is allowed in @protocol context only");
864 objc_method_optional_flag = false;
868 /* This routine looks for a given PROPERTY in a list of CLASS, CATEGORY, or
869 PROTOCOL. */
870 static tree
871 lookup_property_in_list (tree chain, tree property)
873 tree x;
874 for (x = CLASS_PROPERTY_DECL (chain); x; x = TREE_CHAIN (x))
875 if (PROPERTY_NAME (x) == property)
876 return x;
877 return NULL_TREE;
880 /* This routine looks for a given PROPERTY in the tree chain of RPROTO_LIST. */
881 static tree lookup_property_in_protocol_list (tree rproto_list, tree property)
883 tree rproto, x;
884 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
886 tree p = TREE_VALUE (rproto);
887 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
889 if ((x = lookup_property_in_list (p, property)))
890 return x;
891 if (PROTOCOL_LIST (p))
892 return lookup_property_in_protocol_list (PROTOCOL_LIST (p), property);
894 else
896 ; /* An identifier...if we could not find a protocol. */
899 return NULL_TREE;
902 /* This routine looks up the PROPERTY in current INTERFACE, its categories and up the
903 chain of interface hierarchy. */
904 static tree
905 lookup_property (tree interface_type, tree property)
907 tree inter = interface_type;
908 while (inter)
910 tree x, category;
911 if ((x = lookup_property_in_list (inter, property)))
912 return x;
913 /* Failing that, look for the property in each category of the class. */
914 category = inter;
915 while ((category = CLASS_CATEGORY_LIST (category)))
917 if ((x = lookup_property_in_list (category, property)))
918 return x;
920 /* When checking a category, also check the protocols
921 attached with the category itself. */
922 if (CLASS_PROTOCOL_LIST (category)
923 && (x = lookup_property_in_protocol_list
924 (CLASS_PROTOCOL_LIST (category), property)))
925 return x;
928 /* Failing to find in categories, look for property in protocol list. */
929 if (CLASS_PROTOCOL_LIST (inter)
930 && (x = lookup_property_in_protocol_list
931 (CLASS_PROTOCOL_LIST (inter), property)))
932 return x;
934 /* Failing that, climb up the inheritance hierarchy. */
935 inter = lookup_interface (CLASS_SUPER_NAME (inter));
937 return inter;
940 /* This routine is called by the parser when a
941 @property... declaration is found. 'decl' is the declaration of
942 the property (type/identifier), and the other arguments represent
943 property attributes that may have been specified in the Objective-C
944 declaration. 'parsed_property_readonly' is 'true' if the attribute
945 'readonly' was specified, and 'false' if not; similarly for the
946 other bool parameters. 'parsed_property_getter_ident' is NULL_TREE
947 if the attribute 'getter' was not specified, and is the identifier
948 corresponding to the specified getter if it was; similarly for
949 'parsed_property_setter_ident'. */
950 void
951 objc_add_property_declaration (location_t location, tree decl,
952 bool parsed_property_readonly, bool parsed_property_readwrite,
953 bool parsed_property_assign, bool parsed_property_retain,
954 bool parsed_property_copy, bool parsed_property_nonatomic,
955 tree parsed_property_getter_ident, tree parsed_property_setter_ident)
957 tree property_decl;
958 tree x;
959 /* 'property_readonly' and 'property_assign_semantics' are the final
960 attributes of the property after all parsed attributes have been
961 considered (eg, if we parsed no 'readonly' and no 'readwrite', ie
962 parsed_property_readonly = false and parsed_property_readwrite =
963 false, then property_readonly will be false because the default
964 is readwrite). */
965 bool property_readonly = false;
966 objc_property_assign_semantics property_assign_semantics = OBJC_PROPERTY_ASSIGN;
967 bool property_extension_in_class_extension = false;
969 if (flag_objc1_only)
970 error_at (input_location, "%<@property%> is not available in Objective-C 1.0");
972 if (parsed_property_readonly && parsed_property_readwrite)
974 error_at (location, "%<readonly%> attribute conflicts with %<readwrite%> attribute");
975 /* In case of conflicting attributes (here and below), after
976 producing an error, we pick one of the attributes and keep
977 going. */
978 property_readonly = false;
980 else
982 if (parsed_property_readonly)
983 property_readonly = true;
985 if (parsed_property_readwrite)
986 property_readonly = false;
989 if (parsed_property_readonly && parsed_property_setter_ident)
991 error_at (location, "%<readonly%> attribute conflicts with %<setter%> attribute");
992 property_readonly = false;
995 if (parsed_property_assign && parsed_property_retain)
997 error_at (location, "%<assign%> attribute conflicts with %<retain%> attribute");
998 property_assign_semantics = OBJC_PROPERTY_RETAIN;
1000 else if (parsed_property_assign && parsed_property_copy)
1002 error_at (location, "%<assign%> attribute conflicts with %<copy%> attribute");
1003 property_assign_semantics = OBJC_PROPERTY_COPY;
1005 else if (parsed_property_retain && parsed_property_copy)
1007 error_at (location, "%<retain%> attribute conflicts with %<copy%> attribute");
1008 property_assign_semantics = OBJC_PROPERTY_COPY;
1010 else
1012 if (parsed_property_assign)
1013 property_assign_semantics = OBJC_PROPERTY_ASSIGN;
1015 if (parsed_property_retain)
1016 property_assign_semantics = OBJC_PROPERTY_RETAIN;
1018 if (parsed_property_copy)
1019 property_assign_semantics = OBJC_PROPERTY_COPY;
1022 if (!objc_interface_context)
1024 error_at (location, "property declaration not in @interface or @protocol context");
1025 return;
1028 /* At this point we know that we are either in an interface, a
1029 category, or a protocol. */
1031 /* We expect a FIELD_DECL from the parser. Make sure we didn't get
1032 something else, as that would confuse the checks below. */
1033 if (TREE_CODE (decl) != FIELD_DECL)
1035 error_at (location, "invalid property declaration");
1036 return;
1039 /* Do some spot-checks for the most obvious invalid types. */
1041 if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1043 error_at (location, "property can not be an array");
1044 return;
1047 /* The C++/ObjC++ parser seems to reject the ':' for a bitfield when
1048 parsing, while the C/ObjC parser accepts it and gives us a
1049 FIELD_DECL with a DECL_INITIAL set. So we use the DECL_INITIAL
1050 to check for a bitfield when doing ObjC. */
1051 #ifndef OBJCPLUS
1052 if (DECL_INITIAL (decl))
1054 /* A @property is not an actual variable, but it is a way to
1055 describe a pair of accessor methods, so its type (which is
1056 the type of the return value of the getter and the first
1057 argument of the setter) can't be a bitfield (as return values
1058 and arguments of functions can not be bitfields). The
1059 underlying instance variable could be a bitfield, but that is
1060 a different matter. */
1061 error_at (location, "property can not be a bit-field");
1062 return;
1064 #endif
1066 /* TODO: Check that the property type is an Objective-C object or a
1067 "POD". */
1069 /* Implement -Wproperty-assign-default (which is enabled by default). */
1070 if (warn_property_assign_default
1071 /* If garbage collection is not being used, then 'assign' is
1072 valid for objects (and typically used for delegates) but it
1073 is wrong in most cases (since most objects need to be
1074 retained or copied in setters). Warn users when 'assign' is
1075 used implicitly. */
1076 && property_assign_semantics == OBJC_PROPERTY_ASSIGN
1077 /* Read-only properties are never assigned, so the assignment
1078 semantics do not matter in that case. */
1079 && !property_readonly
1080 && !flag_objc_gc)
1082 /* Please note that it would make sense to default to 'assign'
1083 for non-{Objective-C objects}, and to 'retain' for
1084 Objective-C objects. But that would break compatibility with
1085 other compilers. */
1086 if (!parsed_property_assign && !parsed_property_retain && !parsed_property_copy)
1088 /* Use 'false' so we do not warn for Class objects. */
1089 if (objc_type_valid_for_messaging (TREE_TYPE (decl), false))
1091 warning_at (location,
1093 "object property %qD has no %<assign%>, %<retain%> or %<copy%> attribute; assuming %<assign%>",
1094 decl);
1095 inform (location,
1096 "%<assign%> can be unsafe for Objective-C objects; please state explicitly if you need it");
1101 if (property_assign_semantics == OBJC_PROPERTY_RETAIN
1102 && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1103 error_at (location, "%<retain%> attribute is only valid for Objective-C objects");
1105 if (property_assign_semantics == OBJC_PROPERTY_COPY
1106 && !objc_type_valid_for_messaging (TREE_TYPE (decl), true))
1107 error_at (location, "%<copy%> attribute is only valid for Objective-C objects");
1109 /* Now determine the final property getter and setter names. They
1110 will be stored in the PROPERTY_DECL, from which they'll always be
1111 extracted and used. */
1113 /* Adjust, or fill in, setter and getter names. We overwrite the
1114 parsed_property_setter_ident and parsed_property_getter_ident
1115 with the final setter and getter identifiers that will be
1116 used. */
1117 if (parsed_property_setter_ident)
1119 /* The setter should be terminated by ':', but the parser only
1120 gives us an identifier without ':'. So, we need to add ':'
1121 at the end. */
1122 const char *parsed_setter = IDENTIFIER_POINTER (parsed_property_setter_ident);
1123 size_t length = strlen (parsed_setter);
1124 char *final_setter = (char *)alloca (length + 2);
1126 sprintf (final_setter, "%s:", parsed_setter);
1127 parsed_property_setter_ident = get_identifier (final_setter);
1129 else
1131 if (!property_readonly)
1132 parsed_property_setter_ident = get_identifier (objc_build_property_setter_name
1133 (DECL_NAME (decl)));
1136 if (!parsed_property_getter_ident)
1137 parsed_property_getter_ident = DECL_NAME (decl);
1139 /* Check for duplicate property declarations. We first check the
1140 immediate context for a property with the same name. Any such
1141 declarations are an error, unless this is a class extension and
1142 we are extending a property from readonly to readwrite. */
1143 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
1145 if (PROPERTY_NAME (x) == DECL_NAME (decl))
1147 if (objc_in_class_extension
1148 && property_readonly == 0
1149 && PROPERTY_READONLY (x) == 1)
1151 /* This is a class extension, and we are extending an
1152 existing readonly property to a readwrite one.
1153 That's fine. :-) */
1154 property_extension_in_class_extension = true;
1155 break;
1157 else
1159 location_t original_location = DECL_SOURCE_LOCATION (x);
1161 error_at (location, "redeclaration of property %qD", decl);
1163 if (original_location != UNKNOWN_LOCATION)
1164 inform (original_location, "originally specified here");
1165 return;
1170 /* If x is not NULL_TREE, we must be in a class extension and we're
1171 extending a readonly property. In that case, no point in
1172 searching for another declaration. */
1173 if (x == NULL_TREE)
1175 /* We now need to check for existing property declarations (in
1176 the superclass, other categories or protocols) and check that
1177 the new declaration is not in conflict with existing
1178 ones. */
1180 /* Search for a previous, existing declaration of a property
1181 with the same name in superclasses, protocols etc. If one is
1182 found, it will be in the 'x' variable. */
1184 /* Note that, for simplicity, the following may search again the
1185 local context. That's Ok as nothing will be found (else we'd
1186 have thrown an error above); it's only a little inefficient,
1187 but the code is simpler. */
1188 switch (TREE_CODE (objc_interface_context))
1190 case CLASS_INTERFACE_TYPE:
1191 /* Look up the property in the current @interface (which
1192 will find nothing), then its protocols and categories and
1193 superclasses. */
1194 x = lookup_property (objc_interface_context, DECL_NAME (decl));
1195 break;
1196 case CATEGORY_INTERFACE_TYPE:
1197 /* Look up the property in the main @interface, then
1198 protocols and categories (one of them is ours, and will
1199 find nothing) and superclasses. */
1200 x = lookup_property (lookup_interface (CLASS_NAME (objc_interface_context)),
1201 DECL_NAME (decl));
1202 break;
1203 case PROTOCOL_INTERFACE_TYPE:
1204 /* Looks up the property in any protocols attached to the
1205 current protocol. */
1206 if (PROTOCOL_LIST (objc_interface_context))
1208 x = lookup_property_in_protocol_list (PROTOCOL_LIST (objc_interface_context),
1209 DECL_NAME (decl));
1211 break;
1212 default:
1213 gcc_unreachable ();
1217 if (x != NULL_TREE)
1219 /* An existing property was found; check that it has the same
1220 types, or it is compatible. */
1221 location_t original_location = DECL_SOURCE_LOCATION (x);
1223 if (PROPERTY_NONATOMIC (x) != parsed_property_nonatomic)
1225 warning_at (location, 0,
1226 "'nonatomic' attribute of property %qD conflicts with previous declaration", decl);
1228 if (original_location != UNKNOWN_LOCATION)
1229 inform (original_location, "originally specified here");
1230 return;
1233 if (PROPERTY_GETTER_NAME (x) != parsed_property_getter_ident)
1235 warning_at (location, 0,
1236 "'getter' attribute of property %qD conflicts with previous declaration", decl);
1238 if (original_location != UNKNOWN_LOCATION)
1239 inform (original_location, "originally specified here");
1240 return;
1243 /* We can only compare the setter names if both the old and new property have a setter. */
1244 if (!property_readonly && !PROPERTY_READONLY(x))
1246 if (PROPERTY_SETTER_NAME (x) != parsed_property_setter_ident)
1248 warning_at (location, 0,
1249 "'setter' attribute of property %qD conflicts with previous declaration", decl);
1251 if (original_location != UNKNOWN_LOCATION)
1252 inform (original_location, "originally specified here");
1253 return;
1257 if (PROPERTY_ASSIGN_SEMANTICS (x) != property_assign_semantics)
1259 warning_at (location, 0,
1260 "assign semantics attributes of property %qD conflict with previous declaration", decl);
1262 if (original_location != UNKNOWN_LOCATION)
1263 inform (original_location, "originally specified here");
1264 return;
1267 /* It's ok to have a readonly property that becomes a readwrite, but not vice versa. */
1268 if (PROPERTY_READONLY (x) == 0 && property_readonly == 1)
1270 warning_at (location, 0,
1271 "'readonly' attribute of property %qD conflicts with previous declaration", decl);
1273 if (original_location != UNKNOWN_LOCATION)
1274 inform (original_location, "originally specified here");
1275 return;
1278 /* We now check that the new and old property declarations have
1279 the same types (or compatible one). In the Objective-C
1280 tradition of loose type checking, we do type-checking but
1281 only generate warnings (not errors) if they do not match.
1282 For non-readonly properties, the types must match exactly;
1283 for readonly properties, it is allowed to use a "more
1284 specialized" type in the new property declaration. Eg, the
1285 superclass has a getter returning (NSArray *) and the
1286 subclass a getter returning (NSMutableArray *). The object's
1287 getter returns an (NSMutableArray *); but if you cast the
1288 object to the superclass, which is allowed, you'd still
1289 expect the getter to return an (NSArray *), which works since
1290 an (NSMutableArray *) is an (NSArray *) too. So, the set of
1291 objects belonging to the type of the new @property should be
1292 a subset of the set of objects belonging to the type of the
1293 old @property. This is what "specialization" means. And the
1294 reason it only applies to readonly properties is that for a
1295 readwrite property the setter would have the opposite
1296 requirement - ie that the superclass type is more specialized
1297 then the subclass one; hence the only way to satisfy both
1298 constraints is that the types match. */
1300 /* If the types are not the same in the C sense, we warn ... */
1301 if (!comptypes (TREE_TYPE (x), TREE_TYPE (decl))
1302 /* ... unless the property is readonly, in which case we
1303 allow a new, more specialized, declaration. */
1304 && (!property_readonly
1305 || !objc_compare_types (TREE_TYPE (x),
1306 TREE_TYPE (decl), -5, NULL_TREE)))
1308 warning_at (location, 0,
1309 "type of property %qD conflicts with previous declaration", decl);
1310 if (original_location != UNKNOWN_LOCATION)
1311 inform (original_location, "originally specified here");
1312 return;
1315 /* If we are in a class extension and we're extending a readonly
1316 property in the main @interface, we'll just update the
1317 existing property with the readwrite flag and potentially the
1318 new setter name. */
1319 if (property_extension_in_class_extension)
1321 PROPERTY_READONLY (x) = 0;
1322 PROPERTY_SETTER_NAME (x) = parsed_property_setter_ident;
1323 return;
1327 /* Create a PROPERTY_DECL node. */
1328 property_decl = make_node (PROPERTY_DECL);
1330 /* Copy the basic information from the original decl. */
1331 TREE_TYPE (property_decl) = TREE_TYPE (decl);
1332 DECL_SOURCE_LOCATION (property_decl) = DECL_SOURCE_LOCATION (decl);
1333 TREE_DEPRECATED (property_decl) = TREE_DEPRECATED (decl);
1335 /* Add property-specific information. */
1336 PROPERTY_NAME (property_decl) = DECL_NAME (decl);
1337 PROPERTY_GETTER_NAME (property_decl) = parsed_property_getter_ident;
1338 PROPERTY_SETTER_NAME (property_decl) = parsed_property_setter_ident;
1339 PROPERTY_READONLY (property_decl) = property_readonly;
1340 PROPERTY_NONATOMIC (property_decl) = parsed_property_nonatomic;
1341 PROPERTY_ASSIGN_SEMANTICS (property_decl) = property_assign_semantics;
1342 PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1343 PROPERTY_DYNAMIC (property_decl) = 0;
1345 /* Remember the fact that the property was found in the @optional
1346 section in a @protocol, or not. */
1347 if (objc_method_optional_flag)
1348 PROPERTY_OPTIONAL (property_decl) = 1;
1349 else
1350 PROPERTY_OPTIONAL (property_decl) = 0;
1352 /* Note that PROPERTY_GETTER_NAME is always set for all
1353 PROPERTY_DECLs, and PROPERTY_SETTER_NAME is always set for all
1354 PROPERTY_DECLs where PROPERTY_READONLY == 0. Any time we deal
1355 with a getter or setter, we should get the PROPERTY_DECL and use
1356 PROPERTY_GETTER_NAME and PROPERTY_SETTER_NAME to know the correct
1357 names. */
1359 /* Add the PROPERTY_DECL to the list of properties for the class. */
1360 TREE_CHAIN (property_decl) = CLASS_PROPERTY_DECL (objc_interface_context);
1361 CLASS_PROPERTY_DECL (objc_interface_context) = property_decl;
1364 /* This is a subroutine of objc_maybe_build_component_ref. Search the
1365 list of methods in the interface (and, failing that, the local list
1366 in the implementation, and failing that, the protocol list)
1367 provided for a 'setter' or 'getter' for 'component' with default
1368 names (ie, if 'component' is "name", then search for "name" and
1369 "setName:"). It is also possible to specify a different
1370 'getter_name' (this is used for @optional readonly properties). If
1371 any is found, then create an artificial property that uses them.
1372 Return NULL_TREE if 'getter' or 'setter' could not be found. */
1373 static tree
1374 maybe_make_artificial_property_decl (tree interface, tree implementation,
1375 tree protocol_list, tree component, bool is_class,
1376 tree getter_name)
1378 tree setter_name = get_identifier (objc_build_property_setter_name (component));
1379 tree getter = NULL_TREE;
1380 tree setter = NULL_TREE;
1382 if (getter_name == NULL_TREE)
1383 getter_name = component;
1385 /* First, check the @interface and all superclasses. */
1386 if (interface)
1388 int flags = 0;
1390 /* Using instance methods of the root class as accessors is most
1391 likely unwanted and can be extremely confusing (and, most
1392 importantly, other Objective-C 2.0 compilers do not do it).
1393 Turn it off. */
1394 if (is_class)
1395 flags = OBJC_LOOKUP_CLASS | OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS;
1397 getter = lookup_method_static (interface, getter_name, flags);
1398 setter = lookup_method_static (interface, setter_name, flags);
1401 /* Second, check the local @implementation context. */
1402 if (!getter && !setter)
1404 if (implementation)
1406 if (is_class)
1408 getter = lookup_method (CLASS_CLS_METHODS (implementation), getter_name);
1409 setter = lookup_method (CLASS_CLS_METHODS (implementation), setter_name);
1411 else
1413 getter = lookup_method (CLASS_NST_METHODS (implementation), getter_name);
1414 setter = lookup_method (CLASS_NST_METHODS (implementation), setter_name);
1419 /* Try the protocol_list if we didn't find anything in the
1420 @interface and in the @implementation. */
1421 if (!getter && !setter)
1423 getter = lookup_method_in_protocol_list (protocol_list, getter_name, is_class);
1424 setter = lookup_method_in_protocol_list (protocol_list, setter_name, is_class);
1427 /* There needs to be at least a getter or setter for this to be a
1428 valid 'object.component' syntax. */
1429 if (getter || setter)
1431 /* Yes ... determine the type of the expression. */
1432 tree property_decl;
1433 tree type;
1435 if (getter)
1436 type = TREE_VALUE (TREE_TYPE (getter));
1437 else
1438 type = TREE_VALUE (TREE_TYPE (METHOD_SEL_ARGS (setter)));
1440 /* Create an artificial property declaration with the
1441 information we collected on the type and getter/setter
1442 names. */
1443 property_decl = make_node (PROPERTY_DECL);
1445 TREE_TYPE (property_decl) = type;
1446 DECL_SOURCE_LOCATION (property_decl) = input_location;
1447 TREE_DEPRECATED (property_decl) = 0;
1448 DECL_ARTIFICIAL (property_decl) = 1;
1450 /* Add property-specific information. Note that one of
1451 PROPERTY_GETTER_NAME or PROPERTY_SETTER_NAME may refer to a
1452 non-existing method; this will generate an error when the
1453 expression is later compiled. At this stage we don't know if
1454 the getter or setter will be used, so we can't generate an
1455 error. */
1456 PROPERTY_NAME (property_decl) = component;
1457 PROPERTY_GETTER_NAME (property_decl) = getter_name;
1458 PROPERTY_SETTER_NAME (property_decl) = setter_name;
1459 PROPERTY_READONLY (property_decl) = 0;
1460 PROPERTY_NONATOMIC (property_decl) = 0;
1461 PROPERTY_ASSIGN_SEMANTICS (property_decl) = 0;
1462 PROPERTY_IVAR_NAME (property_decl) = NULL_TREE;
1463 PROPERTY_DYNAMIC (property_decl) = 0;
1464 PROPERTY_OPTIONAL (property_decl) = 0;
1466 if (!getter)
1467 PROPERTY_HAS_NO_GETTER (property_decl) = 1;
1469 /* The following is currently unused, but it's nice to have
1470 there. We may use it if we need in the future. */
1471 if (!setter)
1472 PROPERTY_HAS_NO_SETTER (property_decl) = 1;
1474 return property_decl;
1477 return NULL_TREE;
1480 /* This hook routine is invoked by the parser when an expression such
1481 as 'xxx.yyy' is parsed. We get a chance to process these
1482 expressions in a way that is specified to Objective-C (to implement
1483 the Objective-C 2.0 dot-syntax, properties, or non-fragile ivars).
1484 If the expression is not an Objective-C specified expression, we
1485 should return NULL_TREE; else we return the expression.
1487 At the moment this only implements dot-syntax and properties (not
1488 non-fragile ivars yet), ie 'object.property' or 'object.component'
1489 where 'component' is not a declared property, but a valid getter or
1490 setter for it could be found. */
1491 tree
1492 objc_maybe_build_component_ref (tree object, tree property_ident)
1494 tree x = NULL_TREE;
1495 tree rtype;
1497 /* If we are in Objective-C 1.0 mode, dot-syntax and properties are
1498 not available. */
1499 if (flag_objc1_only)
1500 return NULL_TREE;
1502 /* Try to determine if 'object' is an Objective-C object or not. If
1503 not, return. */
1504 if (object == NULL_TREE || object == error_mark_node
1505 || (rtype = TREE_TYPE (object)) == NULL_TREE)
1506 return NULL_TREE;
1508 if (property_ident == NULL_TREE || property_ident == error_mark_node
1509 || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1510 return NULL_TREE;
1512 /* The following analysis of 'object' is similar to the one used for
1513 the 'receiver' of a method invocation. We need to determine what
1514 'object' is and find the appropriate property (either declared,
1515 or artificial) for it (in the same way as we need to find the
1516 appropriate method prototype for a method invocation). There are
1517 some simplifications here though: "object.property" is invalid if
1518 "object" has a type of "id" or "Class"; it must at least have a
1519 protocol attached to it, and "object" is never a class name as
1520 that is done by objc_build_class_component_ref. Finally, we
1521 don't know if this really is a dot-syntax expression, so we want
1522 to make a quick exit if it is not; for this reason, we try to
1523 postpone checks after determining that 'object' looks like an
1524 Objective-C object. */
1526 if (objc_is_id (rtype))
1528 /* This is the case that the 'object' is of type 'id' or
1529 'Class'. */
1531 /* Check if at least it is of type 'id <Protocol>' or 'Class
1532 <Protocol>'; if so, look the property up in the
1533 protocols. */
1534 if (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype)))
1536 tree rprotos = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype));
1538 if (rprotos)
1540 /* No point looking up declared @properties if we are
1541 dealing with a class. Classes have no declared
1542 properties. */
1543 if (!IS_CLASS (rtype))
1544 x = lookup_property_in_protocol_list (rprotos, property_ident);
1546 if (x == NULL_TREE)
1548 /* Ok, no property. Maybe it was an
1549 object.component dot-syntax without a declared
1550 property (this is valid for classes too). Look
1551 for getter/setter methods and internally declare
1552 an artifical property based on them if found. */
1553 x = maybe_make_artificial_property_decl (NULL_TREE,
1554 NULL_TREE,
1555 rprotos,
1556 property_ident,
1557 IS_CLASS (rtype),
1558 NULL_TREE);
1560 else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
1562 /* This is a special, complicated case. If the
1563 property is optional, and is read-only, then the
1564 property is always used for reading, but an
1565 eventual existing non-property setter can be used
1566 for writing. We create an artificial property
1567 decl copying the getter from the optional
1568 property, and looking up the setter in the
1569 interface. */
1570 x = maybe_make_artificial_property_decl (NULL_TREE,
1571 NULL_TREE,
1572 rprotos,
1573 property_ident,
1574 false,
1575 PROPERTY_GETTER_NAME (x));
1579 else if (objc_method_context)
1581 /* Else, if we are inside a method it could be the case of
1582 'super' or 'self'. */
1583 tree interface_type = NULL_TREE;
1584 tree t = object;
1585 while (TREE_CODE (t) == COMPOUND_EXPR
1586 || TREE_CODE (t) == MODIFY_EXPR
1587 || CONVERT_EXPR_P (t)
1588 || TREE_CODE (t) == COMPONENT_REF)
1589 t = TREE_OPERAND (t, 0);
1591 if (t == UOBJC_SUPER_decl)
1592 interface_type = lookup_interface (CLASS_SUPER_NAME (implementation_template));
1593 else if (t == self_decl)
1594 interface_type = lookup_interface (CLASS_NAME (implementation_template));
1596 if (interface_type)
1598 if (TREE_CODE (objc_method_context) != CLASS_METHOD_DECL)
1599 x = lookup_property (interface_type, property_ident);
1601 if (x == NULL_TREE)
1603 /* Try the dot-syntax without a declared property.
1604 If this is an access to 'self', it is possible
1605 that they may refer to a setter/getter that is
1606 not declared in the interface, but exists locally
1607 in the implementation. In that case, get the
1608 implementation context and use it. */
1609 tree implementation = NULL_TREE;
1611 if (t == self_decl)
1612 implementation = objc_implementation_context;
1614 x = maybe_make_artificial_property_decl
1615 (interface_type, implementation, NULL_TREE,
1616 property_ident,
1617 (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL),
1618 NULL_TREE);
1620 else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
1622 tree implementation = NULL_TREE;
1624 if (t == self_decl)
1625 implementation = objc_implementation_context;
1627 x = maybe_make_artificial_property_decl (interface_type,
1628 implementation,
1629 NULL_TREE,
1630 property_ident,
1631 false,
1632 PROPERTY_GETTER_NAME (x));
1637 else
1639 /* This is the case where we have more information on 'rtype'. */
1640 tree basetype = TYPE_MAIN_VARIANT (rtype);
1642 /* Skip the pointer - if none, it's not an Objective-C object or
1643 class. */
1644 if (basetype != NULL_TREE && TREE_CODE (basetype) == POINTER_TYPE)
1645 basetype = TREE_TYPE (basetype);
1646 else
1647 return NULL_TREE;
1649 /* Traverse typedefs. */
1650 while (basetype != NULL_TREE
1651 && TREE_CODE (basetype) == RECORD_TYPE
1652 && OBJC_TYPE_NAME (basetype)
1653 && TREE_CODE (OBJC_TYPE_NAME (basetype)) == TYPE_DECL
1654 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype)))
1655 basetype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (basetype));
1657 if (basetype != NULL_TREE && TYPED_OBJECT (basetype))
1659 tree interface_type = TYPE_OBJC_INTERFACE (basetype);
1660 tree protocol_list = TYPE_OBJC_PROTOCOL_LIST (basetype);
1662 if (interface_type
1663 && (TREE_CODE (interface_type) == CLASS_INTERFACE_TYPE
1664 || TREE_CODE (interface_type) == CATEGORY_INTERFACE_TYPE
1665 || TREE_CODE (interface_type) == PROTOCOL_INTERFACE_TYPE))
1667 /* Not sure 'rtype' could ever be a class here! Just
1668 for safety we keep the checks. */
1669 if (!IS_CLASS (rtype))
1671 x = lookup_property (interface_type, property_ident);
1673 if (x == NULL_TREE)
1674 x = lookup_property_in_protocol_list (protocol_list,
1675 property_ident);
1678 if (x == NULL_TREE)
1680 /* Try the dot-syntax without a declared property.
1681 If we are inside a method implementation, it is
1682 possible that they may refer to a setter/getter
1683 that is not declared in the interface, but exists
1684 locally in the implementation. In that case, get
1685 the implementation context and use it. */
1686 tree implementation = NULL_TREE;
1688 if (objc_implementation_context
1689 && CLASS_NAME (objc_implementation_context)
1690 == OBJC_TYPE_NAME (interface_type))
1691 implementation = objc_implementation_context;
1693 x = maybe_make_artificial_property_decl (interface_type,
1694 implementation,
1695 protocol_list,
1696 property_ident,
1697 IS_CLASS (rtype),
1698 NULL_TREE);
1700 else if (PROPERTY_OPTIONAL (x) && PROPERTY_READONLY (x))
1702 tree implementation = NULL_TREE;
1704 if (objc_implementation_context
1705 && CLASS_NAME (objc_implementation_context)
1706 == OBJC_TYPE_NAME (interface_type))
1707 implementation = objc_implementation_context;
1709 x = maybe_make_artificial_property_decl (interface_type,
1710 implementation,
1711 protocol_list,
1712 property_ident,
1713 false,
1714 PROPERTY_GETTER_NAME (x));
1720 if (x)
1722 tree expression;
1723 tree getter_call;
1725 /* We have an additional nasty problem here; if this
1726 PROPERTY_REF needs to become a 'getter', then the conversion
1727 from PROPERTY_REF into a getter call happens in gimplify,
1728 after the selector table has already been generated and when
1729 it is too late to add another selector to it. To work around
1730 the problem, we always create the getter call at this stage,
1731 which puts the selector in the table. Note that if the
1732 PROPERTY_REF becomes a 'setter' instead of a 'getter', then
1733 we have added a selector too many to the selector table.
1734 This is a little inefficient.
1736 Also note that method calls to 'self' and 'super' require the
1737 context (self_decl, UOBJS_SUPER_decl,
1738 objc_implementation_context etc) to be built correctly; this
1739 is yet another reason why building the call at the gimplify
1740 stage (when this context has been lost) is not very
1741 practical. If we build it at this stage, we know it will
1742 always be built correctly.
1744 If the PROPERTY_HAS_NO_GETTER() (ie, it is an artificial
1745 property decl created to deal with a dotsyntax not really
1746 referring to an existing property) then do not try to build a
1747 call to the getter as there is no getter. */
1748 if (PROPERTY_HAS_NO_GETTER (x))
1749 getter_call = NULL_TREE;
1750 else
1751 getter_call = objc_finish_message_expr (object,
1752 PROPERTY_GETTER_NAME (x),
1753 NULL_TREE);
1755 if (TREE_DEPRECATED (x))
1756 warn_deprecated_use (x, NULL_TREE);
1758 expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1759 SET_EXPR_LOCATION (expression, input_location);
1760 TREE_SIDE_EFFECTS (expression) = 1;
1762 return expression;
1765 return NULL_TREE;
1768 /* This hook routine is invoked by the parser when an expression such
1769 as 'xxx.yyy' is parsed, and 'xxx' is a class name. This is the
1770 Objective-C 2.0 dot-syntax applied to classes, so we need to
1771 convert it into a setter/getter call on the class. */
1772 tree
1773 objc_build_class_component_ref (tree class_name, tree property_ident)
1775 tree x = NULL_TREE;
1776 tree object, rtype;
1778 if (flag_objc1_only)
1779 error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
1781 if (class_name == NULL_TREE || class_name == error_mark_node
1782 || TREE_CODE (class_name) != IDENTIFIER_NODE)
1783 return error_mark_node;
1785 if (property_ident == NULL_TREE || property_ident == error_mark_node
1786 || TREE_CODE (property_ident) != IDENTIFIER_NODE)
1787 return NULL_TREE;
1789 object = objc_get_class_reference (class_name);
1790 if (!object)
1792 /* We know that 'class_name' is an Objective-C class name as the
1793 parser won't call this function if it is not. This is only a
1794 double-check for safety. */
1795 error_at (input_location, "could not find class %qE", class_name);
1796 return error_mark_node;
1799 rtype = lookup_interface (class_name);
1800 if (!rtype)
1802 /* Again, this should never happen, but we do check. */
1803 error_at (input_location, "could not find interface for class %qE", class_name);
1804 return error_mark_node;
1806 else
1808 if (TREE_DEPRECATED (rtype))
1809 warning (OPT_Wdeprecated_declarations, "class %qE is deprecated", class_name);
1812 x = maybe_make_artificial_property_decl (rtype, NULL_TREE, NULL_TREE,
1813 property_ident,
1814 true, NULL_TREE);
1816 if (x)
1818 tree expression;
1819 tree getter_call;
1821 if (PROPERTY_HAS_NO_GETTER (x))
1822 getter_call = NULL_TREE;
1823 else
1824 getter_call = objc_finish_message_expr (object,
1825 PROPERTY_GETTER_NAME (x),
1826 NULL_TREE);
1827 if (TREE_DEPRECATED (x))
1828 warn_deprecated_use (x, NULL_TREE);
1830 expression = build3 (PROPERTY_REF, TREE_TYPE(x), object, x, getter_call);
1831 SET_EXPR_LOCATION (expression, input_location);
1832 TREE_SIDE_EFFECTS (expression) = 1;
1834 return expression;
1836 else
1838 error_at (input_location, "could not find setter/getter for %qE in class %qE",
1839 property_ident, class_name);
1840 return error_mark_node;
1843 return NULL_TREE;
1848 /* This is used because we don't want to expose PROPERTY_REF to the
1849 C/C++ frontends. Maybe we should! */
1850 bool
1851 objc_is_property_ref (tree node)
1853 if (node && TREE_CODE (node) == PROPERTY_REF)
1854 return true;
1855 else
1856 return false;
1859 /* This function builds a setter call for a PROPERTY_REF (real, for a
1860 declared property, or artificial, for a dot-syntax accessor which
1861 is not corresponding to a property). 'lhs' must be a PROPERTY_REF
1862 (the caller must check this beforehand). 'rhs' is the value to
1863 assign to the property. A plain setter call is returned, or
1864 error_mark_node if the property is readonly. */
1866 static tree
1867 objc_build_setter_call (tree lhs, tree rhs)
1869 tree object_expr = PROPERTY_REF_OBJECT (lhs);
1870 tree property_decl = PROPERTY_REF_PROPERTY_DECL (lhs);
1872 if (PROPERTY_READONLY (property_decl))
1874 error ("readonly property can not be set");
1875 return error_mark_node;
1877 else
1879 tree setter_argument = build_tree_list (NULL_TREE, rhs);
1880 tree setter;
1882 /* TODO: Check that the setter return type is 'void'. */
1884 /* TODO: Decay arguments in C. */
1885 setter = objc_finish_message_expr (object_expr,
1886 PROPERTY_SETTER_NAME (property_decl),
1887 setter_argument);
1888 return setter;
1891 /* Unreachable, but the compiler may not realize. */
1892 return error_mark_node;
1895 /* This hook routine is called when a MODIFY_EXPR is being built. We
1896 check what is being modified; if it is a PROPERTY_REF, we need to
1897 generate a 'setter' function call for the property. If this is not
1898 a PROPERTY_REF, we return NULL_TREE and the C/C++ frontend will go
1899 on creating their MODIFY_EXPR.
1901 This is used for example if you write
1903 object.count = 1;
1905 where 'count' is a property. The left-hand side creates a
1906 PROPERTY_REF, and then the compiler tries to generate a MODIFY_EXPR
1907 to assign something to it. We intercept that here, and generate a
1908 call to the 'setter' method instead. */
1909 tree
1910 objc_maybe_build_modify_expr (tree lhs, tree rhs)
1912 if (lhs && TREE_CODE (lhs) == PROPERTY_REF)
1914 /* Building a simple call to the setter method would work for cases such as
1916 object.count = 1;
1918 but wouldn't work for cases such as
1920 count = object2.count = 1;
1922 to get these to work with very little effort, we build a
1923 compound statement which does the setter call (to set the
1924 property to 'rhs'), but which can also be evaluated returning
1925 the 'rhs'. So, we want to create the following:
1927 (temp = rhs; [object setProperty: temp]; temp)
1929 tree temp_variable_decl, bind;
1930 /* s1, s2 and s3 are the tree statements that we need in the
1931 compound expression. */
1932 tree s1, s2, s3, compound_expr;
1934 /* TODO: If 'rhs' is a constant, we could maybe do without the
1935 'temp' variable ? */
1937 /* Declare __objc_property_temp in a local bind. */
1938 temp_variable_decl = objc_create_temporary_var (TREE_TYPE (rhs), "__objc_property_temp");
1939 DECL_SOURCE_LOCATION (temp_variable_decl) = input_location;
1940 bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
1941 SET_EXPR_LOCATION (bind, input_location);
1942 TREE_SIDE_EFFECTS (bind) = 1;
1943 add_stmt (bind);
1945 /* Now build the compound statement. */
1947 /* s1: __objc_property_temp = rhs */
1948 s1 = build_modify_expr (input_location, temp_variable_decl, NULL_TREE,
1949 NOP_EXPR,
1950 input_location, rhs, NULL_TREE);
1951 SET_EXPR_LOCATION (s1, input_location);
1953 /* s2: [object setProperty: __objc_property_temp] */
1954 s2 = objc_build_setter_call (lhs, temp_variable_decl);
1956 /* This happens if building the setter failed because the property
1957 is readonly. */
1958 if (s2 == error_mark_node)
1959 return error_mark_node;
1961 SET_EXPR_LOCATION (s2, input_location);
1963 /* s3: __objc_property_temp */
1964 s3 = convert (TREE_TYPE (lhs), temp_variable_decl);
1966 /* Now build the compound statement (s1, s2, s3) */
1967 compound_expr = build_compound_expr (input_location, build_compound_expr (input_location, s1, s2), s3);
1969 /* Without this, with -Wall you get a 'valued computed is not
1970 used' every time there is a "object.property = x" where the
1971 value of the resulting MODIFY_EXPR is not used. That is
1972 correct (maybe a more sophisticated implementation could
1973 avoid generating the compound expression if not needed), but
1974 we need to turn it off. */
1975 TREE_NO_WARNING (compound_expr) = 1;
1976 return compound_expr;
1978 else
1979 return NULL_TREE;
1982 /* This hook is called by the frontend when one of the four unary
1983 expressions PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
1984 PREDECREMENT_EXPR and POSTDECREMENT_EXPR is being built with an
1985 argument which is a PROPERTY_REF. For example, this happens if you have
1987 object.count++;
1989 where 'count' is a property. We need to use the 'getter' and
1990 'setter' for the property in an appropriate way to build the
1991 appropriate expression. 'code' is the code for the expression (one
1992 of the four mentioned above); 'argument' is the PROPERTY_REF, and
1993 'increment' is how much we need to add or subtract. */
1994 tree
1995 objc_build_incr_expr_for_property_ref (location_t location,
1996 enum tree_code code,
1997 tree argument, tree increment)
1999 /* Here are the expressions that we want to build:
2001 For PREINCREMENT_EXPR / PREDECREMENT_EXPR:
2002 (temp = [object property] +/- increment, [object setProperty: temp], temp)
2004 For POSTINCREMENT_EXPR / POSTECREMENT_EXPR:
2005 (temp = [object property], [object setProperty: temp +/- increment], temp) */
2007 tree temp_variable_decl, bind;
2008 /* s1, s2 and s3 are the tree statements that we need in the
2009 compound expression. */
2010 tree s1, s2, s3, compound_expr;
2012 /* Safety check. */
2013 if (!argument || TREE_CODE (argument) != PROPERTY_REF)
2014 return error_mark_node;
2016 /* Declare __objc_property_temp in a local bind. */
2017 temp_variable_decl = objc_create_temporary_var (TREE_TYPE (argument), "__objc_property_temp");
2018 DECL_SOURCE_LOCATION (temp_variable_decl) = location;
2019 bind = build3 (BIND_EXPR, void_type_node, temp_variable_decl, NULL, NULL);
2020 SET_EXPR_LOCATION (bind, location);
2021 TREE_SIDE_EFFECTS (bind) = 1;
2022 add_stmt (bind);
2024 /* Now build the compound statement. */
2026 /* Note that the 'getter' is generated at gimplify time; at this
2027 time, we can simply put the property_ref (ie, argument) wherever
2028 we want the getter ultimately to be. */
2030 /* s1: __objc_property_temp = [object property] <+/- increment> */
2031 switch (code)
2033 case PREINCREMENT_EXPR:
2034 /* __objc_property_temp = [object property] + increment */
2035 s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
2036 NOP_EXPR,
2037 location, build2 (PLUS_EXPR, TREE_TYPE (argument),
2038 argument, increment), NULL_TREE);
2039 break;
2040 case PREDECREMENT_EXPR:
2041 /* __objc_property_temp = [object property] - increment */
2042 s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
2043 NOP_EXPR,
2044 location, build2 (MINUS_EXPR, TREE_TYPE (argument),
2045 argument, increment), NULL_TREE);
2046 break;
2047 case POSTINCREMENT_EXPR:
2048 case POSTDECREMENT_EXPR:
2049 /* __objc_property_temp = [object property] */
2050 s1 = build_modify_expr (location, temp_variable_decl, NULL_TREE,
2051 NOP_EXPR,
2052 location, argument, NULL_TREE);
2053 break;
2054 default:
2055 gcc_unreachable ();
2058 /* s2: [object setProperty: __objc_property_temp <+/- increment>] */
2059 switch (code)
2061 case PREINCREMENT_EXPR:
2062 case PREDECREMENT_EXPR:
2063 /* [object setProperty: __objc_property_temp] */
2064 s2 = objc_build_setter_call (argument, temp_variable_decl);
2065 break;
2066 case POSTINCREMENT_EXPR:
2067 /* [object setProperty: __objc_property_temp + increment] */
2068 s2 = objc_build_setter_call (argument,
2069 build2 (PLUS_EXPR, TREE_TYPE (argument),
2070 temp_variable_decl, increment));
2071 break;
2072 case POSTDECREMENT_EXPR:
2073 /* [object setProperty: __objc_property_temp - increment] */
2074 s2 = objc_build_setter_call (argument,
2075 build2 (MINUS_EXPR, TREE_TYPE (argument),
2076 temp_variable_decl, increment));
2077 break;
2078 default:
2079 gcc_unreachable ();
2082 /* This happens if building the setter failed because the property
2083 is readonly. */
2084 if (s2 == error_mark_node)
2085 return error_mark_node;
2087 SET_EXPR_LOCATION (s2, location);
2089 /* s3: __objc_property_temp */
2090 s3 = convert (TREE_TYPE (argument), temp_variable_decl);
2092 /* Now build the compound statement (s1, s2, s3) */
2093 compound_expr = build_compound_expr (location, build_compound_expr (location, s1, s2), s3);
2095 /* Prevent C++ from warning with -Wall that "right operand of comma
2096 operator has no effect". */
2097 TREE_NO_WARNING (compound_expr) = 1;
2098 return compound_expr;
2101 tree
2102 objc_build_method_signature (bool is_class_method, tree rettype, tree selector,
2103 tree optparms, bool ellipsis)
2105 if (is_class_method)
2106 return build_method_decl (CLASS_METHOD_DECL, rettype, selector,
2107 optparms, ellipsis);
2108 else
2109 return build_method_decl (INSTANCE_METHOD_DECL, rettype, selector,
2110 optparms, ellipsis);
2113 void
2114 objc_add_method_declaration (bool is_class_method, tree decl, tree attributes)
2116 if (!objc_interface_context)
2118 /* PS: At the moment, due to how the parser works, it should be
2119 impossible to get here. But it's good to have the check in
2120 case the parser changes.
2122 fatal_error ("method declaration not in @interface context");
2125 if (flag_objc1_only && attributes)
2126 error_at (input_location, "method attributes are not available in Objective-C 1.0");
2128 objc_decl_method_attributes (&decl, attributes, 0);
2129 objc_add_method (objc_interface_context,
2130 decl,
2131 is_class_method,
2132 objc_method_optional_flag);
2135 /* Return 'true' if the method definition could be started, and
2136 'false' if not (because we are outside an @implementation context).
2138 bool
2139 objc_start_method_definition (bool is_class_method, tree decl, tree attributes)
2141 if (!objc_implementation_context)
2143 error ("method definition not in @implementation context");
2144 return false;
2147 if (decl != NULL_TREE && METHOD_SEL_NAME (decl) == error_mark_node)
2148 return false;
2150 #ifndef OBJCPLUS
2151 /* Indicate no valid break/continue context by setting these variables
2152 to some non-null, non-label value. We'll notice and emit the proper
2153 error message in c_finish_bc_stmt. */
2154 c_break_label = c_cont_label = size_zero_node;
2155 #endif
2157 if (attributes)
2158 warning_at (input_location, 0, "method attributes can not be specified in @implementation context");
2159 else
2160 objc_decl_method_attributes (&decl, attributes, 0);
2162 objc_add_method (objc_implementation_context,
2163 decl,
2164 is_class_method,
2165 /* is optional */ false);
2166 start_method_def (decl);
2167 return true;
2170 void
2171 objc_add_instance_variable (tree decl)
2173 (void) add_instance_variable (objc_ivar_context,
2174 objc_ivar_visibility,
2175 decl);
2178 /* Return true if TYPE is 'id'. */
2180 static bool
2181 objc_is_object_id (tree type)
2183 return OBJC_TYPE_NAME (type) == objc_object_id;
2186 static bool
2187 objc_is_class_id (tree type)
2189 return OBJC_TYPE_NAME (type) == objc_class_id;
2192 /* Construct a C struct with same name as KLASS, a base struct with tag
2193 SUPER_NAME (if any), and FIELDS indicated. */
2195 static tree
2196 objc_build_struct (tree klass, tree fields, tree super_name)
2198 tree name = CLASS_NAME (klass);
2199 tree s = objc_start_struct (name);
2200 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
2201 tree t;
2202 VEC(tree,heap) *objc_info = NULL;
2203 int i;
2205 if (super)
2207 /* Prepend a packed variant of the base class into the layout. This
2208 is necessary to preserve ObjC ABI compatibility. */
2209 tree base = build_decl (input_location,
2210 FIELD_DECL, NULL_TREE, super);
2211 tree field = TYPE_FIELDS (super);
2213 while (field && DECL_CHAIN (field)
2214 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
2215 field = DECL_CHAIN (field);
2217 /* For ObjC ABI purposes, the "packed" size of a base class is
2218 the sum of the offset and the size (in bits) of the last field
2219 in the class. */
2220 DECL_SIZE (base)
2221 = (field && TREE_CODE (field) == FIELD_DECL
2222 ? size_binop (PLUS_EXPR,
2223 size_binop (PLUS_EXPR,
2224 size_binop
2225 (MULT_EXPR,
2226 convert (bitsizetype,
2227 DECL_FIELD_OFFSET (field)),
2228 bitsize_int (BITS_PER_UNIT)),
2229 DECL_FIELD_BIT_OFFSET (field)),
2230 DECL_SIZE (field))
2231 : bitsize_zero_node);
2232 DECL_SIZE_UNIT (base)
2233 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
2234 size_int (BITS_PER_UNIT));
2235 DECL_ARTIFICIAL (base) = 1;
2236 DECL_ALIGN (base) = 1;
2237 DECL_FIELD_CONTEXT (base) = s;
2238 #ifdef OBJCPLUS
2239 DECL_FIELD_IS_BASE (base) = 1;
2241 if (fields)
2242 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
2243 #endif /* are following the ObjC ABI here. */
2244 DECL_CHAIN (base) = fields;
2245 fields = base;
2248 /* NB: Calling finish_struct() may cause type TYPE_OBJC_INFO
2249 information in all variants of this RECORD_TYPE to be destroyed
2250 (this is because the C frontend manipulates TYPE_LANG_SPECIFIC
2251 for something else and then will change all variants to use the
2252 same resulting TYPE_LANG_SPECIFIC, ignoring the fact that we use
2253 it for ObjC protocols and that such propagation will make all
2254 variants use the same objc_info), but it is therein that we store
2255 protocol conformance info (e.g., 'NSObject <MyProtocol>').
2256 Hence, we must save the ObjC-specific information before calling
2257 finish_struct(), and then reinstate it afterwards. */
2259 for (t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
2261 INIT_TYPE_OBJC_INFO (t);
2262 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
2265 s = objc_finish_struct (s, fields);
2267 for (i = 0, t = TYPE_MAIN_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
2269 /* We now want to restore the different TYPE_OBJC_INFO, but we
2270 have the additional problem that the C frontend doesn't just
2271 copy TYPE_LANG_SPECIFIC from one variant to the other; it
2272 actually makes all of them the *same* TYPE_LANG_SPECIFIC. As
2273 we need a different TYPE_OBJC_INFO for each (and
2274 TYPE_OBJC_INFO is a field in TYPE_LANG_SPECIFIC), we need to
2275 make a copy of each TYPE_LANG_SPECIFIC before we modify
2276 TYPE_OBJC_INFO. */
2277 if (TYPE_LANG_SPECIFIC (t))
2279 /* Create a copy of TYPE_LANG_SPECIFIC. */
2280 struct lang_type *old_lang_type = TYPE_LANG_SPECIFIC (t);
2281 ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
2282 memcpy (TYPE_LANG_SPECIFIC (t), old_lang_type,
2283 SIZEOF_OBJC_TYPE_LANG_SPECIFIC);
2285 else
2287 /* Just create a new one. */
2288 ALLOC_OBJC_TYPE_LANG_SPECIFIC (t);
2290 /* Replace TYPE_OBJC_INFO with the saved one. This restores any
2291 protocol information that may have been associated with the
2292 type. */
2293 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
2294 /* Replace the IDENTIFIER_NODE with an actual @interface now
2295 that we have it. */
2296 TYPE_OBJC_INTERFACE (t) = klass;
2298 VEC_free (tree, heap, objc_info);
2300 /* Use TYPE_BINFO structures to point at the super class, if any. */
2301 objc_xref_basetypes (s, super);
2303 /* Mark this struct as a class template. */
2304 CLASS_STATIC_TEMPLATE (klass) = s;
2306 return s;
2309 /* Mark DECL as being 'volatile' for purposes of Darwin
2310 _setjmp()/_longjmp() exception handling. Called from
2311 objc_mark_locals_volatile(). */
2312 void
2313 objc_volatilize_decl (tree decl)
2315 /* Do not mess with variables that are 'static' or (already)
2316 'volatile'. */
2317 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
2318 && (TREE_CODE (decl) == VAR_DECL
2319 || TREE_CODE (decl) == PARM_DECL))
2321 if (local_variables_to_volatilize == NULL)
2322 local_variables_to_volatilize = VEC_alloc (tree, gc, 8);
2324 VEC_safe_push (tree, gc, local_variables_to_volatilize, decl);
2328 /* Called when parsing of a function completes; if any local variables
2329 in the function were marked as variables to volatilize, change them
2330 to volatile. We do this at the end of the function when the
2331 warnings about discarding 'volatile' have already been produced.
2332 We are making the variables as volatile just to force the compiler
2333 to preserve them between setjmp/longjmp, but we don't want warnings
2334 for them as they aren't really volatile. */
2335 void
2336 objc_finish_function (void)
2338 /* If there are any local variables to volatilize, volatilize them. */
2339 if (local_variables_to_volatilize)
2341 int i;
2342 tree decl;
2343 FOR_EACH_VEC_ELT (tree, local_variables_to_volatilize, i, decl)
2345 tree t = TREE_TYPE (decl);
2347 t = build_qualified_type (t, TYPE_QUALS (t) | TYPE_QUAL_VOLATILE);
2348 TREE_TYPE (decl) = t;
2349 TREE_THIS_VOLATILE (decl) = 1;
2350 TREE_SIDE_EFFECTS (decl) = 1;
2351 DECL_REGISTER (decl) = 0;
2352 #ifndef OBJCPLUS
2353 C_DECL_REGISTER (decl) = 0;
2354 #endif
2357 /* Now we delete the vector. This sets it to NULL as well. */
2358 VEC_free (tree, gc, local_variables_to_volatilize);
2362 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
2363 (including its categories and superclasses) or by object type TYP.
2364 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
2366 static bool
2367 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
2369 bool class_type = (cls != NULL_TREE);
2371 while (cls)
2373 tree c;
2375 /* Check protocols adopted by the class and its categories. */
2376 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
2378 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
2379 return true;
2382 /* Repeat for superclasses. */
2383 cls = lookup_interface (CLASS_SUPER_NAME (cls));
2386 /* Check for any protocols attached directly to the object type. */
2387 if (TYPE_HAS_OBJC_INFO (typ))
2389 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
2390 return true;
2393 if (warn)
2395 *errbuf = 0;
2396 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
2397 /* NB: Types 'id' and 'Class' cannot reasonably be described as
2398 "implementing" a given protocol, since they do not have an
2399 implementation. */
2400 if (class_type)
2401 warning (0, "class %qs does not implement the %qE protocol",
2402 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2403 else
2404 warning (0, "type %qs does not conform to the %qE protocol",
2405 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
2408 return false;
2411 /* Check if class RCLS and instance struct type RTYP conform to at least the
2412 same protocols that LCLS and LTYP conform to. */
2414 static bool
2415 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
2417 tree p;
2418 bool have_lproto = false;
2420 while (lcls)
2422 /* NB: We do _not_ look at categories defined for LCLS; these may or
2423 may not get loaded in, and therefore it is unreasonable to require
2424 that RCLS/RTYP must implement any of their protocols. */
2425 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
2427 have_lproto = true;
2429 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2430 return warn;
2433 /* Repeat for superclasses. */
2434 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
2437 /* Check for any protocols attached directly to the object type. */
2438 if (TYPE_HAS_OBJC_INFO (ltyp))
2440 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
2442 have_lproto = true;
2444 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
2445 return warn;
2449 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
2450 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
2451 away with simply checking for 'id' or 'Class' (!RCLS), since this
2452 routine will not get called in other cases. */
2453 return have_lproto || (rcls != NULL_TREE);
2456 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
2457 Both TYPE1 and TYPE2 must be pointers, and already determined to be
2458 compatible by objc_compare_types() below. */
2460 tree
2461 objc_common_type (tree type1, tree type2)
2463 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
2465 while (POINTER_TYPE_P (inner1))
2467 inner1 = TREE_TYPE (inner1);
2468 inner2 = TREE_TYPE (inner2);
2471 /* If one type is derived from another, return the base type. */
2472 if (DERIVED_FROM_P (inner1, inner2))
2473 return type1;
2474 else if (DERIVED_FROM_P (inner2, inner1))
2475 return type2;
2477 /* If both types are 'Class', return 'Class'. */
2478 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
2479 return objc_class_type;
2481 /* Otherwise, return 'id'. */
2482 return objc_object_type;
2485 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
2486 an instance of RTYP to an instance of LTYP or to compare the two
2487 (if ARGNO is equal to -3), per ObjC type system rules. Before
2488 returning 'true', this routine may issue warnings related to, e.g.,
2489 protocol conformance. When returning 'false', the routine must
2490 produce absolutely no warnings; the C or C++ front-end will do so
2491 instead, if needed. If either LTYP or RTYP is not an Objective-C
2492 type, the routine must return 'false'.
2494 The ARGNO parameter is encoded as follows:
2495 >= 1 Parameter number (CALLEE contains function being called);
2496 0 Return value;
2497 -1 Assignment;
2498 -2 Initialization;
2499 -3 Comparison (LTYP and RTYP may match in either direction);
2500 -4 Silent comparison (for C++ overload resolution);
2501 -5 Silent "specialization" comparison for RTYP to be a "specialization"
2502 of LTYP (a specialization means that RTYP is LTYP plus some constraints,
2503 so that each object of type RTYP is also of type LTYP). This is used
2504 when comparing property types. */
2506 bool
2507 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
2509 tree lcls, rcls, lproto, rproto;
2510 bool pointers_compatible;
2512 /* We must be dealing with pointer types */
2513 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
2514 return false;
2518 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
2519 rtyp = TREE_TYPE (rtyp);
2521 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2523 /* We must also handle function pointers, since ObjC is a bit more
2524 lenient than C or C++ on this. */
2525 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
2527 /* Return types must be covariant. */
2528 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
2529 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
2530 argno, callee))
2531 return false;
2533 /* Argument types must be contravariant. */
2534 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
2535 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
2537 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
2538 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
2539 argno, callee))
2540 return false;
2543 return (ltyp == rtyp);
2546 /* Past this point, we are only interested in ObjC class instances,
2547 or 'id' or 'Class'. */
2548 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
2549 return false;
2551 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
2552 && !TYPE_HAS_OBJC_INFO (ltyp))
2553 return false;
2555 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
2556 && !TYPE_HAS_OBJC_INFO (rtyp))
2557 return false;
2559 /* Past this point, we are committed to returning 'true' to the caller
2560 (unless performing a silent comparison; see below). However, we can
2561 still warn about type and/or protocol mismatches. */
2563 if (TYPE_HAS_OBJC_INFO (ltyp))
2565 lcls = TYPE_OBJC_INTERFACE (ltyp);
2566 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
2568 else
2569 lcls = lproto = NULL_TREE;
2571 if (TYPE_HAS_OBJC_INFO (rtyp))
2573 rcls = TYPE_OBJC_INTERFACE (rtyp);
2574 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
2576 else
2577 rcls = rproto = NULL_TREE;
2579 /* If we could not find an @interface declaration, we must have
2580 only seen a @class declaration; for purposes of type comparison,
2581 treat it as a stand-alone (root) class. */
2583 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
2584 lcls = NULL_TREE;
2586 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
2587 rcls = NULL_TREE;
2589 /* If either type is an unqualified 'id', we're done. This is because
2590 an 'id' can be assigned to or from any type with no warnings. */
2591 if (argno != -5)
2593 if ((!lproto && objc_is_object_id (ltyp))
2594 || (!rproto && objc_is_object_id (rtyp)))
2595 return true;
2597 else
2599 /* For property checks, though, an 'id' is considered the most
2600 general type of object, hence if you try to specialize an
2601 'NSArray *' (ltyp) property with an 'id' (rtyp) one, we need
2602 to warn. */
2603 if (!lproto && objc_is_object_id (ltyp))
2604 return true;
2607 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
2609 /* If the underlying types are the same, and at most one of them has
2610 a protocol list, we do not need to issue any diagnostics. */
2611 if (pointers_compatible && (!lproto || !rproto))
2612 return true;
2614 /* If exactly one of the types is 'Class', issue a diagnostic; any
2615 exceptions of this rule have already been handled. */
2616 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
2617 pointers_compatible = false;
2618 /* Otherwise, check for inheritance relations. */
2619 else
2621 if (!pointers_compatible)
2623 /* Again, if any of the two is an 'id', we're satisfied,
2624 unless we're comparing properties, in which case only an
2625 'id' on the left-hand side (old property) is good
2626 enough. */
2627 if (argno != -5)
2628 pointers_compatible
2629 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
2630 else
2631 pointers_compatible = objc_is_object_id (ltyp);
2634 if (!pointers_compatible)
2635 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
2637 if (!pointers_compatible && (argno == -3 || argno == -4))
2638 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
2641 /* If the pointers match modulo protocols, check for protocol conformance
2642 mismatches. */
2643 if (pointers_compatible)
2645 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
2646 argno != -3);
2648 if (!pointers_compatible && argno == -3)
2649 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
2650 argno != -3);
2653 if (!pointers_compatible)
2655 /* The two pointers are not exactly compatible. Issue a warning, unless
2656 we are performing a silent comparison, in which case return 'false'
2657 instead. */
2658 /* NB: For the time being, we shall make our warnings look like their
2659 C counterparts. In the future, we may wish to make them more
2660 ObjC-specific. */
2661 switch (argno)
2663 case -5:
2664 case -4:
2665 return false;
2667 case -3:
2668 warning (0, "comparison of distinct Objective-C types lacks a cast");
2669 break;
2671 case -2:
2672 warning (0, "initialization from distinct Objective-C type");
2673 break;
2675 case -1:
2676 warning (0, "assignment from distinct Objective-C type");
2677 break;
2679 case 0:
2680 warning (0, "distinct Objective-C type in return");
2681 break;
2683 default:
2684 warning (0, "passing argument %d of %qE from distinct "
2685 "Objective-C type", argno, callee);
2686 break;
2690 return true;
2693 /* This routine is similar to objc_compare_types except that function-pointers are
2694 excluded. This is because, caller assumes that common types are of (id, Object*)
2695 variety and calls objc_common_type to obtain a common type. There is no commonolty
2696 between two function-pointers in this regard. */
2698 bool
2699 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
2701 if (objc_compare_types (ltyp, rtyp, argno, callee))
2703 /* exclude function-pointer types. */
2706 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
2707 rtyp = TREE_TYPE (rtyp);
2709 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
2710 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
2712 return false;
2715 #ifndef OBJCPLUS
2716 /* Determine if CHILD is derived from PARENT. The routine assumes that
2717 both parameters are RECORD_TYPEs, and is non-reflexive. */
2719 static bool
2720 objc_derived_from_p (tree parent, tree child)
2722 parent = TYPE_MAIN_VARIANT (parent);
2724 for (child = TYPE_MAIN_VARIANT (child);
2725 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
2727 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
2728 (TYPE_BINFO (child),
2729 0)));
2731 if (child == parent)
2732 return true;
2735 return false;
2737 #endif
2739 static tree
2740 objc_build_component_ref (tree datum, tree component)
2742 /* If COMPONENT is NULL, the caller is referring to the anonymous
2743 base class field. */
2744 if (!component)
2746 tree base = TYPE_FIELDS (TREE_TYPE (datum));
2748 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
2751 /* The 'build_component_ref' routine has been removed from the C++
2752 front-end, but 'finish_class_member_access_expr' seems to be
2753 a worthy substitute. */
2754 #ifdef OBJCPLUS
2755 return finish_class_member_access_expr (datum, component, false,
2756 tf_warning_or_error);
2757 #else
2758 return build_component_ref (input_location, datum, component);
2759 #endif
2762 /* Recursively copy inheritance information rooted at BINFO. To do this,
2763 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
2765 static tree
2766 objc_copy_binfo (tree binfo)
2768 tree btype = BINFO_TYPE (binfo);
2769 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
2770 tree base_binfo;
2771 int ix;
2773 BINFO_TYPE (binfo2) = btype;
2774 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
2775 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
2777 /* Recursively copy base binfos of BINFO. */
2778 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
2780 tree base_binfo2 = objc_copy_binfo (base_binfo);
2782 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
2783 BINFO_BASE_APPEND (binfo2, base_binfo2);
2786 return binfo2;
2789 /* Record superclass information provided in BASETYPE for ObjC class REF.
2790 This is loosely based on cp/decl.c:xref_basetypes(). */
2792 static void
2793 objc_xref_basetypes (tree ref, tree basetype)
2795 tree binfo = make_tree_binfo (basetype ? 1 : 0);
2797 TYPE_BINFO (ref) = binfo;
2798 BINFO_OFFSET (binfo) = size_zero_node;
2799 BINFO_TYPE (binfo) = ref;
2801 if (basetype)
2803 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
2805 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
2806 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
2807 BINFO_BASE_APPEND (binfo, base_binfo);
2808 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
2812 /* Called from finish_decl. */
2814 void
2815 objc_check_decl (tree decl)
2817 tree type = TREE_TYPE (decl);
2819 if (TREE_CODE (type) != RECORD_TYPE)
2820 return;
2821 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
2822 error ("statically allocated instance of Objective-C class %qE",
2823 type);
2826 void
2827 objc_check_global_decl (tree decl)
2829 tree id = DECL_NAME (decl);
2830 if (objc_is_class_name (id) && global_bindings_p())
2831 error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id));
2834 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where
2835 INTERFACE may either name an Objective-C class, or refer to the
2836 special 'id' or 'Class' types. If INTERFACE is not a valid ObjC
2837 type, just return it unchanged. This function is often called when
2838 PROTOCOLS is NULL_TREE, in which case we simply look up the
2839 appropriate INTERFACE. */
2841 tree
2842 objc_get_protocol_qualified_type (tree interface, tree protocols)
2844 /* If INTERFACE is not provided, default to 'id'. */
2845 tree type = (interface ? objc_is_id (interface) : objc_object_type);
2846 bool is_ptr = (type != NULL_TREE);
2848 if (!is_ptr)
2850 type = objc_is_class_name (interface);
2852 if (type)
2854 /* If looking at a typedef, retrieve the precise type it
2855 describes. */
2856 if (TREE_CODE (interface) == IDENTIFIER_NODE)
2857 interface = identifier_global_value (interface);
2859 type = ((interface && TREE_CODE (interface) == TYPE_DECL
2860 && DECL_ORIGINAL_TYPE (interface))
2861 ? DECL_ORIGINAL_TYPE (interface)
2862 : xref_tag (RECORD_TYPE, type));
2864 else
2866 /* This case happens when we are given an 'interface' which
2867 is not a valid class name. For example if a typedef was
2868 used, and 'interface' really is the identifier of the
2869 typedef, but when you resolve it you don't get an
2870 Objective-C class, but something else, such as 'int'.
2871 This is an error; protocols make no sense unless you use
2872 them with Objective-C objects. */
2873 error_at (input_location, "only Objective-C object types can be qualified with a protocol");
2875 /* Try to recover. Ignore the invalid class name, and treat
2876 the object as an 'id' to silence further warnings about
2877 the class. */
2878 type = objc_object_type;
2879 is_ptr = true;
2883 if (protocols)
2885 type = build_variant_type_copy (type);
2887 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
2888 to the pointee. */
2889 if (is_ptr)
2891 tree orig_pointee_type = TREE_TYPE (type);
2892 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
2894 /* Set up the canonical type information. */
2895 TYPE_CANONICAL (type)
2896 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
2898 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
2899 type = TREE_TYPE (type);
2902 /* Look up protocols and install in lang specific list. */
2903 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
2904 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
2906 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
2907 return the pointer to the new pointee variant. */
2908 if (is_ptr)
2909 type = TYPE_POINTER_TO (type);
2910 else
2911 TYPE_OBJC_INTERFACE (type)
2912 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
2915 return type;
2918 /* Check for circular dependencies in protocols. The arguments are
2919 PROTO, the protocol to check, and LIST, a list of protocol it
2920 conforms to. */
2922 static void
2923 check_protocol_recursively (tree proto, tree list)
2925 tree p;
2927 for (p = list; p; p = TREE_CHAIN (p))
2929 tree pp = TREE_VALUE (p);
2931 if (TREE_CODE (pp) == IDENTIFIER_NODE)
2932 pp = lookup_protocol (pp, /* warn if deprecated */ false);
2934 if (pp == proto)
2935 fatal_error ("protocol %qE has circular dependency",
2936 PROTOCOL_NAME (pp));
2937 if (pp)
2938 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
2942 /* Look up PROTOCOLS, and return a list of those that are found. If
2943 none are found, return NULL. Note that this function will emit a
2944 warning if a protocol is found and is deprecated. */
2946 static tree
2947 lookup_and_install_protocols (tree protocols)
2949 tree proto;
2950 tree return_value = NULL_TREE;
2952 if (protocols == error_mark_node)
2953 return NULL;
2955 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
2957 tree ident = TREE_VALUE (proto);
2958 tree p = lookup_protocol (ident, /* warn_if_deprecated */ true);
2960 if (p)
2961 return_value = chainon (return_value,
2962 build_tree_list (NULL_TREE, p));
2963 else if (ident != error_mark_node)
2964 error ("cannot find protocol declaration for %qE",
2965 ident);
2968 return return_value;
2971 /* Create a declaration for field NAME of a given TYPE. */
2973 static tree
2974 create_field_decl (tree type, const char *name)
2976 return build_decl (input_location,
2977 FIELD_DECL, get_identifier (name), type);
2980 /* Create a global, static declaration for variable NAME of a given TYPE. The
2981 finish_var_decl() routine will need to be called on it afterwards. */
2983 static tree
2984 start_var_decl (tree type, const char *name)
2986 tree var = build_decl (input_location,
2987 VAR_DECL, get_identifier (name), type);
2989 TREE_STATIC (var) = 1;
2990 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
2991 DECL_IGNORED_P (var) = 1;
2992 DECL_ARTIFICIAL (var) = 1;
2993 DECL_CONTEXT (var) = NULL_TREE;
2994 #ifdef OBJCPLUS
2995 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
2996 #endif
2998 return var;
3001 /* Finish off the variable declaration created by start_var_decl(). */
3003 static void
3004 finish_var_decl (tree var, tree initializer)
3006 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
3009 /* Find the decl for the constant string class reference. This is only
3010 used for the NeXT runtime. */
3012 static tree
3013 setup_string_decl (void)
3015 char *name;
3016 size_t length;
3018 /* %s in format will provide room for terminating null */
3019 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
3020 + strlen (constant_string_class_name);
3021 name = XNEWVEC (char, length);
3022 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
3023 constant_string_class_name);
3024 constant_string_global_id = get_identifier (name);
3025 string_class_decl = lookup_name (constant_string_global_id);
3027 return string_class_decl;
3030 /* Purpose: "play" parser, creating/installing representations
3031 of the declarations that are required by Objective-C.
3033 Model:
3035 type_spec--------->sc_spec
3036 (tree_list) (tree_list)
3039 identifier_node identifier_node */
3041 static void
3042 synth_module_prologue (void)
3044 tree type;
3045 enum debug_info_type save_write_symbols = write_symbols;
3046 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
3048 /* Suppress outputting debug symbols, because
3049 dbxout_init hasn't been called yet. */
3050 write_symbols = NO_DEBUG;
3051 debug_hooks = &do_nothing_debug_hooks;
3053 #ifdef OBJCPLUS
3054 push_lang_context (lang_name_c); /* extern "C" */
3055 #endif
3057 /* The following are also defined in <objc/objc.h> and friends. */
3059 objc_object_id = get_identifier (TAG_OBJECT);
3060 objc_class_id = get_identifier (TAG_CLASS);
3062 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
3063 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
3065 objc_object_type = build_pointer_type (objc_object_reference);
3066 objc_class_type = build_pointer_type (objc_class_reference);
3068 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
3069 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
3071 /* Declare the 'id' and 'Class' typedefs. */
3073 type = lang_hooks.decls.pushdecl (build_decl (input_location,
3074 TYPE_DECL,
3075 objc_object_name,
3076 objc_object_type));
3077 TREE_NO_WARNING (type) = 1;
3078 type = lang_hooks.decls.pushdecl (build_decl (input_location,
3079 TYPE_DECL,
3080 objc_class_name,
3081 objc_class_type));
3082 TREE_NO_WARNING (type) = 1;
3084 /* Forward-declare '@interface Protocol'. */
3086 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
3087 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
3088 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
3089 type));
3091 /* Declare type of selector-objects that represent an operation name. */
3093 if (flag_next_runtime)
3094 /* `struct objc_selector *' */
3095 objc_selector_type
3096 = build_pointer_type (xref_tag (RECORD_TYPE,
3097 get_identifier (TAG_SELECTOR)));
3098 else
3099 /* `const struct objc_selector *' */
3100 objc_selector_type
3101 = build_pointer_type
3102 (build_qualified_type (xref_tag (RECORD_TYPE,
3103 get_identifier (TAG_SELECTOR)),
3104 TYPE_QUAL_CONST));
3106 /* Declare receiver type used for dispatching messages to 'super'. */
3108 /* `struct objc_super *' */
3109 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
3110 get_identifier (TAG_SUPER)));
3112 /* Declare pointers to method and ivar lists. */
3113 objc_method_list_ptr = build_pointer_type
3114 (xref_tag (RECORD_TYPE,
3115 get_identifier (UTAG_METHOD_LIST)));
3116 objc_method_proto_list_ptr
3117 = build_pointer_type (xref_tag (RECORD_TYPE,
3118 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
3119 objc_ivar_list_ptr = build_pointer_type
3120 (xref_tag (RECORD_TYPE,
3121 get_identifier (UTAG_IVAR_LIST)));
3123 /* TREE_NOTHROW is cleared for the message-sending functions,
3124 because the function that gets called can throw in Obj-C++, or
3125 could itself call something that can throw even in Obj-C. */
3127 if (flag_next_runtime)
3129 /* NB: In order to call one of the ..._stret (struct-returning)
3130 functions, the function *MUST* first be cast to a signature that
3131 corresponds to the actual ObjC method being invoked. This is
3132 what is done by the build_objc_method_call() routine below. */
3134 /* id objc_msgSend (id, SEL, ...); */
3135 /* id objc_msgSendNonNil (id, SEL, ...); */
3136 /* id objc_msgSend_stret (id, SEL, ...); */
3137 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
3138 type
3139 = build_varargs_function_type_list (objc_object_type,
3140 objc_object_type,
3141 objc_selector_type,
3142 NULL_TREE);
3143 umsg_decl = add_builtin_function (TAG_MSGSEND,
3144 type, 0, NOT_BUILT_IN,
3145 NULL, NULL_TREE);
3146 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
3147 type, 0, NOT_BUILT_IN,
3148 NULL, NULL_TREE);
3149 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
3150 type, 0, NOT_BUILT_IN,
3151 NULL, NULL_TREE);
3152 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
3153 type, 0, NOT_BUILT_IN,
3154 NULL, NULL_TREE);
3156 /* These can throw, because the function that gets called can throw
3157 in Obj-C++, or could itself call something that can throw even
3158 in Obj-C. */
3159 TREE_NOTHROW (umsg_decl) = 0;
3160 TREE_NOTHROW (umsg_nonnil_decl) = 0;
3161 TREE_NOTHROW (umsg_stret_decl) = 0;
3162 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
3164 /* id objc_msgSend_Fast (id, SEL, ...)
3165 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
3166 #ifdef OFFS_MSGSEND_FAST
3167 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
3168 type, 0, NOT_BUILT_IN,
3169 NULL, NULL_TREE);
3170 TREE_NOTHROW (umsg_fast_decl) = 0;
3171 DECL_ATTRIBUTES (umsg_fast_decl)
3172 = tree_cons (get_identifier ("hard_coded_address"),
3173 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
3174 NULL_TREE);
3175 #else
3176 /* No direct dispatch available. */
3177 umsg_fast_decl = umsg_decl;
3178 #endif
3180 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
3181 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
3182 type
3183 = build_varargs_function_type_list (objc_object_type,
3184 objc_super_type,
3185 objc_selector_type,
3186 NULL_TREE);
3187 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3188 type, 0, NOT_BUILT_IN,
3189 NULL, NULL_TREE);
3190 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
3191 type, 0, NOT_BUILT_IN, 0,
3192 NULL_TREE);
3193 TREE_NOTHROW (umsg_super_decl) = 0;
3194 TREE_NOTHROW (umsg_super_stret_decl) = 0;
3196 else
3198 /* GNU runtime messenger entry points. */
3200 /* typedef id (*IMP)(id, SEL, ...); */
3201 tree ftype =
3202 build_varargs_function_type_list (objc_object_type,
3203 objc_object_type,
3204 objc_selector_type,
3205 NULL_TREE);
3206 tree IMP_type = build_pointer_type (ftype);
3208 /* IMP objc_msg_lookup (id, SEL); */
3209 type = build_function_type_list (IMP_type,
3210 objc_object_type,
3211 objc_selector_type,
3212 NULL_TREE);
3213 umsg_decl = add_builtin_function (TAG_MSGSEND,
3214 type, 0, NOT_BUILT_IN,
3215 NULL, NULL_TREE);
3216 TREE_NOTHROW (umsg_decl) = 0;
3218 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
3219 type
3220 = build_function_type_list (IMP_type,
3221 objc_super_type,
3222 objc_selector_type,
3223 NULL_TREE);
3224 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
3225 type, 0, NOT_BUILT_IN,
3226 NULL, NULL_TREE);
3227 TREE_NOTHROW (umsg_super_decl) = 0;
3229 /* The following GNU runtime entry point is called to initialize
3230 each module:
3232 __objc_exec_class (void *); */
3233 type
3234 = build_function_type_list (void_type_node,
3235 ptr_type_node,
3236 NULL_TREE);
3237 execclass_decl = add_builtin_function (TAG_EXECCLASS,
3238 type, 0, NOT_BUILT_IN,
3239 NULL, NULL_TREE);
3242 /* id objc_getClass (const char *); */
3244 type = build_function_type_list (objc_object_type,
3245 const_string_type_node,
3246 NULL_TREE);
3248 objc_get_class_decl
3249 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
3250 NULL, NULL_TREE);
3252 /* id objc_getMetaClass (const char *); */
3254 objc_get_meta_class_decl
3255 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3257 build_class_template ();
3258 build_super_template ();
3259 build_protocol_template ();
3260 build_category_template ();
3261 build_objc_exception_stuff ();
3263 /* Declare objc_getProperty, object_setProperty and other property
3264 accessor helpers. */
3265 build_objc_property_accessor_helpers ();
3267 if (flag_next_runtime)
3268 build_next_objc_exception_stuff ();
3270 /* static SEL _OBJC_SELECTOR_TABLE[]; */
3272 if (! flag_next_runtime)
3273 build_selector_table_decl ();
3275 /* Forward declare constant_string_id and constant_string_type. */
3276 if (!constant_string_class_name)
3277 constant_string_class_name = default_constant_string_class_name;
3279 constant_string_id = get_identifier (constant_string_class_name);
3280 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
3282 /* Pre-build the following entities - for speed/convenience. */
3283 self_id = get_identifier ("self");
3284 ucmd_id = get_identifier ("_cmd");
3286 /* Declare struct _objc_fast_enumeration_state { ... }; */
3287 build_fast_enumeration_state_template ();
3289 /* void objc_enumeration_mutation (id) */
3290 type = build_function_type (void_type_node,
3291 tree_cons (NULL_TREE, objc_object_type, NULL_TREE));
3292 objc_enumeration_mutation_decl
3293 = add_builtin_function (TAG_ENUMERATION_MUTATION, type, 0, NOT_BUILT_IN,
3294 NULL, NULL_TREE);
3295 TREE_NOTHROW (objc_enumeration_mutation_decl) = 0;
3297 #ifdef OBJCPLUS
3298 pop_lang_context ();
3299 #endif
3301 write_symbols = save_write_symbols;
3302 debug_hooks = save_hooks;
3305 /* Ensure that the ivar list for NSConstantString/NXConstantString
3306 (or whatever was specified via `-fconstant-string-class')
3307 contains fields at least as large as the following three, so that
3308 the runtime can stomp on them with confidence:
3310 struct STRING_OBJECT_CLASS_NAME
3312 Object isa;
3313 char *cString;
3314 unsigned int length;
3315 }; */
3317 static int
3318 check_string_class_template (void)
3320 tree field_decl = objc_get_class_ivars (constant_string_id);
3322 #define AT_LEAST_AS_LARGE_AS(F, T) \
3323 (F && TREE_CODE (F) == FIELD_DECL \
3324 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
3325 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
3327 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3328 return 0;
3330 field_decl = DECL_CHAIN (field_decl);
3331 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
3332 return 0;
3334 field_decl = DECL_CHAIN (field_decl);
3335 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
3337 #undef AT_LEAST_AS_LARGE_AS
3340 /* Avoid calling `check_string_class_template ()' more than once. */
3341 static GTY(()) int string_layout_checked;
3343 /* Construct an internal string layout to be used as a template for
3344 creating NSConstantString/NXConstantString instances. */
3346 static tree
3347 objc_build_internal_const_str_type (void)
3349 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
3350 tree fields = build_decl (input_location,
3351 FIELD_DECL, NULL_TREE, ptr_type_node);
3352 tree field = build_decl (input_location,
3353 FIELD_DECL, NULL_TREE, ptr_type_node);
3355 DECL_CHAIN (field) = fields; fields = field;
3356 field = build_decl (input_location,
3357 FIELD_DECL, NULL_TREE, unsigned_type_node);
3358 DECL_CHAIN (field) = fields; fields = field;
3359 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
3360 reverse order! */
3361 finish_builtin_struct (type, "__builtin_ObjCString",
3362 fields, NULL_TREE);
3364 return type;
3367 /* Custom build_string which sets TREE_TYPE! */
3369 static tree
3370 my_build_string (int len, const char *str)
3372 return fix_string_type (build_string (len, str));
3375 /* Build a string with contents STR and length LEN and convert it to a
3376 pointer. */
3378 static tree
3379 my_build_string_pointer (int len, const char *str)
3381 tree string = my_build_string (len, str);
3382 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
3383 return build1 (ADDR_EXPR, ptrtype, string);
3386 static hashval_t
3387 string_hash (const void *ptr)
3389 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
3390 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
3391 int i, len = TREE_STRING_LENGTH (str);
3392 hashval_t h = len;
3394 for (i = 0; i < len; i++)
3395 h = ((h * 613) + p[i]);
3397 return h;
3400 static int
3401 string_eq (const void *ptr1, const void *ptr2)
3403 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
3404 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
3405 int len1 = TREE_STRING_LENGTH (str1);
3407 return (len1 == TREE_STRING_LENGTH (str2)
3408 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
3409 len1));
3412 /* Given a chain of STRING_CST's, build a static instance of
3413 NXConstantString which points at the concatenation of those
3414 strings. We place the string object in the __string_objects
3415 section of the __OBJC segment. The Objective-C runtime will
3416 initialize the isa pointers of the string objects to point at the
3417 NXConstantString class object. */
3419 tree
3420 objc_build_string_object (tree string)
3422 tree constant_string_class;
3423 int length;
3424 tree fields, addr;
3425 struct string_descriptor *desc, key;
3426 void **loc;
3428 /* Prep the string argument. */
3429 string = fix_string_type (string);
3430 TREE_SET_CODE (string, STRING_CST);
3431 length = TREE_STRING_LENGTH (string) - 1;
3433 /* The target may have different ideas on how to construct an ObjC string
3434 literal. On Darwin (Mac OS X), for example, we may wish to obtain a
3435 constant CFString reference instead.
3436 At present, this is only supported for the NeXT runtime. */
3437 if (flag_next_runtime && targetcm.objc_construct_string_object)
3439 tree constructor = (*targetcm.objc_construct_string_object) (string);
3440 if (constructor)
3441 return build1 (NOP_EXPR, objc_object_type, constructor);
3444 /* Check whether the string class being used actually exists and has the
3445 correct ivar layout. */
3446 if (!string_layout_checked)
3448 string_layout_checked = -1;
3449 constant_string_class = lookup_interface (constant_string_id);
3450 internal_const_str_type = objc_build_internal_const_str_type ();
3452 if (!constant_string_class
3453 || !(constant_string_type
3454 = CLASS_STATIC_TEMPLATE (constant_string_class)))
3455 error ("cannot find interface declaration for %qE",
3456 constant_string_id);
3457 /* The NSConstantString/NXConstantString ivar layout is now known. */
3458 else if (!check_string_class_template ())
3459 error ("interface %qE does not have valid constant string layout",
3460 constant_string_id);
3461 /* For the NeXT runtime, we can generate a literal reference
3462 to the string class, don't need to run a constructor. */
3463 else if (flag_next_runtime && !setup_string_decl ())
3464 error ("cannot find reference tag for class %qE",
3465 constant_string_id);
3466 else
3468 string_layout_checked = 1; /* Success! */
3469 add_class_reference (constant_string_id);
3473 if (string_layout_checked == -1)
3474 return error_mark_node;
3476 /* Perhaps we already constructed a constant string just like this one? */
3477 key.literal = string;
3478 loc = htab_find_slot (string_htab, &key, INSERT);
3479 desc = (struct string_descriptor *) *loc;
3481 if (!desc)
3483 tree var, constructor;
3484 VEC(constructor_elt,gc) *v = NULL;
3485 *loc = desc = ggc_alloc_string_descriptor ();
3486 desc->literal = string;
3488 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
3489 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
3490 fields = TYPE_FIELDS (internal_const_str_type);
3491 CONSTRUCTOR_APPEND_ELT (v, fields,
3492 flag_next_runtime
3493 ? build_unary_op (input_location,
3494 ADDR_EXPR, string_class_decl, 0)
3495 : build_int_cst (NULL_TREE, 0));
3496 fields = DECL_CHAIN (fields);
3497 CONSTRUCTOR_APPEND_ELT (v, fields,
3498 build_unary_op (input_location,
3499 ADDR_EXPR, string, 1));
3500 fields = DECL_CHAIN (fields);
3501 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
3502 constructor = objc_build_constructor (internal_const_str_type, v);
3504 if (!flag_next_runtime)
3505 constructor
3506 = objc_add_static_instance (constructor, constant_string_type);
3507 else
3509 var = build_decl (input_location,
3510 CONST_DECL, NULL, TREE_TYPE (constructor));
3511 DECL_INITIAL (var) = constructor;
3512 TREE_STATIC (var) = 1;
3513 pushdecl_top_level (var);
3514 constructor = var;
3516 desc->constructor = constructor;
3519 addr = convert (build_pointer_type (constant_string_type),
3520 build_unary_op (input_location,
3521 ADDR_EXPR, desc->constructor, 1));
3523 return addr;
3526 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
3528 static GTY(()) int num_static_inst;
3530 static tree
3531 objc_add_static_instance (tree constructor, tree class_decl)
3533 tree *chain, decl;
3534 char buf[256];
3536 /* Find the list of static instances for the CLASS_DECL. Create one if
3537 not found. */
3538 for (chain = &objc_static_instances;
3539 *chain && TREE_VALUE (*chain) != class_decl;
3540 chain = &TREE_CHAIN (*chain));
3541 if (!*chain)
3543 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
3544 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
3547 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
3548 decl = build_decl (input_location,
3549 VAR_DECL, get_identifier (buf), class_decl);
3550 TREE_STATIC (decl) = 1;
3551 DECL_ARTIFICIAL (decl) = 1;
3552 TREE_USED (decl) = 1;
3553 DECL_INITIAL (decl) = constructor;
3555 /* We may be writing something else just now.
3556 Postpone till end of input. */
3557 DECL_DEFER_OUTPUT (decl) = 1;
3558 pushdecl_top_level (decl);
3559 rest_of_decl_compilation (decl, 1, 0);
3561 /* Add the DECL to the head of this CLASS' list. */
3562 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
3564 return decl;
3567 /* Build a static constant CONSTRUCTOR
3568 with type TYPE and elements ELTS. */
3570 static tree
3571 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
3573 tree constructor = build_constructor (type, elts);
3575 TREE_CONSTANT (constructor) = 1;
3576 TREE_STATIC (constructor) = 1;
3577 TREE_READONLY (constructor) = 1;
3579 #ifdef OBJCPLUS
3580 /* Adjust for impedance mismatch. We should figure out how to build
3581 CONSTRUCTORs that consistently please both the C and C++ gods. */
3582 if (!VEC_index (constructor_elt, elts, 0)->index)
3583 TREE_TYPE (constructor) = init_list_type_node;
3584 #endif
3586 return constructor;
3589 /* Take care of defining and initializing _OBJC_SYMBOLS. */
3591 /* Predefine the following data type:
3593 struct _objc_symtab
3595 long sel_ref_cnt;
3596 SEL *refs;
3597 short cls_def_cnt;
3598 short cat_def_cnt;
3599 void *defs[cls_def_cnt + cat_def_cnt];
3600 }; */
3602 static void
3603 build_objc_symtab_template (void)
3605 tree fields, *chain = NULL;
3607 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
3609 /* long sel_ref_cnt; */
3610 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
3612 /* SEL *refs; */
3613 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
3615 /* short cls_def_cnt; */
3616 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
3618 /* short cat_def_cnt; */
3619 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
3621 if (imp_count || cat_count || !flag_next_runtime)
3623 /* void *defs[imp_count + cat_count (+ 1)]; */
3624 /* NB: The index is one less than the size of the array. */
3625 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
3626 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
3627 add_field_decl (array_type, "defs", &chain);
3630 objc_finish_struct (objc_symtab_template, fields);
3633 /* Create the initial value for the `defs' field of _objc_symtab.
3634 This is a CONSTRUCTOR. */
3636 static tree
3637 init_def_list (tree type)
3639 tree expr;
3640 struct imp_entry *impent;
3641 VEC(constructor_elt,gc) *v = NULL;
3643 if (imp_count)
3644 for (impent = imp_list; impent; impent = impent->next)
3646 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
3648 expr = build_unary_op (input_location,
3649 ADDR_EXPR, impent->class_decl, 0);
3650 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3654 if (cat_count)
3655 for (impent = imp_list; impent; impent = impent->next)
3657 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3659 expr = build_unary_op (input_location,
3660 ADDR_EXPR, impent->class_decl, 0);
3661 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3665 if (!flag_next_runtime)
3667 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
3668 if (static_instances_decl)
3669 expr = build_unary_op (input_location,
3670 ADDR_EXPR, static_instances_decl, 0);
3671 else
3672 expr = integer_zero_node;
3674 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3677 return objc_build_constructor (type, v);
3680 /* Construct the initial value for all of _objc_symtab. */
3682 static tree
3683 init_objc_symtab (tree type)
3685 VEC(constructor_elt,gc) *v = NULL;
3687 /* sel_ref_cnt = { ..., 5, ... } */
3689 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3690 build_int_cst (long_integer_type_node, 0));
3692 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
3694 if (flag_next_runtime || ! sel_ref_chain)
3695 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
3696 build_pointer_type (objc_selector_type),
3697 integer_zero_node));
3698 else
3700 tree expr = build_unary_op (input_location, ADDR_EXPR,
3701 UOBJC_SELECTOR_TABLE_decl, 1);
3703 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3704 convert (build_pointer_type (objc_selector_type),
3705 expr));
3708 /* cls_def_cnt = { ..., 5, ... } */
3710 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3711 build_int_cst (short_integer_type_node, imp_count));
3713 /* cat_def_cnt = { ..., 5, ... } */
3715 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
3716 build_int_cst (short_integer_type_node, cat_count));
3718 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
3720 if (imp_count || cat_count || !flag_next_runtime)
3723 tree field = TYPE_FIELDS (type);
3724 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
3726 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
3729 return objc_build_constructor (type, v);
3732 /* Generate forward declarations for metadata such as
3733 'OBJC_CLASS_...'. */
3735 static tree
3736 build_metadata_decl (const char *name, tree type)
3738 tree decl;
3740 /* struct TYPE NAME_<name>; */
3741 decl = start_var_decl (type, synth_id_with_class_suffix
3742 (name,
3743 objc_implementation_context));
3745 return decl;
3748 /* Push forward-declarations of all the categories so that
3749 init_def_list can use them in a CONSTRUCTOR. */
3751 static void
3752 forward_declare_categories (void)
3754 struct imp_entry *impent;
3755 tree sav = objc_implementation_context;
3757 for (impent = imp_list; impent; impent = impent->next)
3759 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
3761 /* Set an invisible arg to synth_id_with_class_suffix. */
3762 objc_implementation_context = impent->imp_context;
3763 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
3764 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
3765 objc_category_template);
3768 objc_implementation_context = sav;
3771 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
3772 and initialized appropriately. */
3774 static void
3775 generate_objc_symtab_decl (void)
3778 build_objc_symtab_template ();
3779 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
3780 finish_var_decl (UOBJC_SYMBOLS_decl,
3781 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
3784 static tree
3785 init_module_descriptor (tree type)
3787 tree expr;
3788 VEC(constructor_elt,gc) *v = NULL;
3790 /* version = { 1, ... } */
3792 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
3793 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3795 /* size = { ..., sizeof (struct _objc_module), ... } */
3797 expr = convert (long_integer_type_node,
3798 size_in_bytes (objc_module_template));
3799 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3801 /* Don't provide any file name for security reasons. */
3802 /* name = { ..., "", ... } */
3804 expr = add_objc_string (get_identifier (""), class_names);
3805 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3807 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
3809 if (UOBJC_SYMBOLS_decl)
3810 expr = build_unary_op (input_location,
3811 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
3812 else
3813 expr = null_pointer_node;
3814 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
3816 return objc_build_constructor (type, v);
3819 /* Write out the data structures to describe Objective C classes defined.
3821 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
3823 static void
3824 build_module_descriptor (void)
3826 tree decls, *chain = NULL;
3828 #ifdef OBJCPLUS
3829 push_lang_context (lang_name_c); /* extern "C" */
3830 #endif
3832 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
3834 /* long version; */
3835 decls = add_field_decl (long_integer_type_node, "version", &chain);
3837 /* long size; */
3838 add_field_decl (long_integer_type_node, "size", &chain);
3840 /* char *name; */
3841 add_field_decl (string_type_node, "name", &chain);
3843 /* struct _objc_symtab *symtab; */
3844 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
3845 get_identifier (UTAG_SYMTAB))),
3846 "symtab", &chain);
3848 objc_finish_struct (objc_module_template, decls);
3850 /* Create an instance of "_objc_module". */
3851 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
3852 /* This is the root of the metadata for defined classes and categories, it
3853 is referenced by the runtime and, therefore, needed. */
3854 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
3855 finish_var_decl (UOBJC_MODULES_decl,
3856 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
3858 #ifdef OBJCPLUS
3859 pop_lang_context ();
3860 #endif
3863 /* The GNU runtime requires us to provide a static initializer function
3864 for each module:
3866 static void __objc_gnu_init (void) {
3867 __objc_exec_class (&L_OBJC_MODULES);
3868 } */
3870 static void
3871 build_module_initializer_routine (void)
3873 tree body;
3875 #ifdef OBJCPLUS
3876 push_lang_context (lang_name_c); /* extern "C" */
3877 #endif
3879 objc_push_parm (build_decl (input_location,
3880 PARM_DECL, NULL_TREE, void_type_node));
3881 #ifdef OBJCPLUS
3882 objc_start_function (get_identifier (TAG_GNUINIT),
3883 build_function_type_list (void_type_node, NULL_TREE),
3884 NULL_TREE, NULL_TREE);
3885 #else
3886 objc_start_function (get_identifier (TAG_GNUINIT),
3887 build_function_type_list (void_type_node, NULL_TREE),
3888 NULL_TREE, objc_get_parm_info (0));
3889 #endif
3890 body = c_begin_compound_stmt (true);
3891 add_stmt (build_function_call
3892 (input_location,
3893 execclass_decl,
3894 build_tree_list
3895 (NULL_TREE,
3896 build_unary_op (input_location, ADDR_EXPR,
3897 UOBJC_MODULES_decl, 0))));
3898 add_stmt (c_end_compound_stmt (input_location, body, true));
3900 TREE_PUBLIC (current_function_decl) = 0;
3902 #ifndef OBJCPLUS
3903 /* For Objective-C++, we will need to call __objc_gnu_init
3904 from objc_generate_static_init_call() below. */
3905 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
3906 #endif
3908 GNU_INIT_decl = current_function_decl;
3909 finish_function ();
3911 #ifdef OBJCPLUS
3912 pop_lang_context ();
3913 #endif
3916 #ifdef OBJCPLUS
3917 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
3918 to be called by the module initializer routine. */
3921 objc_static_init_needed_p (void)
3923 return (GNU_INIT_decl != NULL_TREE);
3926 /* Generate a call to the __objc_gnu_init initializer function. */
3928 tree
3929 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
3931 add_stmt (build_stmt (input_location, EXPR_STMT,
3932 build_function_call (input_location,
3933 GNU_INIT_decl, NULL_TREE)));
3935 return ctors;
3937 #endif /* OBJCPLUS */
3939 /* Return the DECL of the string IDENT in the SECTION. */
3941 static tree
3942 get_objc_string_decl (tree ident, enum string_section section)
3944 tree chain;
3946 switch (section)
3948 case class_names:
3949 chain = class_names_chain;
3950 break;
3951 case meth_var_names:
3952 chain = meth_var_names_chain;
3953 break;
3954 case meth_var_types:
3955 chain = meth_var_types_chain;
3956 break;
3957 default:
3958 gcc_unreachable ();
3961 for (; chain != 0; chain = TREE_CHAIN (chain))
3962 if (TREE_VALUE (chain) == ident)
3963 return (TREE_PURPOSE (chain));
3965 gcc_unreachable ();
3966 return NULL_TREE;
3969 /* Output references to all statically allocated objects. Return the DECL
3970 for the array built. */
3972 static void
3973 generate_static_references (void)
3975 tree expr = NULL_TREE;
3976 tree class_name, klass, decl;
3977 tree cl_chain, in_chain, type
3978 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
3979 int num_inst, num_class;
3980 char buf[256];
3981 VEC(constructor_elt,gc) *decls = NULL;
3983 if (flag_next_runtime)
3984 gcc_unreachable ();
3986 for (cl_chain = objc_static_instances, num_class = 0;
3987 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
3989 VEC(constructor_elt,gc) *v = NULL;
3991 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
3992 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
3994 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
3995 decl = start_var_decl (type, buf);
3997 /* Output {class_name, ...}. */
3998 klass = TREE_VALUE (cl_chain);
3999 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
4000 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
4001 build_unary_op (input_location,
4002 ADDR_EXPR, class_name, 1));
4004 /* Output {..., instance, ...}. */
4005 for (in_chain = TREE_PURPOSE (cl_chain);
4006 in_chain; in_chain = TREE_CHAIN (in_chain))
4008 expr = build_unary_op (input_location,
4009 ADDR_EXPR, TREE_VALUE (in_chain), 1);
4010 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
4013 /* Output {..., NULL}. */
4014 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
4016 expr = objc_build_constructor (TREE_TYPE (decl), v);
4017 finish_var_decl (decl, expr);
4018 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
4019 build_unary_op (input_location,
4020 ADDR_EXPR, decl, 1));
4023 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
4024 expr = objc_build_constructor (type, decls);
4025 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
4026 finish_var_decl (static_instances_decl, expr);
4029 static GTY(()) int selector_reference_idx;
4031 static tree
4032 build_selector_reference_decl (void)
4034 tree decl;
4035 char buf[256];
4037 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
4038 decl = start_var_decl (objc_selector_type, buf);
4040 return decl;
4043 static void
4044 build_selector_table_decl (void)
4046 tree temp;
4048 if (flag_typed_selectors)
4050 build_selector_template ();
4051 temp = build_array_type (objc_selector_template, NULL_TREE);
4053 else
4054 temp = build_array_type (objc_selector_type, NULL_TREE);
4056 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
4059 /* Just a handy wrapper for add_objc_string. */
4061 static tree
4062 build_selector (tree ident)
4064 return convert (objc_selector_type,
4065 add_objc_string (ident, meth_var_names));
4068 /* Used only by build_*_selector_translation_table (). */
4069 static void
4070 diagnose_missing_method (tree meth, location_t here)
4072 tree method_chain;
4073 bool found = false;
4074 for (method_chain = meth_var_names_chain;
4075 method_chain;
4076 method_chain = TREE_CHAIN (method_chain))
4078 if (TREE_VALUE (method_chain) == meth)
4080 found = true;
4081 break;
4085 if (!found)
4086 warning_at (here, 0, "creating selector for nonexistent method %qE",
4087 meth);
4090 static void
4091 build_next_selector_translation_table (void)
4093 tree chain;
4094 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
4096 tree expr;
4097 tree decl = TREE_PURPOSE (chain);
4098 if (warn_selector && objc_implementation_context)
4100 location_t loc;
4101 if (decl)
4102 loc = DECL_SOURCE_LOCATION (decl);
4103 else
4104 loc = input_location;
4105 diagnose_missing_method (TREE_VALUE (chain), loc);
4108 expr = build_selector (TREE_VALUE (chain));
4110 if (decl)
4112 /* Entries of this form are used for references to methods.
4113 The runtime re-writes these on start-up, but the compiler can't see
4114 that and optimizes it away unless we force it. */
4115 DECL_PRESERVE_P (decl) = 1;
4116 finish_var_decl (decl, expr);
4121 static void
4122 build_gnu_selector_translation_table (void)
4124 tree chain;
4125 /* int offset = 0;
4126 tree decl = NULL_TREE;*/
4127 VEC(constructor_elt,gc) *inits = NULL;
4129 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
4131 tree expr;
4133 if (warn_selector && objc_implementation_context)
4134 diagnose_missing_method (TREE_VALUE (chain), input_location);
4136 expr = build_selector (TREE_VALUE (chain));
4137 /* add one for the '\0' character
4138 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
4141 if (flag_typed_selectors)
4143 VEC(constructor_elt,gc) *v = NULL;
4144 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
4145 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
4146 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
4147 expr = objc_build_constructor (objc_selector_template, v);
4150 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4152 } /* each element in the chain */
4155 /* Cause the selector table (previously forward-declared)
4156 to be actually output. */
4157 tree expr;
4159 if (flag_typed_selectors)
4161 VEC(constructor_elt,gc) *v = NULL;
4162 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
4163 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
4164 expr = objc_build_constructor (objc_selector_template, v);
4166 else
4167 expr = integer_zero_node;
4169 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4170 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
4171 inits);
4172 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
4176 static tree
4177 get_proto_encoding (tree proto)
4179 tree encoding;
4180 if (proto)
4182 if (! METHOD_ENCODING (proto))
4184 encoding = encode_method_prototype (proto);
4185 METHOD_ENCODING (proto) = encoding;
4187 else
4188 encoding = METHOD_ENCODING (proto);
4190 return add_objc_string (encoding, meth_var_types);
4192 else
4193 return build_int_cst (NULL_TREE, 0);
4196 /* sel_ref_chain is a list whose "value" fields will be instances of
4197 identifier_node that represent the selector. LOC is the location of
4198 the @selector. */
4200 static tree
4201 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
4203 tree *chain = &sel_ref_chain;
4204 tree expr;
4205 int index = 0;
4207 while (*chain)
4209 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
4210 goto return_at_index;
4212 index++;
4213 chain = &TREE_CHAIN (*chain);
4216 *chain = tree_cons (prototype, ident, NULL_TREE);
4218 return_at_index:
4219 expr = build_unary_op (loc, ADDR_EXPR,
4220 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4221 build_int_cst (NULL_TREE, index)),
4223 return convert (objc_selector_type, expr);
4226 static tree
4227 build_selector_reference (location_t loc, tree ident)
4229 tree *chain = &sel_ref_chain;
4230 tree expr;
4231 int index = 0;
4233 while (*chain)
4235 if (TREE_VALUE (*chain) == ident)
4236 return (flag_next_runtime
4237 ? TREE_PURPOSE (*chain)
4238 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4239 build_int_cst (NULL_TREE, index)));
4241 index++;
4242 chain = &TREE_CHAIN (*chain);
4245 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
4247 *chain = tree_cons (expr, ident, NULL_TREE);
4249 return (flag_next_runtime
4250 ? expr
4251 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
4252 build_int_cst (NULL_TREE, index)));
4255 static GTY(()) int class_reference_idx;
4257 static tree
4258 build_class_reference_decl (void)
4260 tree decl;
4261 char buf[256];
4263 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
4264 decl = start_var_decl (objc_class_type, buf);
4266 return decl;
4269 /* Create a class reference, but don't create a variable to reference
4270 it. */
4272 static void
4273 add_class_reference (tree ident)
4275 tree chain;
4277 if ((chain = cls_ref_chain))
4279 tree tail;
4282 if (ident == TREE_VALUE (chain))
4283 return;
4285 tail = chain;
4286 chain = TREE_CHAIN (chain);
4288 while (chain);
4290 /* Append to the end of the list */
4291 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
4293 else
4294 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
4297 /* Get a class reference, creating it if necessary. Also create the
4298 reference variable. */
4299 tree
4300 objc_get_class_reference (tree ident)
4302 tree orig_ident = (DECL_P (ident)
4303 ? DECL_NAME (ident)
4304 : TYPE_P (ident)
4305 ? OBJC_TYPE_NAME (ident)
4306 : ident);
4307 bool local_scope = false;
4309 #ifdef OBJCPLUS
4310 if (processing_template_decl)
4311 /* Must wait until template instantiation time. */
4312 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
4313 #endif
4315 if (TREE_CODE (ident) == TYPE_DECL)
4316 ident = (DECL_ORIGINAL_TYPE (ident)
4317 ? DECL_ORIGINAL_TYPE (ident)
4318 : TREE_TYPE (ident));
4320 #ifdef OBJCPLUS
4321 if (TYPE_P (ident)
4322 && CP_TYPE_CONTEXT (ident) != global_namespace)
4323 local_scope = true;
4324 #endif
4326 if (local_scope || !(ident = objc_is_class_name (ident)))
4328 error ("%qE is not an Objective-C class name or alias",
4329 orig_ident);
4330 return error_mark_node;
4333 if (flag_next_runtime && !flag_zero_link)
4335 tree *chain;
4336 tree decl;
4338 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
4339 if (TREE_VALUE (*chain) == ident)
4341 if (! TREE_PURPOSE (*chain))
4342 TREE_PURPOSE (*chain) = build_class_reference_decl ();
4344 return TREE_PURPOSE (*chain);
4347 decl = build_class_reference_decl ();
4348 *chain = tree_cons (decl, ident, NULL_TREE);
4349 return decl;
4351 else
4353 tree params;
4355 add_class_reference (ident);
4357 params = build_tree_list (NULL_TREE,
4358 my_build_string_pointer
4359 (IDENTIFIER_LENGTH (ident) + 1,
4360 IDENTIFIER_POINTER (ident)));
4362 assemble_external (objc_get_class_decl);
4363 return build_function_call (input_location, objc_get_class_decl, params);
4367 /* For each string section we have a chain which maps identifier nodes
4368 to decls for the strings. */
4370 static GTY(()) int class_names_idx;
4371 static GTY(()) int meth_var_names_idx;
4372 static GTY(()) int meth_var_types_idx;
4374 static tree
4375 add_objc_string (tree ident, enum string_section section)
4377 tree *chain, decl, type, string_expr;
4378 char buf[256];
4380 buf[0] = 0;
4381 switch (section)
4383 case class_names:
4384 chain = &class_names_chain;
4385 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
4386 break;
4387 case meth_var_names:
4388 chain = &meth_var_names_chain;
4389 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
4390 break;
4391 case meth_var_types:
4392 chain = &meth_var_types_chain;
4393 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
4394 break;
4395 default:
4396 gcc_unreachable ();
4399 while (*chain)
4401 if (TREE_VALUE (*chain) == ident)
4402 return convert (string_type_node,
4403 build_unary_op (input_location,
4404 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
4406 chain = &TREE_CHAIN (*chain);
4409 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
4410 decl = start_var_decl (type, buf);
4411 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
4412 IDENTIFIER_POINTER (ident));
4413 TREE_CONSTANT (decl) = 1;
4414 finish_var_decl (decl, string_expr);
4416 *chain = tree_cons (decl, ident, NULL_TREE);
4418 return convert (string_type_node, build_unary_op (input_location,
4419 ADDR_EXPR, decl, 1));
4422 void
4423 objc_declare_alias (tree alias_ident, tree class_ident)
4425 tree underlying_class;
4427 #ifdef OBJCPLUS
4428 if (current_namespace != global_namespace) {
4429 error ("Objective-C declarations may only appear in global scope");
4431 #endif /* OBJCPLUS */
4433 if (!(underlying_class = objc_is_class_name (class_ident)))
4434 warning (0, "cannot find class %qE", class_ident);
4435 else if (objc_is_class_name (alias_ident))
4436 warning (0, "class %qE already exists", alias_ident);
4437 else
4439 /* Implement @compatibility_alias as a typedef. */
4440 #ifdef OBJCPLUS
4441 push_lang_context (lang_name_c); /* extern "C" */
4442 #endif
4443 lang_hooks.decls.pushdecl (build_decl
4444 (input_location,
4445 TYPE_DECL,
4446 alias_ident,
4447 xref_tag (RECORD_TYPE, underlying_class)));
4448 #ifdef OBJCPLUS
4449 pop_lang_context ();
4450 #endif
4451 hash_class_name_enter (als_name_hash_list, alias_ident,
4452 underlying_class);
4456 void
4457 objc_declare_class (tree ident_list)
4459 tree list;
4460 #ifdef OBJCPLUS
4461 if (current_namespace != global_namespace) {
4462 error ("Objective-C declarations may only appear in global scope");
4464 #endif /* OBJCPLUS */
4466 for (list = ident_list; list; list = TREE_CHAIN (list))
4468 tree ident = TREE_VALUE (list);
4470 if (! objc_is_class_name (ident))
4472 tree record = lookup_name (ident), type = record;
4474 if (record)
4476 if (TREE_CODE (record) == TYPE_DECL)
4477 type = DECL_ORIGINAL_TYPE (record) ?
4478 DECL_ORIGINAL_TYPE (record) :
4479 TREE_TYPE (record);
4481 if (!TYPE_HAS_OBJC_INFO (type)
4482 || !TYPE_OBJC_INTERFACE (type))
4484 error ("%qE redeclared as different kind of symbol",
4485 ident);
4486 error ("previous declaration of %q+D",
4487 record);
4491 record = xref_tag (RECORD_TYPE, ident);
4492 INIT_TYPE_OBJC_INFO (record);
4493 /* In the case of a @class declaration, we store the ident
4494 in the TYPE_OBJC_INTERFACE. If later an @interface is
4495 found, we'll replace the ident with the interface. */
4496 TYPE_OBJC_INTERFACE (record) = ident;
4497 hash_class_name_enter (cls_name_hash_list, ident, NULL_TREE);
4502 tree
4503 objc_is_class_name (tree ident)
4505 hash target;
4507 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
4508 && identifier_global_value (ident))
4509 ident = identifier_global_value (ident);
4510 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
4511 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
4513 if (ident && TREE_CODE (ident) == RECORD_TYPE)
4514 ident = OBJC_TYPE_NAME (ident);
4515 #ifdef OBJCPLUS
4516 if (ident && TREE_CODE (ident) == TYPE_DECL)
4518 tree type = TREE_TYPE (ident);
4519 if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
4520 return NULL_TREE;
4521 ident = DECL_NAME (ident);
4523 #endif
4524 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
4525 return NULL_TREE;
4527 if (lookup_interface (ident))
4528 return ident;
4530 target = hash_class_name_lookup (cls_name_hash_list, ident);
4531 if (target)
4532 return target->key;
4534 target = hash_class_name_lookup (als_name_hash_list, ident);
4535 if (target)
4537 gcc_assert (target->list && target->list->value);
4538 return target->list->value;
4541 return 0;
4544 /* Check whether TYPE is either 'id' or 'Class'. */
4546 tree
4547 objc_is_id (tree type)
4549 if (type && TREE_CODE (type) == IDENTIFIER_NODE
4550 && identifier_global_value (type))
4551 type = identifier_global_value (type);
4553 if (type && TREE_CODE (type) == TYPE_DECL)
4554 type = TREE_TYPE (type);
4556 /* NB: This function may be called before the ObjC front-end has
4557 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
4558 return (objc_object_type && type
4559 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
4560 ? type
4561 : NULL_TREE);
4564 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
4565 class instance. This is needed by other parts of the compiler to
4566 handle ObjC types gracefully. */
4568 tree
4569 objc_is_object_ptr (tree type)
4571 tree ret;
4573 type = TYPE_MAIN_VARIANT (type);
4574 if (!POINTER_TYPE_P (type))
4575 return 0;
4577 ret = objc_is_id (type);
4578 if (!ret)
4579 ret = objc_is_class_name (TREE_TYPE (type));
4581 return ret;
4584 static int
4585 objc_is_gcable_type (tree type, int or_strong_p)
4587 tree name;
4589 if (!TYPE_P (type))
4590 return 0;
4591 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
4592 return 1;
4593 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
4594 return 1;
4595 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
4596 return 0;
4597 type = TREE_TYPE (type);
4598 if (TREE_CODE (type) != RECORD_TYPE)
4599 return 0;
4600 name = TYPE_NAME (type);
4601 return (objc_is_class_name (name) != NULL_TREE);
4604 static tree
4605 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
4607 if (expr == oldexpr)
4608 return newexpr;
4610 switch (TREE_CODE (expr))
4612 case COMPONENT_REF:
4613 return objc_build_component_ref
4614 (objc_substitute_decl (TREE_OPERAND (expr, 0),
4615 oldexpr,
4616 newexpr),
4617 DECL_NAME (TREE_OPERAND (expr, 1)));
4618 case ARRAY_REF:
4619 return build_array_ref (input_location,
4620 objc_substitute_decl (TREE_OPERAND (expr, 0),
4621 oldexpr,
4622 newexpr),
4623 TREE_OPERAND (expr, 1));
4624 case INDIRECT_REF:
4625 return build_indirect_ref (input_location,
4626 objc_substitute_decl (TREE_OPERAND (expr, 0),
4627 oldexpr,
4628 newexpr), RO_ARROW);
4629 default:
4630 return expr;
4634 static tree
4635 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
4637 tree func_params;
4638 /* The LHS parameter contains the expression 'outervar->memberspec';
4639 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
4640 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
4642 tree offs
4643 = objc_substitute_decl
4644 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
4645 tree func
4646 = (flag_objc_direct_dispatch
4647 ? objc_assign_ivar_fast_decl
4648 : objc_assign_ivar_decl);
4650 offs = convert (integer_type_node, build_unary_op (input_location,
4651 ADDR_EXPR, offs, 0));
4652 offs = fold (offs);
4653 func_params = tree_cons (NULL_TREE,
4654 convert (objc_object_type, rhs),
4655 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
4656 tree_cons (NULL_TREE, offs,
4657 NULL_TREE)));
4659 assemble_external (func);
4660 return build_function_call (input_location, func, func_params);
4663 static tree
4664 objc_build_global_assignment (tree lhs, tree rhs)
4666 tree func_params = tree_cons (NULL_TREE,
4667 convert (objc_object_type, rhs),
4668 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4669 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4670 NULL_TREE));
4672 assemble_external (objc_assign_global_decl);
4673 return build_function_call (input_location,
4674 objc_assign_global_decl, func_params);
4677 static tree
4678 objc_build_strong_cast_assignment (tree lhs, tree rhs)
4680 tree func_params = tree_cons (NULL_TREE,
4681 convert (objc_object_type, rhs),
4682 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
4683 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
4684 NULL_TREE));
4686 assemble_external (objc_assign_strong_cast_decl);
4687 return build_function_call (input_location,
4688 objc_assign_strong_cast_decl, func_params);
4691 static int
4692 objc_is_gcable_p (tree expr)
4694 return (TREE_CODE (expr) == COMPONENT_REF
4695 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
4696 : TREE_CODE (expr) == ARRAY_REF
4697 ? (objc_is_gcable_p (TREE_TYPE (expr))
4698 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
4699 : TREE_CODE (expr) == ARRAY_TYPE
4700 ? objc_is_gcable_p (TREE_TYPE (expr))
4701 : TYPE_P (expr)
4702 ? objc_is_gcable_type (expr, 1)
4703 : (objc_is_gcable_p (TREE_TYPE (expr))
4704 || (DECL_P (expr)
4705 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
4708 static int
4709 objc_is_ivar_reference_p (tree expr)
4711 return (TREE_CODE (expr) == ARRAY_REF
4712 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
4713 : TREE_CODE (expr) == COMPONENT_REF
4714 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
4715 : 0);
4718 static int
4719 objc_is_global_reference_p (tree expr)
4721 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
4722 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
4723 : DECL_P (expr)
4724 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
4725 : 0);
4728 tree
4729 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
4731 tree result = NULL_TREE, outer;
4732 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
4734 /* This function is currently only used with the next runtime with
4735 garbage collection enabled (-fobjc-gc). */
4736 gcc_assert (flag_next_runtime);
4738 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
4739 will have been transformed to the form '*(type *)&expr'. */
4740 if (TREE_CODE (lhs) == INDIRECT_REF)
4742 outer = TREE_OPERAND (lhs, 0);
4744 while (!strong_cast_p
4745 && (CONVERT_EXPR_P (outer)
4746 || TREE_CODE (outer) == NON_LVALUE_EXPR))
4748 tree lhstype = TREE_TYPE (outer);
4750 /* Descend down the cast chain, and record the first objc_gc
4751 attribute found. */
4752 if (POINTER_TYPE_P (lhstype))
4754 tree attr
4755 = lookup_attribute ("objc_gc",
4756 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
4758 if (attr)
4759 strong_cast_p = 1;
4762 outer = TREE_OPERAND (outer, 0);
4766 /* If we have a __strong cast, it trumps all else. */
4767 if (strong_cast_p)
4769 if (modifycode != NOP_EXPR)
4770 goto invalid_pointer_arithmetic;
4772 if (warn_assign_intercept)
4773 warning (0, "strong-cast assignment has been intercepted");
4775 result = objc_build_strong_cast_assignment (lhs, rhs);
4777 goto exit_point;
4780 /* the lhs must be of a suitable type, regardless of its underlying
4781 structure. */
4782 if (!objc_is_gcable_p (lhs))
4783 goto exit_point;
4785 outer = lhs;
4787 while (outer
4788 && (TREE_CODE (outer) == COMPONENT_REF
4789 || TREE_CODE (outer) == ARRAY_REF))
4790 outer = TREE_OPERAND (outer, 0);
4792 if (TREE_CODE (outer) == INDIRECT_REF)
4794 outer = TREE_OPERAND (outer, 0);
4795 indirect_p = 1;
4798 outer_gc_p = objc_is_gcable_p (outer);
4800 /* Handle ivar assignments. */
4801 if (objc_is_ivar_reference_p (lhs))
4803 /* if the struct to the left of the ivar is not an Objective-C object (__strong
4804 doesn't cut it here), the best we can do here is suggest a cast. */
4805 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
4807 /* We may still be able to use the global write barrier... */
4808 if (!indirect_p && objc_is_global_reference_p (outer))
4809 goto global_reference;
4811 suggest_cast:
4812 if (modifycode == NOP_EXPR)
4814 if (warn_assign_intercept)
4815 warning (0, "strong-cast may possibly be needed");
4818 goto exit_point;
4821 if (modifycode != NOP_EXPR)
4822 goto invalid_pointer_arithmetic;
4824 if (warn_assign_intercept)
4825 warning (0, "instance variable assignment has been intercepted");
4827 result = objc_build_ivar_assignment (outer, lhs, rhs);
4829 goto exit_point;
4832 /* Likewise, intercept assignment to global/static variables if their type is
4833 GC-marked. */
4834 if (objc_is_global_reference_p (outer))
4836 if (indirect_p)
4837 goto suggest_cast;
4839 global_reference:
4840 if (modifycode != NOP_EXPR)
4842 invalid_pointer_arithmetic:
4843 if (outer_gc_p)
4844 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
4846 goto exit_point;
4849 if (warn_assign_intercept)
4850 warning (0, "global/static variable assignment has been intercepted");
4852 result = objc_build_global_assignment (lhs, rhs);
4855 /* In all other cases, fall back to the normal mechanism. */
4856 exit_point:
4857 return result;
4860 struct GTY(()) interface_tuple {
4861 tree id;
4862 tree class_name;
4865 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
4867 static hashval_t
4868 hash_interface (const void *p)
4870 const struct interface_tuple *d = (const struct interface_tuple *) p;
4871 return IDENTIFIER_HASH_VALUE (d->id);
4874 static int
4875 eq_interface (const void *p1, const void *p2)
4877 const struct interface_tuple *d = (const struct interface_tuple *) p1;
4878 return d->id == p2;
4881 static tree
4882 lookup_interface (tree ident)
4884 #ifdef OBJCPLUS
4885 if (ident && TREE_CODE (ident) == TYPE_DECL)
4886 ident = DECL_NAME (ident);
4887 #endif
4889 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
4890 return NULL_TREE;
4893 struct interface_tuple **slot;
4894 tree i = NULL_TREE;
4896 if (interface_htab)
4898 slot = (struct interface_tuple **)
4899 htab_find_slot_with_hash (interface_htab, ident,
4900 IDENTIFIER_HASH_VALUE (ident),
4901 NO_INSERT);
4902 if (slot && *slot)
4903 i = (*slot)->class_name;
4905 return i;
4909 /* Implement @defs (<classname>) within struct bodies. */
4911 tree
4912 objc_get_class_ivars (tree class_name)
4914 tree interface = lookup_interface (class_name);
4916 if (interface)
4917 return get_class_ivars (interface, true);
4919 error ("cannot find interface declaration for %qE",
4920 class_name);
4922 return error_mark_node;
4925 /* Called when checking the variables in a struct. If we are not
4926 doing the ivars list inside an @interface context, then returns
4927 fieldlist unchanged. Else, returns the list of class ivars.
4929 tree
4930 objc_get_interface_ivars (tree fieldlist)
4932 if (!objc_collecting_ivars || !objc_interface_context
4933 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
4934 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
4935 return fieldlist;
4937 return get_class_ivars (objc_interface_context, true);
4940 /* Used by: build_private_template, continue_class,
4941 and for @defs constructs. */
4943 static tree
4944 get_class_ivars (tree interface, bool inherited)
4946 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
4948 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
4949 by the current class (i.e., they do not include super-class ivars).
4950 However, the CLASS_IVARS list will be side-effected by a call to
4951 finish_struct(), which will fill in field offsets. */
4952 if (!CLASS_IVARS (interface))
4953 CLASS_IVARS (interface) = ivar_chain;
4955 if (!inherited)
4956 return ivar_chain;
4958 while (CLASS_SUPER_NAME (interface))
4960 /* Prepend super-class ivars. */
4961 interface = lookup_interface (CLASS_SUPER_NAME (interface));
4962 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
4963 ivar_chain);
4966 return ivar_chain;
4970 /* Exception handling constructs. We begin by having the parser do most
4971 of the work and passing us blocks. What we do next depends on whether
4972 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
4973 We abstract all of this in a handful of appropriately named routines. */
4975 /* Stack of open try blocks. */
4977 struct objc_try_context
4979 struct objc_try_context *outer;
4981 /* Statements (or statement lists) as processed by the parser. */
4982 tree try_body;
4983 tree finally_body;
4985 /* Some file position locations. */
4986 location_t try_locus;
4987 location_t end_try_locus;
4988 location_t end_catch_locus;
4989 location_t finally_locus;
4990 location_t end_finally_locus;
4992 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
4993 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
4994 tree catch_list;
4996 /* The CATCH_EXPR of an open @catch clause. */
4997 tree current_catch;
4999 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
5000 tree caught_decl;
5001 tree stack_decl;
5002 tree rethrow_decl;
5005 static struct objc_try_context *cur_try_context;
5007 static GTY(()) tree objc_eh_personality_decl;
5009 /* This hook, called via lang_eh_runtime_type, generates a runtime object
5010 that represents TYPE. For Objective-C, this is just the class name. */
5011 /* ??? Isn't there a class object or some such? Is it easy to get? */
5013 #ifndef OBJCPLUS
5014 tree
5015 objc_eh_runtime_type (tree type)
5017 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
5018 to prevent an ICE. Note that we know that the compiler will
5019 terminate with an error and this 'ErrorMarkNode' class name will
5020 never be actually used. */
5021 if (type == error_mark_node)
5022 return add_objc_string (get_identifier ("ErrorMarkNode"), class_names);
5023 else
5024 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
5027 tree
5028 objc_eh_personality (void)
5030 if (!flag_objc_sjlj_exceptions && !objc_eh_personality_decl)
5031 objc_eh_personality_decl = build_personality_function ("gnu_objc");
5032 return objc_eh_personality_decl;
5034 #endif
5036 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
5037 of Darwin, we'll arrange for it to be initialized (and associated
5038 with a binding) later. */
5040 static tree
5041 objc_build_exc_ptr (void)
5043 if (flag_objc_sjlj_exceptions)
5045 tree var = cur_try_context->caught_decl;
5046 if (!var)
5048 var = objc_create_temporary_var (objc_object_type, NULL);
5049 cur_try_context->caught_decl = var;
5051 return var;
5053 else
5055 tree t;
5056 t = built_in_decls[BUILT_IN_EH_POINTER];
5057 t = build_call_expr (t, 1, integer_zero_node);
5058 return fold_convert (objc_object_type, t);
5062 /* Build "objc_exception_try_exit(&_stack)". */
5064 static tree
5065 next_sjlj_build_try_exit (void)
5067 tree t;
5068 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
5069 t = tree_cons (NULL, t, NULL);
5070 t = build_function_call (input_location,
5071 objc_exception_try_exit_decl, t);
5072 return t;
5075 /* Build
5076 objc_exception_try_enter (&_stack);
5077 if (_setjmp(&_stack.buf))
5079 else
5081 Return the COND_EXPR. Note that the THEN and ELSE fields are left
5082 empty, ready for the caller to fill them in. */
5084 static tree
5085 next_sjlj_build_enter_and_setjmp (void)
5087 tree t, enter, sj, cond;
5089 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
5090 t = tree_cons (NULL, t, NULL);
5091 enter = build_function_call (input_location,
5092 objc_exception_try_enter_decl, t);
5094 t = objc_build_component_ref (cur_try_context->stack_decl,
5095 get_identifier ("buf"));
5096 t = build_fold_addr_expr_loc (input_location, t);
5097 #ifdef OBJCPLUS
5098 /* Convert _setjmp argument to type that is expected. */
5099 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
5100 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
5101 else
5102 t = convert (ptr_type_node, t);
5103 #else
5104 t = convert (ptr_type_node, t);
5105 #endif
5106 t = tree_cons (NULL, t, NULL);
5107 sj = build_function_call (input_location,
5108 objc_setjmp_decl, t);
5110 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
5111 cond = c_common_truthvalue_conversion (input_location, cond);
5113 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
5116 /* Build:
5118 DECL = objc_exception_extract(&_stack); */
5120 static tree
5121 next_sjlj_build_exc_extract (tree decl)
5123 tree t;
5125 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
5126 t = tree_cons (NULL, t, NULL);
5127 t = build_function_call (input_location,
5128 objc_exception_extract_decl, t);
5129 t = convert (TREE_TYPE (decl), t);
5130 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
5132 return t;
5135 /* Build
5136 if (objc_exception_match(obj_get_class(TYPE), _caught)
5137 BODY
5138 else if (...)
5140 else
5142 _rethrow = _caught;
5143 objc_exception_try_exit(&_stack);
5145 from the sequence of CATCH_EXPRs in the current try context. */
5147 static tree
5148 next_sjlj_build_catch_list (void)
5150 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
5151 tree catch_seq, t;
5152 tree *last = &catch_seq;
5153 bool saw_id = false;
5155 for (; !tsi_end_p (i); tsi_next (&i))
5157 tree stmt = tsi_stmt (i);
5158 tree type = CATCH_TYPES (stmt);
5159 tree body = CATCH_BODY (stmt);
5161 if (type == NULL)
5163 *last = body;
5164 saw_id = true;
5165 break;
5167 else
5169 tree args, cond;
5171 if (type == error_mark_node)
5172 cond = error_mark_node;
5173 else
5175 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
5176 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
5177 args = tree_cons (NULL, t, args);
5178 t = build_function_call (input_location,
5179 objc_exception_match_decl, args);
5180 cond = c_common_truthvalue_conversion (input_location, t);
5182 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
5183 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
5185 *last = t;
5186 last = &COND_EXPR_ELSE (t);
5190 if (!saw_id)
5192 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
5193 cur_try_context->caught_decl);
5194 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
5195 append_to_statement_list (t, last);
5197 t = next_sjlj_build_try_exit ();
5198 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
5199 append_to_statement_list (t, last);
5202 return catch_seq;
5205 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
5206 exception handling. We aim to build:
5209 struct _objc_exception_data _stack;
5210 id _rethrow = 0;
5213 objc_exception_try_enter (&_stack);
5214 if (_setjmp(&_stack.buf))
5216 id _caught = objc_exception_extract(&_stack);
5217 objc_exception_try_enter (&_stack);
5218 if (_setjmp(&_stack.buf))
5219 _rethrow = objc_exception_extract(&_stack);
5220 else
5221 CATCH-LIST
5223 else
5224 TRY-BLOCK
5226 finally
5228 if (!_rethrow)
5229 objc_exception_try_exit(&_stack);
5230 FINALLY-BLOCK
5231 if (_rethrow)
5232 objc_exception_throw(_rethrow);
5236 If CATCH-LIST is empty, we can omit all of the block containing
5237 "_caught" except for the setting of _rethrow. Note the use of
5238 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
5239 but handles goto and other exits from the block. */
5241 static tree
5242 next_sjlj_build_try_catch_finally (void)
5244 tree rethrow_decl, stack_decl, t;
5245 tree catch_seq, try_fin, bind;
5247 /* Create the declarations involved. */
5248 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
5249 stack_decl = objc_create_temporary_var (t, NULL);
5250 cur_try_context->stack_decl = stack_decl;
5252 rethrow_decl = objc_create_temporary_var (objc_object_type, NULL);
5253 cur_try_context->rethrow_decl = rethrow_decl;
5254 TREE_CHAIN (rethrow_decl) = stack_decl;
5256 /* Build the outermost variable binding level. */
5257 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
5258 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
5259 TREE_SIDE_EFFECTS (bind) = 1;
5261 /* Initialize rethrow_decl. */
5262 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
5263 convert (objc_object_type, null_pointer_node));
5264 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
5265 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
5267 /* Build the outermost TRY_FINALLY_EXPR. */
5268 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
5269 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
5270 TREE_SIDE_EFFECTS (try_fin) = 1;
5271 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
5273 /* Create the complete catch sequence. */
5274 if (cur_try_context->catch_list)
5276 tree caught_decl = objc_build_exc_ptr ();
5277 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
5278 TREE_SIDE_EFFECTS (catch_seq) = 1;
5280 t = next_sjlj_build_exc_extract (caught_decl);
5281 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
5283 t = next_sjlj_build_enter_and_setjmp ();
5284 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
5285 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
5286 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
5288 else
5289 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
5290 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
5292 /* Build the main register-and-try if statement. */
5293 t = next_sjlj_build_enter_and_setjmp ();
5294 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
5295 COND_EXPR_THEN (t) = catch_seq;
5296 COND_EXPR_ELSE (t) = cur_try_context->try_body;
5297 TREE_OPERAND (try_fin, 0) = t;
5299 /* Build the complete FINALLY statement list. */
5300 t = next_sjlj_build_try_exit ();
5301 t = build_stmt (input_location, COND_EXPR,
5302 c_common_truthvalue_conversion
5303 (input_location, rethrow_decl),
5304 NULL, t);
5305 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
5306 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
5308 append_to_statement_list (cur_try_context->finally_body,
5309 &TREE_OPERAND (try_fin, 1));
5311 t = tree_cons (NULL, rethrow_decl, NULL);
5312 t = build_function_call (input_location,
5313 objc_exception_throw_decl, t);
5314 t = build_stmt (input_location, COND_EXPR,
5315 c_common_truthvalue_conversion (input_location,
5316 rethrow_decl),
5317 t, NULL);
5318 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
5319 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
5321 return bind;
5324 /* Called just after parsing the @try and its associated BODY. We now
5325 must prepare for the tricky bits -- handling the catches and finally. */
5327 void
5328 objc_begin_try_stmt (location_t try_locus, tree body)
5330 struct objc_try_context *c = XCNEW (struct objc_try_context);
5331 c->outer = cur_try_context;
5332 c->try_body = body;
5333 c->try_locus = try_locus;
5334 c->end_try_locus = input_location;
5335 cur_try_context = c;
5337 /* -fobjc-exceptions is required to enable Objective-C exceptions.
5338 For example, on Darwin, ObjC exceptions require a sufficiently
5339 recent version of the runtime, so the user must ask for them
5340 explicitly. On other platforms, at the moment -fobjc-exceptions
5341 triggers -fexceptions which again is required for exceptions to
5342 work.
5344 if (!flag_objc_exceptions)
5346 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5349 /* Collect the list of local variables. We'll mark them as volatile
5350 at the end of compilation of this function to prevent them being
5351 clobbered by setjmp/longjmp. */
5352 if (flag_objc_sjlj_exceptions)
5353 objc_mark_locals_volatile (NULL);
5356 /* Called just after parsing "@catch (parm)". Open a binding level,
5357 enter DECL into the binding level, and initialize it. Leave the
5358 binding level open while the body of the compound statement is
5359 parsed. If DECL is NULL_TREE, then we are compiling "@catch(...)"
5360 which we compile as "@catch(id tmp_variable)". */
5362 void
5363 objc_begin_catch_clause (tree decl)
5365 tree compound, type, t;
5367 /* Begin a new scope that the entire catch clause will live in. */
5368 compound = c_begin_compound_stmt (true);
5370 /* Create the appropriate declaration for the argument. */
5371 if (decl == error_mark_node)
5372 type = error_mark_node;
5373 else
5375 if (decl == NULL_TREE)
5377 /* If @catch(...) was specified, create a temporary variable of
5378 type 'id' and use it. */
5379 decl = objc_create_temporary_var (objc_object_type, "__objc_generic_catch_var");
5380 DECL_SOURCE_LOCATION (decl) = input_location;
5382 else
5384 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
5385 decl = build_decl (input_location,
5386 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
5388 lang_hooks.decls.pushdecl (decl);
5390 /* Mark the declaration as used so you never any warnings whether
5391 you use the exception argument or not. TODO: Implement a
5392 -Wunused-exception-parameter flag, which would cause warnings
5393 if exception parameter is not used. */
5394 TREE_USED (decl) = 1;
5395 DECL_READ_P (decl) = 1;
5397 type = TREE_TYPE (decl);
5400 /* Verify that the type of the catch is valid. It must be a pointer
5401 to an Objective-C class, or "id" (which is catch-all). */
5402 if (type == error_mark_node)
5404 ;/* Just keep going. */
5406 else if (!objc_type_valid_for_messaging (type, false))
5408 error ("@catch parameter is not a known Objective-C class type");
5409 type = error_mark_node;
5411 else if (TYPE_HAS_OBJC_INFO (TREE_TYPE (type))
5412 && TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (type)))
5414 error ("@catch parameter can not be protocol-qualified");
5415 type = error_mark_node;
5417 else if (objc_is_object_id (TREE_TYPE (type)))
5418 type = NULL;
5419 else
5421 /* If 'type' was built using typedefs, we need to get rid of
5422 them and get a simple pointer to the class. */
5423 bool is_typedef = false;
5424 tree x = TYPE_MAIN_VARIANT (type);
5426 /* Skip from the pointer to the pointee. */
5427 if (TREE_CODE (x) == POINTER_TYPE)
5428 x = TREE_TYPE (x);
5430 /* Traverse typedef aliases */
5431 while (TREE_CODE (x) == RECORD_TYPE && OBJC_TYPE_NAME (x)
5432 && TREE_CODE (OBJC_TYPE_NAME (x)) == TYPE_DECL
5433 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x)))
5435 is_typedef = true;
5436 x = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (x));
5439 /* If it was a typedef, build a pointer to the final, original
5440 class. */
5441 if (is_typedef)
5442 type = build_pointer_type (x);
5444 if (cur_try_context->catch_list)
5446 /* Examine previous @catch clauses and see if we've already
5447 caught the type in question. */
5448 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
5449 for (; !tsi_end_p (i); tsi_next (&i))
5451 tree stmt = tsi_stmt (i);
5452 t = CATCH_TYPES (stmt);
5453 if (t == error_mark_node)
5454 continue;
5455 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
5457 warning (0, "exception of type %<%T%> will be caught",
5458 TREE_TYPE (type));
5459 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
5460 TREE_TYPE (t ? t : objc_object_type));
5461 break;
5467 /* Record the data for the catch in the try context so that we can
5468 finalize it later. */
5469 t = build_stmt (input_location, CATCH_EXPR, type, compound);
5470 cur_try_context->current_catch = t;
5472 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
5473 t = objc_build_exc_ptr ();
5474 t = convert (TREE_TYPE (decl), t);
5475 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
5476 add_stmt (t);
5479 /* Called just after parsing the closing brace of a @catch clause. Close
5480 the open binding level, and record a CATCH_EXPR for it. */
5482 void
5483 objc_finish_catch_clause (void)
5485 tree c = cur_try_context->current_catch;
5486 cur_try_context->current_catch = NULL;
5487 cur_try_context->end_catch_locus = input_location;
5489 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
5490 append_to_statement_list (c, &cur_try_context->catch_list);
5493 /* Called after parsing a @finally clause and its associated BODY.
5494 Record the body for later placement. */
5496 void
5497 objc_build_finally_clause (location_t finally_locus, tree body)
5499 cur_try_context->finally_body = body;
5500 cur_try_context->finally_locus = finally_locus;
5501 cur_try_context->end_finally_locus = input_location;
5504 /* Called to finalize a @try construct. */
5506 tree
5507 objc_finish_try_stmt (void)
5509 struct objc_try_context *c = cur_try_context;
5510 tree stmt;
5512 if (c->catch_list == NULL && c->finally_body == NULL)
5513 error ("%<@try%> without %<@catch%> or %<@finally%>");
5515 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
5516 if (flag_objc_sjlj_exceptions)
5518 bool save = in_late_binary_op;
5519 in_late_binary_op = true;
5520 if (!cur_try_context->finally_body)
5522 cur_try_context->finally_locus = input_location;
5523 cur_try_context->end_finally_locus = input_location;
5525 stmt = next_sjlj_build_try_catch_finally ();
5526 in_late_binary_op = save;
5528 else
5530 /* Otherwise, nest the CATCH inside a FINALLY. */
5531 stmt = c->try_body;
5532 if (c->catch_list)
5534 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
5535 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5537 if (c->finally_body)
5539 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
5540 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
5543 add_stmt (stmt);
5545 cur_try_context = c->outer;
5546 free (c);
5547 return stmt;
5550 tree
5551 objc_build_throw_stmt (location_t loc, tree throw_expr)
5553 tree args;
5555 if (!flag_objc_exceptions)
5557 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
5560 if (throw_expr == NULL)
5562 /* If we're not inside a @catch block, there is no "current
5563 exception" to be rethrown. */
5564 if (cur_try_context == NULL
5565 || cur_try_context->current_catch == NULL)
5567 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
5568 return error_mark_node;
5571 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
5572 value that we get from the runtime. */
5573 throw_expr = objc_build_exc_ptr ();
5575 else if (throw_expr != error_mark_node)
5577 if (!objc_type_valid_for_messaging (TREE_TYPE (throw_expr), true))
5579 error_at (loc, "%<@throw%> argument is not an object");
5580 return error_mark_node;
5584 /* A throw is just a call to the runtime throw function with the
5585 object as a parameter. */
5586 args = tree_cons (NULL, throw_expr, NULL);
5587 return add_stmt (build_function_call (loc,
5588 objc_exception_throw_decl, args));
5591 tree
5592 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
5594 tree args, call;
5596 /* First lock the mutex. */
5597 mutex = save_expr (mutex);
5598 args = tree_cons (NULL, mutex, NULL);
5599 call = build_function_call (input_location,
5600 objc_sync_enter_decl, args);
5601 SET_EXPR_LOCATION (call, start_locus);
5602 add_stmt (call);
5604 /* Build the mutex unlock. */
5605 args = tree_cons (NULL, mutex, NULL);
5606 call = build_function_call (input_location,
5607 objc_sync_exit_decl, args);
5608 SET_EXPR_LOCATION (call, input_location);
5610 /* Put the that and the body in a TRY_FINALLY. */
5611 objc_begin_try_stmt (start_locus, body);
5612 objc_build_finally_clause (input_location, call);
5613 return objc_finish_try_stmt ();
5617 /* Predefine the following data type:
5619 struct _objc_exception_data
5621 int buf[OBJC_JBLEN];
5622 void *pointers[4];
5623 }; */
5625 /* The following yuckiness should prevent users from having to #include
5626 <setjmp.h> in their code... */
5628 /* Define to a harmless positive value so the below code doesn't die. */
5629 #ifndef OBJC_JBLEN
5630 #define OBJC_JBLEN 18
5631 #endif
5633 static void
5634 build_next_objc_exception_stuff (void)
5636 tree decls, temp_type, *chain = NULL;
5638 objc_exception_data_template
5639 = objc_start_struct (get_identifier (UTAG_EXCDATA));
5641 /* int buf[OBJC_JBLEN]; */
5643 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
5644 decls = add_field_decl (temp_type, "buf", &chain);
5646 /* void *pointers[4]; */
5648 temp_type = build_sized_array_type (ptr_type_node, 4);
5649 add_field_decl (temp_type, "pointers", &chain);
5651 objc_finish_struct (objc_exception_data_template, decls);
5653 /* int _setjmp(...); */
5654 /* If the user includes <setjmp.h>, this shall be superseded by
5655 'int _setjmp(jmp_buf);' */
5656 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
5657 objc_setjmp_decl
5658 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
5660 /* id objc_exception_extract(struct _objc_exception_data *); */
5661 temp_type
5662 = build_function_type_list (objc_object_type,
5663 build_pointer_type (objc_exception_data_template),
5664 NULL_TREE);
5665 objc_exception_extract_decl
5666 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
5667 NULL_TREE);
5668 /* void objc_exception_try_enter(struct _objc_exception_data *); */
5669 /* void objc_exception_try_exit(struct _objc_exception_data *); */
5670 temp_type
5671 = build_function_type_list (void_type_node,
5672 build_pointer_type (objc_exception_data_template),
5673 NULL_TREE);
5674 objc_exception_try_enter_decl
5675 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
5676 NULL_TREE);
5677 objc_exception_try_exit_decl
5678 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
5679 NULL_TREE);
5681 /* int objc_exception_match(id, id); */
5682 temp_type
5683 = build_function_type_list (integer_type_node,
5684 objc_object_type, objc_object_type, NULL_TREE);
5685 objc_exception_match_decl
5686 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
5687 NULL_TREE);
5689 /* id objc_assign_ivar (id, id, unsigned int); */
5690 /* id objc_assign_ivar_Fast (id, id, unsigned int)
5691 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
5692 temp_type
5693 = build_function_type_list (objc_object_type,
5694 objc_object_type,
5695 objc_object_type,
5696 unsigned_type_node,
5697 NULL_TREE);
5698 objc_assign_ivar_decl
5699 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
5700 NULL, NULL_TREE);
5701 #ifdef OFFS_ASSIGNIVAR_FAST
5702 objc_assign_ivar_fast_decl
5703 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
5704 NOT_BUILT_IN, NULL, NULL_TREE);
5705 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
5706 = tree_cons (get_identifier ("hard_coded_address"),
5707 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
5708 NULL_TREE);
5709 #else
5710 /* Default to slower ivar method. */
5711 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
5712 #endif
5714 /* id objc_assign_global (id, id *); */
5715 /* id objc_assign_strongCast (id, id *); */
5716 temp_type = build_function_type_list (objc_object_type,
5717 objc_object_type,
5718 build_pointer_type (objc_object_type),
5719 NULL_TREE);
5720 objc_assign_global_decl
5721 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
5722 NULL_TREE);
5723 objc_assign_strong_cast_decl
5724 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
5725 NULL_TREE);
5728 static void
5729 build_objc_exception_stuff (void)
5731 tree noreturn_list, nothrow_list, temp_type;
5733 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
5734 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
5736 /* void objc_exception_throw(id) __attribute__((noreturn)); */
5737 /* void objc_sync_enter(id); */
5738 /* void objc_sync_exit(id); */
5739 temp_type = build_function_type_list (void_type_node,
5740 objc_object_type,
5741 NULL_TREE);
5742 objc_exception_throw_decl
5743 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
5744 noreturn_list);
5745 objc_sync_enter_decl
5746 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
5747 NULL, nothrow_list);
5748 objc_sync_exit_decl
5749 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
5750 NULL, nothrow_list);
5753 /* Construct a C struct corresponding to ObjC class CLASS, with the same
5754 name as the class:
5756 struct <classname> {
5757 struct _objc_class *isa;
5759 }; */
5761 static void
5762 build_private_template (tree klass)
5764 if (!CLASS_STATIC_TEMPLATE (klass))
5766 tree record = objc_build_struct (klass,
5767 get_class_ivars (klass, false),
5768 CLASS_SUPER_NAME (klass));
5770 /* Set the TREE_USED bit for this struct, so that stab generator
5771 can emit stabs for this struct type. */
5772 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
5773 TREE_USED (TYPE_STUB_DECL (record)) = 1;
5775 /* Copy the attributes from the class to the type. */
5776 if (TREE_DEPRECATED (klass))
5777 TREE_DEPRECATED (record) = 1;
5781 /* Begin code generation for protocols... */
5783 /* struct _objc_protocol {
5784 struct _objc_class *isa;
5785 char *protocol_name;
5786 struct _objc_protocol **protocol_list;
5787 struct _objc__method_prototype_list *instance_methods;
5788 struct _objc__method_prototype_list *class_methods;
5789 }; */
5791 static void
5792 build_protocol_template (void)
5794 tree ptype, decls, *chain = NULL;
5796 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
5798 /* struct _objc_class *isa; */
5799 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5800 get_identifier (UTAG_CLASS)));
5801 decls = add_field_decl (ptype, "isa", &chain);
5803 /* char *protocol_name; */
5804 add_field_decl (string_type_node, "protocol_name", &chain);
5806 /* struct _objc_protocol **protocol_list; */
5807 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
5808 add_field_decl (ptype, "protocol_list", &chain);
5810 /* struct _objc__method_prototype_list *instance_methods; */
5811 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
5813 /* struct _objc__method_prototype_list *class_methods; */
5814 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
5816 objc_finish_struct (objc_protocol_template, decls);
5819 static tree
5820 build_descriptor_table_initializer (tree type, tree entries)
5822 VEC(constructor_elt,gc) *inits = NULL;
5826 VEC(constructor_elt,gc) *elts = NULL;
5828 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5829 build_selector (METHOD_SEL_NAME (entries)));
5830 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
5831 add_objc_string (METHOD_ENCODING (entries),
5832 meth_var_types));
5834 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5835 objc_build_constructor (type, elts));
5837 entries = DECL_CHAIN (entries);
5839 while (entries);
5841 return objc_build_constructor (build_array_type (type, 0), inits);
5844 /* struct objc_method_prototype_list {
5845 int count;
5846 struct objc_method_prototype {
5847 SEL name;
5848 char *types;
5849 } list[1];
5850 }; */
5852 static tree
5853 build_method_prototype_list_template (tree list_type, int size)
5855 tree objc_ivar_list_record;
5856 tree array_type, decls, *chain = NULL;
5858 /* Generate an unnamed struct definition. */
5860 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5862 /* int method_count; */
5863 decls = add_field_decl (integer_type_node, "method_count", &chain);
5865 /* struct objc_method method_list[]; */
5866 array_type = build_sized_array_type (list_type, size);
5867 add_field_decl (array_type, "method_list", &chain);
5869 objc_finish_struct (objc_ivar_list_record, decls);
5871 return objc_ivar_list_record;
5874 static tree
5875 build_method_prototype_template (void)
5877 tree proto_record;
5878 tree decls, *chain = NULL;
5880 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
5882 /* SEL _cmd; */
5883 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5885 /* char *method_types; */
5886 add_field_decl (string_type_node, "method_types", &chain);
5888 objc_finish_struct (proto_record, decls);
5890 return proto_record;
5893 static tree
5894 objc_method_parm_type (tree type)
5896 type = TREE_VALUE (TREE_TYPE (type));
5897 if (TREE_CODE (type) == TYPE_DECL)
5898 type = TREE_TYPE (type);
5899 return type;
5902 static int
5903 objc_encoded_type_size (tree type)
5905 int sz = int_size_in_bytes (type);
5907 /* Make all integer and enum types at least as large
5908 as an int. */
5909 if (sz > 0 && INTEGRAL_TYPE_P (type))
5910 sz = MAX (sz, int_size_in_bytes (integer_type_node));
5911 /* Treat arrays as pointers, since that's how they're
5912 passed in. */
5913 else if (TREE_CODE (type) == ARRAY_TYPE)
5914 sz = int_size_in_bytes (ptr_type_node);
5915 return sz;
5918 /* Encode a method prototype.
5920 The format is described in gcc/doc/objc.texi, section 'Method
5921 signatures'.
5923 static tree
5924 encode_method_prototype (tree method_decl)
5926 tree parms;
5927 int parm_offset, i;
5928 char buf[40];
5929 tree result;
5931 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
5932 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
5934 /* Encode return type. */
5935 encode_type (objc_method_parm_type (method_decl),
5936 obstack_object_size (&util_obstack),
5937 OBJC_ENCODE_INLINE_DEFS);
5939 /* Stack size. */
5940 /* The first two arguments (self and _cmd) are pointers; account for
5941 their size. */
5942 i = int_size_in_bytes (ptr_type_node);
5943 parm_offset = 2 * i;
5944 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5945 parms = DECL_CHAIN (parms))
5947 tree type = objc_method_parm_type (parms);
5948 int sz = objc_encoded_type_size (type);
5950 /* If a type size is not known, bail out. */
5951 if (sz < 0)
5953 error ("type %q+D does not have a known size",
5954 type);
5955 /* Pretend that the encoding succeeded; the compilation will
5956 fail nevertheless. */
5957 goto finish_encoding;
5959 parm_offset += sz;
5962 sprintf (buf, "%d@0:%d", parm_offset, i);
5963 obstack_grow (&util_obstack, buf, strlen (buf));
5965 /* Argument types. */
5966 parm_offset = 2 * i;
5967 for (parms = METHOD_SEL_ARGS (method_decl); parms;
5968 parms = DECL_CHAIN (parms))
5970 tree type = objc_method_parm_type (parms);
5972 /* Process argument qualifiers for user supplied arguments. */
5973 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
5975 /* Type. */
5976 encode_type (type, obstack_object_size (&util_obstack),
5977 OBJC_ENCODE_INLINE_DEFS);
5979 /* Compute offset. */
5980 sprintf (buf, "%d", parm_offset);
5981 parm_offset += objc_encoded_type_size (type);
5983 obstack_grow (&util_obstack, buf, strlen (buf));
5986 finish_encoding:
5987 obstack_1grow (&util_obstack, '\0');
5988 result = get_identifier (XOBFINISH (&util_obstack, char *));
5989 obstack_free (&util_obstack, util_firstobj);
5990 return result;
5993 static tree
5994 generate_descriptor_table (tree type, const char *name, int size, tree list,
5995 tree proto)
5997 tree decl;
5998 VEC(constructor_elt,gc) *v = NULL;
6000 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
6002 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
6003 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6005 finish_var_decl (decl, objc_build_constructor (type, v));
6007 return decl;
6010 static void
6011 generate_method_descriptors (tree protocol)
6013 tree initlist, chain, method_list_template;
6014 int size;
6016 if (!objc_method_prototype_template)
6017 objc_method_prototype_template = build_method_prototype_template ();
6019 chain = PROTOCOL_CLS_METHODS (protocol);
6020 if (chain)
6022 size = list_length (chain);
6024 method_list_template
6025 = build_method_prototype_list_template (objc_method_prototype_template,
6026 size);
6028 initlist
6029 = build_descriptor_table_initializer (objc_method_prototype_template,
6030 chain);
6032 UOBJC_CLASS_METHODS_decl
6033 = generate_descriptor_table (method_list_template,
6034 "_OBJC_PROTOCOL_CLASS_METHODS",
6035 size, initlist, protocol);
6037 else
6038 UOBJC_CLASS_METHODS_decl = 0;
6040 chain = PROTOCOL_NST_METHODS (protocol);
6041 if (chain)
6043 size = list_length (chain);
6045 method_list_template
6046 = build_method_prototype_list_template (objc_method_prototype_template,
6047 size);
6048 initlist
6049 = build_descriptor_table_initializer (objc_method_prototype_template,
6050 chain);
6052 UOBJC_INSTANCE_METHODS_decl
6053 = generate_descriptor_table (method_list_template,
6054 "_OBJC_PROTOCOL_INSTANCE_METHODS",
6055 size, initlist, protocol);
6057 else
6058 UOBJC_INSTANCE_METHODS_decl = 0;
6061 static void
6062 generate_protocol_references (tree plist)
6064 tree lproto;
6066 /* Forward declare protocols referenced. */
6067 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
6069 tree proto = TREE_VALUE (lproto);
6071 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
6072 && PROTOCOL_NAME (proto))
6074 if (! PROTOCOL_FORWARD_DECL (proto))
6075 build_protocol_reference (proto);
6077 if (PROTOCOL_LIST (proto))
6078 generate_protocol_references (PROTOCOL_LIST (proto));
6083 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
6084 current class. */
6085 #ifdef OBJCPLUS
6086 static void
6087 objc_generate_cxx_ctor_or_dtor (bool dtor)
6089 tree fn, body, compound_stmt, ivar;
6091 /* - (id) .cxx_construct { ... return self; } */
6092 /* - (void) .cxx_construct { ... } */
6094 objc_start_method_definition
6095 (false /* is_class_method */,
6096 objc_build_method_signature (false /* is_class_method */,
6097 build_tree_list (NULL_TREE,
6098 dtor
6099 ? void_type_node
6100 : objc_object_type),
6101 get_identifier (dtor
6102 ? TAG_CXX_DESTRUCT
6103 : TAG_CXX_CONSTRUCT),
6104 make_node (TREE_LIST),
6105 false), NULL);
6106 body = begin_function_body ();
6107 compound_stmt = begin_compound_stmt (0);
6109 ivar = CLASS_IVARS (implementation_template);
6110 /* Destroy ivars in reverse order. */
6111 if (dtor)
6112 ivar = nreverse (copy_list (ivar));
6114 for (; ivar; ivar = TREE_CHAIN (ivar))
6116 if (TREE_CODE (ivar) == FIELD_DECL)
6118 tree type = TREE_TYPE (ivar);
6120 /* Call the ivar's default constructor or destructor. Do not
6121 call the destructor unless a corresponding constructor call
6122 has also been made (or is not needed). */
6123 if (MAYBE_CLASS_TYPE_P (type)
6124 && (dtor
6125 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
6126 && (!TYPE_NEEDS_CONSTRUCTING (type)
6127 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
6128 : (TYPE_NEEDS_CONSTRUCTING (type)
6129 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
6130 finish_expr_stmt
6131 (build_special_member_call
6132 (build_ivar_reference (DECL_NAME (ivar)),
6133 dtor ? complete_dtor_identifier : complete_ctor_identifier,
6134 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
6138 /* The constructor returns 'self'. */
6139 if (!dtor)
6140 finish_return_stmt (self_decl);
6142 finish_compound_stmt (compound_stmt);
6143 finish_function_body (body);
6144 fn = current_function_decl;
6145 finish_function ();
6146 objc_finish_method_definition (fn);
6149 /* The following routine will examine the current @interface for any
6150 non-POD C++ ivars requiring non-trivial construction and/or
6151 destruction, and then synthesize special '- .cxx_construct' and/or
6152 '- .cxx_destruct' methods which will run the appropriate
6153 construction or destruction code. Note that ivars inherited from
6154 super-classes are _not_ considered. */
6155 static void
6156 objc_generate_cxx_cdtors (void)
6158 bool need_ctor = false, need_dtor = false;
6159 tree ivar;
6161 /* Error case, due to possibly an extra @end. */
6162 if (!objc_implementation_context)
6163 return;
6165 /* We do not want to do this for categories, since they do not have
6166 their own ivars. */
6168 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
6169 return;
6171 /* First, determine if we even need a constructor and/or destructor. */
6173 for (ivar = CLASS_IVARS (implementation_template); ivar;
6174 ivar = TREE_CHAIN (ivar))
6176 if (TREE_CODE (ivar) == FIELD_DECL)
6178 tree type = TREE_TYPE (ivar);
6180 if (MAYBE_CLASS_TYPE_P (type))
6182 if (TYPE_NEEDS_CONSTRUCTING (type)
6183 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
6184 /* NB: If a default constructor is not available, we will not
6185 be able to initialize this ivar; the add_instance_variable()
6186 routine will already have warned about this. */
6187 need_ctor = true;
6189 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
6190 && (!TYPE_NEEDS_CONSTRUCTING (type)
6191 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
6192 /* NB: If a default constructor is not available, we will not
6193 call the destructor either, for symmetry. */
6194 need_dtor = true;
6199 /* Generate '- .cxx_construct' if needed. */
6201 if (need_ctor)
6202 objc_generate_cxx_ctor_or_dtor (false);
6204 /* Generate '- .cxx_destruct' if needed. */
6206 if (need_dtor)
6207 objc_generate_cxx_ctor_or_dtor (true);
6209 /* The 'imp_list' variable points at an imp_entry record for the current
6210 @implementation. Record the existence of '- .cxx_construct' and/or
6211 '- .cxx_destruct' methods therein; it will be included in the
6212 metadata for the class. */
6213 if (flag_next_runtime)
6214 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
6216 #endif
6218 /* For each protocol which was referenced either from a @protocol()
6219 expression, or because a class/category implements it (then a
6220 pointer to the protocol is stored in the struct describing the
6221 class/category), we create a statically allocated instance of the
6222 Protocol class. The code is written in such a way as to generate
6223 as few Protocol objects as possible; we generate a unique Protocol
6224 instance for each protocol, and we don't generate a Protocol
6225 instance if the protocol is never referenced (either from a
6226 @protocol() or from a class/category implementation). These
6227 statically allocated objects can be referred to via the static
6228 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
6230 The statically allocated Protocol objects that we generate here
6231 need to be fixed up at runtime in order to be used: the 'isa'
6232 pointer of the objects need to be set up to point to the 'Protocol'
6233 class, as known at runtime.
6235 The NeXT runtime fixes up all protocols at program startup time,
6236 before main() is entered. It uses a low-level trick to look up all
6237 those symbols, then loops on them and fixes them up.
6239 The GNU runtime as well fixes up all protocols before user code
6240 from the module is executed; it requires pointers to those symbols
6241 to be put in the objc_symtab (which is then passed as argument to
6242 the function __objc_exec_class() which the compiler sets up to be
6243 executed automatically when the module is loaded); setup of those
6244 Protocol objects happen in two ways in the GNU runtime: all
6245 Protocol objects referred to by a class or category implementation
6246 are fixed up when the class/category is loaded; all Protocol
6247 objects referred to by a @protocol() expression are added by the
6248 compiler to the list of statically allocated instances to fixup
6249 (the same list holding the statically allocated constant string
6250 objects). Because, as explained above, the compiler generates as
6251 few Protocol objects as possible, some Protocol object might end up
6252 being referenced multiple times when compiled with the GNU runtime,
6253 and end up being fixed up multiple times at runtime initialization.
6254 But that doesn't hurt, it's just a little inefficient. */
6256 static void
6257 generate_protocols (void)
6259 tree p, encoding;
6260 tree decl;
6261 tree initlist, protocol_name_expr, refs_decl, refs_expr;
6263 /* If a protocol was directly referenced, pull in indirect references. */
6264 for (p = protocol_chain; p; p = TREE_CHAIN (p))
6265 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
6266 generate_protocol_references (PROTOCOL_LIST (p));
6268 for (p = protocol_chain; p; p = TREE_CHAIN (p))
6270 tree nst_methods = PROTOCOL_NST_METHODS (p);
6271 tree cls_methods = PROTOCOL_CLS_METHODS (p);
6273 /* If protocol wasn't referenced, don't generate any code. */
6274 decl = PROTOCOL_FORWARD_DECL (p);
6276 if (!decl)
6277 continue;
6279 /* Make sure we link in the Protocol class. */
6280 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6282 while (nst_methods)
6284 if (! METHOD_ENCODING (nst_methods))
6286 encoding = encode_method_prototype (nst_methods);
6287 METHOD_ENCODING (nst_methods) = encoding;
6289 nst_methods = DECL_CHAIN (nst_methods);
6292 while (cls_methods)
6294 if (! METHOD_ENCODING (cls_methods))
6296 encoding = encode_method_prototype (cls_methods);
6297 METHOD_ENCODING (cls_methods) = encoding;
6300 cls_methods = DECL_CHAIN (cls_methods);
6302 generate_method_descriptors (p);
6304 if (PROTOCOL_LIST (p))
6305 refs_decl = generate_protocol_list (p);
6306 else
6307 refs_decl = 0;
6309 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
6310 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
6312 if (refs_decl)
6313 refs_expr = convert (build_pointer_type (build_pointer_type
6314 (objc_protocol_template)),
6315 build_unary_op (input_location,
6316 ADDR_EXPR, refs_decl, 0));
6317 else
6318 refs_expr = build_int_cst (NULL_TREE, 0);
6320 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
6321 by generate_method_descriptors, which is called above. */
6322 initlist = build_protocol_initializer (TREE_TYPE (decl),
6323 protocol_name_expr, refs_expr,
6324 UOBJC_INSTANCE_METHODS_decl,
6325 UOBJC_CLASS_METHODS_decl);
6326 finish_var_decl (decl, initlist);
6330 static tree
6331 build_protocol_initializer (tree type, tree protocol_name,
6332 tree protocol_list, tree instance_methods,
6333 tree class_methods)
6335 tree expr;
6336 tree cast_type = build_pointer_type
6337 (xref_tag (RECORD_TYPE,
6338 get_identifier (UTAG_CLASS)));
6339 VEC(constructor_elt,gc) *inits = NULL;
6341 /* Filling the "isa" in with one allows the runtime system to
6342 detect that the version change...should remove before final release. */
6344 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
6345 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6346 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
6347 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
6349 if (!instance_methods)
6350 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
6351 else
6353 expr = convert (objc_method_proto_list_ptr,
6354 build_unary_op (input_location,
6355 ADDR_EXPR, instance_methods, 0));
6356 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6359 if (!class_methods)
6360 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
6361 else
6363 expr = convert (objc_method_proto_list_ptr,
6364 build_unary_op (input_location,
6365 ADDR_EXPR, class_methods, 0));
6366 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
6369 return objc_build_constructor (type, inits);
6372 /* struct _objc_category {
6373 char *category_name;
6374 char *class_name;
6375 struct _objc_method_list *instance_methods;
6376 struct _objc_method_list *class_methods;
6377 struct _objc_protocol_list *protocols;
6378 }; */
6380 static void
6381 build_category_template (void)
6383 tree ptype, decls, *chain = NULL;
6385 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
6387 /* char *category_name; */
6388 decls = add_field_decl (string_type_node, "category_name", &chain);
6390 /* char *class_name; */
6391 add_field_decl (string_type_node, "class_name", &chain);
6393 /* struct _objc_method_list *instance_methods; */
6394 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
6396 /* struct _objc_method_list *class_methods; */
6397 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
6399 /* struct _objc_protocol **protocol_list; */
6400 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
6401 add_field_decl (ptype, "protocol_list", &chain);
6403 objc_finish_struct (objc_category_template, decls);
6406 /* struct _objc_selector {
6407 SEL sel_id;
6408 char *sel_type;
6409 }; */
6411 static void
6412 build_selector_template (void)
6414 tree decls, *chain = NULL;
6416 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
6418 /* SEL sel_id; */
6419 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
6421 /* char *sel_type; */
6422 add_field_decl (string_type_node, "sel_type", &chain);
6424 objc_finish_struct (objc_selector_template, decls);
6427 /* struct _objc_class {
6428 struct _objc_class *isa;
6429 struct _objc_class *super_class;
6430 char *name;
6431 long version;
6432 long info;
6433 long instance_size;
6434 struct _objc_ivar_list *ivars;
6435 struct _objc_method_list *methods;
6436 #ifdef __NEXT_RUNTIME__
6437 struct objc_cache *cache;
6438 #else
6439 struct sarray *dtable;
6440 struct _objc_class *subclass_list;
6441 struct _objc_class *sibling_class;
6442 #endif
6443 struct _objc_protocol_list *protocols;
6444 #ifdef __NEXT_RUNTIME__
6445 void *sel_id;
6446 #endif
6447 void *gc_object_type;
6448 }; */
6450 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
6451 the NeXT/Apple runtime; still, the compiler must generate them to
6452 maintain backward binary compatibility (and to allow for future
6453 expansion). */
6455 static void
6456 build_class_template (void)
6458 tree ptype, decls, *chain = NULL;
6460 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
6462 /* struct _objc_class *isa; */
6463 decls = add_field_decl (build_pointer_type (objc_class_template),
6464 "isa", &chain);
6466 /* struct _objc_class *super_class; */
6467 add_field_decl (build_pointer_type (objc_class_template),
6468 "super_class", &chain);
6470 /* char *name; */
6471 add_field_decl (string_type_node, "name", &chain);
6473 /* long version; */
6474 add_field_decl (long_integer_type_node, "version", &chain);
6476 /* long info; */
6477 add_field_decl (long_integer_type_node, "info", &chain);
6479 /* long instance_size; */
6480 add_field_decl (long_integer_type_node, "instance_size", &chain);
6482 /* struct _objc_ivar_list *ivars; */
6483 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
6485 /* struct _objc_method_list *methods; */
6486 add_field_decl (objc_method_list_ptr, "methods", &chain);
6488 if (flag_next_runtime)
6490 /* struct objc_cache *cache; */
6491 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
6492 get_identifier ("objc_cache")));
6493 add_field_decl (ptype, "cache", &chain);
6495 else
6497 /* struct sarray *dtable; */
6498 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
6499 get_identifier ("sarray")));
6500 add_field_decl (ptype, "dtable", &chain);
6502 /* struct objc_class *subclass_list; */
6503 ptype = build_pointer_type (objc_class_template);
6504 add_field_decl (ptype, "subclass_list", &chain);
6506 /* struct objc_class *sibling_class; */
6507 ptype = build_pointer_type (objc_class_template);
6508 add_field_decl (ptype, "sibling_class", &chain);
6511 /* struct _objc_protocol **protocol_list; */
6512 ptype = build_pointer_type (build_pointer_type
6513 (xref_tag (RECORD_TYPE,
6514 get_identifier (UTAG_PROTOCOL))));
6515 add_field_decl (ptype, "protocol_list", &chain);
6517 if (flag_next_runtime)
6519 /* void *sel_id; */
6520 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
6523 /* void *gc_object_type; */
6524 add_field_decl (build_pointer_type (void_type_node),
6525 "gc_object_type", &chain);
6527 objc_finish_struct (objc_class_template, decls);
6530 /* Generate appropriate forward declarations for an implementation. */
6532 static void
6533 synth_forward_declarations (void)
6535 tree an_id;
6537 /* static struct objc_class _OBJC_CLASS_<my_name>; */
6538 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
6539 objc_class_template);
6541 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
6542 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
6543 objc_class_template);
6545 /* Pre-build the following entities - for speed/convenience. */
6547 an_id = get_identifier ("super_class");
6548 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
6549 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
6552 static void
6553 error_with_ivar (const char *message, tree decl)
6555 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
6556 message, identifier_to_locale (gen_declaration (decl)));
6560 static void
6561 check_ivars (tree inter, tree imp)
6563 tree intdecls = CLASS_RAW_IVARS (inter);
6564 tree impdecls = CLASS_RAW_IVARS (imp);
6566 while (1)
6568 tree t1, t2;
6570 #ifdef OBJCPLUS
6571 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
6572 intdecls = TREE_CHAIN (intdecls);
6573 #endif
6574 if (intdecls == 0 && impdecls == 0)
6575 break;
6576 if (intdecls == 0 || impdecls == 0)
6578 error ("inconsistent instance variable specification");
6579 break;
6582 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
6584 if (!comptypes (t1, t2)
6585 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
6586 DECL_INITIAL (impdecls)))
6588 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
6590 error_with_ivar ("conflicting instance variable type",
6591 impdecls);
6592 error_with_ivar ("previous declaration of",
6593 intdecls);
6595 else /* both the type and the name don't match */
6597 error ("inconsistent instance variable specification");
6598 break;
6602 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
6604 error_with_ivar ("conflicting instance variable name",
6605 impdecls);
6606 error_with_ivar ("previous declaration of",
6607 intdecls);
6610 intdecls = DECL_CHAIN (intdecls);
6611 impdecls = DECL_CHAIN (impdecls);
6615 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
6616 This needs to be done just once per compilation. */
6618 /* struct _objc_super {
6619 struct _objc_object *self;
6620 struct _objc_class *super_class;
6621 }; */
6623 static void
6624 build_super_template (void)
6626 tree decls, *chain = NULL;
6628 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
6630 /* struct _objc_object *self; */
6631 decls = add_field_decl (objc_object_type, "self", &chain);
6633 /* struct _objc_class *super_class; */
6634 add_field_decl (build_pointer_type (objc_class_template),
6635 "super_class", &chain);
6637 objc_finish_struct (objc_super_template, decls);
6640 /* struct _objc_ivar {
6641 char *ivar_name;
6642 char *ivar_type;
6643 int ivar_offset;
6644 }; */
6646 static tree
6647 build_ivar_template (void)
6649 tree objc_ivar_id, objc_ivar_record;
6650 tree decls, *chain = NULL;
6652 objc_ivar_id = get_identifier (UTAG_IVAR);
6653 objc_ivar_record = objc_start_struct (objc_ivar_id);
6655 /* char *ivar_name; */
6656 decls = add_field_decl (string_type_node, "ivar_name", &chain);
6658 /* char *ivar_type; */
6659 add_field_decl (string_type_node, "ivar_type", &chain);
6661 /* int ivar_offset; */
6662 add_field_decl (integer_type_node, "ivar_offset", &chain);
6664 objc_finish_struct (objc_ivar_record, decls);
6666 return objc_ivar_record;
6669 /* struct {
6670 int ivar_count;
6671 struct objc_ivar ivar_list[ivar_count];
6672 }; */
6674 static tree
6675 build_ivar_list_template (tree list_type, int size)
6677 tree objc_ivar_list_record;
6678 tree array_type, decls, *chain = NULL;
6680 objc_ivar_list_record = objc_start_struct (NULL_TREE);
6682 /* int ivar_count; */
6683 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
6685 /* struct objc_ivar ivar_list[]; */
6686 array_type = build_sized_array_type (list_type, size);
6687 add_field_decl (array_type, "ivar_list", &chain);
6689 objc_finish_struct (objc_ivar_list_record, decls);
6691 return objc_ivar_list_record;
6694 /* struct {
6695 struct _objc__method_prototype_list *method_next;
6696 int method_count;
6697 struct objc_method method_list[method_count];
6698 }; */
6700 static tree
6701 build_method_list_template (tree list_type, int size)
6703 tree objc_ivar_list_record;
6704 tree array_type, decls, *chain = NULL;
6706 objc_ivar_list_record = objc_start_struct (NULL_TREE);
6708 /* struct _objc__method_prototype_list *method_next; */
6709 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
6711 /* int method_count; */
6712 add_field_decl (integer_type_node, "method_count", &chain);
6714 /* struct objc_method method_list[]; */
6715 array_type = build_sized_array_type (list_type, size);
6716 add_field_decl (array_type, "method_list", &chain);
6718 objc_finish_struct (objc_ivar_list_record, decls);
6720 return objc_ivar_list_record;
6723 static tree
6724 build_ivar_list_initializer (tree type, tree field_decl)
6726 VEC(constructor_elt,gc) *inits = NULL;
6730 VEC(constructor_elt,gc) *ivar = NULL;
6731 tree id;
6733 /* Set name. */
6734 if (DECL_NAME (field_decl))
6735 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
6736 add_objc_string (DECL_NAME (field_decl),
6737 meth_var_names));
6738 else
6739 /* Unnamed bit-field ivar (yuck). */
6740 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
6742 /* Set type. */
6743 encode_field_decl (field_decl,
6744 obstack_object_size (&util_obstack),
6745 OBJC_ENCODE_DONT_INLINE_DEFS);
6747 /* Null terminate string. */
6748 obstack_1grow (&util_obstack, 0);
6749 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
6750 meth_var_types);
6751 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
6752 obstack_free (&util_obstack, util_firstobj);
6754 /* Set offset. */
6755 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
6756 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6757 objc_build_constructor (type, ivar));
6759 field_decl = DECL_CHAIN (field_decl);
6760 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
6762 while (field_decl);
6764 return objc_build_constructor (build_array_type (type, 0), inits);
6767 static tree
6768 generate_ivars_list (tree type, const char *name, int size, tree list)
6770 tree decl;
6771 VEC(constructor_elt,gc) *inits = NULL;
6773 decl = start_var_decl (type, synth_id_with_class_suffix
6774 (name, objc_implementation_context));
6776 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
6777 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
6779 finish_var_decl (decl,
6780 objc_build_constructor (TREE_TYPE (decl), inits));
6782 return decl;
6785 /* Count only the fields occurring in T. */
6787 static int
6788 ivar_list_length (tree t)
6790 int count = 0;
6792 for (; t; t = DECL_CHAIN (t))
6793 if (TREE_CODE (t) == FIELD_DECL)
6794 ++count;
6796 return count;
6799 static void
6800 generate_ivar_lists (void)
6802 tree initlist, ivar_list_template, chain;
6803 int size;
6805 generating_instance_variables = 1;
6807 if (!objc_ivar_template)
6808 objc_ivar_template = build_ivar_template ();
6810 /* Only generate class variables for the root of the inheritance
6811 hierarchy since these will be the same for every class. */
6813 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
6814 && (chain = TYPE_FIELDS (objc_class_template)))
6816 size = ivar_list_length (chain);
6818 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6819 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6821 UOBJC_CLASS_VARIABLES_decl
6822 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
6823 size, initlist);
6825 else
6826 UOBJC_CLASS_VARIABLES_decl = 0;
6828 chain = CLASS_IVARS (implementation_template);
6829 if (chain)
6831 size = ivar_list_length (chain);
6832 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
6833 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
6835 UOBJC_INSTANCE_VARIABLES_decl
6836 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
6837 size, initlist);
6839 else
6840 UOBJC_INSTANCE_VARIABLES_decl = 0;
6842 generating_instance_variables = 0;
6845 static tree
6846 build_dispatch_table_initializer (tree type, tree entries)
6848 VEC(constructor_elt,gc) *inits = NULL;
6852 VEC(constructor_elt,gc) *elems = NULL;
6853 tree expr;
6855 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6856 build_selector (METHOD_SEL_NAME (entries)));
6858 /* Generate the method encoding if we don't have one already. */
6859 if (! METHOD_ENCODING (entries))
6860 METHOD_ENCODING (entries) =
6861 encode_method_prototype (entries);
6863 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
6864 add_objc_string (METHOD_ENCODING (entries),
6865 meth_var_types));
6867 expr = convert (ptr_type_node,
6868 build_unary_op (input_location, ADDR_EXPR,
6869 METHOD_DEFINITION (entries), 1));
6870 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
6872 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
6873 objc_build_constructor (type, elems));
6875 entries = DECL_CHAIN (entries);
6877 while (entries);
6879 return objc_build_constructor (build_array_type (type, 0), inits);
6882 /* To accomplish method prototyping without generating all kinds of
6883 inane warnings, the definition of the dispatch table entries were
6884 changed from:
6886 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
6888 struct objc_method { SEL _cmd; ...; void *_imp; }; */
6890 static tree
6891 build_method_template (void)
6893 tree _SLT_record;
6894 tree decls, *chain = NULL;
6896 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
6898 /* SEL _cmd; */
6899 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
6901 /* char *method_types; */
6902 add_field_decl (string_type_node, "method_types", &chain);
6904 /* void *_imp; */
6905 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
6907 objc_finish_struct (_SLT_record, decls);
6909 return _SLT_record;
6913 static tree
6914 generate_dispatch_table (tree type, const char *name, int size, tree list)
6916 tree decl;
6917 VEC(constructor_elt,gc) *v = NULL;
6919 decl = start_var_decl (type, synth_id_with_class_suffix
6920 (name, objc_implementation_context));
6922 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
6923 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
6924 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
6926 finish_var_decl (decl,
6927 objc_build_constructor (TREE_TYPE (decl), v));
6929 return decl;
6932 static void
6933 mark_referenced_methods (void)
6935 struct imp_entry *impent;
6936 tree chain;
6938 for (impent = imp_list; impent; impent = impent->next)
6940 chain = CLASS_CLS_METHODS (impent->imp_context);
6941 while (chain)
6943 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6944 chain = DECL_CHAIN (chain);
6947 chain = CLASS_NST_METHODS (impent->imp_context);
6948 while (chain)
6950 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
6951 chain = DECL_CHAIN (chain);
6956 static void
6957 generate_dispatch_tables (void)
6959 tree initlist, chain, method_list_template;
6960 int size;
6962 if (!objc_method_template)
6963 objc_method_template = build_method_template ();
6965 chain = CLASS_CLS_METHODS (objc_implementation_context);
6966 if (chain)
6968 size = list_length (chain);
6970 method_list_template
6971 = build_method_list_template (objc_method_template, size);
6972 initlist
6973 = build_dispatch_table_initializer (objc_method_template, chain);
6975 UOBJC_CLASS_METHODS_decl
6976 = generate_dispatch_table (method_list_template,
6977 ((TREE_CODE (objc_implementation_context)
6978 == CLASS_IMPLEMENTATION_TYPE)
6979 ? "_OBJC_CLASS_METHODS"
6980 : "_OBJC_CATEGORY_CLASS_METHODS"),
6981 size, initlist);
6983 else
6984 UOBJC_CLASS_METHODS_decl = 0;
6986 chain = CLASS_NST_METHODS (objc_implementation_context);
6987 if (chain)
6989 size = list_length (chain);
6991 method_list_template
6992 = build_method_list_template (objc_method_template, size);
6993 initlist
6994 = build_dispatch_table_initializer (objc_method_template, chain);
6996 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
6997 UOBJC_INSTANCE_METHODS_decl
6998 = generate_dispatch_table (method_list_template,
6999 "_OBJC_INSTANCE_METHODS",
7000 size, initlist);
7001 else
7002 /* We have a category. */
7003 UOBJC_INSTANCE_METHODS_decl
7004 = generate_dispatch_table (method_list_template,
7005 "_OBJC_CATEGORY_INSTANCE_METHODS",
7006 size, initlist);
7008 else
7009 UOBJC_INSTANCE_METHODS_decl = 0;
7012 static tree
7013 generate_protocol_list (tree i_or_p)
7015 tree array_type, ptype, refs_decl, lproto, e, plist;
7016 int size = 0;
7017 const char *ref_name;
7018 VEC(constructor_elt,gc) *v = NULL;
7020 switch (TREE_CODE (i_or_p))
7022 case CLASS_INTERFACE_TYPE:
7023 case CATEGORY_INTERFACE_TYPE:
7024 plist = CLASS_PROTOCOL_LIST (i_or_p);
7025 break;
7026 case PROTOCOL_INTERFACE_TYPE:
7027 plist = PROTOCOL_LIST (i_or_p);
7028 break;
7029 default:
7030 gcc_unreachable ();
7033 /* Compute size. */
7034 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
7035 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
7036 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
7037 size++;
7039 /* Build initializer. */
7040 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7041 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
7042 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
7044 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
7046 tree pval = TREE_VALUE (lproto);
7048 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
7049 && PROTOCOL_FORWARD_DECL (pval))
7051 e = build_unary_op (input_location, ADDR_EXPR,
7052 PROTOCOL_FORWARD_DECL (pval), 0);
7053 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
7057 /* static struct objc_protocol *refs[n]; */
7059 switch (TREE_CODE (i_or_p))
7061 case PROTOCOL_INTERFACE_TYPE:
7062 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
7063 break;
7064 case CLASS_INTERFACE_TYPE:
7065 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
7066 break;
7067 case CATEGORY_INTERFACE_TYPE:
7068 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
7069 break;
7070 default:
7071 gcc_unreachable ();
7074 ptype = build_pointer_type (objc_protocol_template);
7075 array_type = build_sized_array_type (ptype, size + 3);
7076 refs_decl = start_var_decl (array_type, ref_name);
7078 finish_var_decl (refs_decl,
7079 objc_build_constructor (TREE_TYPE (refs_decl), v));
7081 return refs_decl;
7084 static tree
7085 build_category_initializer (tree type, tree cat_name, tree class_name,
7086 tree instance_methods, tree class_methods,
7087 tree protocol_list)
7089 tree expr;
7090 VEC(constructor_elt,gc) *v = NULL;
7092 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
7093 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
7095 if (!instance_methods)
7096 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7097 else
7099 expr = convert (objc_method_list_ptr,
7100 build_unary_op (input_location, ADDR_EXPR,
7101 instance_methods, 0));
7102 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7104 if (!class_methods)
7105 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7106 else
7108 expr = convert (objc_method_list_ptr,
7109 build_unary_op (input_location, ADDR_EXPR,
7110 class_methods, 0));
7111 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7114 /* protocol_list = */
7115 if (!protocol_list)
7116 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7117 else
7119 expr = convert (build_pointer_type
7120 (build_pointer_type
7121 (objc_protocol_template)),
7122 build_unary_op (input_location, ADDR_EXPR,
7123 protocol_list, 0));
7124 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7127 return objc_build_constructor (type, v);
7130 /* struct _objc_class {
7131 struct objc_class *isa;
7132 struct objc_class *super_class;
7133 char *name;
7134 long version;
7135 long info;
7136 long instance_size;
7137 struct objc_ivar_list *ivars;
7138 struct objc_method_list *methods;
7139 if (flag_next_runtime)
7140 struct objc_cache *cache;
7141 else {
7142 struct sarray *dtable;
7143 struct objc_class *subclass_list;
7144 struct objc_class *sibling_class;
7146 struct objc_protocol_list *protocols;
7147 if (flag_next_runtime)
7148 void *sel_id;
7149 void *gc_object_type;
7150 }; */
7152 static tree
7153 build_shared_structure_initializer (tree type, tree isa, tree super,
7154 tree name, tree size, int status,
7155 tree dispatch_table, tree ivar_list,
7156 tree protocol_list)
7158 tree expr;
7159 VEC(constructor_elt,gc) *v = NULL;
7161 /* isa = */
7162 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
7164 /* super_class = */
7165 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
7167 /* name = */
7168 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
7170 /* version = */
7171 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7172 build_int_cst (long_integer_type_node, 0));
7174 /* info = */
7175 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7176 build_int_cst (long_integer_type_node, status));
7178 /* instance_size = */
7179 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
7180 convert (long_integer_type_node, size));
7182 /* objc_ivar_list = */
7183 if (!ivar_list)
7184 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7185 else
7187 expr = convert (objc_ivar_list_ptr,
7188 build_unary_op (input_location, ADDR_EXPR,
7189 ivar_list, 0));
7190 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7193 /* objc_method_list = */
7194 if (!dispatch_table)
7195 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7196 else
7198 expr = convert (objc_method_list_ptr,
7199 build_unary_op (input_location, ADDR_EXPR,
7200 dispatch_table, 0));
7201 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7204 if (flag_next_runtime)
7205 /* method_cache = */
7206 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7207 else
7209 /* dtable = */
7210 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7212 /* subclass_list = */
7213 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7215 /* sibling_class = */
7216 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7219 /* protocol_list = */
7220 if (! protocol_list)
7221 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7222 else
7224 expr = convert (build_pointer_type
7225 (build_pointer_type
7226 (objc_protocol_template)),
7227 build_unary_op (input_location, ADDR_EXPR,
7228 protocol_list, 0));
7229 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
7232 if (flag_next_runtime)
7233 /* sel_id = NULL */
7234 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7236 /* gc_object_type = NULL */
7237 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
7239 return objc_build_constructor (type, v);
7242 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
7244 static inline tree
7245 lookup_category (tree klass, tree cat_name)
7247 tree category = CLASS_CATEGORY_LIST (klass);
7249 while (category && CLASS_SUPER_NAME (category) != cat_name)
7250 category = CLASS_CATEGORY_LIST (category);
7251 return category;
7254 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
7256 static void
7257 generate_category (struct imp_entry *impent)
7259 tree initlist, cat_name_expr, class_name_expr;
7260 tree protocol_decl, category;
7261 tree cat = impent->imp_context;
7263 implementation_template = impent->imp_template;
7264 UOBJC_CLASS_decl = impent->class_decl;
7265 UOBJC_METACLASS_decl = impent->meta_decl;
7267 add_class_reference (CLASS_NAME (cat));
7268 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
7270 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
7272 category = lookup_category (implementation_template,
7273 CLASS_SUPER_NAME (cat));
7275 if (category && CLASS_PROTOCOL_LIST (category))
7277 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
7278 protocol_decl = generate_protocol_list (category);
7280 else
7281 protocol_decl = 0;
7283 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
7284 cat_name_expr, class_name_expr,
7285 UOBJC_INSTANCE_METHODS_decl,
7286 UOBJC_CLASS_METHODS_decl,
7287 protocol_decl);
7288 /* Finish and initialize the forward decl. */
7289 finish_var_decl (UOBJC_CLASS_decl, initlist);
7292 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
7293 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
7295 static void
7296 generate_shared_structures (struct imp_entry *impent)
7298 tree name_expr, super_expr, root_expr;
7299 tree my_root_id, my_super_id;
7300 tree cast_type, initlist, protocol_decl;
7301 int cls_flags;
7303 objc_implementation_context = impent->imp_context;
7304 implementation_template = impent->imp_template;
7305 UOBJC_CLASS_decl = impent->class_decl;
7306 UOBJC_METACLASS_decl = impent->meta_decl;
7307 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
7309 my_super_id = CLASS_SUPER_NAME (implementation_template);
7310 if (my_super_id)
7312 add_class_reference (my_super_id);
7314 /* Compute "my_root_id" - this is required for code generation.
7315 the "isa" for all meta class structures points to the root of
7316 the inheritance hierarchy (e.g. "__Object")... */
7317 my_root_id = my_super_id;
7320 tree my_root_int = lookup_interface (my_root_id);
7322 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
7323 my_root_id = CLASS_SUPER_NAME (my_root_int);
7324 else
7325 break;
7327 while (1);
7329 else
7330 /* No super class. */
7331 my_root_id = CLASS_NAME (implementation_template);
7333 cast_type = build_pointer_type (objc_class_template);
7334 name_expr = add_objc_string (CLASS_NAME (implementation_template),
7335 class_names);
7337 /* Install class `isa' and `super' pointers at runtime. */
7338 if (my_super_id)
7339 super_expr = add_objc_string (my_super_id, class_names);
7340 else
7341 super_expr = integer_zero_node;
7343 super_expr = build_c_cast (input_location,
7344 cast_type, super_expr); /* cast! */
7346 root_expr = add_objc_string (my_root_id, class_names);
7347 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
7349 if (CLASS_PROTOCOL_LIST (implementation_template))
7351 generate_protocol_references
7352 (CLASS_PROTOCOL_LIST (implementation_template));
7353 protocol_decl = generate_protocol_list (implementation_template);
7355 else
7356 protocol_decl = 0;
7358 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
7360 initlist
7361 = build_shared_structure_initializer
7362 (TREE_TYPE (UOBJC_METACLASS_decl),
7363 root_expr, super_expr, name_expr,
7364 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
7365 2 /*CLS_META*/,
7366 UOBJC_CLASS_METHODS_decl,
7367 UOBJC_CLASS_VARIABLES_decl,
7368 protocol_decl);
7370 finish_var_decl (UOBJC_METACLASS_decl, initlist);
7372 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
7374 initlist
7375 = build_shared_structure_initializer
7376 (TREE_TYPE (UOBJC_CLASS_decl),
7377 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
7378 super_expr, name_expr,
7379 convert (integer_type_node,
7380 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
7381 (implementation_template))),
7382 1 /*CLS_FACTORY*/ | cls_flags,
7383 UOBJC_INSTANCE_METHODS_decl,
7384 UOBJC_INSTANCE_VARIABLES_decl,
7385 protocol_decl);
7387 finish_var_decl (UOBJC_CLASS_decl, initlist);
7391 static const char *
7392 synth_id_with_class_suffix (const char *preamble, tree ctxt)
7394 static char string[BUFSIZE];
7396 switch (TREE_CODE (ctxt))
7398 case CLASS_IMPLEMENTATION_TYPE:
7399 case CLASS_INTERFACE_TYPE:
7400 sprintf (string, "%s_%s", preamble,
7401 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
7402 break;
7403 case CATEGORY_IMPLEMENTATION_TYPE:
7404 case CATEGORY_INTERFACE_TYPE:
7406 /* We have a category. */
7407 const char *const class_name
7408 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7409 const char *const class_super_name
7410 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
7411 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
7412 break;
7414 case PROTOCOL_INTERFACE_TYPE:
7416 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
7417 sprintf (string, "%s_%s", preamble, protocol_name);
7418 break;
7420 default:
7421 gcc_unreachable ();
7424 return string;
7427 /* If type is empty or only type qualifiers are present, add default
7428 type of id (otherwise grokdeclarator will default to int). */
7429 static inline tree
7430 adjust_type_for_id_default (tree type)
7432 if (!type)
7433 type = make_node (TREE_LIST);
7435 if (!TREE_VALUE (type))
7436 TREE_VALUE (type) = objc_object_type;
7437 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
7438 && TYPED_OBJECT (TREE_VALUE (type)))
7439 error ("can not use an object as parameter to a method");
7441 return type;
7444 /* Return a KEYWORD_DECL built using the specified key_name, arg_type,
7445 arg_name and attributes. (TODO: Rename KEYWORD_DECL to
7446 OBJC_METHOD_PARM_DECL ?)
7448 A KEYWORD_DECL is a tree representing the declaration of a
7449 parameter of an Objective-C method. It is produced when parsing a
7450 fragment of Objective-C method declaration of the form
7452 keyworddecl:
7453 selector ':' '(' typename ')' identifier
7455 For example, take the Objective-C method
7457 -(NSString *)pathForResource:(NSString *)resource ofType:(NSString *)type;
7459 the two fragments "pathForResource:(NSString *)resource" and
7460 "ofType:(NSString *)type" will generate a KEYWORD_DECL each. The
7461 KEYWORD_DECL stores the 'key_name' (eg, identifier for
7462 "pathForResource"), the 'arg_type' (eg, tree representing a
7463 NSString *), the 'arg_name' (eg identifier for "resource") and
7464 potentially some attributes (for example, a tree representing
7465 __attribute__ ((unused)) if such an attribute was attached to a
7466 certain parameter). You can access this information using the
7467 TREE_TYPE (for arg_type), KEYWORD_ARG_NAME (for arg_name),
7468 KEYWORD_KEY_NAME (for key_name), DECL_ATTRIBUTES (for attributes).
7470 'key_name' is an identifier node (and is optional as you can omit
7471 it in Objective-C methods).
7472 'arg_type' is a tree list (and is optional too if no parameter type
7473 was specified).
7474 'arg_name' is an identifier node and is required.
7475 'attributes' is an optional tree containing parameter attributes. */
7476 tree
7477 objc_build_keyword_decl (tree key_name, tree arg_type,
7478 tree arg_name, tree attributes)
7480 tree keyword_decl;
7482 if (flag_objc1_only && attributes)
7483 error_at (input_location, "method argument attributes are not available in Objective-C 1.0");
7485 /* If no type is specified, default to "id". */
7486 arg_type = adjust_type_for_id_default (arg_type);
7488 keyword_decl = make_node (KEYWORD_DECL);
7490 TREE_TYPE (keyword_decl) = arg_type;
7491 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
7492 KEYWORD_KEY_NAME (keyword_decl) = key_name;
7493 DECL_ATTRIBUTES (keyword_decl) = attributes;
7495 return keyword_decl;
7498 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
7499 static tree
7500 build_keyword_selector (tree selector)
7502 int len = 0;
7503 tree key_chain, key_name;
7504 char *buf;
7506 /* Scan the selector to see how much space we'll need. */
7507 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7509 switch (TREE_CODE (selector))
7511 case KEYWORD_DECL:
7512 key_name = KEYWORD_KEY_NAME (key_chain);
7513 break;
7514 case TREE_LIST:
7515 key_name = TREE_PURPOSE (key_chain);
7516 break;
7517 default:
7518 gcc_unreachable ();
7521 if (key_name)
7522 len += IDENTIFIER_LENGTH (key_name) + 1;
7523 else
7524 /* Just a ':' arg. */
7525 len++;
7528 buf = (char *) alloca (len + 1);
7529 /* Start the buffer out as an empty string. */
7530 buf[0] = '\0';
7532 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
7534 switch (TREE_CODE (selector))
7536 case KEYWORD_DECL:
7537 key_name = KEYWORD_KEY_NAME (key_chain);
7538 break;
7539 case TREE_LIST:
7540 key_name = TREE_PURPOSE (key_chain);
7541 /* The keyword decl chain will later be used as a function
7542 argument chain. Unhook the selector itself so as to not
7543 confuse other parts of the compiler. */
7544 TREE_PURPOSE (key_chain) = NULL_TREE;
7545 break;
7546 default:
7547 gcc_unreachable ();
7550 if (key_name)
7551 strcat (buf, IDENTIFIER_POINTER (key_name));
7552 strcat (buf, ":");
7555 return get_identifier (buf);
7558 /* Used for declarations and definitions. */
7560 static tree
7561 build_method_decl (enum tree_code code, tree ret_type, tree selector,
7562 tree add_args, bool ellipsis)
7564 tree method_decl;
7566 /* If no type is specified, default to "id". */
7567 ret_type = adjust_type_for_id_default (ret_type);
7569 /* Note how a method_decl has a TREE_TYPE which is not the function
7570 type of the function implementing the method, but only the return
7571 type of the method. We may want to change this, and store the
7572 entire function type in there (eg, it may be used to simplify
7573 dealing with attributes below). */
7574 method_decl = make_node (code);
7575 TREE_TYPE (method_decl) = ret_type;
7577 /* If we have a keyword selector, create an identifier_node that
7578 represents the full selector name (`:' included)... */
7579 if (TREE_CODE (selector) == KEYWORD_DECL)
7581 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
7582 METHOD_SEL_ARGS (method_decl) = selector;
7583 METHOD_ADD_ARGS (method_decl) = add_args;
7584 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
7586 else
7588 METHOD_SEL_NAME (method_decl) = selector;
7589 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
7590 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
7593 return method_decl;
7596 #define METHOD_DEF 0
7597 #define METHOD_REF 1
7599 /* This routine processes objective-c method attributes. */
7601 static void
7602 objc_decl_method_attributes (tree *node, tree attributes, int flags)
7604 /* TODO: Replace the hackery below. An idea would be to store the
7605 full function type in the method declaration (for example in
7606 TREE_TYPE) and then expose ObjC method declarations to c-family
7607 and they could deal with them by simply treating them as
7608 functions. */
7610 /* Because of the dangers in the hackery below, we filter out any
7611 attribute that we do not know about. For the ones we know about,
7612 we know that they work with the hackery. For the other ones,
7613 there is no guarantee, so we have to filter them out. */
7614 tree filtered_attributes = NULL_TREE;
7616 if (attributes)
7618 tree attribute;
7619 for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
7621 tree name = TREE_PURPOSE (attribute);
7623 if (is_attribute_p ("deprecated", name)
7624 || is_attribute_p ("sentinel", name)
7625 || is_attribute_p ("noreturn", name))
7627 /* An attribute that we support; add it to the filtered
7628 attributes. */
7629 filtered_attributes = chainon (filtered_attributes,
7630 copy_node (attribute));
7632 else if (is_attribute_p ("format", name))
7634 /* "format" is special because before adding it to the
7635 filtered attributes we need to adjust the specified
7636 format by adding the hidden function parameters for
7637 an Objective-C method (self, _cmd). */
7638 tree new_attribute = copy_node (attribute);
7640 /* Check the arguments specified with the attribute, and
7641 modify them adding 2 for the two hidden arguments.
7642 Note how this differs from C++; according to the
7643 specs, C++ does not do it so you have to add the +1
7644 yourself. For Objective-C, instead, the compiler
7645 adds the +2 for you. */
7647 /* The attribute arguments have not been checked yet, so
7648 we need to be careful as they could be missing or
7649 invalid. If anything looks wrong, we skip the
7650 process and the compiler will complain about it later
7651 when it validates the attribute. */
7652 /* Check that we have at least three arguments. */
7653 if (TREE_VALUE (new_attribute)
7654 && TREE_CHAIN (TREE_VALUE (new_attribute))
7655 && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (new_attribute))))
7657 tree second_argument = TREE_CHAIN (TREE_VALUE (new_attribute));
7658 tree third_argument = TREE_CHAIN (second_argument);
7659 tree number;
7661 /* This is the second argument, the "string-index",
7662 which specifies the index of the format string
7663 argument. Add 2. */
7664 number = TREE_VALUE (second_argument);
7665 if (number
7666 && TREE_CODE (number) == INTEGER_CST
7667 && TREE_INT_CST_HIGH (number) == 0)
7669 TREE_VALUE (second_argument)
7670 = build_int_cst (integer_type_node,
7671 TREE_INT_CST_LOW (number) + 2);
7674 /* This is the third argument, the "first-to-check",
7675 which specifies the index of the first argument to
7676 check. This could be 0, meaning it is not available,
7677 in which case we don't need to add 2. Add 2 if not
7678 0. */
7679 number = TREE_VALUE (third_argument);
7680 if (number
7681 && TREE_CODE (number) == INTEGER_CST
7682 && TREE_INT_CST_HIGH (number) == 0
7683 && TREE_INT_CST_LOW (number) != 0)
7685 TREE_VALUE (third_argument)
7686 = build_int_cst (integer_type_node,
7687 TREE_INT_CST_LOW (number) + 2);
7690 filtered_attributes = chainon (filtered_attributes,
7691 new_attribute);
7693 else
7694 warning (OPT_Wattributes, "%qE attribute directive ignored", name);
7698 if (filtered_attributes)
7700 /* This hackery changes the TREE_TYPE of the ObjC method
7701 declaration to be a function type, so that decl_attributes
7702 will treat the ObjC method as if it was a function. Some
7703 attributes (sentinel, format) will be applied to the function
7704 type, changing it in place; so after calling decl_attributes,
7705 we extract the function type attributes and store them in
7706 METHOD_TYPE_ATTRIBUTES. Some other attributes (noreturn,
7707 deprecated) are applied directly to the method declaration
7708 (by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
7709 is nothing to do. */
7710 tree saved_type = TREE_TYPE (*node);
7711 TREE_TYPE (*node) = build_function_type
7712 (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
7713 decl_attributes (node, filtered_attributes, flags);
7714 METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
7715 TREE_TYPE (*node) = saved_type;
7719 bool
7720 objc_method_decl (enum tree_code opcode)
7722 return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
7725 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
7726 an argument list for method METH. CONTEXT is either METHOD_DEF or
7727 METHOD_REF, saying whether we are trying to define a method or call
7728 one. SUPERFLAG says this is for a send to super; this makes a
7729 difference for the NeXT calling sequence in which the lookup and
7730 the method call are done together. If METH is null, user-defined
7731 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
7733 static tree
7734 get_arg_type_list (tree meth, int context, int superflag)
7736 tree arglist, akey;
7738 /* Receiver type. */
7739 if (flag_next_runtime && superflag)
7740 arglist = build_tree_list (NULL_TREE, objc_super_type);
7741 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
7742 arglist = build_tree_list (NULL_TREE, objc_instance_type);
7743 else
7744 arglist = build_tree_list (NULL_TREE, objc_object_type);
7746 /* Selector type - will eventually change to `int'. */
7747 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
7749 /* No actual method prototype given -- assume that remaining arguments
7750 are `...'. */
7751 if (!meth)
7752 return arglist;
7754 /* Build a list of argument types. */
7755 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
7757 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
7759 /* Decay argument types for the underlying C function as appropriate. */
7760 arg_type = objc_decay_parm_type (arg_type);
7762 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7765 if (METHOD_ADD_ARGS (meth))
7767 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
7768 akey; akey = TREE_CHAIN (akey))
7770 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
7772 arg_type = objc_decay_parm_type (arg_type);
7774 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
7777 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
7778 goto lack_of_ellipsis;
7780 else
7782 lack_of_ellipsis:
7783 chainon (arglist, OBJC_VOID_AT_END);
7786 return arglist;
7789 static tree
7790 check_duplicates (hash hsh, int methods, int is_class)
7792 tree meth = NULL_TREE;
7794 if (hsh)
7796 meth = hsh->key;
7798 if (hsh->list)
7800 /* We have two or more methods with the same name but
7801 different types. */
7802 attr loop;
7804 /* But just how different are those types? If
7805 -Wno-strict-selector-match is specified, we shall not
7806 complain if the differences are solely among types with
7807 identical size and alignment. */
7808 if (!warn_strict_selector_match)
7810 for (loop = hsh->list; loop; loop = loop->next)
7811 if (!comp_proto_with_proto (meth, loop->value, 0))
7812 goto issue_warning;
7814 return meth;
7817 issue_warning:
7818 if (methods)
7820 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7822 warning_at (input_location, 0,
7823 "multiple methods named %<%c%E%> found",
7824 (is_class ? '+' : '-'),
7825 METHOD_SEL_NAME (meth));
7826 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
7827 (type ? '-' : '+'),
7828 identifier_to_locale (gen_method_decl (meth)));
7830 else
7832 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
7834 warning_at (input_location, 0,
7835 "multiple selectors named %<%c%E%> found",
7836 (is_class ? '+' : '-'),
7837 METHOD_SEL_NAME (meth));
7838 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
7839 (type ? '-' : '+'),
7840 identifier_to_locale (gen_method_decl (meth)));
7843 for (loop = hsh->list; loop; loop = loop->next)
7845 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
7847 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
7848 (type ? '-' : '+'),
7849 identifier_to_locale (gen_method_decl (loop->value)));
7853 return meth;
7856 /* If RECEIVER is a class reference, return the identifier node for
7857 the referenced class. RECEIVER is created by objc_get_class_reference,
7858 so we check the exact form created depending on which runtimes are
7859 used. */
7861 static tree
7862 receiver_is_class_object (tree receiver, int self, int super)
7864 tree chain, exp, arg;
7866 /* The receiver is 'self' or 'super' in the context of a class method. */
7867 if (objc_method_context
7868 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
7869 && (self || super))
7870 return (super
7871 ? CLASS_SUPER_NAME (implementation_template)
7872 : CLASS_NAME (implementation_template));
7874 if (flag_next_runtime)
7876 /* The receiver is a variable created by
7877 build_class_reference_decl. */
7878 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
7879 /* Look up the identifier. */
7880 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
7881 if (TREE_PURPOSE (chain) == receiver)
7882 return TREE_VALUE (chain);
7885 /* The receiver is a function call that returns an id. Check if
7886 it is a call to objc_getClass, if so, pick up the class name. */
7887 if (TREE_CODE (receiver) == CALL_EXPR
7888 && (exp = CALL_EXPR_FN (receiver))
7889 && TREE_CODE (exp) == ADDR_EXPR
7890 && (exp = TREE_OPERAND (exp, 0))
7891 && TREE_CODE (exp) == FUNCTION_DECL
7892 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
7893 prototypes for objc_get_class(). Thankfully, they seem to share the
7894 same function type. */
7895 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
7896 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
7897 /* We have a call to objc_get_class/objc_getClass! */
7898 && (arg = CALL_EXPR_ARG (receiver, 0)))
7900 STRIP_NOPS (arg);
7901 if (TREE_CODE (arg) == ADDR_EXPR
7902 && (arg = TREE_OPERAND (arg, 0))
7903 && TREE_CODE (arg) == STRING_CST)
7904 /* Finally, we have the class name. */
7905 return get_identifier (TREE_STRING_POINTER (arg));
7907 return 0;
7910 /* If we are currently building a message expr, this holds
7911 the identifier of the selector of the message. This is
7912 used when printing warnings about argument mismatches. */
7914 static tree current_objc_message_selector = 0;
7916 tree
7917 objc_message_selector (void)
7919 return current_objc_message_selector;
7922 /* Construct an expression for sending a message.
7923 MESS has the object to send to in TREE_PURPOSE
7924 and the argument list (including selector) in TREE_VALUE.
7926 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
7927 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
7929 tree
7930 objc_build_message_expr (tree mess)
7932 tree receiver = TREE_PURPOSE (mess);
7933 tree sel_name;
7934 #ifdef OBJCPLUS
7935 tree args = TREE_PURPOSE (TREE_VALUE (mess));
7936 #else
7937 tree args = TREE_VALUE (mess);
7938 #endif
7939 tree method_params = NULL_TREE;
7941 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
7942 return error_mark_node;
7944 /* Obtain the full selector name. */
7945 switch (TREE_CODE (args))
7947 case IDENTIFIER_NODE:
7948 /* A unary selector. */
7949 sel_name = args;
7950 break;
7951 case TREE_LIST:
7952 sel_name = build_keyword_selector (args);
7953 break;
7954 default:
7955 gcc_unreachable ();
7958 /* Build the parameter list to give to the method. */
7959 if (TREE_CODE (args) == TREE_LIST)
7960 #ifdef OBJCPLUS
7961 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
7962 #else
7964 tree chain = args, prev = NULL_TREE;
7966 /* We have a keyword selector--check for comma expressions. */
7967 while (chain)
7969 tree element = TREE_VALUE (chain);
7971 /* We have a comma expression, must collapse... */
7972 if (TREE_CODE (element) == TREE_LIST)
7974 if (prev)
7975 TREE_CHAIN (prev) = element;
7976 else
7977 args = element;
7979 prev = chain;
7980 chain = TREE_CHAIN (chain);
7982 method_params = args;
7984 #endif
7986 #ifdef OBJCPLUS
7987 if (processing_template_decl)
7988 /* Must wait until template instantiation time. */
7989 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
7990 method_params);
7991 #endif
7993 return objc_finish_message_expr (receiver, sel_name, method_params);
7996 /* Look up method SEL_NAME that would be suitable for receiver
7997 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
7998 nonzero), and report on any duplicates. */
8000 static tree
8001 lookup_method_in_hash_lists (tree sel_name, int is_class)
8003 hash method_prototype = NULL;
8005 if (!is_class)
8006 method_prototype = hash_lookup (nst_method_hash_list,
8007 sel_name);
8009 if (!method_prototype)
8011 method_prototype = hash_lookup (cls_method_hash_list,
8012 sel_name);
8013 is_class = 1;
8016 return check_duplicates (method_prototype, 1, is_class);
8019 /* The 'objc_finish_message_expr' routine is called from within
8020 'objc_build_message_expr' for non-template functions. In the case of
8021 C++ template functions, it is called from 'build_expr_from_tree'
8022 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
8024 tree
8025 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
8027 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
8028 tree selector, retval, class_tree;
8029 int self, super, have_cast;
8031 /* We have used the receiver, so mark it as read. */
8032 mark_exp_read (receiver);
8034 /* Extract the receiver of the message, as well as its type
8035 (where the latter may take the form of a cast or be inferred
8036 from the implementation context). */
8037 rtype = receiver;
8038 while (TREE_CODE (rtype) == COMPOUND_EXPR
8039 || TREE_CODE (rtype) == MODIFY_EXPR
8040 || CONVERT_EXPR_P (rtype)
8041 || TREE_CODE (rtype) == COMPONENT_REF)
8042 rtype = TREE_OPERAND (rtype, 0);
8044 self = (rtype == self_decl);
8045 super = (rtype == UOBJC_SUPER_decl);
8046 rtype = TREE_TYPE (receiver);
8048 have_cast = (TREE_CODE (receiver) == NOP_EXPR
8049 || (TREE_CODE (receiver) == COMPOUND_EXPR
8050 && !IS_SUPER (rtype)));
8052 /* If we are calling [super dealloc], reset our warning flag. */
8053 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
8054 should_call_super_dealloc = 0;
8056 /* If the receiver is a class object, retrieve the corresponding
8057 @interface, if one exists. */
8058 class_tree = receiver_is_class_object (receiver, self, super);
8060 /* Now determine the receiver type (if an explicit cast has not been
8061 provided). */
8062 if (!have_cast)
8064 if (class_tree)
8065 rtype = lookup_interface (class_tree);
8066 /* Handle `self' and `super'. */
8067 else if (super)
8069 if (!CLASS_SUPER_NAME (implementation_template))
8071 error ("no super class declared in @interface for %qE",
8072 CLASS_NAME (implementation_template));
8073 return error_mark_node;
8075 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
8077 else if (self)
8078 rtype = lookup_interface (CLASS_NAME (implementation_template));
8081 /* If receiver is of type `id' or `Class' (or if the @interface for a
8082 class is not visible), we shall be satisfied with the existence of
8083 any instance or class method. */
8084 if (objc_is_id (rtype))
8086 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
8087 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
8088 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
8089 : NULL_TREE);
8090 rtype = NULL_TREE;
8092 if (rprotos)
8094 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
8095 in protocols themselves for the method prototype. */
8096 method_prototype
8097 = lookup_method_in_protocol_list (rprotos, sel_name,
8098 class_tree != NULL_TREE);
8100 /* If messaging 'Class <Proto>' but did not find a class method
8101 prototype, search for an instance method instead, and warn
8102 about having done so. */
8103 if (!method_prototype && !rtype && class_tree != NULL_TREE)
8105 method_prototype
8106 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
8108 if (method_prototype)
8109 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
8110 sel_name, sel_name);
8114 else if (rtype)
8116 tree orig_rtype = rtype;
8118 if (TREE_CODE (rtype) == POINTER_TYPE)
8119 rtype = TREE_TYPE (rtype);
8120 /* Traverse typedef aliases */
8121 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
8122 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
8123 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
8124 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
8125 if (TYPED_OBJECT (rtype))
8127 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
8128 rtype = TYPE_OBJC_INTERFACE (rtype);
8130 /* If we could not find an @interface declaration, we must have
8131 only seen a @class declaration; so, we cannot say anything
8132 more intelligent about which methods the receiver will
8133 understand. */
8134 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
8136 rtype = NULL_TREE;
8137 /* We could not find an @interface declaration, yet Message maybe in a
8138 @class's protocol. */
8139 if (!method_prototype && rprotos)
8140 method_prototype
8141 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
8143 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
8144 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
8146 /* We have a valid ObjC class name. Look up the method name
8147 in the published @interface for the class (and its
8148 superclasses). */
8149 method_prototype
8150 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
8152 /* If the method was not found in the @interface, it may still
8153 exist locally as part of the @implementation. */
8154 if (!method_prototype && objc_implementation_context
8155 && CLASS_NAME (objc_implementation_context)
8156 == OBJC_TYPE_NAME (rtype))
8157 method_prototype
8158 = lookup_method
8159 ((class_tree
8160 ? CLASS_CLS_METHODS (objc_implementation_context)
8161 : CLASS_NST_METHODS (objc_implementation_context)),
8162 sel_name);
8164 /* If we haven't found a candidate method by now, try looking for
8165 it in the protocol list. */
8166 if (!method_prototype && rprotos)
8167 method_prototype
8168 = lookup_method_in_protocol_list (rprotos, sel_name,
8169 class_tree != NULL_TREE);
8171 else
8173 warning (0, "invalid receiver type %qs",
8174 identifier_to_locale (gen_type_name (orig_rtype)));
8175 /* After issuing the "invalid receiver" warning, perform method
8176 lookup as if we were messaging 'id'. */
8177 rtype = rprotos = NULL_TREE;
8182 /* For 'id' or 'Class' receivers, search in the global hash table
8183 as a last resort. For all receivers, warn if protocol searches
8184 have failed. */
8185 if (!method_prototype)
8187 if (rprotos)
8188 warning (0, "%<%c%E%> not found in protocol(s)",
8189 (class_tree ? '+' : '-'),
8190 sel_name);
8192 if (!rtype)
8193 method_prototype
8194 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
8197 if (!method_prototype)
8199 static bool warn_missing_methods = false;
8201 if (rtype)
8202 warning (0, "%qE may not respond to %<%c%E%>",
8203 OBJC_TYPE_NAME (rtype),
8204 (class_tree ? '+' : '-'),
8205 sel_name);
8206 /* If we are messaging an 'id' or 'Class' object and made it here,
8207 then we have failed to find _any_ instance or class method,
8208 respectively. */
8209 else
8210 warning (0, "no %<%c%E%> method found",
8211 (class_tree ? '+' : '-'),
8212 sel_name);
8214 if (!warn_missing_methods)
8216 warning_at (input_location,
8217 0, "(Messages without a matching method signature");
8218 warning_at (input_location,
8219 0, "will be assumed to return %<id%> and accept");
8220 warning_at (input_location,
8221 0, "%<...%> as arguments.)");
8222 warn_missing_methods = true;
8225 else
8227 /* Warn if the method is deprecated, but not if the receiver is
8228 a generic 'id'. 'id' is used to cast an object to a generic
8229 object of an unspecified class; in that case, we'll use
8230 whatever method prototype we can find to get the method
8231 argument and return types, but it is not appropriate to
8232 produce deprecation warnings since we don't know the class
8233 that the object will be of at runtime. The @interface(s) for
8234 that class may not even be available to the compiler right
8235 now, and it is perfectly possible that the method is marked
8236 as non-deprecated in such @interface(s).
8238 In practice this makes sense since casting an object to 'id'
8239 is often used precisely to turn off warnings associated with
8240 the object being of a particular class. */
8241 if (TREE_DEPRECATED (method_prototype) && rtype != NULL_TREE)
8242 warn_deprecated_use (method_prototype, NULL_TREE);
8246 /* Save the selector name for printing error messages. */
8247 current_objc_message_selector = sel_name;
8249 /* Build the parameters list for looking up the method.
8250 These are the object itself and the selector. */
8252 if (flag_typed_selectors)
8253 selector = build_typed_selector_reference (input_location,
8254 sel_name, method_prototype);
8255 else
8256 selector = build_selector_reference (input_location, sel_name);
8258 retval = build_objc_method_call (input_location, super, method_prototype,
8259 receiver,
8260 selector, method_params);
8262 current_objc_message_selector = 0;
8264 return retval;
8267 /* Build a tree expression to send OBJECT the operation SELECTOR,
8268 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
8269 assuming the method has prototype METHOD_PROTOTYPE.
8270 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
8271 LOC is the location of the expression to build.
8272 Use METHOD_PARAMS as list of args to pass to the method.
8273 If SUPER_FLAG is nonzero, we look up the superclass's method. */
8275 static tree
8276 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
8277 tree lookup_object, tree selector,
8278 tree method_params)
8280 tree sender = (super_flag ? umsg_super_decl :
8281 (!flag_next_runtime || flag_nil_receivers
8282 ? (flag_objc_direct_dispatch
8283 ? umsg_fast_decl
8284 : umsg_decl)
8285 : umsg_nonnil_decl));
8286 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
8287 VEC(tree, gc) *parms = NULL;
8288 unsigned nparm = (method_params ? list_length (method_params) : 0);
8290 /* If a prototype for the method to be called exists, then cast
8291 the sender's return type and arguments to match that of the method.
8292 Otherwise, leave sender as is. */
8293 tree ret_type
8294 = (method_prototype
8295 ? TREE_VALUE (TREE_TYPE (method_prototype))
8296 : objc_object_type);
8298 tree method_param_types =
8299 get_arg_type_list (method_prototype, METHOD_REF, super_flag);
8300 tree ftype = build_function_type (ret_type, method_param_types);
8301 tree sender_cast;
8302 tree method, t;
8304 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
8305 ftype = build_type_attribute_variant (ftype,
8306 METHOD_TYPE_ATTRIBUTES
8307 (method_prototype));
8309 sender_cast = build_pointer_type (ftype);
8311 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
8313 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
8314 lookup_object = save_expr (lookup_object);
8316 /* Param list + 2 slots for object and selector. */
8317 parms = VEC_alloc (tree, gc, nparm + 2);
8319 if (flag_next_runtime)
8321 /* If we are returning a struct in memory, and the address
8322 of that memory location is passed as a hidden first
8323 argument, then change which messenger entry point this
8324 expr will call. NB: Note that sender_cast remains
8325 unchanged (it already has a struct return type). */
8326 if (!targetm.calls.struct_value_rtx (0, 0)
8327 && (TREE_CODE (ret_type) == RECORD_TYPE
8328 || TREE_CODE (ret_type) == UNION_TYPE)
8329 && targetm.calls.return_in_memory (ret_type, 0))
8330 sender = (super_flag ? umsg_super_stret_decl :
8331 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
8333 method = build_fold_addr_expr_loc (input_location, sender);
8334 /* Pass the object to the method. */
8335 VEC_quick_push (tree, parms, lookup_object);
8337 else
8339 /* This is the portable (GNU) way. */
8340 /* First, call the lookup function to get a pointer to the method,
8341 then cast the pointer, then call it with the method arguments. */
8342 VEC(tree, gc) *tv = VEC_alloc (tree, gc, 2);
8343 VEC_quick_push (tree, tv, lookup_object);
8344 VEC_quick_push (tree, tv, selector);
8345 method = build_function_call_vec (loc, sender, tv, NULL);
8346 VEC_free (tree, gc, tv);
8348 /* Pass the appropriate object to the method. */
8349 VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
8352 /* Pass the selector to the method. */
8353 VEC_quick_push (tree, parms, selector);
8354 /* Now append the remainder of the parms. */
8355 if (nparm)
8356 for (; method_params; method_params = TREE_CHAIN (method_params))
8357 VEC_quick_push (tree, parms, TREE_VALUE (method_params));
8359 /* Build an obj_type_ref, with the correct cast for the method call. */
8360 t = build3 (OBJ_TYPE_REF, sender_cast, method,
8361 lookup_object, size_zero_node);
8362 t = build_function_call_vec (loc, t, parms, NULL);\
8363 VEC_free (tree, gc, parms);
8364 return t;
8367 static void
8368 build_protocol_reference (tree p)
8370 tree decl;
8371 const char *proto_name;
8373 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
8375 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
8376 decl = start_var_decl (objc_protocol_template, proto_name);
8378 PROTOCOL_FORWARD_DECL (p) = decl;
8381 /* This function is called by the parser when (and only when) a
8382 @protocol() expression is found, in order to compile it. */
8383 tree
8384 objc_build_protocol_expr (tree protoname)
8386 tree expr;
8387 tree p = lookup_protocol (protoname, /* warn if deprecated */ true);
8389 if (!p)
8391 error ("cannot find protocol declaration for %qE",
8392 protoname);
8393 return error_mark_node;
8396 if (!PROTOCOL_FORWARD_DECL (p))
8397 build_protocol_reference (p);
8399 expr = build_unary_op (input_location,
8400 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
8402 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
8403 if we have it, rather than converting it here. */
8404 expr = convert (objc_protocol_type, expr);
8406 /* The @protocol() expression is being compiled into a pointer to a
8407 statically allocated instance of the Protocol class. To become
8408 usable at runtime, the 'isa' pointer of the instance need to be
8409 fixed up at runtime by the runtime library, to point to the
8410 actual 'Protocol' class. */
8412 /* For the GNU runtime, put the static Protocol instance in the list
8413 of statically allocated instances, so that we make sure that its
8414 'isa' pointer is fixed up at runtime by the GNU runtime library
8415 to point to the Protocol class (at runtime, when loading the
8416 module, the GNU runtime library loops on the statically allocated
8417 instances (as found in the defs field in objc_symtab) and fixups
8418 all the 'isa' pointers of those objects). */
8419 if (! flag_next_runtime)
8421 /* This type is a struct containing the fields of a Protocol
8422 object. (Cfr. objc_protocol_type instead is the type of a pointer
8423 to such a struct). */
8424 tree protocol_struct_type = xref_tag
8425 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
8426 tree *chain;
8428 /* Look for the list of Protocol statically allocated instances
8429 to fixup at runtime. Create a new list to hold Protocol
8430 statically allocated instances, if the list is not found. At
8431 present there is only another list, holding NSConstantString
8432 static instances to be fixed up at runtime. */
8433 for (chain = &objc_static_instances;
8434 *chain && TREE_VALUE (*chain) != protocol_struct_type;
8435 chain = &TREE_CHAIN (*chain));
8436 if (!*chain)
8438 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
8439 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
8440 class_names);
8443 /* Add this statically allocated instance to the Protocol list. */
8444 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
8445 PROTOCOL_FORWARD_DECL (p),
8446 TREE_PURPOSE (*chain));
8450 return expr;
8453 /* This function is called by the parser when a @selector() expression
8454 is found, in order to compile it. It is only called by the parser
8455 and only to compile a @selector(). LOC is the location of the
8456 @selector. */
8457 tree
8458 objc_build_selector_expr (location_t loc, tree selnamelist)
8460 tree selname;
8462 /* Obtain the full selector name. */
8463 switch (TREE_CODE (selnamelist))
8465 case IDENTIFIER_NODE:
8466 /* A unary selector. */
8467 selname = selnamelist;
8468 break;
8469 case TREE_LIST:
8470 selname = build_keyword_selector (selnamelist);
8471 break;
8472 default:
8473 gcc_unreachable ();
8476 /* If we are required to check @selector() expressions as they
8477 are found, check that the selector has been declared. */
8478 if (warn_undeclared_selector)
8480 /* Look the selector up in the list of all known class and
8481 instance methods (up to this line) to check that the selector
8482 exists. */
8483 hash hsh;
8485 /* First try with instance methods. */
8486 hsh = hash_lookup (nst_method_hash_list, selname);
8488 /* If not found, try with class methods. */
8489 if (!hsh)
8491 hsh = hash_lookup (cls_method_hash_list, selname);
8494 /* If still not found, print out a warning. */
8495 if (!hsh)
8497 warning (0, "undeclared selector %qE", selname);
8502 if (flag_typed_selectors)
8503 return build_typed_selector_reference (loc, selname, 0);
8504 else
8505 return build_selector_reference (loc, selname);
8508 /* This is used to implement @encode(). See gcc/doc/objc.texi,
8509 section '@encode'. */
8510 tree
8511 objc_build_encode_expr (tree type)
8513 tree result;
8514 const char *string;
8516 encode_type (type, obstack_object_size (&util_obstack),
8517 OBJC_ENCODE_INLINE_DEFS);
8518 obstack_1grow (&util_obstack, 0); /* null terminate string */
8519 string = XOBFINISH (&util_obstack, const char *);
8521 /* Synthesize a string that represents the encoded struct/union. */
8522 result = my_build_string (strlen (string) + 1, string);
8523 obstack_free (&util_obstack, util_firstobj);
8524 return result;
8527 static tree
8528 build_ivar_reference (tree id)
8530 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8532 /* Historically, a class method that produced objects (factory
8533 method) would assign `self' to the instance that it
8534 allocated. This would effectively turn the class method into
8535 an instance method. Following this assignment, the instance
8536 variables could be accessed. That practice, while safe,
8537 violates the simple rule that a class method should not refer
8538 to an instance variable. It's better to catch the cases
8539 where this is done unknowingly than to support the above
8540 paradigm. */
8541 warning (0, "instance variable %qE accessed in class method",
8542 id);
8543 self_decl = convert (objc_instance_type, self_decl); /* cast */
8546 return objc_build_component_ref (build_indirect_ref (input_location,
8547 self_decl, RO_ARROW),
8548 id);
8551 /* Compute a hash value for a given method SEL_NAME. */
8553 static size_t
8554 hash_func (tree sel_name)
8556 const unsigned char *s
8557 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
8558 size_t h = 0;
8560 while (*s)
8561 h = h * 67 + *s++ - 113;
8562 return h;
8565 static void
8566 hash_init (void)
8568 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8569 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8571 cls_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8572 als_name_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
8574 /* Initialize the hash table used to hold the constant string objects. */
8575 string_htab = htab_create_ggc (31, string_hash,
8576 string_eq, NULL);
8579 /* This routine adds sel_name to the hash list. sel_name is a class or alias
8580 name for the class. If alias name, then value is its underlying class.
8581 If class, the value is NULL_TREE. */
8583 static void
8584 hash_class_name_enter (hash *hashlist, tree sel_name, tree value)
8586 hash obj;
8587 int slot = hash_func (sel_name) % SIZEHASHTABLE;
8589 obj = ggc_alloc_hashed_entry ();
8590 if (value != NULL_TREE)
8592 /* Save the underlying class for the 'alias' in the hash table */
8593 attr obj_attr = ggc_alloc_hashed_attribute ();
8594 obj_attr->value = value;
8595 obj->list = obj_attr;
8597 else
8598 obj->list = 0;
8599 obj->next = hashlist[slot];
8600 obj->key = sel_name;
8602 hashlist[slot] = obj; /* append to front */
8607 Searches in the hash table looking for a match for class or alias name.
8610 static hash
8611 hash_class_name_lookup (hash *hashlist, tree sel_name)
8613 hash target;
8615 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8617 while (target)
8619 if (sel_name == target->key)
8620 return target;
8622 target = target->next;
8624 return 0;
8627 /* WARNING!!!! hash_enter is called with a method, and will peek
8628 inside to find its selector! But hash_lookup is given a selector
8629 directly, and looks for the selector that's inside the found
8630 entry's key (method) for comparison. */
8632 static void
8633 hash_enter (hash *hashlist, tree method)
8635 hash obj;
8636 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
8638 obj = ggc_alloc_hashed_entry ();
8639 obj->list = 0;
8640 obj->next = hashlist[slot];
8641 obj->key = method;
8643 hashlist[slot] = obj; /* append to front */
8646 static hash
8647 hash_lookup (hash *hashlist, tree sel_name)
8649 hash target;
8651 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
8653 while (target)
8655 if (sel_name == METHOD_SEL_NAME (target->key))
8656 return target;
8658 target = target->next;
8660 return 0;
8663 static void
8664 hash_add_attr (hash entry, tree value)
8666 attr obj;
8668 obj = ggc_alloc_hashed_attribute ();
8669 obj->next = entry->list;
8670 obj->value = value;
8672 entry->list = obj; /* append to front */
8675 static tree
8676 lookup_method (tree mchain, tree method)
8678 tree key;
8680 if (TREE_CODE (method) == IDENTIFIER_NODE)
8681 key = method;
8682 else
8683 key = METHOD_SEL_NAME (method);
8685 while (mchain)
8687 if (METHOD_SEL_NAME (mchain) == key)
8688 return mchain;
8690 mchain = DECL_CHAIN (mchain);
8692 return NULL_TREE;
8695 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance
8696 method in INTERFACE, along with any categories and protocols
8697 attached thereto. If method is not found, and the
8698 OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS, recursively examine the
8699 INTERFACE's superclass. If OBJC_LOOKUP_CLASS is set,
8700 OBJC_LOOKUP_NO_SUPER is clear, and no suitable class method could
8701 be found in INTERFACE or any of its superclasses, look for an
8702 _instance_ method of the same name in the root class as a last
8703 resort. This behaviour can be turned off by using
8704 OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS.
8706 If a suitable method cannot be found, return NULL_TREE. */
8708 static tree
8709 lookup_method_static (tree interface, tree ident, int flags)
8711 tree meth = NULL_TREE, root_inter = NULL_TREE;
8712 tree inter = interface;
8713 int is_class = (flags & OBJC_LOOKUP_CLASS);
8714 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
8715 int no_instance_methods_of_root_class = (flags & OBJC_LOOKUP_NO_INSTANCE_METHODS_OF_ROOT_CLASS);
8717 while (inter)
8719 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
8720 tree category = inter;
8722 /* First, look up the method in the class itself. */
8723 if ((meth = lookup_method (chain, ident)))
8724 return meth;
8726 /* Failing that, look for the method in each category of the class. */
8727 while ((category = CLASS_CATEGORY_LIST (category)))
8729 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
8731 /* Check directly in each category. */
8732 if ((meth = lookup_method (chain, ident)))
8733 return meth;
8735 /* Failing that, check in each category's protocols. */
8736 if (CLASS_PROTOCOL_LIST (category))
8738 if ((meth = (lookup_method_in_protocol_list
8739 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
8740 return meth;
8744 /* If not found in categories, check in protocols of the main class. */
8745 if (CLASS_PROTOCOL_LIST (inter))
8747 if ((meth = (lookup_method_in_protocol_list
8748 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
8749 return meth;
8752 /* If we were instructed not to look in superclasses, don't. */
8753 if (no_superclasses)
8754 return NULL_TREE;
8756 /* Failing that, climb up the inheritance hierarchy. */
8757 root_inter = inter;
8758 inter = lookup_interface (CLASS_SUPER_NAME (inter));
8760 while (inter);
8762 if (is_class && !no_instance_methods_of_root_class)
8764 /* If no class (factory) method was found, check if an _instance_
8765 method of the same name exists in the root class. This is what
8766 the Objective-C runtime will do. */
8767 return lookup_method_static (root_inter, ident, 0);
8769 else
8771 /* If an instance method was not found, return 0. */
8772 return NULL_TREE;
8776 /* Add the method to the hash list if it doesn't contain an identical
8777 method already. */
8779 static void
8780 add_method_to_hash_list (hash *hash_list, tree method)
8782 hash hsh;
8784 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
8786 /* Install on a global chain. */
8787 hash_enter (hash_list, method);
8789 else
8791 /* Check types against those; if different, add to a list. */
8792 attr loop;
8793 int already_there = comp_proto_with_proto (method, hsh->key, 1);
8794 for (loop = hsh->list; !already_there && loop; loop = loop->next)
8795 already_there |= comp_proto_with_proto (method, loop->value, 1);
8796 if (!already_there)
8797 hash_add_attr (hsh, method);
8801 static tree
8802 objc_add_method (tree klass, tree method, int is_class, bool is_optional)
8804 tree mth;
8806 /* @optional methods are added to protocol's OPTIONAL list. Note
8807 that this disables checking that the methods are implemented by
8808 classes implementing the protocol, since these checks only use
8809 the CLASS_CLS_METHODS and CLASS_NST_METHODS. */
8810 if (is_optional)
8812 gcc_assert (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE);
8813 if (!(mth = lookup_method (is_class
8814 ? PROTOCOL_OPTIONAL_CLS_METHODS (klass)
8815 : PROTOCOL_OPTIONAL_NST_METHODS (klass),
8816 method)))
8818 if (is_class)
8820 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_CLS_METHODS (klass);
8821 PROTOCOL_OPTIONAL_CLS_METHODS (klass) = method;
8823 else
8825 TREE_CHAIN (method) = PROTOCOL_OPTIONAL_NST_METHODS (klass);
8826 PROTOCOL_OPTIONAL_NST_METHODS (klass) = method;
8830 else if (!(mth = lookup_method (is_class
8831 ? CLASS_CLS_METHODS (klass)
8832 : CLASS_NST_METHODS (klass), method)))
8834 /* put method on list in reverse order */
8835 if (is_class)
8837 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
8838 CLASS_CLS_METHODS (klass) = method;
8840 else
8842 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
8843 CLASS_NST_METHODS (klass) = method;
8846 else
8848 /* When processing an @interface for a class or category, give hard
8849 errors on methods with identical selectors but differing argument
8850 and/or return types. We do not do this for @implementations, because
8851 C/C++ will do it for us (i.e., there will be duplicate function
8852 definition errors). */
8853 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
8854 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
8855 && !comp_proto_with_proto (method, mth, 1))
8856 error ("duplicate declaration of method %<%c%E%>",
8857 is_class ? '+' : '-',
8858 METHOD_SEL_NAME (mth));
8861 if (is_class)
8862 add_method_to_hash_list (cls_method_hash_list, method);
8863 else
8865 add_method_to_hash_list (nst_method_hash_list, method);
8867 /* Instance methods in root classes (and categories thereof)
8868 may act as class methods as a last resort. We also add
8869 instance methods listed in @protocol declarations to
8870 the class hash table, on the assumption that @protocols
8871 may be adopted by root classes or categories. */
8872 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
8873 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
8874 klass = lookup_interface (CLASS_NAME (klass));
8876 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
8877 || !CLASS_SUPER_NAME (klass))
8878 add_method_to_hash_list (cls_method_hash_list, method);
8881 return method;
8884 static tree
8885 add_class (tree class_name, tree name)
8887 struct interface_tuple **slot;
8889 /* Put interfaces on list in reverse order. */
8890 TREE_CHAIN (class_name) = interface_chain;
8891 interface_chain = class_name;
8893 if (interface_htab == NULL)
8894 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
8895 slot = (struct interface_tuple **)
8896 htab_find_slot_with_hash (interface_htab, name,
8897 IDENTIFIER_HASH_VALUE (name),
8898 INSERT);
8899 if (!*slot)
8901 *slot = ggc_alloc_cleared_interface_tuple ();
8902 (*slot)->id = name;
8904 (*slot)->class_name = class_name;
8906 return interface_chain;
8909 static void
8910 add_category (tree klass, tree category)
8912 /* Put categories on list in reverse order. */
8913 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
8915 if (cat)
8917 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
8918 CLASS_NAME (klass),
8919 CLASS_SUPER_NAME (category));
8921 else
8923 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
8924 CLASS_CATEGORY_LIST (klass) = category;
8928 /* Called after parsing each instance variable declaration. Necessary to
8929 preserve typedefs and implement public/private...
8931 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
8933 static tree
8934 add_instance_variable (tree klass, objc_ivar_visibility_kind visibility,
8935 tree field_decl)
8937 tree field_type = TREE_TYPE (field_decl);
8938 const char *ivar_name = DECL_NAME (field_decl)
8939 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
8940 : _("<unnamed>");
8942 #ifdef OBJCPLUS
8943 if (TREE_CODE (field_type) == REFERENCE_TYPE)
8945 error ("illegal reference type specified for instance variable %qs",
8946 ivar_name);
8947 /* Return class as is without adding this ivar. */
8948 return klass;
8950 #endif
8952 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
8953 || TYPE_SIZE (field_type) == error_mark_node)
8954 /* 'type[0]' is allowed, but 'type[]' is not! */
8956 error ("instance variable %qs has unknown size", ivar_name);
8957 /* Return class as is without adding this ivar. */
8958 return klass;
8961 #ifdef OBJCPLUS
8962 /* Check if the ivar being added has a non-POD C++ type. If so, we will
8963 need to either (1) warn the user about it or (2) generate suitable
8964 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
8965 methods (if '-fobjc-call-cxx-cdtors' was specified). */
8966 if (MAYBE_CLASS_TYPE_P (field_type)
8967 && (TYPE_NEEDS_CONSTRUCTING (field_type)
8968 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
8969 || TYPE_POLYMORPHIC_P (field_type)))
8971 tree type_name = OBJC_TYPE_NAME (field_type);
8973 if (flag_objc_call_cxx_cdtors)
8975 /* Since the ObjC runtime will be calling the constructors and
8976 destructors for us, the only thing we can't handle is the lack
8977 of a default constructor. */
8978 if (TYPE_NEEDS_CONSTRUCTING (field_type)
8979 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
8981 warning (0, "type %qE has no default constructor to call",
8982 type_name);
8984 /* If we cannot call a constructor, we should also avoid
8985 calling the destructor, for symmetry. */
8986 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
8987 warning (0, "destructor for %qE shall not be run either",
8988 type_name);
8991 else
8993 static bool warn_cxx_ivars = false;
8995 if (TYPE_POLYMORPHIC_P (field_type))
8997 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
8998 initialize them. */
8999 error ("type %qE has virtual member functions", type_name);
9000 error ("illegal aggregate type %qE specified "
9001 "for instance variable %qs",
9002 type_name, ivar_name);
9003 /* Return class as is without adding this ivar. */
9004 return klass;
9007 /* User-defined constructors and destructors are not known to Obj-C
9008 and hence will not be called. This may or may not be a problem. */
9009 if (TYPE_NEEDS_CONSTRUCTING (field_type))
9010 warning (0, "type %qE has a user-defined constructor", type_name);
9011 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
9012 warning (0, "type %qE has a user-defined destructor", type_name);
9014 if (!warn_cxx_ivars)
9016 warning (0, "C++ constructors and destructors will not "
9017 "be invoked for Objective-C fields");
9018 warn_cxx_ivars = true;
9022 #endif
9024 /* Overload the public attribute, it is not used for FIELD_DECLs. */
9025 switch (visibility)
9027 case OBJC_IVAR_VIS_PROTECTED:
9028 TREE_PUBLIC (field_decl) = 0;
9029 TREE_PRIVATE (field_decl) = 0;
9030 TREE_PROTECTED (field_decl) = 1;
9031 break;
9033 case OBJC_IVAR_VIS_PACKAGE:
9034 /* TODO: Implement the package variant. */
9035 case OBJC_IVAR_VIS_PUBLIC:
9036 TREE_PUBLIC (field_decl) = 1;
9037 TREE_PRIVATE (field_decl) = 0;
9038 TREE_PROTECTED (field_decl) = 0;
9039 break;
9041 case OBJC_IVAR_VIS_PRIVATE:
9042 TREE_PUBLIC (field_decl) = 0;
9043 TREE_PRIVATE (field_decl) = 1;
9044 TREE_PROTECTED (field_decl) = 0;
9045 break;
9049 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
9051 return klass;
9055 static tree
9056 is_ivar (tree decl_chain, tree ident)
9058 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
9059 if (DECL_NAME (decl_chain) == ident)
9060 return decl_chain;
9061 return NULL_TREE;
9064 /* True if the ivar is private and we are not in its implementation. */
9066 static int
9067 is_private (tree decl)
9069 return (TREE_PRIVATE (decl)
9070 && ! is_ivar (CLASS_IVARS (implementation_template),
9071 DECL_NAME (decl)));
9074 /* We have an instance variable reference;, check to see if it is public. */
9077 objc_is_public (tree expr, tree identifier)
9079 tree basetype, decl;
9081 #ifdef OBJCPLUS
9082 if (processing_template_decl)
9083 return 1;
9084 #endif
9086 if (TREE_TYPE (expr) == error_mark_node)
9087 return 1;
9089 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
9091 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
9093 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
9095 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
9097 if (!klass)
9099 error ("cannot find interface declaration for %qE",
9100 OBJC_TYPE_NAME (basetype));
9101 return 0;
9104 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
9106 if (TREE_PUBLIC (decl))
9107 return 1;
9109 /* Important difference between the Stepstone translator:
9110 all instance variables should be public within the context
9111 of the implementation. */
9112 if (objc_implementation_context
9113 && ((TREE_CODE (objc_implementation_context)
9114 == CLASS_IMPLEMENTATION_TYPE)
9115 || (TREE_CODE (objc_implementation_context)
9116 == CATEGORY_IMPLEMENTATION_TYPE)))
9118 tree curtype = TYPE_MAIN_VARIANT
9119 (CLASS_STATIC_TEMPLATE
9120 (implementation_template));
9122 if (basetype == curtype
9123 || DERIVED_FROM_P (basetype, curtype))
9125 int priv = is_private (decl);
9127 if (priv)
9128 error ("instance variable %qE is declared private",
9129 DECL_NAME (decl));
9131 return !priv;
9135 /* The 2.95.2 compiler sometimes allowed C functions to access
9136 non-@public ivars. We will let this slide for now... */
9137 if (!objc_method_context)
9139 warning (0, "instance variable %qE is %s; "
9140 "this will be a hard error in the future",
9141 identifier,
9142 TREE_PRIVATE (decl) ? "@private" : "@protected");
9143 return 1;
9146 error ("instance variable %qE is declared %s",
9147 identifier,
9148 TREE_PRIVATE (decl) ? "private" : "protected");
9149 return 0;
9154 return 1;
9157 /* Make sure all methods in CHAIN (a list of method declarations from
9158 an @interface or a @protocol) are in IMPLEMENTATION (the
9159 implementation context). This is used to check for example that
9160 all methods declared in an @interface were implemented in an
9161 @implementation.
9163 Some special methods (property setters/getters) are special and if
9164 they are not found in IMPLEMENTATION, we look them up in its
9165 superclasses. */
9167 static int
9168 check_methods (tree chain, tree implementation, int mtype)
9170 int first = 1;
9171 tree list;
9173 if (mtype == (int)'+')
9174 list = CLASS_CLS_METHODS (implementation);
9175 else
9176 list = CLASS_NST_METHODS (implementation);
9178 while (chain)
9180 /* If the method is associated with a dynamic property, then it
9181 is Ok not to have the method implementation, as it will be
9182 generated dynamically at runtime. To decide if the method is
9183 associated with a @dynamic property, we search the list of
9184 @synthesize and @dynamic for this implementation, and look
9185 for any @dynamic property with the same setter or getter name
9186 as this method. */
9187 tree x;
9188 for (x = IMPL_PROPERTY_DECL (implementation); x; x = TREE_CHAIN (x))
9189 if (PROPERTY_DYNAMIC (x)
9190 && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
9191 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
9192 break;
9194 if (x != NULL_TREE)
9196 chain = TREE_CHAIN (chain); /* next method... */
9197 continue;
9200 if (!lookup_method (list, chain))
9202 /* If the method is a property setter/getter, we'll still
9203 allow it to be missing if it is implemented by
9204 'interface' or any of its superclasses. */
9205 tree property = METHOD_PROPERTY_CONTEXT (chain);
9206 if (property)
9208 /* Note that since this is a property getter/setter, it
9209 is obviously an instance method. */
9210 tree interface = NULL_TREE;
9212 /* For a category, first check the main class
9213 @interface. */
9214 if (TREE_CODE (implementation) == CATEGORY_IMPLEMENTATION_TYPE)
9216 interface = lookup_interface (CLASS_NAME (implementation));
9218 /* If the method is found in the main class, it's Ok. */
9219 if (lookup_method (CLASS_NST_METHODS (interface), chain))
9221 chain = DECL_CHAIN (chain);
9222 continue;
9225 /* Else, get the superclass. */
9226 if (CLASS_SUPER_NAME (interface))
9227 interface = lookup_interface (CLASS_SUPER_NAME (interface));
9228 else
9229 interface = NULL_TREE;
9232 /* Get the superclass for classes. */
9233 if (TREE_CODE (implementation) == CLASS_IMPLEMENTATION_TYPE)
9235 if (CLASS_SUPER_NAME (implementation))
9236 interface = lookup_interface (CLASS_SUPER_NAME (implementation));
9237 else
9238 interface = NULL_TREE;
9241 /* Now, interface is the superclass, if any; go check it. */
9242 if (interface)
9244 if (lookup_method_static (interface, chain, 0))
9246 chain = DECL_CHAIN (chain);
9247 continue;
9250 /* Else, fall through - warn. */
9252 if (first)
9254 switch (TREE_CODE (implementation))
9256 case CLASS_IMPLEMENTATION_TYPE:
9257 warning (0, "incomplete implementation of class %qE",
9258 CLASS_NAME (implementation));
9259 break;
9260 case CATEGORY_IMPLEMENTATION_TYPE:
9261 warning (0, "incomplete implementation of category %qE",
9262 CLASS_SUPER_NAME (implementation));
9263 break;
9264 default:
9265 gcc_unreachable ();
9267 first = 0;
9270 warning (0, "method definition for %<%c%E%> not found",
9271 mtype, METHOD_SEL_NAME (chain));
9274 chain = DECL_CHAIN (chain);
9277 return first;
9280 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
9282 static int
9283 conforms_to_protocol (tree klass, tree protocol)
9285 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
9287 tree p = CLASS_PROTOCOL_LIST (klass);
9288 while (p && TREE_VALUE (p) != protocol)
9289 p = TREE_CHAIN (p);
9291 if (!p)
9293 tree super = (CLASS_SUPER_NAME (klass)
9294 ? lookup_interface (CLASS_SUPER_NAME (klass))
9295 : NULL_TREE);
9296 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
9297 if (!tmp)
9298 return 0;
9302 return 1;
9305 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
9306 CONTEXT. This is one of two mechanisms to check protocol integrity. */
9308 static int
9309 check_methods_accessible (tree chain, tree context, int mtype)
9311 int first = 1;
9312 tree list;
9313 tree base_context = context;
9315 while (chain)
9317 /* If the method is associated with a dynamic property, then it
9318 is Ok not to have the method implementation, as it will be
9319 generated dynamically at runtime. Search for any @dynamic
9320 property with the same setter or getter name as this
9321 method. TODO: Use a hashtable lookup. */
9322 tree x;
9323 for (x = IMPL_PROPERTY_DECL (base_context); x; x = TREE_CHAIN (x))
9324 if (PROPERTY_DYNAMIC (x)
9325 && (PROPERTY_GETTER_NAME (x) == METHOD_SEL_NAME (chain)
9326 || PROPERTY_SETTER_NAME (x) == METHOD_SEL_NAME (chain)))
9327 break;
9329 if (x != NULL_TREE)
9331 chain = TREE_CHAIN (chain); /* next method... */
9332 continue;
9335 context = base_context;
9336 while (context)
9338 if (mtype == '+')
9339 list = CLASS_CLS_METHODS (context);
9340 else
9341 list = CLASS_NST_METHODS (context);
9343 if (lookup_method (list, chain))
9344 break;
9346 switch (TREE_CODE (context))
9348 case CLASS_IMPLEMENTATION_TYPE:
9349 case CLASS_INTERFACE_TYPE:
9350 context = (CLASS_SUPER_NAME (context)
9351 ? lookup_interface (CLASS_SUPER_NAME (context))
9352 : NULL_TREE);
9353 break;
9354 case CATEGORY_IMPLEMENTATION_TYPE:
9355 case CATEGORY_INTERFACE_TYPE:
9356 context = (CLASS_NAME (context)
9357 ? lookup_interface (CLASS_NAME (context))
9358 : NULL_TREE);
9359 break;
9360 default:
9361 gcc_unreachable ();
9365 if (context == NULL_TREE)
9367 if (first)
9369 switch (TREE_CODE (objc_implementation_context))
9371 case CLASS_IMPLEMENTATION_TYPE:
9372 warning (0, "incomplete implementation of class %qE",
9373 CLASS_NAME (objc_implementation_context));
9374 break;
9375 case CATEGORY_IMPLEMENTATION_TYPE:
9376 warning (0, "incomplete implementation of category %qE",
9377 CLASS_SUPER_NAME (objc_implementation_context));
9378 break;
9379 default:
9380 gcc_unreachable ();
9382 first = 0;
9384 warning (0, "method definition for %<%c%E%> not found",
9385 mtype, METHOD_SEL_NAME (chain));
9388 chain = TREE_CHAIN (chain); /* next method... */
9390 return first;
9393 /* Check whether the current interface (accessible via
9394 'objc_implementation_context') actually implements protocol P, along
9395 with any protocols that P inherits. */
9397 static void
9398 check_protocol (tree p, const char *type, tree name)
9400 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
9402 int f1, f2;
9404 /* Ensure that all protocols have bodies! */
9405 if (warn_protocol)
9407 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
9408 objc_implementation_context,
9409 '+');
9410 f2 = check_methods (PROTOCOL_NST_METHODS (p),
9411 objc_implementation_context,
9412 '-');
9414 else
9416 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
9417 objc_implementation_context,
9418 '+');
9419 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
9420 objc_implementation_context,
9421 '-');
9424 if (!f1 || !f2)
9425 warning (0, "%s %qE does not fully implement the %qE protocol",
9426 type, name, PROTOCOL_NAME (p));
9429 /* Check protocols recursively. */
9430 if (PROTOCOL_LIST (p))
9432 tree subs = PROTOCOL_LIST (p);
9433 tree super_class =
9434 lookup_interface (CLASS_SUPER_NAME (implementation_template));
9436 while (subs)
9438 tree sub = TREE_VALUE (subs);
9440 /* If the superclass does not conform to the protocols
9441 inherited by P, then we must! */
9442 if (!super_class || !conforms_to_protocol (super_class, sub))
9443 check_protocol (sub, type, name);
9444 subs = TREE_CHAIN (subs);
9449 /* Check whether the current interface (accessible via
9450 'objc_implementation_context') actually implements the protocols listed
9451 in PROTO_LIST. */
9453 static void
9454 check_protocols (tree proto_list, const char *type, tree name)
9456 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
9458 tree p = TREE_VALUE (proto_list);
9460 check_protocol (p, type, name);
9464 /* Make sure that the class CLASS_NAME is defined CODE says which kind
9465 of thing CLASS_NAME ought to be. It can be CLASS_INTERFACE_TYPE,
9466 CLASS_IMPLEMENTATION_TYPE, CATEGORY_INTERFACE_TYPE, or
9467 CATEGORY_IMPLEMENTATION_TYPE. For a CATEGORY_INTERFACE_TYPE,
9468 SUPER_NAME is the name of the category. For a class extension,
9469 CODE is CATEGORY_INTERFACE_TYPE and SUPER_NAME is NULL_TREE. */
9470 static tree
9471 start_class (enum tree_code code, tree class_name, tree super_name,
9472 tree protocol_list, tree attributes)
9474 tree klass = NULL_TREE;
9475 tree decl;
9477 #ifdef OBJCPLUS
9478 if (current_namespace != global_namespace)
9480 error ("Objective-C declarations may only appear in global scope");
9482 #endif /* OBJCPLUS */
9484 if (objc_implementation_context)
9486 warning (0, "%<@end%> missing in implementation context");
9487 finish_class (objc_implementation_context);
9488 objc_ivar_chain = NULL_TREE;
9489 objc_implementation_context = NULL_TREE;
9492 /* If this is a class extension, we'll be "reopening" the existing
9493 CLASS_INTERFACE_TYPE, so in that case there is no need to create
9494 a new node. */
9495 if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
9497 klass = make_node (code);
9498 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
9501 /* Check for existence of the super class, if one was specified. Note
9502 that we must have seen an @interface, not just a @class. If we
9503 are looking at a @compatibility_alias, traverse it first. */
9504 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
9505 && super_name)
9507 tree super = objc_is_class_name (super_name);
9508 tree super_interface = NULL_TREE;
9510 if (super)
9511 super_interface = lookup_interface (super);
9513 if (!super_interface)
9515 error ("cannot find interface declaration for %qE, superclass of %qE",
9516 super ? super : super_name,
9517 class_name);
9518 super_name = NULL_TREE;
9520 else
9522 if (TREE_DEPRECATED (super_interface))
9523 warning (OPT_Wdeprecated_declarations, "class %qE is deprecated",
9524 super);
9525 super_name = super;
9529 if (code != CATEGORY_INTERFACE_TYPE || super_name != NULL_TREE)
9531 CLASS_NAME (klass) = class_name;
9532 CLASS_SUPER_NAME (klass) = super_name;
9533 CLASS_CLS_METHODS (klass) = NULL_TREE;
9536 if (! objc_is_class_name (class_name)
9537 && (decl = lookup_name (class_name)))
9539 error ("%qE redeclared as different kind of symbol",
9540 class_name);
9541 error ("previous declaration of %q+D",
9542 decl);
9545 switch (code)
9547 case CLASS_IMPLEMENTATION_TYPE:
9549 tree chain;
9551 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
9552 if (TREE_VALUE (chain) == class_name)
9554 error ("reimplementation of class %qE",
9555 class_name);
9556 /* TODO: error message saying where it was previously
9557 implemented. */
9558 break;
9560 if (chain == NULL_TREE)
9561 implemented_classes = tree_cons (NULL_TREE, class_name,
9562 implemented_classes);
9565 /* Reset for multiple classes per file. */
9566 method_slot = 0;
9568 objc_implementation_context = klass;
9570 /* Lookup the interface for this implementation. */
9572 if (!(implementation_template = lookup_interface (class_name)))
9574 warning (0, "cannot find interface declaration for %qE",
9575 class_name);
9576 add_class (implementation_template = objc_implementation_context,
9577 class_name);
9580 /* If a super class has been specified in the implementation,
9581 insure it conforms to the one specified in the interface. */
9583 if (super_name
9584 && (super_name != CLASS_SUPER_NAME (implementation_template)))
9586 tree previous_name = CLASS_SUPER_NAME (implementation_template);
9587 error ("conflicting super class name %qE",
9588 super_name);
9589 if (previous_name)
9590 error ("previous declaration of %qE", previous_name);
9591 else
9592 error ("previous declaration");
9595 else if (! super_name)
9597 CLASS_SUPER_NAME (objc_implementation_context)
9598 = CLASS_SUPER_NAME (implementation_template);
9600 break;
9602 case CLASS_INTERFACE_TYPE:
9603 if (lookup_interface (class_name))
9604 #ifdef OBJCPLUS
9605 error ("duplicate interface declaration for class %qE", class_name);
9606 #else
9607 warning (0, "duplicate interface declaration for class %qE", class_name);
9608 #endif
9609 else
9610 add_class (klass, class_name);
9612 if (protocol_list)
9613 CLASS_PROTOCOL_LIST (klass)
9614 = lookup_and_install_protocols (protocol_list);
9616 /* Determine if 'deprecated', the only attribute we recognize
9617 for classes, was used. Ignore all other attributes for now,
9618 but store them in the klass. */
9619 if (attributes)
9621 tree attribute;
9622 for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
9624 tree name = TREE_PURPOSE (attribute);
9626 if (is_attribute_p ("deprecated", name))
9627 TREE_DEPRECATED (klass) = 1;
9629 TYPE_ATTRIBUTES (klass) = attributes;
9631 break;
9633 case CATEGORY_INTERFACE_TYPE:
9635 tree class_category_is_assoc_with;
9637 /* For a category, class_name is really the name of the class that
9638 the following set of methods will be associated with. We must
9639 find the interface so that can derive the objects template. */
9640 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
9642 error ("cannot find interface declaration for %qE",
9643 class_name);
9644 exit (FATAL_EXIT_CODE);
9646 else
9648 if (TREE_DEPRECATED (class_category_is_assoc_with))
9649 warning (OPT_Wdeprecated_declarations, "class %qE is deprecated",
9650 class_name);
9652 if (super_name == NULL_TREE)
9654 /* This is a class extension. Get the original
9655 interface, and continue working on it. */
9656 objc_in_class_extension = true;
9657 klass = class_category_is_assoc_with;
9659 if (protocol_list)
9661 /* Append protocols to the original protocol
9662 list. */
9663 CLASS_PROTOCOL_LIST (klass)
9664 = chainon (CLASS_PROTOCOL_LIST (klass),
9665 lookup_and_install_protocols (protocol_list));
9668 else
9670 add_category (class_category_is_assoc_with, klass);
9672 if (protocol_list)
9673 CLASS_PROTOCOL_LIST (klass)
9674 = lookup_and_install_protocols (protocol_list);
9678 break;
9680 case CATEGORY_IMPLEMENTATION_TYPE:
9681 /* Reset for multiple classes per file. */
9682 method_slot = 0;
9684 objc_implementation_context = klass;
9686 /* For a category, class_name is really the name of the class that
9687 the following set of methods will be associated with. We must
9688 find the interface so that can derive the objects template. */
9690 if (!(implementation_template = lookup_interface (class_name)))
9692 error ("cannot find interface declaration for %qE",
9693 class_name);
9694 exit (FATAL_EXIT_CODE);
9696 break;
9697 default:
9698 gcc_unreachable ();
9700 return klass;
9703 static tree
9704 continue_class (tree klass)
9706 switch (TREE_CODE (klass))
9708 case CLASS_IMPLEMENTATION_TYPE:
9709 case CATEGORY_IMPLEMENTATION_TYPE:
9711 struct imp_entry *imp_entry;
9713 /* Check consistency of the instance variables. */
9715 if (CLASS_RAW_IVARS (klass))
9716 check_ivars (implementation_template, klass);
9718 /* code generation */
9719 #ifdef OBJCPLUS
9720 push_lang_context (lang_name_c);
9721 #endif
9722 build_private_template (implementation_template);
9723 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
9724 objc_instance_type = build_pointer_type (uprivate_record);
9726 imp_entry = ggc_alloc_imp_entry ();
9728 imp_entry->next = imp_list;
9729 imp_entry->imp_context = klass;
9730 imp_entry->imp_template = implementation_template;
9732 synth_forward_declarations ();
9733 imp_entry->class_decl = UOBJC_CLASS_decl;
9734 imp_entry->meta_decl = UOBJC_METACLASS_decl;
9735 imp_entry->has_cxx_cdtors = 0;
9737 /* Append to front and increment count. */
9738 imp_list = imp_entry;
9739 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
9740 imp_count++;
9741 else
9742 cat_count++;
9743 #ifdef OBJCPLUS
9744 pop_lang_context ();
9745 #endif /* OBJCPLUS */
9747 return get_class_ivars (implementation_template, true);
9748 break;
9750 case CLASS_INTERFACE_TYPE:
9752 if (objc_in_class_extension)
9753 return NULL_TREE;
9754 #ifdef OBJCPLUS
9755 push_lang_context (lang_name_c);
9756 #endif /* OBJCPLUS */
9757 objc_collecting_ivars = 1;
9758 build_private_template (klass);
9759 objc_collecting_ivars = 0;
9760 #ifdef OBJCPLUS
9761 pop_lang_context ();
9762 #endif /* OBJCPLUS */
9763 return NULL_TREE;
9764 break;
9766 default:
9767 return error_mark_node;
9771 /* This routine builds name of the setter synthesized function. */
9772 static char *
9773 objc_build_property_setter_name (tree ident)
9775 /* TODO: Use alloca to allocate buffer of appropriate size. */
9776 static char string[BUFSIZE];
9777 sprintf (string, "set%s:", IDENTIFIER_POINTER (ident));
9778 string[3] = TOUPPER (string[3]);
9779 return string;
9782 /* This routine prepares the declarations of the property accessor
9783 helper functions (objc_getProperty(), etc) that are used when
9784 @synthesize is used. */
9785 static void
9786 build_objc_property_accessor_helpers (void)
9788 tree type;
9790 /* Declare the following function:
9792 objc_getProperty (id self, SEL _cmd,
9793 ptrdiff_t offset, BOOL is_atomic); */
9794 type = build_function_type_list (objc_object_type,
9795 objc_object_type,
9796 objc_selector_type,
9797 ptrdiff_type_node,
9798 boolean_type_node,
9799 NULL_TREE);
9800 objc_getProperty_decl = add_builtin_function ("objc_getProperty",
9801 type, 0, NOT_BUILT_IN,
9802 NULL, NULL_TREE);
9803 TREE_NOTHROW (objc_getProperty_decl) = 0;
9805 /* Declare the following function:
9806 void
9807 objc_setProperty (id self, SEL _cmd,
9808 ptrdiff_t offset, id new_value,
9809 BOOL is_atomic, BOOL should_copy); */
9810 type = build_function_type_list (void_type_node,
9811 objc_object_type,
9812 objc_selector_type,
9813 ptrdiff_type_node,
9814 objc_object_type,
9815 boolean_type_node,
9816 boolean_type_node,
9817 NULL_TREE);
9818 objc_setProperty_decl = add_builtin_function ("objc_setProperty",
9819 type, 0, NOT_BUILT_IN,
9820 NULL, NULL_TREE);
9821 TREE_NOTHROW (objc_setProperty_decl) = 0;
9823 /* This is the type of all of the following functions
9824 (objc_copyStruct(), objc_getPropertyStruct() and
9825 objc_setPropertyStruct()). */
9826 type = build_function_type_list (void_type_node,
9827 ptr_type_node,
9828 const_ptr_type_node,
9829 ptrdiff_type_node,
9830 boolean_type_node,
9831 boolean_type_node,
9832 NULL_TREE);
9834 if (flag_next_runtime)
9836 /* Declare the following function:
9837 void
9838 objc_copyStruct (void *destination, const void *source,
9839 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
9840 objc_copyStruct_decl = add_builtin_function ("objc_copyStruct",
9841 type, 0, NOT_BUILT_IN,
9842 NULL, NULL_TREE);
9843 TREE_NOTHROW (objc_copyStruct_decl) = 0;
9844 objc_getPropertyStruct_decl = NULL_TREE;
9845 objc_setPropertyStruct_decl = NULL_TREE;
9847 else
9849 objc_copyStruct_decl = NULL_TREE;
9851 /* Declare the following function:
9852 void
9853 objc_getPropertyStruct (void *destination, const void *source,
9854 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
9855 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
9856 type, 0, NOT_BUILT_IN,
9857 NULL, NULL_TREE);
9858 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
9859 /* Declare the following function:
9860 void
9861 objc_setPropertyStruct (void *destination, const void *source,
9862 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
9863 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
9864 type, 0, NOT_BUILT_IN,
9865 NULL, NULL_TREE);
9866 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
9870 /* This looks up an ivar in a class (including superclasses). */
9871 static tree
9872 lookup_ivar (tree interface, tree instance_variable_name)
9874 while (interface)
9876 tree decl_chain;
9878 for (decl_chain = CLASS_IVARS (interface); decl_chain; decl_chain = DECL_CHAIN (decl_chain))
9879 if (DECL_NAME (decl_chain) == instance_variable_name)
9880 return decl_chain;
9882 /* Not found. Search superclass if any. */
9883 if (CLASS_SUPER_NAME (interface))
9884 interface = lookup_interface (CLASS_SUPER_NAME (interface));
9887 return NULL_TREE;
9890 /* This routine synthesizes a 'getter' method. This is only called
9891 for @synthesize properties. */
9892 static void
9893 objc_synthesize_getter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
9895 location_t location = DECL_SOURCE_LOCATION (property);
9896 tree fn, decl;
9897 tree body;
9898 tree ret_val;
9900 /* If user has implemented a getter with same name then do nothing. */
9901 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
9902 PROPERTY_GETTER_NAME (property)))
9903 return;
9905 /* Find declaration of the property getter in the interface (or
9906 superclass, or protocol). There must be one. */
9907 decl = lookup_method_static (klass, PROPERTY_GETTER_NAME (property), 0);
9909 /* If one not declared in the interface, this condition has already
9910 been reported as user error (because property was not declared in
9911 the interface). */
9912 if (!decl)
9913 return;
9915 /* Adapt the 'decl'. Use the source location of the @synthesize
9916 statement for error messages. */
9917 decl = copy_node (decl);
9918 DECL_SOURCE_LOCATION (decl) = location;
9920 objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
9921 body = c_begin_compound_stmt (true);
9923 /* Now we need to decide how we build the getter. There are three
9924 cases:
9926 for 'copy' or 'retain' properties we need to use the
9927 objc_getProperty() accessor helper which knows about retain and
9928 copy. It supports both 'nonatomic' and 'atomic' access.
9930 for 'nonatomic, assign' properties we can access the instance
9931 variable directly. 'nonatomic' means we don't have to use locks,
9932 and 'assign' means we don't have to worry about retain or copy.
9933 If you combine the two, it means we can just access the instance
9934 variable directly.
9936 for 'atomic, assign' properties we use objc_copyStruct() (for the
9937 next runtime) or objc_getPropertyStruct() (for the GNU runtime). */
9938 switch (PROPERTY_ASSIGN_SEMANTICS (property))
9940 case OBJC_PROPERTY_RETAIN:
9941 case OBJC_PROPERTY_COPY:
9943 /* We build "return objc_getProperty (self, _cmd, offset, is_atomic);" */
9944 tree cmd, ivar, offset, is_atomic;
9945 cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
9947 /* Find the ivar to compute the offset. */
9948 ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
9949 if (!ivar || is_private (ivar))
9951 /* This should never happen. */
9952 error_at (location,
9953 "can not find instance variable associated with property");
9954 ret_val = error_mark_node;
9955 break;
9957 offset = byte_position (ivar);
9959 if (PROPERTY_NONATOMIC (property))
9960 is_atomic = boolean_false_node;
9961 else
9962 is_atomic = boolean_true_node;
9964 ret_val = build_function_call
9965 (location,
9966 /* Function prototype. */
9967 objc_getProperty_decl,
9968 /* Parameters. */
9969 tree_cons /* self */
9970 (NULL_TREE, self_decl,
9971 tree_cons /* _cmd */
9972 (NULL_TREE, cmd,
9973 tree_cons /* offset */
9974 (NULL_TREE, offset,
9975 tree_cons /* is_atomic */
9976 (NULL_TREE, is_atomic, NULL_TREE)))));
9978 break;
9979 case OBJC_PROPERTY_ASSIGN:
9980 if (PROPERTY_NONATOMIC (property))
9982 /* We build "return self->PROPERTY_IVAR_NAME;" */
9983 ret_val = objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property));
9984 break;
9986 else
9988 /* We build
9989 <property type> __objc_property_temp;
9990 objc_getPropertyStruct (&__objc_property_temp,
9991 &(self->PROPERTY_IVAR_NAME),
9992 sizeof (type of self->PROPERTY_IVAR_NAME),
9993 is_atomic,
9994 false)
9995 return __objc_property_temp;
9997 For the NeXT runtime, we need to use objc_copyStruct
9998 instead of objc_getPropertyStruct. */
9999 tree objc_property_temp_decl, function_decl, function_call;
10000 tree size_of, is_atomic;
10002 objc_property_temp_decl = objc_create_temporary_var (TREE_TYPE (property), "__objc_property_temp");
10003 DECL_SOURCE_LOCATION (objc_property_temp_decl) = location;
10004 objc_property_temp_decl = lang_hooks.decls.pushdecl (objc_property_temp_decl);
10006 /* sizeof (ivar type). Since the ivar and the property have
10007 the same type, there is no need to lookup the ivar. */
10008 size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
10009 true /* is_sizeof */,
10010 false /* complain */);
10012 if (PROPERTY_NONATOMIC (property))
10013 is_atomic = boolean_false_node;
10014 else
10015 is_atomic = boolean_true_node;
10017 if (flag_next_runtime)
10018 function_decl = objc_copyStruct_decl;
10019 else
10020 function_decl = objc_getPropertyStruct_decl;
10022 function_call = build_function_call
10023 (location,
10024 /* Function prototype. */
10025 function_decl,
10026 /* Parameters. */
10027 tree_cons /* &__objc_property_temp_decl */
10028 /* Warning: note that using build_fold_addr_expr_loc()
10029 here causes invalid code to be generated. */
10030 (NULL_TREE, build_unary_op (location, ADDR_EXPR, objc_property_temp_decl, 0),
10031 tree_cons /* &(self->PROPERTY_IVAR_NAME); */
10032 (NULL_TREE, build_fold_addr_expr_loc (location,
10033 objc_lookup_ivar
10034 (NULL_TREE, PROPERTY_IVAR_NAME (property))),
10035 tree_cons /* sizeof (PROPERTY_IVAR) */
10036 (NULL_TREE, size_of,
10037 tree_cons /* is_atomic */
10038 (NULL_TREE, is_atomic,
10039 /* TODO: This is currently ignored by the GNU
10040 runtime, but what about the next one ? */
10041 tree_cons /* has_strong */
10042 (NULL_TREE, boolean_true_node, NULL_TREE))))));
10044 add_stmt (function_call);
10046 ret_val = objc_property_temp_decl;
10048 break;
10049 default:
10050 gcc_unreachable ();
10053 gcc_assert (ret_val);
10055 #ifdef OBJCPLUS
10056 finish_return_stmt (ret_val);
10057 #else
10058 c_finish_return (location, ret_val, NULL_TREE);
10059 #endif
10061 add_stmt (c_end_compound_stmt (location, body, true));
10062 fn = current_function_decl;
10063 #ifdef OBJCPLUS
10064 finish_function ();
10065 #endif
10066 objc_finish_method_definition (fn);
10069 /* This routine synthesizes a 'setter' method. */
10071 static void
10072 objc_synthesize_setter (tree klass, tree class_methods ATTRIBUTE_UNUSED, tree property)
10074 location_t location = DECL_SOURCE_LOCATION (property);
10075 tree fn, decl;
10076 tree body;
10077 tree new_value, statement;
10079 /* If user has implemented a setter with same name then do nothing. */
10080 if (lookup_method (CLASS_NST_METHODS (objc_implementation_context),
10081 PROPERTY_SETTER_NAME (property)))
10082 return;
10084 /* Find declaration of the property setter in the interface (or
10085 superclass, or protocol). There must be one. */
10086 decl = lookup_method_static (klass, PROPERTY_SETTER_NAME (property), 0);
10088 /* If one not declared in the interface, this condition has already
10089 been reported as user error (because property was not declared in
10090 the interface). */
10091 if (!decl)
10092 return;
10094 /* Adapt the 'decl'. Use the source location of the @synthesize
10095 statement for error messages. */
10096 decl = copy_node (decl);
10097 DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (property);
10099 objc_start_method_definition (false /* is_class_method */, decl, NULL_TREE);
10101 body = c_begin_compound_stmt (true);
10103 /* The 'new_value' is the only argument to the method, which is the
10104 3rd argument of the function, after self and _cmd. We use twice
10105 TREE_CHAIN to move forward two arguments. */
10106 new_value = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)));
10108 /* This would presumably happen if the user has specified a
10109 prototype for the setter that does not have an argument! */
10110 if (new_value == NULL_TREE)
10112 /* TODO: This should be caught much earlier than this. */
10113 error_at (DECL_SOURCE_LOCATION (decl), "invalid setter, it must have one argument");
10114 /* Try to recover somehow. */
10115 new_value = error_mark_node;
10118 /* Now we need to decide how we build the setter. There are three
10119 cases:
10121 for 'copy' or 'retain' properties we need to use the
10122 objc_setProperty() accessor helper which knows about retain and
10123 copy. It supports both 'nonatomic' and 'atomic' access.
10125 for 'nonatomic, assign' properties we can access the instance
10126 variable directly. 'nonatomic' means we don't have to use locks,
10127 and 'assign' means we don't have to worry about retain or copy.
10128 If you combine the two, it means we can just access the instance
10129 variable directly.
10131 for 'atomic, assign' properties we use objc_copyStruct() (for the
10132 next runtime) or objc_setPropertyStruct() (for the GNU runtime). */
10133 switch (PROPERTY_ASSIGN_SEMANTICS (property))
10135 case OBJC_PROPERTY_RETAIN:
10136 case OBJC_PROPERTY_COPY:
10138 /* We build "objc_setProperty (self, _cmd, new_value, offset, is_atomic, should_copy);" */
10139 tree cmd, ivar, offset, is_atomic, should_copy;
10140 cmd = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
10142 /* Find the ivar to compute the offset. */
10143 ivar = lookup_ivar (klass, PROPERTY_IVAR_NAME (property));
10144 if (!ivar || is_private (ivar))
10146 error_at (location,
10147 "can not find instance variable associated with property");
10148 statement = error_mark_node;
10149 break;
10151 offset = byte_position (ivar);
10153 if (PROPERTY_NONATOMIC (property))
10154 is_atomic = boolean_false_node;
10155 else
10156 is_atomic = boolean_true_node;
10158 if (PROPERTY_ASSIGN_SEMANTICS (property) == OBJC_PROPERTY_COPY)
10159 should_copy = boolean_true_node;
10160 else
10161 should_copy = boolean_false_node;
10163 statement = build_function_call
10164 (location,
10165 /* Function prototype. */
10166 objc_setProperty_decl,
10167 /* Parameters. */
10168 tree_cons /* self */
10169 (NULL_TREE, self_decl,
10170 tree_cons /* _cmd */
10171 (NULL_TREE, cmd,
10172 tree_cons /* offset */
10173 (NULL_TREE, offset,
10174 tree_cons /* new_value */
10175 (NULL_TREE, new_value,
10176 tree_cons /* is_atomic */
10177 (NULL_TREE, is_atomic,
10178 tree_cons /* should_copy */
10179 (NULL_TREE, should_copy, NULL_TREE)))))));
10181 break;
10182 case OBJC_PROPERTY_ASSIGN:
10183 if (PROPERTY_NONATOMIC (property))
10185 /* We build "self->PROPERTY_IVAR_NAME = new_value;" */
10186 statement = build_modify_expr
10187 (location,
10188 objc_lookup_ivar (NULL_TREE, PROPERTY_IVAR_NAME (property)),
10189 NULL_TREE, NOP_EXPR,
10190 location, new_value, NULL_TREE);
10191 break;
10193 else
10195 /* We build
10196 objc_setPropertyStruct (&(self->PROPERTY_IVAR_NAME),
10197 &new_value,
10198 sizeof (type of self->PROPERTY_IVAR_NAME),
10199 is_atomic,
10200 false)
10202 For the NeXT runtime, we need to use objc_copyStruct
10203 instead of objc_getPropertyStruct. */
10204 tree function_decl, size_of, is_atomic;
10206 /* sizeof (ivar type). Since the ivar and the property have
10207 the same type, there is no need to lookup the ivar. */
10208 size_of = c_sizeof_or_alignof_type (location, TREE_TYPE (property),
10209 true /* is_sizeof */,
10210 false /* complain */);
10212 if (PROPERTY_NONATOMIC (property))
10213 is_atomic = boolean_false_node;
10214 else
10215 is_atomic = boolean_true_node;
10217 if (flag_next_runtime)
10218 function_decl = objc_copyStruct_decl;
10219 else
10220 function_decl = objc_setPropertyStruct_decl;
10222 statement = build_function_call
10223 (location,
10224 /* Function prototype. */
10225 function_decl,
10226 /* Parameters. */
10227 tree_cons /* &(self->PROPERTY_IVAR_NAME); */
10228 (NULL_TREE, build_fold_addr_expr_loc (location,
10229 objc_lookup_ivar
10230 (NULL_TREE, PROPERTY_IVAR_NAME (property))),
10231 tree_cons /* &new_value */
10232 (NULL_TREE, build_fold_addr_expr_loc (location, new_value),
10233 tree_cons /* sizeof (PROPERTY_IVAR) */
10234 (NULL_TREE, size_of,
10235 tree_cons /* is_atomic */
10236 (NULL_TREE, is_atomic,
10237 /* TODO: This is currently ignored by the GNU
10238 runtime, but what about the next one ? */
10239 tree_cons /* has_strong */
10240 (NULL_TREE, boolean_true_node, NULL_TREE))))));
10242 break;
10243 default:
10244 gcc_unreachable ();
10246 gcc_assert (statement);
10248 add_stmt (statement);
10249 add_stmt (c_end_compound_stmt (location, body, true));
10250 fn = current_function_decl;
10251 #ifdef OBJCPLUS
10252 finish_function ();
10253 #endif
10254 objc_finish_method_definition (fn);
10257 /* This function is a sub-routine of objc_add_synthesize_declaration.
10258 It is called for each property to synthesize once we have
10259 determined that the context is Ok. */
10260 static void
10261 objc_add_synthesize_declaration_for_property (location_t location, tree interface,
10262 tree property_name, tree ivar_name)
10264 /* Find the @property declaration. */
10265 tree property;
10266 tree x;
10268 /* Check that synthesize or dynamic has not already been used for
10269 the same property. */
10270 for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
10271 if (PROPERTY_NAME (property) == property_name)
10273 location_t original_location = DECL_SOURCE_LOCATION (property);
10275 if (PROPERTY_DYNAMIC (property))
10276 error_at (location, "property %qs already specified in %<@dynamic%>",
10277 IDENTIFIER_POINTER (property_name));
10278 else
10279 error_at (location, "property %qs already specified in %<@synthesize%>",
10280 IDENTIFIER_POINTER (property_name));
10282 if (original_location != UNKNOWN_LOCATION)
10283 inform (original_location, "originally specified here");
10284 return;
10287 /* Check that the property is declared in the interface. It could
10288 also be declared in a superclass or protocol. */
10289 property = lookup_property (interface, property_name);
10291 if (!property)
10293 error_at (location, "no declaration of property %qs found in the interface",
10294 IDENTIFIER_POINTER (property_name));
10295 return;
10297 else
10299 /* We have to copy the property, because we want to chain it to
10300 the implementation context, and we want to store the source
10301 location of the @synthesize, not of the original
10302 @property. */
10303 property = copy_node (property);
10304 DECL_SOURCE_LOCATION (property) = location;
10307 /* Determine PROPERTY_IVAR_NAME. */
10308 if (ivar_name == NULL_TREE)
10309 ivar_name = property_name;
10311 /* Check that the instance variable exists. You can only use an
10312 instance variable from the same class, not one from the
10313 superclass (this makes sense as it allows us to check that an
10314 instance variable is only used in one synthesized property). */
10316 tree ivar = is_ivar (CLASS_IVARS (interface), ivar_name);
10317 tree type_of_ivar;
10318 if (!ivar)
10320 error_at (location, "ivar %qs used by %<@synthesize%> declaration must be an existing ivar",
10321 IDENTIFIER_POINTER (property_name));
10322 return;
10325 if (DECL_BIT_FIELD_TYPE (ivar))
10326 type_of_ivar = DECL_BIT_FIELD_TYPE (ivar);
10327 else
10328 type_of_ivar = TREE_TYPE (ivar);
10330 /* If the instance variable has a different C type, we throw an error ... */
10331 if (!comptypes (TREE_TYPE (property), type_of_ivar)
10332 /* ... unless the property is readonly, in which case we allow
10333 the instance variable to be more specialized (this means we
10334 can generate the getter all right and it works). */
10335 && (!PROPERTY_READONLY (property)
10336 || !objc_compare_types (TREE_TYPE (property),
10337 type_of_ivar, -5, NULL_TREE)))
10339 location_t original_location = DECL_SOURCE_LOCATION (ivar);
10341 error_at (location, "property %qs is using instance variable %qs of incompatible type",
10342 IDENTIFIER_POINTER (property_name),
10343 IDENTIFIER_POINTER (ivar_name));
10345 if (original_location != UNKNOWN_LOCATION)
10346 inform (original_location, "originally specified here");
10349 /* If the instance variable is a bitfield, the property must be
10350 'assign', 'nonatomic' because the runtime getter/setter helper
10351 do not work with bitfield instance variables. */
10352 if (DECL_BIT_FIELD_TYPE (ivar))
10354 /* If there is an error, we return and not generate any
10355 getter/setter because trying to set up the runtime
10356 getter/setter helper calls with bitfields is at high risk
10357 of ICE. */
10359 if (PROPERTY_ASSIGN_SEMANTICS (property) != OBJC_PROPERTY_ASSIGN)
10361 location_t original_location = DECL_SOURCE_LOCATION (ivar);
10363 error_at (location, "'assign' property %qs is using bit-field instance variable %qs",
10364 IDENTIFIER_POINTER (property_name),
10365 IDENTIFIER_POINTER (ivar_name));
10367 if (original_location != UNKNOWN_LOCATION)
10368 inform (original_location, "originally specified here");
10369 return;
10372 if (!PROPERTY_NONATOMIC (property))
10374 location_t original_location = DECL_SOURCE_LOCATION (ivar);
10376 error_at (location, "'atomic' property %qs is using bit-field instance variable %qs",
10377 IDENTIFIER_POINTER (property_name),
10378 IDENTIFIER_POINTER (ivar_name));
10380 if (original_location != UNKNOWN_LOCATION)
10381 inform (original_location, "originally specified here");
10382 return;
10387 /* Check that no other property is using the same instance
10388 variable. */
10389 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10390 if (PROPERTY_IVAR_NAME (x) == ivar_name)
10392 location_t original_location = DECL_SOURCE_LOCATION (x);
10394 error_at (location, "property %qs is using the same instance variable as property %qs",
10395 IDENTIFIER_POINTER (property_name),
10396 IDENTIFIER_POINTER (PROPERTY_NAME (x)));
10398 if (original_location != UNKNOWN_LOCATION)
10399 inform (original_location, "originally specified here");
10401 /* We keep going on. This won't cause the compiler to fail;
10402 the failure would most likely be at runtime. */
10405 /* Note that a @synthesize (and only a @synthesize) always sets
10406 PROPERTY_IVAR_NAME to a non-NULL_TREE. You can recognize a
10407 @synthesize by that. */
10408 PROPERTY_IVAR_NAME (property) = ivar_name;
10410 /* PROPERTY_SETTER_NAME and PROPERTY_GETTER_NAME are copied from the
10411 original declaration; they are always set (with the exception of
10412 PROPERTY_SETTER_NAME not being set if PROPERTY_READONLY == 1). */
10414 /* Add the property to the list of properties for current implementation. */
10415 TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10416 IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10418 /* Note how we don't actually synthesize the getter/setter here; it
10419 would be very natural, but we may miss the fact that the user has
10420 implemented his own getter/setter later on in the @implementation
10421 (in which case we shouldn't generate getter/setter). We wait
10422 until we have parsed it all before generating the code. */
10425 /* This function is called by the parser after a @synthesize
10426 expression is parsed. 'location' is the location of the
10427 @synthesize expression, and 'property_and_ivar_list' is a chained
10428 list of the property and ivar names. */
10429 void
10430 objc_add_synthesize_declaration (location_t location, tree property_and_ivar_list)
10432 tree interface, chain;
10434 if (flag_objc1_only)
10435 error_at (input_location, "%<@synthesize%> is not available in Objective-C 1.0");
10437 if (property_and_ivar_list == error_mark_node)
10438 return;
10440 if (!objc_implementation_context)
10442 /* We can get here only in Objective-C; the Objective-C++ parser
10443 detects the problem while parsing, outputs the error
10444 "misplaced '@synthesize' Objective-C++ construct" and skips
10445 the declaration. */
10446 error_at (location, "%<@synthesize%> not in @implementation context");
10447 return;
10450 if (TREE_CODE (objc_implementation_context) == CATEGORY_IMPLEMENTATION_TYPE)
10452 error_at (location, "%<@synthesize%> can not be used in categories");
10453 return;
10456 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10457 if (!interface)
10459 /* I can't see how this could happen, but it is good as a safety check. */
10460 error_at (location,
10461 "%<@synthesize%> requires the @interface of the class to be available");
10462 return;
10465 /* Now, iterate over the properties and do each of them. */
10466 for (chain = property_and_ivar_list; chain; chain = TREE_CHAIN (chain))
10468 objc_add_synthesize_declaration_for_property (location, interface, TREE_VALUE (chain),
10469 TREE_PURPOSE (chain));
10473 /* This function is a sub-routine of objc_add_dynamic_declaration. It
10474 is called for each property to mark as dynamic once we have
10475 determined that the context is Ok. */
10476 static void
10477 objc_add_dynamic_declaration_for_property (location_t location, tree interface,
10478 tree property_name)
10480 /* Find the @property declaration. */
10481 tree property;
10483 /* Check that synthesize or dynamic has not already been used for
10484 the same property. */
10485 for (property = IMPL_PROPERTY_DECL (objc_implementation_context); property; property = TREE_CHAIN (property))
10486 if (PROPERTY_NAME (property) == property_name)
10488 location_t original_location = DECL_SOURCE_LOCATION (property);
10490 if (PROPERTY_DYNAMIC (property))
10491 error_at (location, "property %qs already specified in %<@dynamic%>",
10492 IDENTIFIER_POINTER (property_name));
10493 else
10494 error_at (location, "property %qs already specified in %<@synthesize%>",
10495 IDENTIFIER_POINTER (property_name));
10497 if (original_location != UNKNOWN_LOCATION)
10498 inform (original_location, "originally specified here");
10499 return;
10502 /* Check that the property is declared in the interface. It could
10503 also be declared in a superclass or protocol. */
10504 property = lookup_property (interface, property_name);
10506 if (!property)
10508 error_at (location, "no declaration of property %qs found in the interface",
10509 IDENTIFIER_POINTER (property_name));
10510 return;
10512 else
10514 /* We have to copy the property, because we want to chain it to
10515 the implementation context, and we want to store the source
10516 location of the @synthesize, not of the original
10517 @property. */
10518 property = copy_node (property);
10519 DECL_SOURCE_LOCATION (property) = location;
10522 /* Note that a @dynamic (and only a @dynamic) always sets
10523 PROPERTY_DYNAMIC to 1. You can recognize a @dynamic by that.
10524 (actually, as explained above, PROPERTY_DECL generated by
10525 @property and associated with a @dynamic property are also marked
10526 as PROPERTY_DYNAMIC). */
10527 PROPERTY_DYNAMIC (property) = 1;
10529 /* Add the property to the list of properties for current implementation. */
10530 TREE_CHAIN (property) = IMPL_PROPERTY_DECL (objc_implementation_context);
10531 IMPL_PROPERTY_DECL (objc_implementation_context) = property;
10534 /* This function is called by the parser after a @dynamic expression
10535 is parsed. 'location' is the location of the @dynamic expression,
10536 and 'property_list' is a chained list of all the property
10537 names. */
10538 void
10539 objc_add_dynamic_declaration (location_t location, tree property_list)
10541 tree interface, chain;
10543 if (flag_objc1_only)
10544 error_at (input_location, "%<@dynamic%> is not available in Objective-C 1.0");
10546 if (property_list == error_mark_node)
10547 return;
10549 if (!objc_implementation_context)
10551 /* We can get here only in Objective-C; the Objective-C++ parser
10552 detects the problem while parsing, outputs the error
10553 "misplaced '@dynamic' Objective-C++ construct" and skips the
10554 declaration. */
10555 error_at (location, "%<@dynamic%> not in @implementation context");
10556 return;
10559 /* @dynamic is allowed in categories. */
10560 switch (TREE_CODE (objc_implementation_context))
10562 case CLASS_IMPLEMENTATION_TYPE:
10563 interface = lookup_interface (CLASS_NAME (objc_implementation_context));
10564 break;
10565 case CATEGORY_IMPLEMENTATION_TYPE:
10566 interface = lookup_category (implementation_template,
10567 CLASS_SUPER_NAME (objc_implementation_context));
10568 break;
10569 default:
10570 gcc_unreachable ();
10573 if (!interface)
10575 /* I can't see how this could happen, but it is good as a safety check. */
10576 error_at (location,
10577 "%<@dynamic%> requires the @interface of the class to be available");
10578 return;
10581 /* Now, iterate over the properties and do each of them. */
10582 for (chain = property_list; chain; chain = TREE_CHAIN (chain))
10584 objc_add_dynamic_declaration_for_property (location, interface, TREE_VALUE (chain));
10588 /* Main routine to generate code/data for all the property information for
10589 current implementation (class or category). CLASS is the interface where
10590 ivars are declared. CLASS_METHODS is where methods are found which
10591 could be a class or a category depending on whether we are implementing
10592 property of a class or a category. */
10594 static void
10595 objc_gen_property_data (tree klass, tree class_methods)
10597 tree x;
10599 for (x = IMPL_PROPERTY_DECL (objc_implementation_context); x; x = TREE_CHAIN (x))
10601 /* @dynamic property - nothing to check or synthesize. */
10602 if (PROPERTY_DYNAMIC (x))
10603 continue;
10605 /* @synthesize property - need to synthesize the accessors. */
10606 if (PROPERTY_IVAR_NAME (x))
10608 objc_synthesize_getter (klass, class_methods, x);
10610 if (PROPERTY_READONLY (x) == 0)
10611 objc_synthesize_setter (klass, class_methods, x);
10613 continue;
10616 gcc_unreachable ();
10620 /* This is called once we see the "@end" in an interface/implementation. */
10622 static void
10623 finish_class (tree klass)
10625 switch (TREE_CODE (klass))
10627 case CLASS_IMPLEMENTATION_TYPE:
10629 /* All code generation is done in finish_objc. */
10631 /* Generate what needed for property; setters, getters, etc. */
10632 objc_gen_property_data (implementation_template, implementation_template);
10634 if (implementation_template != objc_implementation_context)
10636 /* Ensure that all method listed in the interface contain bodies. */
10637 check_methods (CLASS_CLS_METHODS (implementation_template),
10638 objc_implementation_context, '+');
10639 check_methods (CLASS_NST_METHODS (implementation_template),
10640 objc_implementation_context, '-');
10642 if (CLASS_PROTOCOL_LIST (implementation_template))
10643 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
10644 "class",
10645 CLASS_NAME (objc_implementation_context));
10647 break;
10649 case CATEGORY_IMPLEMENTATION_TYPE:
10651 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
10653 if (category)
10655 /* Generate what needed for property; setters, getters, etc. */
10656 objc_gen_property_data (implementation_template, category);
10658 /* Ensure all method listed in the interface contain bodies. */
10659 check_methods (CLASS_CLS_METHODS (category),
10660 objc_implementation_context, '+');
10661 check_methods (CLASS_NST_METHODS (category),
10662 objc_implementation_context, '-');
10664 if (CLASS_PROTOCOL_LIST (category))
10665 check_protocols (CLASS_PROTOCOL_LIST (category),
10666 "category",
10667 CLASS_SUPER_NAME (objc_implementation_context));
10669 break;
10671 case CLASS_INTERFACE_TYPE:
10672 case CATEGORY_INTERFACE_TYPE:
10673 case PROTOCOL_INTERFACE_TYPE:
10675 /* Process properties of the class. */
10676 tree x;
10677 for (x = CLASS_PROPERTY_DECL (objc_interface_context); x; x = TREE_CHAIN (x))
10679 /* Now we check that the appropriate getter is declared,
10680 and if not, we declare one ourselves. */
10681 tree getter_decl = lookup_method (CLASS_NST_METHODS (klass),
10682 PROPERTY_GETTER_NAME (x));
10684 if (getter_decl)
10686 /* TODO: Check that the declaration is consistent with the property. */
10689 else
10691 /* Generate an instance method declaration for the
10692 getter; for example "- (id) name;". In general it
10693 will be of the form
10694 -(type)property_getter_name; */
10695 tree rettype = build_tree_list (NULL_TREE, TREE_TYPE (x));
10696 getter_decl = build_method_decl (INSTANCE_METHOD_DECL,
10697 rettype, PROPERTY_GETTER_NAME (x),
10698 NULL_TREE, false);
10699 if (PROPERTY_OPTIONAL (x))
10700 objc_add_method (objc_interface_context, getter_decl, false, true);
10701 else
10702 objc_add_method (objc_interface_context, getter_decl, false, false);
10703 METHOD_PROPERTY_CONTEXT (getter_decl) = x;
10706 if (PROPERTY_READONLY (x) == 0)
10708 /* Now we check that the appropriate setter is declared,
10709 and if not, we declare on ourselves. */
10710 tree setter_decl = lookup_method (CLASS_NST_METHODS (klass),
10711 PROPERTY_SETTER_NAME (x));
10713 if (setter_decl)
10715 /* TODO: Check that the declaration is consistent with the property. */
10718 else
10720 /* The setter name is something like 'setName:'.
10721 We need the substring 'setName' to build the
10722 method declaration due to how the declaration
10723 works. TODO: build_method_decl() will then
10724 generate back 'setName:' from 'setName'; it
10725 would be more efficient to hook into there. */
10726 const char *full_setter_name = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (x));
10727 size_t length = strlen (full_setter_name);
10728 char *setter_name = (char *) alloca (length);
10729 tree ret_type, selector, arg_type, arg_name;
10731 strcpy (setter_name, full_setter_name);
10732 setter_name[length - 1] = '\0';
10733 ret_type = build_tree_list (NULL_TREE, void_type_node);
10734 arg_type = build_tree_list (NULL_TREE, TREE_TYPE (x));
10735 arg_name = get_identifier ("_value");
10736 selector = objc_build_keyword_decl (get_identifier (setter_name),
10737 arg_type, arg_name, NULL);
10738 setter_decl = build_method_decl (INSTANCE_METHOD_DECL,
10739 ret_type, selector,
10740 build_tree_list (NULL_TREE, NULL_TREE),
10741 false);
10742 if (PROPERTY_OPTIONAL (x))
10743 objc_add_method (objc_interface_context, setter_decl, false, true);
10744 else
10745 objc_add_method (objc_interface_context, setter_decl, false, false);
10746 METHOD_PROPERTY_CONTEXT (setter_decl) = x;
10750 break;
10752 default:
10753 gcc_unreachable ();
10754 break;
10758 static tree
10759 add_protocol (tree protocol)
10761 /* Put protocol on list in reverse order. */
10762 TREE_CHAIN (protocol) = protocol_chain;
10763 protocol_chain = protocol;
10764 return protocol_chain;
10767 /* Looks up a protocol. If 'warn_if_deprecated' is true, a warning is
10768 emitted if the protocol is deprecated. */
10770 static tree
10771 lookup_protocol (tree ident, bool warn_if_deprecated)
10773 tree chain;
10775 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
10776 if (ident == PROTOCOL_NAME (chain))
10778 if (warn_if_deprecated && TREE_DEPRECATED (chain))
10780 /* It would be nice to use warn_deprecated_use() here, but
10781 we are using TREE_CHAIN (which is supposed to be the
10782 TYPE_STUB_DECL for a TYPE) for something different. */
10783 warning (OPT_Wdeprecated_declarations, "protocol %qE is deprecated",
10784 PROTOCOL_NAME (chain));
10787 return chain;
10790 return NULL_TREE;
10793 /* This function forward declares the protocols named by NAMES. If
10794 they are already declared or defined, the function has no effect. */
10796 void
10797 objc_declare_protocols (tree names, tree attributes)
10799 tree list;
10800 bool deprecated = false;
10802 #ifdef OBJCPLUS
10803 if (current_namespace != global_namespace) {
10804 error ("Objective-C declarations may only appear in global scope");
10806 #endif /* OBJCPLUS */
10808 /* Determine if 'deprecated', the only attribute we recognize for
10809 protocols, was used. Ignore all other attributes. */
10810 if (attributes)
10812 tree attribute;
10813 for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
10815 tree name = TREE_PURPOSE (attribute);
10817 if (is_attribute_p ("deprecated", name))
10818 deprecated = true;
10822 for (list = names; list; list = TREE_CHAIN (list))
10824 tree name = TREE_VALUE (list);
10826 if (lookup_protocol (name, /* warn if deprecated */ false) == NULL_TREE)
10828 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
10830 TYPE_LANG_SLOT_1 (protocol)
10831 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10832 PROTOCOL_NAME (protocol) = name;
10833 PROTOCOL_LIST (protocol) = NULL_TREE;
10834 add_protocol (protocol);
10835 PROTOCOL_DEFINED (protocol) = 0;
10836 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10838 if (attributes)
10840 TYPE_ATTRIBUTES (protocol) = attributes;
10841 if (deprecated)
10842 TREE_DEPRECATED (protocol) = 1;
10848 static tree
10849 start_protocol (enum tree_code code, tree name, tree list, tree attributes)
10851 tree protocol;
10852 bool deprecated = false;
10854 #ifdef OBJCPLUS
10855 if (current_namespace != global_namespace) {
10856 error ("Objective-C declarations may only appear in global scope");
10858 #endif /* OBJCPLUS */
10860 /* Determine if 'deprecated', the only attribute we recognize for
10861 protocols, was used. Ignore all other attributes. */
10862 if (attributes)
10864 tree attribute;
10865 for (attribute = attributes; attribute; attribute = TREE_CHAIN (attribute))
10867 tree name = TREE_PURPOSE (attribute);
10869 if (is_attribute_p ("deprecated", name))
10870 deprecated = true;
10874 protocol = lookup_protocol (name, /* warn_if_deprecated */ false);
10876 if (!protocol)
10878 protocol = make_node (code);
10879 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
10881 PROTOCOL_NAME (protocol) = name;
10882 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10883 add_protocol (protocol);
10884 PROTOCOL_DEFINED (protocol) = 1;
10885 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
10887 check_protocol_recursively (protocol, list);
10889 else if (! PROTOCOL_DEFINED (protocol))
10891 PROTOCOL_DEFINED (protocol) = 1;
10892 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
10894 check_protocol_recursively (protocol, list);
10896 else
10898 warning (0, "duplicate declaration for protocol %qE",
10899 name);
10902 if (attributes)
10904 TYPE_ATTRIBUTES (protocol) = attributes;
10905 if (deprecated)
10906 TREE_DEPRECATED (protocol) = 1;
10909 return protocol;
10913 /* "Encode" a data type into a string, which grows in util_obstack.
10915 The format is described in gcc/doc/objc.texi, section 'Type
10916 encoding'.
10918 Most of the encode_xxx functions have a 'type' argument, which is
10919 the type to encode, and an integer 'curtype' argument, which is the
10920 index in the encoding string of the beginning of the encoding of
10921 the current type, and allows you to find what characters have
10922 already been written for the current type (they are the ones in the
10923 current encoding string starting from 'curtype').
10925 For example, if we are encoding a method which returns 'int' and
10926 takes a 'char **' argument, then when we get to the point of
10927 encoding the 'char **' argument, the encoded string already
10928 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
10929 'curtype' will be set to 7 when starting to encode 'char **'.
10930 During the whole of the encoding of 'char **', 'curtype' will be
10931 fixed at 7, so the routine encoding the second pointer can find out
10932 that it's actually encoding a pointer to a pointer by looking
10933 backwards at what has already been encoded for the current type,
10934 and seeing there is a "^" (meaning a pointer) in there.
10938 /* Encode type qualifiers encodes one of the "PQ" Objective-C
10939 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
10940 'const', instead, is encoded directly as part of the type.
10943 static void
10944 encode_type_qualifiers (tree declspecs)
10946 tree spec;
10948 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
10950 /* FIXME: Shouldn't we use token->keyword here ? */
10951 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
10952 obstack_1grow (&util_obstack, 'n');
10953 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
10954 obstack_1grow (&util_obstack, 'N');
10955 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
10956 obstack_1grow (&util_obstack, 'o');
10957 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
10958 obstack_1grow (&util_obstack, 'O');
10959 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
10960 obstack_1grow (&util_obstack, 'R');
10961 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
10962 obstack_1grow (&util_obstack, 'V');
10963 else
10964 gcc_unreachable ();
10968 /* Determine if a pointee is marked read-only. Only used by the NeXT
10969 runtime to be compatible with gcc-3.3. */
10971 static bool
10972 pointee_is_readonly (tree pointee)
10974 while (POINTER_TYPE_P (pointee))
10975 pointee = TREE_TYPE (pointee);
10977 return TYPE_READONLY (pointee);
10980 /* Encode a pointer type. */
10982 static void
10983 encode_pointer (tree type, int curtype, int format)
10985 tree pointer_to = TREE_TYPE (type);
10987 if (flag_next_runtime)
10989 /* This code is used to be compatible with gcc-3.3. */
10990 /* For historical/compatibility reasons, the read-only qualifier
10991 of the pointee gets emitted _before_ the '^'. The read-only
10992 qualifier of the pointer itself gets ignored, _unless_ we are
10993 looking at a typedef! Also, do not emit the 'r' for anything
10994 but the outermost type! */
10995 if (!generating_instance_variables
10996 && (obstack_object_size (&util_obstack) - curtype <= 1)
10997 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
10998 ? TYPE_READONLY (type)
10999 : pointee_is_readonly (pointer_to)))
11000 obstack_1grow (&util_obstack, 'r');
11003 if (TREE_CODE (pointer_to) == RECORD_TYPE)
11005 if (OBJC_TYPE_NAME (pointer_to)
11006 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
11008 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
11010 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
11012 obstack_1grow (&util_obstack, '@');
11013 return;
11015 else if (TYPE_HAS_OBJC_INFO (pointer_to)
11016 && TYPE_OBJC_INTERFACE (pointer_to))
11018 if (generating_instance_variables)
11020 obstack_1grow (&util_obstack, '@');
11021 obstack_1grow (&util_obstack, '"');
11022 obstack_grow (&util_obstack, name, strlen (name));
11023 obstack_1grow (&util_obstack, '"');
11024 return;
11026 else
11028 obstack_1grow (&util_obstack, '@');
11029 return;
11032 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
11034 obstack_1grow (&util_obstack, '#');
11035 return;
11037 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
11039 obstack_1grow (&util_obstack, ':');
11040 return;
11044 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
11045 && TYPE_MODE (pointer_to) == QImode)
11047 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
11048 ? OBJC_TYPE_NAME (pointer_to)
11049 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
11051 /* (BOOL *) are an exception and are encoded as ^c, while all
11052 other pointers to char are encoded as *. */
11053 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
11055 if (!flag_next_runtime)
11057 /* The NeXT runtime adds the 'r' before getting here. */
11059 /* It appears that "r*" means "const char *" rather than
11060 "char *const". "char *const" is encoded as "*",
11061 which is identical to "char *", so the "const" is
11062 unfortunately lost. */
11063 if (TYPE_READONLY (pointer_to))
11064 obstack_1grow (&util_obstack, 'r');
11067 obstack_1grow (&util_obstack, '*');
11068 return;
11072 /* We have a normal pointer type that does not get special treatment. */
11073 obstack_1grow (&util_obstack, '^');
11074 encode_type (pointer_to, curtype, format);
11077 static void
11078 encode_array (tree type, int curtype, int format)
11080 tree an_int_cst = TYPE_SIZE (type);
11081 tree array_of = TREE_TYPE (type);
11082 char buffer[40];
11084 if (an_int_cst == NULL)
11086 /* We are trying to encode an incomplete array. An incomplete
11087 array is forbidden as part of an instance variable. */
11088 if (generating_instance_variables)
11090 /* TODO: Detect this error earlier. */
11091 error ("instance variable has unknown size");
11092 return;
11095 /* So the only case in which an incomplete array could occur is
11096 if we are encoding the arguments or return value of a method.
11097 In that case, an incomplete array argument or return value
11098 (eg, -(void)display: (char[])string) is treated like a
11099 pointer because that is how the compiler does the function
11100 call. A special, more complicated case, is when the
11101 incomplete array is the last member of a struct (eg, if we
11102 are encoding "struct { unsigned long int a;double b[];}"),
11103 which is again part of a method argument/return value. In
11104 that case, we really need to communicate to the runtime that
11105 there is an incomplete array (not a pointer!) there. So, we
11106 detect that special case and encode it as a zero-length
11107 array.
11109 Try to detect that we are part of a struct. We do this by
11110 searching for '=' in the type encoding for the current type.
11111 NB: This hack assumes that you can't use '=' as part of a C
11112 identifier.
11115 char *enc = obstack_base (&util_obstack) + curtype;
11116 if (memchr (enc, '=',
11117 obstack_object_size (&util_obstack) - curtype) == NULL)
11119 /* We are not inside a struct. Encode the array as a
11120 pointer. */
11121 encode_pointer (type, curtype, format);
11122 return;
11126 /* Else, we are in a struct, and we encode it as a zero-length
11127 array. */
11128 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
11130 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
11131 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
11132 else
11133 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
11134 TREE_INT_CST_LOW (an_int_cst)
11135 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
11137 obstack_grow (&util_obstack, buffer, strlen (buffer));
11138 encode_type (array_of, curtype, format);
11139 obstack_1grow (&util_obstack, ']');
11140 return;
11143 /* Encode a vector. The vector type is a GCC extension to C. */
11144 static void
11145 encode_vector (tree type, int curtype, int format)
11147 tree vector_of = TREE_TYPE (type);
11148 char buffer[40];
11150 /* Vectors are like simple fixed-size arrays. */
11152 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
11153 alignment of the vector, and <code> is the base type. Eg, int
11154 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
11155 assuming that the alignment is 32 bytes. We include size and
11156 alignment in bytes so that the runtime does not have to have any
11157 knowledge of the actual types.
11159 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
11160 /* We want to compute the equivalent of sizeof (<vector>).
11161 Code inspired by c_sizeof_or_alignof_type. */
11162 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
11163 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
11164 /* We want to compute the equivalent of __alignof__
11165 (<vector>). Code inspired by
11166 c_sizeof_or_alignof_type. */
11167 TYPE_ALIGN_UNIT (type));
11168 obstack_grow (&util_obstack, buffer, strlen (buffer));
11169 encode_type (vector_of, curtype, format);
11170 obstack_1grow (&util_obstack, ']');
11171 return;
11174 static void
11175 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
11177 tree field = TYPE_FIELDS (type);
11179 for (; field; field = DECL_CHAIN (field))
11181 #ifdef OBJCPLUS
11182 /* C++ static members, and things that are not field at all,
11183 should not appear in the encoding. */
11184 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
11185 continue;
11186 #endif
11188 /* Recursively encode fields of embedded base classes. */
11189 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
11190 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
11192 encode_aggregate_fields (TREE_TYPE (field),
11193 pointed_to, curtype, format);
11194 continue;
11197 if (generating_instance_variables && !pointed_to)
11199 tree fname = DECL_NAME (field);
11201 obstack_1grow (&util_obstack, '"');
11203 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
11204 obstack_grow (&util_obstack,
11205 IDENTIFIER_POINTER (fname),
11206 strlen (IDENTIFIER_POINTER (fname)));
11208 obstack_1grow (&util_obstack, '"');
11211 encode_field_decl (field, curtype, format);
11215 static void
11216 encode_aggregate_within (tree type, int curtype, int format, int left,
11217 int right)
11219 tree name;
11220 /* NB: aggregates that are pointed to have slightly different encoding
11221 rules in that you never encode the names of instance variables. */
11222 int ob_size = obstack_object_size (&util_obstack);
11223 bool inline_contents = false;
11224 bool pointed_to = false;
11226 if (flag_next_runtime)
11228 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
11229 pointed_to = true;
11231 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
11232 && (!pointed_to || ob_size - curtype == 1
11233 || (ob_size - curtype == 2
11234 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
11235 inline_contents = true;
11237 else
11239 /* c0 and c1 are the last two characters in the encoding of the
11240 current type; if the last two characters were '^' or '^r',
11241 then we are encoding an aggregate that is "pointed to". The
11242 comment above applies: in that case we should avoid encoding
11243 the names of instance variables.
11245 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
11246 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
11248 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
11249 pointed_to = true;
11251 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
11253 if (!pointed_to)
11254 inline_contents = true;
11255 else
11257 /* Note that the check (ob_size - curtype < 2) prevents
11258 infinite recursion when encoding a structure which is
11259 a linked list (eg, struct node { struct node *next;
11260 }). Each time we follow a pointer, we add one
11261 character to ob_size, and curtype is fixed, so after
11262 at most two pointers we stop inlining contents and
11263 break the loop.
11265 The other case where we don't inline is "^r", which
11266 is a pointer to a constant struct.
11268 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
11269 inline_contents = true;
11274 /* Traverse struct aliases; it is important to get the
11275 original struct and its tag name (if any). */
11276 type = TYPE_MAIN_VARIANT (type);
11277 name = OBJC_TYPE_NAME (type);
11278 /* Open parenth/bracket. */
11279 obstack_1grow (&util_obstack, left);
11281 /* Encode the struct/union tag name, or '?' if a tag was
11282 not provided. Typedef aliases do not qualify. */
11283 #ifdef OBJCPLUS
11284 /* For compatibility with the NeXT runtime, ObjC++ encodes template
11285 args as a composite struct tag name. */
11286 if (name && TREE_CODE (name) == IDENTIFIER_NODE
11287 /* Did this struct have a tag? */
11288 && !TYPE_WAS_ANONYMOUS (type))
11289 obstack_grow (&util_obstack,
11290 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
11291 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
11292 #else
11293 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
11294 obstack_grow (&util_obstack,
11295 IDENTIFIER_POINTER (name),
11296 strlen (IDENTIFIER_POINTER (name)));
11297 #endif
11298 else
11299 obstack_1grow (&util_obstack, '?');
11301 /* Encode the types (and possibly names) of the inner fields,
11302 if required. */
11303 if (inline_contents)
11305 obstack_1grow (&util_obstack, '=');
11306 encode_aggregate_fields (type, pointed_to, curtype, format);
11308 /* Close parenth/bracket. */
11309 obstack_1grow (&util_obstack, right);
11312 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
11313 field type. */
11315 static void
11316 encode_next_bitfield (int width)
11318 char buffer[40];
11319 sprintf (buffer, "b%d", width);
11320 obstack_grow (&util_obstack, buffer, strlen (buffer));
11324 /* Encodes 'type', ignoring type qualifiers (which you should encode
11325 beforehand if needed) with the exception of 'const', which is
11326 encoded by encode_type. See above for the explanation of
11327 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
11328 OBJC_ENCODE_DONT_INLINE_DEFS.
11330 static void
11331 encode_type (tree type, int curtype, int format)
11333 enum tree_code code = TREE_CODE (type);
11335 /* Ignore type qualifiers other than 'const' when encoding a
11336 type. */
11338 if (type == error_mark_node)
11339 return;
11341 if (!flag_next_runtime)
11343 if (TYPE_READONLY (type))
11344 obstack_1grow (&util_obstack, 'r');
11347 switch (code)
11349 case ENUMERAL_TYPE:
11350 if (flag_next_runtime)
11352 /* Kludge for backwards-compatibility with gcc-3.3: enums
11353 are always encoded as 'i' no matter what type they
11354 actually are (!). */
11355 obstack_1grow (&util_obstack, 'i');
11356 break;
11358 /* Else, they are encoded exactly like the integer type that is
11359 used by the compiler to store them. */
11360 case INTEGER_TYPE:
11362 char c;
11363 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
11365 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
11366 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
11367 case 32:
11369 tree int_type = type;
11370 if (flag_next_runtime)
11372 /* Another legacy kludge for compatiblity with
11373 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
11374 but not always. For typedefs, we need to use 'i'
11375 or 'I' instead if encoding a struct field, or a
11376 pointer! */
11377 int_type = ((!generating_instance_variables
11378 && (obstack_object_size (&util_obstack)
11379 == (unsigned) curtype))
11380 ? TYPE_MAIN_VARIANT (type)
11381 : type);
11383 if (int_type == long_unsigned_type_node
11384 || int_type == long_integer_type_node)
11385 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
11386 else
11387 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
11389 break;
11390 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
11391 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
11392 default: gcc_unreachable ();
11394 obstack_1grow (&util_obstack, c);
11395 break;
11397 case REAL_TYPE:
11399 char c;
11400 /* Floating point types. */
11401 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
11403 case 32: c = 'f'; break;
11404 case 64: c = 'd'; break;
11405 case 96:
11406 case 128: c = 'D'; break;
11407 default: gcc_unreachable ();
11409 obstack_1grow (&util_obstack, c);
11410 break;
11412 case VOID_TYPE:
11413 obstack_1grow (&util_obstack, 'v');
11414 break;
11416 case BOOLEAN_TYPE:
11417 obstack_1grow (&util_obstack, 'B');
11418 break;
11420 case ARRAY_TYPE:
11421 encode_array (type, curtype, format);
11422 break;
11424 case POINTER_TYPE:
11425 #ifdef OBJCPLUS
11426 case REFERENCE_TYPE:
11427 #endif
11428 encode_pointer (type, curtype, format);
11429 break;
11431 case RECORD_TYPE:
11432 encode_aggregate_within (type, curtype, format, '{', '}');
11433 break;
11435 case UNION_TYPE:
11436 encode_aggregate_within (type, curtype, format, '(', ')');
11437 break;
11439 case FUNCTION_TYPE: /* '?' means an unknown type. */
11440 obstack_1grow (&util_obstack, '?');
11441 break;
11443 case COMPLEX_TYPE:
11444 /* A complex is encoded as 'j' followed by the inner type (eg,
11445 "_Complex int" is encoded as 'ji'). */
11446 obstack_1grow (&util_obstack, 'j');
11447 encode_type (TREE_TYPE (type), curtype, format);
11448 break;
11450 case VECTOR_TYPE:
11451 encode_vector (type, curtype, format);
11452 break;
11454 default:
11455 warning (0, "unknown type %s found during Objective-C encoding",
11456 gen_type_name (type));
11457 obstack_1grow (&util_obstack, '?');
11458 break;
11461 if (flag_next_runtime)
11463 /* Super-kludge. Some ObjC qualifier and type combinations need
11464 to be rearranged for compatibility with gcc-3.3. */
11465 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
11467 char *enc = obstack_base (&util_obstack) + curtype;
11469 /* Rewrite "in const" from "nr" to "rn". */
11470 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
11471 strncpy (enc - 1, "rn", 2);
11476 static void
11477 encode_gnu_bitfield (int position, tree type, int size)
11479 enum tree_code code = TREE_CODE (type);
11480 char buffer[40];
11481 char charType = '?';
11483 /* This code is only executed for the GNU runtime, so we can ignore
11484 the NeXT runtime kludge of always encoding enums as 'i' no matter
11485 what integers they actually are. */
11486 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
11488 if (integer_zerop (TYPE_MIN_VALUE (type)))
11489 /* Unsigned integer types. */
11491 switch (TYPE_MODE (type))
11493 case QImode:
11494 charType = 'C'; break;
11495 case HImode:
11496 charType = 'S'; break;
11497 case SImode:
11499 if (type == long_unsigned_type_node)
11500 charType = 'L';
11501 else
11502 charType = 'I';
11503 break;
11505 case DImode:
11506 charType = 'Q'; break;
11507 default:
11508 gcc_unreachable ();
11511 else
11512 /* Signed integer types. */
11514 switch (TYPE_MODE (type))
11516 case QImode:
11517 charType = 'c'; break;
11518 case HImode:
11519 charType = 's'; break;
11520 case SImode:
11522 if (type == long_integer_type_node)
11523 charType = 'l';
11524 else
11525 charType = 'i';
11526 break;
11528 case DImode:
11529 charType = 'q'; break;
11530 default:
11531 gcc_unreachable ();
11535 else
11537 /* Do not do any encoding, produce an error and keep going. */
11538 error ("trying to encode non-integer type as a bitfield");
11539 return;
11542 sprintf (buffer, "b%d%c%d", position, charType, size);
11543 obstack_grow (&util_obstack, buffer, strlen (buffer));
11546 static void
11547 encode_field_decl (tree field_decl, int curtype, int format)
11549 #ifdef OBJCPLUS
11550 /* C++ static members, and things that are not fields at all,
11551 should not appear in the encoding. */
11552 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
11553 return;
11554 #endif
11556 /* Generate the bitfield typing information, if needed. Note the difference
11557 between GNU and NeXT runtimes. */
11558 if (DECL_BIT_FIELD_TYPE (field_decl))
11560 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
11562 if (flag_next_runtime)
11563 encode_next_bitfield (size);
11564 else
11565 encode_gnu_bitfield (int_bit_position (field_decl),
11566 DECL_BIT_FIELD_TYPE (field_decl), size);
11568 else
11569 encode_type (TREE_TYPE (field_decl), curtype, format);
11572 /* Decay array and function parameters into pointers. */
11574 static tree
11575 objc_decay_parm_type (tree type)
11577 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == FUNCTION_TYPE)
11578 type = build_pointer_type (TREE_CODE (type) == ARRAY_TYPE
11579 ? TREE_TYPE (type)
11580 : type);
11582 return type;
11585 static GTY(()) tree objc_parmlist = NULL_TREE;
11587 /* Append PARM to a list of formal parameters of a method, making a necessary
11588 array-to-pointer adjustment along the way. */
11590 static void
11591 objc_push_parm (tree parm)
11593 tree type;
11595 if (TREE_TYPE (parm) == error_mark_node)
11597 objc_parmlist = chainon (objc_parmlist, parm);
11598 return;
11601 /* Decay arrays and functions into pointers. */
11602 type = objc_decay_parm_type (TREE_TYPE (parm));
11604 /* If the parameter type has been decayed, a new PARM_DECL needs to be
11605 built as well. */
11606 if (type != TREE_TYPE (parm))
11607 parm = build_decl (input_location, PARM_DECL, DECL_NAME (parm), type);
11609 DECL_ARG_TYPE (parm)
11610 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
11612 /* Record constancy and volatility. */
11613 c_apply_type_quals_to_decl
11614 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
11615 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
11616 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
11618 objc_parmlist = chainon (objc_parmlist, parm);
11621 /* Retrieve the formal parameter list constructed via preceding calls to
11622 objc_push_parm(). */
11624 #ifdef OBJCPLUS
11625 static tree
11626 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
11627 #else
11628 static struct c_arg_info *
11629 objc_get_parm_info (int have_ellipsis)
11630 #endif
11632 #ifdef OBJCPLUS
11633 tree parm_info = objc_parmlist;
11634 objc_parmlist = NULL_TREE;
11636 return parm_info;
11637 #else
11638 tree parm_info = objc_parmlist;
11639 struct c_arg_info *arg_info;
11640 /* The C front-end requires an elaborate song and dance at
11641 this point. */
11642 push_scope ();
11643 declare_parm_level ();
11644 while (parm_info)
11646 tree next = DECL_CHAIN (parm_info);
11648 DECL_CHAIN (parm_info) = NULL_TREE;
11649 parm_info = pushdecl (parm_info);
11650 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
11651 parm_info = next;
11653 arg_info = get_parm_info (have_ellipsis);
11654 pop_scope ();
11655 objc_parmlist = NULL_TREE;
11656 return arg_info;
11657 #endif
11660 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
11661 method definitions. In the case of instance methods, we can be more
11662 specific as to the type of 'self'. */
11664 static void
11665 synth_self_and_ucmd_args (void)
11667 tree self_type;
11669 if (objc_method_context
11670 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
11671 self_type = objc_instance_type;
11672 else
11673 /* Really a `struct objc_class *'. However, we allow people to
11674 assign to self, which changes its type midstream. */
11675 self_type = objc_object_type;
11677 /* id self; */
11678 objc_push_parm (build_decl (input_location,
11679 PARM_DECL, self_id, self_type));
11681 /* SEL _cmd; */
11682 objc_push_parm (build_decl (input_location,
11683 PARM_DECL, ucmd_id, objc_selector_type));
11686 /* Transform an Objective-C method definition into a static C function
11687 definition, synthesizing the first two arguments, "self" and "_cmd",
11688 in the process. */
11690 static void
11691 start_method_def (tree method)
11693 tree parmlist;
11694 #ifdef OBJCPLUS
11695 tree parm_info;
11696 #else
11697 struct c_arg_info *parm_info;
11698 #endif
11699 int have_ellipsis = 0;
11701 /* If we are defining a "dealloc" method in a non-root class, we
11702 will need to check if a [super dealloc] is missing, and warn if
11703 it is. */
11704 if(CLASS_SUPER_NAME (objc_implementation_context)
11705 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
11706 should_call_super_dealloc = 1;
11707 else
11708 should_call_super_dealloc = 0;
11710 /* Required to implement _msgSuper. */
11711 objc_method_context = method;
11712 UOBJC_SUPER_decl = NULL_TREE;
11714 /* Generate prototype declarations for arguments..."new-style". */
11715 synth_self_and_ucmd_args ();
11717 /* Generate argument declarations if a keyword_decl. */
11718 parmlist = METHOD_SEL_ARGS (method);
11719 while (parmlist)
11721 /* parmlist is a KEYWORD_DECL. */
11722 tree type = TREE_VALUE (TREE_TYPE (parmlist));
11723 tree parm;
11725 parm = build_decl (input_location,
11726 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
11727 decl_attributes (&parm, DECL_ATTRIBUTES (parmlist), 0);
11728 objc_push_parm (parm);
11729 parmlist = DECL_CHAIN (parmlist);
11732 if (METHOD_ADD_ARGS (method))
11734 tree akey;
11736 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
11737 akey; akey = TREE_CHAIN (akey))
11739 objc_push_parm (TREE_VALUE (akey));
11742 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
11743 have_ellipsis = 1;
11746 parm_info = objc_get_parm_info (have_ellipsis);
11748 really_start_method (objc_method_context, parm_info);
11751 /* Return 1 if TYPE1 is equivalent to TYPE2
11752 for purposes of method overloading. */
11754 static int
11755 objc_types_are_equivalent (tree type1, tree type2)
11757 if (type1 == type2)
11758 return 1;
11760 /* Strip away indirections. */
11761 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
11762 && (TREE_CODE (type1) == TREE_CODE (type2)))
11763 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
11764 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
11765 return 0;
11767 type1 = (TYPE_HAS_OBJC_INFO (type1)
11768 ? TYPE_OBJC_PROTOCOL_LIST (type1)
11769 : NULL_TREE);
11770 type2 = (TYPE_HAS_OBJC_INFO (type2)
11771 ? TYPE_OBJC_PROTOCOL_LIST (type2)
11772 : NULL_TREE);
11774 if (list_length (type1) == list_length (type2))
11776 for (; type2; type2 = TREE_CHAIN (type2))
11777 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
11778 return 0;
11779 return 1;
11781 return 0;
11784 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
11786 static int
11787 objc_types_share_size_and_alignment (tree type1, tree type2)
11789 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
11790 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
11793 /* Return 1 if PROTO1 is equivalent to PROTO2
11794 for purposes of method overloading. Ordinarily, the type signatures
11795 should match up exactly, unless STRICT is zero, in which case we
11796 shall allow differences in which the size and alignment of a type
11797 is the same. */
11799 static int
11800 comp_proto_with_proto (tree proto1, tree proto2, int strict)
11802 /* The following test is needed in case there are hashing
11803 collisions. */
11804 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
11805 return 0;
11807 return match_proto_with_proto (proto1, proto2, strict);
11810 static int
11811 match_proto_with_proto (tree proto1, tree proto2, int strict)
11813 tree type1, type2;
11815 /* Compare return types. */
11816 type1 = TREE_VALUE (TREE_TYPE (proto1));
11817 type2 = TREE_VALUE (TREE_TYPE (proto2));
11819 if (!objc_types_are_equivalent (type1, type2)
11820 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
11821 return 0;
11823 /* Compare argument types. */
11824 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
11825 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
11826 type1 && type2;
11827 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
11829 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
11830 && (strict
11831 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
11832 TREE_VALUE (type2))))
11833 return 0;
11836 return (!type1 && !type2);
11839 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
11840 this occurs. ObjC method dispatches are _not_ like C++ virtual
11841 member function dispatches, and we account for the difference here. */
11842 tree
11843 #ifdef OBJCPLUS
11844 objc_fold_obj_type_ref (tree ref, tree known_type)
11845 #else
11846 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
11847 tree known_type ATTRIBUTE_UNUSED)
11848 #endif
11850 #ifdef OBJCPLUS
11851 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
11853 /* If the receiver does not have virtual member functions, there
11854 is nothing we can (or need to) do here. */
11855 if (!v)
11856 return NULL_TREE;
11858 /* Let C++ handle C++ virtual functions. */
11859 return cp_fold_obj_type_ref (ref, known_type);
11860 #else
11861 /* For plain ObjC, we currently do not need to do anything. */
11862 return NULL_TREE;
11863 #endif
11866 static void
11867 objc_start_function (tree name, tree type, tree attrs,
11868 #ifdef OBJCPLUS
11869 tree params
11870 #else
11871 struct c_arg_info *params
11872 #endif
11875 tree fndecl = build_decl (input_location,
11876 FUNCTION_DECL, name, type);
11878 #ifdef OBJCPLUS
11879 DECL_ARGUMENTS (fndecl) = params;
11880 DECL_INITIAL (fndecl) = error_mark_node;
11881 DECL_EXTERNAL (fndecl) = 0;
11882 TREE_STATIC (fndecl) = 1;
11883 retrofit_lang_decl (fndecl);
11884 cplus_decl_attributes (&fndecl, attrs, 0);
11885 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
11886 #else
11887 current_function_returns_value = 0; /* Assume, until we see it does. */
11888 current_function_returns_null = 0;
11889 decl_attributes (&fndecl, attrs, 0);
11890 announce_function (fndecl);
11891 DECL_INITIAL (fndecl) = error_mark_node;
11892 DECL_EXTERNAL (fndecl) = 0;
11893 TREE_STATIC (fndecl) = 1;
11894 current_function_decl = pushdecl (fndecl);
11895 push_scope ();
11896 declare_parm_level ();
11897 DECL_RESULT (current_function_decl)
11898 = build_decl (input_location,
11899 RESULT_DECL, NULL_TREE,
11900 TREE_TYPE (TREE_TYPE (current_function_decl)));
11901 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
11902 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
11903 start_fname_decls ();
11904 store_parm_decls_from (params);
11905 #endif
11907 TREE_USED (current_function_decl) = 1;
11910 /* - Generate an identifier for the function. the format is "_n_cls",
11911 where 1 <= n <= nMethods, and cls is the name the implementation we
11912 are processing.
11913 - Install the return type from the method declaration.
11914 - If we have a prototype, check for type consistency. */
11916 static void
11917 really_start_method (tree method,
11918 #ifdef OBJCPLUS
11919 tree parmlist
11920 #else
11921 struct c_arg_info *parmlist
11922 #endif
11925 tree ret_type, meth_type;
11926 tree method_id;
11927 const char *sel_name, *class_name, *cat_name;
11928 char *buf;
11930 /* Synth the storage class & assemble the return type. */
11931 ret_type = TREE_VALUE (TREE_TYPE (method));
11933 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
11934 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
11935 cat_name = ((TREE_CODE (objc_implementation_context)
11936 == CLASS_IMPLEMENTATION_TYPE)
11937 ? NULL
11938 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
11939 method_slot++;
11941 /* Make sure this is big enough for any plausible method label. */
11942 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
11943 + (cat_name ? strlen (cat_name) : 0));
11945 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
11946 class_name, cat_name, sel_name, method_slot);
11948 method_id = get_identifier (buf);
11950 #ifdef OBJCPLUS
11951 /* Objective-C methods cannot be overloaded, so we don't need
11952 the type encoding appended. It looks bad anyway... */
11953 push_lang_context (lang_name_c);
11954 #endif
11956 meth_type
11957 = build_function_type (ret_type,
11958 get_arg_type_list (method, METHOD_DEF, 0));
11959 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
11961 /* Set self_decl from the first argument. */
11962 self_decl = DECL_ARGUMENTS (current_function_decl);
11964 /* Suppress unused warnings. */
11965 TREE_USED (self_decl) = 1;
11966 DECL_READ_P (self_decl) = 1;
11967 TREE_USED (DECL_CHAIN (self_decl)) = 1;
11968 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
11969 #ifdef OBJCPLUS
11970 pop_lang_context ();
11971 #endif
11973 METHOD_DEFINITION (method) = current_function_decl;
11975 /* Check consistency...start_function, pushdecl, duplicate_decls. */
11977 if (implementation_template != objc_implementation_context)
11979 tree proto
11980 = lookup_method_static (implementation_template,
11981 METHOD_SEL_NAME (method),
11982 ((TREE_CODE (method) == CLASS_METHOD_DECL)
11983 | OBJC_LOOKUP_NO_SUPER));
11985 if (proto)
11987 if (!comp_proto_with_proto (method, proto, 1))
11989 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
11991 warning_at (DECL_SOURCE_LOCATION (method), 0,
11992 "conflicting types for %<%c%s%>",
11993 (type ? '-' : '+'),
11994 identifier_to_locale (gen_method_decl (method)));
11995 inform (DECL_SOURCE_LOCATION (proto),
11996 "previous declaration of %<%c%s%>",
11997 (type ? '-' : '+'),
11998 identifier_to_locale (gen_method_decl (proto)));
12000 else
12002 /* If the method in the @interface was deprecated, mark
12003 the implemented method as deprecated too. It should
12004 never be used for messaging (when the deprecation
12005 warnings are produced), but just in case. */
12006 if (TREE_DEPRECATED (proto))
12007 TREE_DEPRECATED (method) = 1;
12009 /* If the method in the @interface was marked as
12010 'noreturn', mark the function implementing the method
12011 as 'noreturn' too. */
12012 TREE_THIS_VOLATILE (current_function_decl) = TREE_THIS_VOLATILE (proto);
12015 else
12017 /* We have a method @implementation even though we did not
12018 see a corresponding @interface declaration (which is allowed
12019 by Objective-C rules). Go ahead and place the method in
12020 the @interface anyway, so that message dispatch lookups
12021 will see it. */
12022 tree interface = implementation_template;
12024 if (TREE_CODE (objc_implementation_context)
12025 == CATEGORY_IMPLEMENTATION_TYPE)
12026 interface = lookup_category
12027 (interface,
12028 CLASS_SUPER_NAME (objc_implementation_context));
12030 if (interface)
12031 objc_add_method (interface, copy_node (method),
12032 TREE_CODE (method) == CLASS_METHOD_DECL,
12033 /* is_optional= */ false);
12038 static void *UOBJC_SUPER_scope = 0;
12040 /* _n_Method (id self, SEL sel, ...)
12042 struct objc_super _S;
12043 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
12044 } */
12046 static tree
12047 get_super_receiver (void)
12049 if (objc_method_context)
12051 tree super_expr, super_expr_list;
12053 if (!UOBJC_SUPER_decl)
12055 UOBJC_SUPER_decl = build_decl (input_location,
12056 VAR_DECL, get_identifier (TAG_SUPER),
12057 objc_super_template);
12058 /* This prevents `unused variable' warnings when compiling with -Wall. */
12059 TREE_USED (UOBJC_SUPER_decl) = 1;
12060 DECL_READ_P (UOBJC_SUPER_decl) = 1;
12061 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
12062 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
12063 NULL_TREE);
12064 UOBJC_SUPER_scope = objc_get_current_scope ();
12067 /* Set receiver to self. */
12068 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
12069 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
12070 NOP_EXPR, input_location, self_decl,
12071 NULL_TREE);
12072 super_expr_list = super_expr;
12074 /* Set class to begin searching. */
12075 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
12076 get_identifier ("super_class"));
12078 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
12080 /* [_cls, __cls]Super are "pre-built" in
12081 synth_forward_declarations. */
12083 super_expr = build_modify_expr (input_location, super_expr,
12084 NULL_TREE, NOP_EXPR,
12085 input_location,
12086 ((TREE_CODE (objc_method_context)
12087 == INSTANCE_METHOD_DECL)
12088 ? ucls_super_ref
12089 : uucls_super_ref),
12090 NULL_TREE);
12093 else
12094 /* We have a category. */
12096 tree super_name = CLASS_SUPER_NAME (implementation_template);
12097 tree super_class;
12099 /* Barf if super used in a category of Object. */
12100 if (!super_name)
12102 error ("no super class declared in interface for %qE",
12103 CLASS_NAME (implementation_template));
12104 return error_mark_node;
12107 if (flag_next_runtime && !flag_zero_link)
12109 super_class = objc_get_class_reference (super_name);
12110 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
12111 /* If we are in a class method, we must retrieve the
12112 _metaclass_ for the current class, pointed at by
12113 the class's "isa" pointer. The following assumes that
12114 "isa" is the first ivar in a class (which it must be). */
12115 super_class
12116 = build_indirect_ref
12117 (input_location,
12118 build_c_cast (input_location,
12119 build_pointer_type (objc_class_type),
12120 super_class), RO_UNARY_STAR);
12122 else
12124 add_class_reference (super_name);
12125 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
12126 ? objc_get_class_decl : objc_get_meta_class_decl);
12127 assemble_external (super_class);
12128 super_class
12129 = build_function_call
12130 (input_location,
12131 super_class,
12132 build_tree_list
12133 (NULL_TREE,
12134 my_build_string_pointer
12135 (IDENTIFIER_LENGTH (super_name) + 1,
12136 IDENTIFIER_POINTER (super_name))));
12139 super_expr
12140 = build_modify_expr (input_location, super_expr, NULL_TREE,
12141 NOP_EXPR,
12142 input_location,
12143 build_c_cast (input_location,
12144 TREE_TYPE (super_expr),
12145 super_class),
12146 NULL_TREE);
12149 super_expr_list = build_compound_expr (input_location,
12150 super_expr_list, super_expr);
12152 super_expr = build_unary_op (input_location,
12153 ADDR_EXPR, UOBJC_SUPER_decl, 0);
12154 super_expr_list = build_compound_expr (input_location,
12155 super_expr_list, super_expr);
12157 return super_expr_list;
12159 else
12161 error ("[super ...] must appear in a method context");
12162 return error_mark_node;
12166 /* When exiting a scope, sever links to a 'super' declaration (if any)
12167 therein contained. */
12169 void
12170 objc_clear_super_receiver (void)
12172 if (objc_method_context
12173 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
12174 UOBJC_SUPER_decl = 0;
12175 UOBJC_SUPER_scope = 0;
12179 void
12180 objc_finish_method_definition (tree fndecl)
12182 /* We cannot validly inline ObjC methods, at least not without a language
12183 extension to declare that a method need not be dynamically
12184 dispatched, so suppress all thoughts of doing so. */
12185 DECL_UNINLINABLE (fndecl) = 1;
12187 #ifndef OBJCPLUS
12188 /* The C++ front-end will have called finish_function() for us. */
12189 finish_function ();
12190 #endif
12192 METHOD_ENCODING (objc_method_context)
12193 = encode_method_prototype (objc_method_context);
12195 /* Required to implement _msgSuper. This must be done AFTER finish_function,
12196 since the optimizer may find "may be used before set" errors. */
12197 objc_method_context = NULL_TREE;
12199 if (should_call_super_dealloc)
12200 warning (0, "method possibly missing a [super dealloc] call");
12203 /* Given a tree DECL node, produce a printable description of it in the given
12204 buffer, overwriting the buffer. */
12206 static char *
12207 gen_declaration (tree decl)
12209 errbuf[0] = '\0';
12211 if (DECL_P (decl))
12213 gen_type_name_0 (TREE_TYPE (decl));
12215 if (DECL_NAME (decl))
12217 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
12218 strcat (errbuf, " ");
12220 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
12223 if (DECL_INITIAL (decl)
12224 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
12225 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
12226 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
12229 return errbuf;
12232 /* Given a tree TYPE node, produce a printable description of it in the given
12233 buffer, overwriting the buffer. */
12235 static char *
12236 gen_type_name_0 (tree type)
12238 tree orig = type, proto;
12240 if (TYPE_P (type) && TYPE_NAME (type))
12241 type = TYPE_NAME (type);
12242 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
12244 tree inner = TREE_TYPE (type);
12246 while (TREE_CODE (inner) == ARRAY_TYPE)
12247 inner = TREE_TYPE (inner);
12249 gen_type_name_0 (inner);
12251 if (!POINTER_TYPE_P (inner))
12252 strcat (errbuf, " ");
12254 if (POINTER_TYPE_P (type))
12255 strcat (errbuf, "*");
12256 else
12257 while (type != inner)
12259 strcat (errbuf, "[");
12261 if (TYPE_DOMAIN (type))
12263 char sz[20];
12265 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
12266 (TREE_INT_CST_LOW
12267 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
12268 strcat (errbuf, sz);
12271 strcat (errbuf, "]");
12272 type = TREE_TYPE (type);
12275 goto exit_function;
12278 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
12279 type = DECL_NAME (type);
12281 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
12282 ? IDENTIFIER_POINTER (type)
12283 : "");
12285 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
12286 if (objc_is_id (orig))
12287 orig = TREE_TYPE (orig);
12289 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
12291 if (proto)
12293 strcat (errbuf, " <");
12295 while (proto) {
12296 strcat (errbuf,
12297 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
12298 proto = TREE_CHAIN (proto);
12299 strcat (errbuf, proto ? ", " : ">");
12303 exit_function:
12304 return errbuf;
12307 static char *
12308 gen_type_name (tree type)
12310 errbuf[0] = '\0';
12312 return gen_type_name_0 (type);
12315 /* Given a method tree, put a printable description into the given
12316 buffer (overwriting) and return a pointer to the buffer. */
12318 static char *
12319 gen_method_decl (tree method)
12321 tree chain;
12323 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
12324 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
12325 strcat (errbuf, ")");
12326 chain = METHOD_SEL_ARGS (method);
12328 if (chain)
12330 /* We have a chain of keyword_decls. */
12333 if (KEYWORD_KEY_NAME (chain))
12334 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
12336 strcat (errbuf, ":(");
12337 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
12338 strcat (errbuf, ")");
12340 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
12341 if ((chain = DECL_CHAIN (chain)))
12342 strcat (errbuf, " ");
12344 while (chain);
12346 if (METHOD_ADD_ARGS (method))
12348 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
12350 /* Know we have a chain of parm_decls. */
12351 while (chain)
12353 strcat (errbuf, ", ");
12354 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
12355 chain = TREE_CHAIN (chain);
12358 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
12359 strcat (errbuf, ", ...");
12363 else
12364 /* We have a unary selector. */
12365 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
12367 return errbuf;
12370 /* Debug info. */
12373 /* Dump an @interface declaration of the supplied class CHAIN to the
12374 supplied file FP. Used to implement the -gen-decls option (which
12375 prints out an @interface declaration of all classes compiled in
12376 this run); potentially useful for debugging the compiler too. */
12377 static void
12378 dump_interface (FILE *fp, tree chain)
12380 /* FIXME: A heap overflow here whenever a method (or ivar)
12381 declaration is so long that it doesn't fit in the buffer. The
12382 code and all the related functions should be rewritten to avoid
12383 using fixed size buffers. */
12384 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
12385 tree ivar_decls = CLASS_RAW_IVARS (chain);
12386 tree nst_methods = CLASS_NST_METHODS (chain);
12387 tree cls_methods = CLASS_CLS_METHODS (chain);
12389 fprintf (fp, "\n@interface %s", my_name);
12391 /* CLASS_SUPER_NAME is used to store the superclass name for
12392 classes, and the category name for categories. */
12393 if (CLASS_SUPER_NAME (chain))
12395 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
12397 switch (TREE_CODE (chain))
12399 case CATEGORY_IMPLEMENTATION_TYPE:
12400 case CATEGORY_INTERFACE_TYPE:
12401 fprintf (fp, " (%s)\n", name);
12402 break;
12403 default:
12404 fprintf (fp, " : %s\n", name);
12405 break;
12408 else
12409 fprintf (fp, "\n");
12411 /* FIXME - the following doesn't seem to work at the moment. */
12412 if (ivar_decls)
12414 fprintf (fp, "{\n");
12417 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
12418 ivar_decls = TREE_CHAIN (ivar_decls);
12420 while (ivar_decls);
12421 fprintf (fp, "}\n");
12424 while (nst_methods)
12426 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
12427 nst_methods = TREE_CHAIN (nst_methods);
12430 while (cls_methods)
12432 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
12433 cls_methods = TREE_CHAIN (cls_methods);
12436 fprintf (fp, "@end\n");
12439 #if 0
12440 /* Produce the pretty printing for an Objective-C method. This is
12441 currently unused, but could be handy while reorganizing the pretty
12442 printing to be more robust. */
12443 static const char *
12444 objc_pretty_print_method (bool is_class_method,
12445 const char *class_name,
12446 const char *category_name,
12447 const char *selector)
12449 if (category_name)
12451 char *result = XNEWVEC (char, strlen (class_name) + strlen (category_name)
12452 + strlen (selector) + 7);
12454 if (is_class_method)
12455 sprintf (result, "+[%s(%s) %s]", class_name, category_name, selector);
12456 else
12457 sprintf (result, "-[%s(%s) %s]", class_name, category_name, selector);
12459 return result;
12461 else
12463 char *result = XNEWVEC (char, strlen (class_name)
12464 + strlen (selector) + 5);
12466 if (is_class_method)
12467 sprintf (result, "+[%s %s]", class_name, selector);
12468 else
12469 sprintf (result, "-[%s %s]", class_name, selector);
12471 return result;
12474 #endif
12476 /* Demangle function for Objective-C. Attempt to demangle the
12477 function name associated with a method (eg, going from
12478 "_i_NSObject__class" to "-[NSObject class]"); usually for the
12479 purpose of pretty printing or error messages. Return the demangled
12480 name, or NULL if the string is not an Objective-C mangled method
12481 name.
12483 Because of how the mangling is done, any method that has a '_' in
12484 its original name is at risk of being demangled incorrectly. In
12485 some cases there are multiple valid ways to demangle a method name
12486 and there is no way we can decide.
12488 TODO: objc_demangle() can't always get it right; the right way to
12489 get this correct for all method names would be to store the
12490 Objective-C method name somewhere in the function decl. Then,
12491 there is no demangling to do; we'd just pull the method name out of
12492 the decl. As an additional bonus, when printing error messages we
12493 could check for such a method name, and if we find it, we know the
12494 function is actually an Objective-C method and we could print error
12495 messages saying "In method '+[NSObject class]" instead of "In
12496 function '+[NSObject class]" as we do now. */
12497 static const char *
12498 objc_demangle (const char *mangled)
12500 char *demangled, *cp;
12502 /* First of all, if the name is too short it can't be an Objective-C
12503 mangled method name. */
12504 if (mangled[0] == '\0' || mangled[1] == '\0' || mangled[2] == '\0')
12505 return NULL;
12507 /* If the name looks like an already demangled one, return it
12508 unchanged. This should only happen on Darwin, where method names
12509 are mangled differently into a pretty-print form (such as
12510 '+[NSObject class]', see darwin.h). In that case, demangling is
12511 a no-op, but we need to return the demangled name if it was an
12512 ObjC one, and return NULL if not. We should be safe as no C/C++
12513 function can start with "-[" or "+[". */
12514 if ((mangled[0] == '-' || mangled[0] == '+')
12515 && (mangled[1] == '['))
12516 return mangled;
12518 if (mangled[0] == '_' &&
12519 (mangled[1] == 'i' || mangled[1] == 'c') &&
12520 mangled[2] == '_')
12522 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
12523 if (mangled[1] == 'i')
12524 *cp++ = '-'; /* for instance method */
12525 else
12526 *cp++ = '+'; /* for class method */
12527 *cp++ = '['; /* opening left brace */
12528 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
12529 while (*cp && *cp == '_')
12530 cp++; /* skip any initial underbars in class name */
12531 cp = strchr(cp, '_'); /* find first non-initial underbar */
12532 if (cp == NULL)
12534 free(demangled); /* not mangled name */
12535 return NULL;
12537 if (cp[1] == '_') /* easy case: no category name */
12539 *cp++ = ' '; /* replace two '_' with one ' ' */
12540 strcpy(cp, mangled + (cp - demangled) + 2);
12542 else
12544 *cp++ = '('; /* less easy case: category name */
12545 cp = strchr(cp, '_');
12546 if (cp == 0)
12548 free(demangled); /* not mangled name */
12549 return NULL;
12551 *cp++ = ')';
12552 *cp++ = ' '; /* overwriting 1st char of method name... */
12553 strcpy(cp, mangled + (cp - demangled)); /* get it back */
12555 /* Now we have the method name. We need to generally replace
12556 '_' with ':' but trying to preserve '_' if it could only have
12557 been in the mangled string because it was already in the
12558 original name. In cases where it's ambiguous, we assume that
12559 any '_' originated from a ':'. */
12561 /* Initial '_'s in method name can't have been generating by
12562 converting ':'s. Skip them. */
12563 while (*cp && *cp == '_')
12564 cp++;
12566 /* If the method name does not end with '_', then it has no
12567 arguments and there was no replacement of ':'s with '_'s
12568 during mangling. Check for that case, and skip any
12569 replacement if so. This at least guarantees that methods
12570 with no arguments are always demangled correctly (unless the
12571 original name ends with '_'). */
12572 if (*(mangled + strlen (mangled) - 1) != '_')
12574 /* Skip to the end. */
12575 for (; *cp; cp++)
12578 else
12580 /* Replace remaining '_' with ':'. This may get it wrong if
12581 there were '_'s in the original name. In most cases it
12582 is impossible to disambiguate. */
12583 for (; *cp; cp++)
12584 if (*cp == '_')
12585 *cp = ':';
12587 *cp++ = ']'; /* closing right brace */
12588 *cp++ = 0; /* string terminator */
12589 return demangled;
12591 else
12592 return NULL; /* not an objc mangled name */
12595 /* Try to pretty-print a decl. If the 'decl' is an Objective-C
12596 specific decl, return the printable name for it. If not, return
12597 NULL. */
12598 const char *
12599 objc_maybe_printable_name (tree decl, int v ATTRIBUTE_UNUSED)
12601 switch (TREE_CODE (decl))
12603 case FUNCTION_DECL:
12604 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
12605 break;
12607 /* The following happens when we are printing a deprecation
12608 warning for a method. The warn_deprecation() will end up
12609 trying to print the decl for INSTANCE_METHOD_DECL or
12610 CLASS_METHOD_DECL. It would be nice to be able to print
12611 "-[NSObject autorelease] is deprecated", but to do that, we'd
12612 need to store the class and method name in the method decl,
12613 which we currently don't do. For now, just return the name
12614 of the method. We don't return NULL, because that may
12615 trigger further attempts to pretty-print the decl in C/C++,
12616 but they wouldn't know how to pretty-print it. */
12617 case INSTANCE_METHOD_DECL:
12618 case CLASS_METHOD_DECL:
12619 return IDENTIFIER_POINTER (DECL_NAME (decl));
12620 break;
12621 /* This happens when printing a deprecation warning for a
12622 property. We may want to consider some sort of pretty
12623 printing (eg, include the class name where it was declared
12624 ?). */
12625 case PROPERTY_DECL:
12626 return IDENTIFIER_POINTER (PROPERTY_NAME (decl));
12627 break;
12628 default:
12629 return NULL;
12630 break;
12634 /* Return a printable name for 'decl'. This first tries
12635 objc_maybe_printable_name(), and if that fails, it returns the name
12636 in the decl. This is used as LANG_HOOKS_DECL_PRINTABLE_NAME for
12637 Objective-C; in Objective-C++, setting the hook is not enough
12638 because lots of C++ Front-End code calls cxx_printable_name,
12639 dump_decl and other C++ functions directly. So instead we have
12640 modified dump_decl to call objc_maybe_printable_name directly. */
12641 const char *
12642 objc_printable_name (tree decl, int v)
12644 const char *demangled_name = objc_maybe_printable_name (decl, v);
12646 if (demangled_name != NULL)
12647 return demangled_name;
12648 else
12649 return IDENTIFIER_POINTER (DECL_NAME (decl));
12652 static void
12653 init_objc (void)
12655 gcc_obstack_init (&util_obstack);
12656 util_firstobj = (char *) obstack_finish (&util_obstack);
12658 errbuf = XNEWVEC (char, 1024 * 10);
12659 hash_init ();
12660 synth_module_prologue ();
12663 static void
12664 finish_objc (void)
12666 struct imp_entry *impent;
12667 tree chain;
12668 /* The internally generated initializers appear to have missing braces.
12669 Don't warn about this. */
12670 int save_warn_missing_braces = warn_missing_braces;
12671 warn_missing_braces = 0;
12673 /* A missing @end may not be detected by the parser. */
12674 if (objc_implementation_context)
12676 warning (0, "%<@end%> missing in implementation context");
12677 finish_class (objc_implementation_context);
12678 objc_ivar_chain = NULL_TREE;
12679 objc_implementation_context = NULL_TREE;
12682 /* Process the static instances here because initialization of objc_symtab
12683 depends on them. */
12684 if (objc_static_instances)
12685 generate_static_references ();
12687 /* forward declare categories */
12688 if (cat_count)
12689 forward_declare_categories ();
12691 for (impent = imp_list; impent; impent = impent->next)
12693 objc_implementation_context = impent->imp_context;
12694 implementation_template = impent->imp_template;
12696 /* FIXME: This needs reworking to be more obvious. */
12698 UOBJC_CLASS_decl = impent->class_decl;
12699 UOBJC_METACLASS_decl = impent->meta_decl;
12701 /* Dump the @interface of each class as we compile it, if the
12702 -gen-decls option is in use. TODO: Dump the classes in the
12703 order they were found, rather than in reverse order as we
12704 are doing now. */
12705 if (flag_gen_declaration)
12707 dump_interface (gen_declaration_file, objc_implementation_context);
12710 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
12712 /* all of the following reference the string pool... */
12713 generate_ivar_lists ();
12714 generate_dispatch_tables ();
12715 generate_shared_structures (impent);
12717 else
12719 generate_dispatch_tables ();
12720 generate_category (impent);
12723 impent->class_decl = UOBJC_CLASS_decl;
12724 impent->meta_decl = UOBJC_METACLASS_decl;
12727 /* If we are using an array of selectors, we must always
12728 finish up the array decl even if no selectors were used. */
12729 if (flag_next_runtime)
12730 build_next_selector_translation_table ();
12731 else
12732 build_gnu_selector_translation_table ();
12734 if (protocol_chain)
12735 generate_protocols ();
12737 if (flag_next_runtime)
12738 generate_objc_image_info ();
12740 if (imp_list || class_names_chain
12741 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12742 generate_objc_symtab_decl ();
12744 /* Arrange for ObjC data structures to be initialized at run time. */
12745 if (objc_implementation_context || class_names_chain || objc_static_instances
12746 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
12748 build_module_descriptor ();
12750 if (!flag_next_runtime)
12751 build_module_initializer_routine ();
12754 /* Dump the class references. This forces the appropriate classes
12755 to be linked into the executable image, preserving unix archive
12756 semantics. This can be removed when we move to a more dynamically
12757 linked environment. */
12759 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
12761 handle_class_ref (chain);
12762 if (TREE_PURPOSE (chain))
12763 generate_classref_translation_entry (chain);
12766 for (impent = imp_list; impent; impent = impent->next)
12767 handle_impent (impent);
12769 if (warn_selector)
12771 int slot;
12772 hash hsh;
12774 /* Run through the selector hash tables and print a warning for any
12775 selector which has multiple methods. */
12777 for (slot = 0; slot < SIZEHASHTABLE; slot++)
12779 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
12780 check_duplicates (hsh, 0, 1);
12781 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
12782 check_duplicates (hsh, 0, 1);
12786 warn_missing_braces = save_warn_missing_braces;
12789 /* Subroutines of finish_objc. */
12791 static void
12792 generate_classref_translation_entry (tree chain)
12794 tree expr, decl, type;
12796 decl = TREE_PURPOSE (chain);
12797 type = TREE_TYPE (decl);
12799 expr = add_objc_string (TREE_VALUE (chain), class_names);
12800 expr = convert (type, expr); /* cast! */
12802 /* This is a class reference. It is re-written by the runtime,
12803 but will be optimized away unless we force it. */
12804 DECL_PRESERVE_P (decl) = 1;
12805 finish_var_decl (decl, expr);
12806 return;
12809 static void
12810 handle_class_ref (tree chain)
12812 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
12813 char *string = (char *) alloca (strlen (name) + 30);
12814 tree decl;
12815 tree exp;
12817 sprintf (string, "%sobjc_class_name_%s",
12818 (flag_next_runtime ? "." : "__"), name);
12820 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
12821 if (flag_next_runtime)
12823 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
12824 return;
12826 #endif
12828 /* Make a decl for this name, so we can use its address in a tree. */
12829 decl = build_decl (input_location,
12830 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
12831 DECL_EXTERNAL (decl) = 1;
12832 TREE_PUBLIC (decl) = 1;
12833 pushdecl (decl);
12834 finish_var_decl (decl, 0);
12836 /* Make a decl for the address. */
12837 sprintf (string, "%sobjc_class_ref_%s",
12838 (flag_next_runtime ? "." : "__"), name);
12839 exp = build1 (ADDR_EXPR, string_type_node, decl);
12840 decl = build_decl (input_location,
12841 VAR_DECL, get_identifier (string), string_type_node);
12842 TREE_STATIC (decl) = 1;
12843 TREE_USED (decl) = 1;
12844 DECL_READ_P (decl) = 1;
12845 DECL_ARTIFICIAL (decl) = 1;
12846 DECL_INITIAL (decl) = error_mark_node;
12848 /* We must force the reference. */
12849 DECL_PRESERVE_P (decl) = 1;
12851 pushdecl (decl);
12852 finish_var_decl (decl, exp);
12855 static void
12856 handle_impent (struct imp_entry *impent)
12858 char *string;
12860 objc_implementation_context = impent->imp_context;
12861 implementation_template = impent->imp_template;
12863 switch (TREE_CODE (impent->imp_context))
12865 case CLASS_IMPLEMENTATION_TYPE:
12867 const char *const class_name =
12868 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12870 string = (char *) alloca (strlen (class_name) + 30);
12872 sprintf (string, "%sobjc_class_name_%s",
12873 (flag_next_runtime ? "." : "__"), class_name);
12874 break;
12876 case CATEGORY_IMPLEMENTATION_TYPE:
12878 const char *const class_name =
12879 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
12880 const char *const class_super_name =
12881 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
12883 string = (char *) alloca (strlen (class_name)
12884 + strlen (class_super_name) + 30);
12886 /* Do the same for categories. Even though no references to
12887 these symbols are generated automatically by the compiler,
12888 it gives you a handle to pull them into an archive by
12889 hand. */
12890 sprintf (string, "*%sobjc_category_name_%s_%s",
12891 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
12892 break;
12894 default:
12895 return;
12898 #ifdef ASM_DECLARE_CLASS_REFERENCE
12899 if (flag_next_runtime)
12901 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
12902 return;
12904 else
12905 #endif
12907 tree decl, init;
12909 init = integer_zero_node;
12910 decl = build_decl (input_location,
12911 VAR_DECL, get_identifier (string), TREE_TYPE (init));
12912 TREE_PUBLIC (decl) = 1;
12913 TREE_READONLY (decl) = 1;
12914 TREE_USED (decl) = 1;
12915 TREE_CONSTANT (decl) = 1;
12916 DECL_CONTEXT (decl) = NULL_TREE;
12917 DECL_ARTIFICIAL (decl) = 1;
12918 TREE_STATIC (decl) = 1;
12919 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
12920 /* We must force the reference. */
12921 DECL_PRESERVE_P (decl) = 1;
12923 finish_var_decl(decl, init) ;
12927 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
12928 later requires that ObjC translation units participating in F&C be
12929 specially marked. The following routine accomplishes this. */
12931 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
12933 static void
12934 generate_objc_image_info (void)
12936 tree decl;
12937 int flags
12938 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
12939 | (flag_objc_gc ? 2 : 0));
12940 VEC(constructor_elt,gc) *v = NULL;
12941 tree array_type;
12943 if (!flags)
12944 return; /* No need for an image_info entry. */
12946 array_type = build_sized_array_type (integer_type_node, 2);
12948 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
12950 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
12951 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
12952 /* If we need this (determined above) it is because the runtime wants to
12953 refer to it in a manner hidden from the compiler. So we must force the
12954 output. */
12955 DECL_PRESERVE_P (decl) = 1;
12956 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
12959 /* Routine is called to issue diagnostic when reference to a private
12960 ivar is made and no other variable with same name is found in
12961 current scope. */
12962 bool
12963 objc_diagnose_private_ivar (tree id)
12965 tree ivar;
12966 if (!objc_method_context)
12967 return false;
12968 ivar = is_ivar (objc_ivar_chain, id);
12969 if (ivar && is_private (ivar))
12971 error ("instance variable %qs is declared private",
12972 IDENTIFIER_POINTER (id));
12973 return true;
12975 return false;
12978 /* Look up ID as an instance variable. OTHER contains the result of
12979 the C or C++ lookup, which we may want to use instead. */
12980 /* To use properties inside an instance method, use self.property. */
12981 tree
12982 objc_lookup_ivar (tree other, tree id)
12984 tree ivar;
12986 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
12987 if (!objc_method_context)
12988 return other;
12990 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
12991 /* We have a message to super. */
12992 return get_super_receiver ();
12994 /* In a class method, look up an instance variable only as a last
12995 resort. */
12996 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
12997 && other && other != error_mark_node)
12998 return other;
13000 /* Look up the ivar, but do not use it if it is not accessible. */
13001 ivar = is_ivar (objc_ivar_chain, id);
13003 if (!ivar || is_private (ivar))
13004 return other;
13006 /* In an instance method, a local variable (or parameter) may hide the
13007 instance variable. */
13008 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
13009 && other && other != error_mark_node
13010 #ifdef OBJCPLUS
13011 && CP_DECL_CONTEXT (other) != global_namespace)
13012 #else
13013 && !DECL_FILE_SCOPE_P (other))
13014 #endif
13016 warning (0, "local declaration of %qE hides instance variable", id);
13018 return other;
13021 /* At this point, we are either in an instance method with no obscuring
13022 local definitions, or in a class method with no alternate definitions
13023 at all. */
13024 return build_ivar_reference (id);
13027 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
13028 needs to be done if we are calling a function through a cast. */
13030 tree
13031 objc_rewrite_function_call (tree function, tree first_param)
13033 if (TREE_CODE (function) == NOP_EXPR
13034 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
13035 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
13036 == FUNCTION_DECL)
13038 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
13039 TREE_OPERAND (function, 0),
13040 first_param, size_zero_node);
13043 return function;
13046 /* This is called to "gimplify" a PROPERTY_REF node. It builds the
13047 corresponding 'getter' function call. Note that we assume the
13048 PROPERTY_REF to be valid since we generated it while parsing. */
13049 static void
13050 objc_gimplify_property_ref (tree *expr_p)
13052 tree getter = PROPERTY_REF_GETTER_CALL (*expr_p);
13053 tree call_exp;
13055 if (getter == NULL_TREE)
13057 tree property_decl = PROPERTY_REF_PROPERTY_DECL (*expr_p);
13058 /* This can happen if DECL_ARTIFICIAL (*expr_p), but
13059 should be impossible for real properties, which always
13060 have a getter. */
13061 error_at (EXPR_LOCATION (*expr_p), "no %qs getter found",
13062 IDENTIFIER_POINTER (PROPERTY_NAME (property_decl)));
13063 /* Try to recover from the error to prevent an ICE. We take
13064 zero and cast it to the type of the property. */
13065 *expr_p = convert (TREE_TYPE (property_decl),
13066 integer_zero_node);
13067 return;
13070 call_exp = getter;
13071 #ifdef OBJCPLUS
13072 /* In C++, a getter which returns an aggregate value results in a
13073 target_expr which initializes a temporary to the call
13074 expression. */
13075 if (TREE_CODE (getter) == TARGET_EXPR)
13077 gcc_assert (MAYBE_CLASS_TYPE_P (TREE_TYPE (getter)));
13078 gcc_assert (TREE_CODE (TREE_OPERAND (getter, 0)) == VAR_DECL);
13079 call_exp = TREE_OPERAND (getter, 1);
13081 #endif
13082 gcc_assert (TREE_CODE (call_exp) == CALL_EXPR);
13084 *expr_p = call_exp;
13087 /* This is called when "gimplifying" the trees. We need to gimplify
13088 the Objective-C/Objective-C++ specific trees, then hand over the
13089 process to C/C++. */
13091 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
13093 enum tree_code code = TREE_CODE (*expr_p);
13094 switch (code)
13096 /* Look for the special case of OBJC_TYPE_REF with the address
13097 of a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend
13098 or one of its cousins). */
13099 case OBJ_TYPE_REF:
13100 if (TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
13101 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
13102 == FUNCTION_DECL)
13104 enum gimplify_status r0, r1;
13106 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
13107 value of the OBJ_TYPE_REF, so force them to be emitted
13108 during subexpression evaluation rather than after the
13109 OBJ_TYPE_REF. This permits objc_msgSend calls in
13110 Objective C to use direct rather than indirect calls when
13111 the object expression has a postincrement. */
13112 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
13113 is_gimple_val, fb_rvalue);
13114 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
13115 is_gimple_val, fb_rvalue);
13117 return MIN (r0, r1);
13119 break;
13120 case PROPERTY_REF:
13121 objc_gimplify_property_ref (expr_p);
13122 /* Do not return yet; let C/C++ gimplify the resulting expression. */
13123 break;
13124 default:
13125 break;
13128 #ifdef OBJCPLUS
13129 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
13130 #else
13131 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
13132 #endif
13135 /* This routine returns true if TYPE is a valid objc object type,
13136 suitable for messaging; false otherwise. If 'accept_class' is
13137 'true', then a Class object is considered valid for messaging and
13138 'true' is returned if 'type' refers to a Class. If 'accept_class'
13139 is 'false', then a Class object is not considered valid for
13140 messaging and 'false' is returned in that case. */
13142 static bool
13143 objc_type_valid_for_messaging (tree type, bool accept_classes)
13145 if (!POINTER_TYPE_P (type))
13146 return false;
13148 /* Remove the pointer indirection; don't remove more than one
13149 otherwise we'd consider "NSObject **" a valid type for messaging,
13150 which it isn't. */
13151 type = TREE_TYPE (type);
13153 if (TREE_CODE (type) != RECORD_TYPE)
13154 return false;
13156 if (objc_is_object_id (type))
13157 return true;
13159 if (objc_is_class_id (type))
13160 return accept_classes;
13162 if (TYPE_HAS_OBJC_INFO (type))
13163 return true;
13165 return false;
13168 /* Begin code generation for fast enumeration (foreach) ... */
13170 /* Defines
13172 struct __objcFastEnumerationState
13174 unsigned long state;
13175 id *itemsPtr;
13176 unsigned long *mutationsPtr;
13177 unsigned long extra[5];
13180 Confusingly enough, NSFastEnumeration is then defined by libraries
13181 to be the same structure.
13184 static void
13185 build_fast_enumeration_state_template (void)
13187 tree decls, *chain = NULL;
13189 /* { */
13190 objc_fast_enumeration_state_template = objc_start_struct (get_identifier
13191 (TAG_FAST_ENUMERATION_STATE));
13193 /* unsigned long state; */
13194 decls = add_field_decl (long_unsigned_type_node, "state", &chain);
13196 /* id *itemsPtr; */
13197 add_field_decl (build_pointer_type (objc_object_type),
13198 "itemsPtr", &chain);
13200 /* unsigned long *mutationsPtr; */
13201 add_field_decl (build_pointer_type (long_unsigned_type_node),
13202 "mutationsPtr", &chain);
13204 /* unsigned long extra[5]; */
13205 add_field_decl (build_sized_array_type (long_unsigned_type_node, 5),
13206 "extra", &chain);
13208 /* } */
13209 objc_finish_struct (objc_fast_enumeration_state_template, decls);
13213 'objc_finish_foreach_loop()' generates the code for an Objective-C
13214 foreach loop. The 'location' argument is the location of the 'for'
13215 that starts the loop. The 'object_expression' is the expression of
13216 the 'object' that iterates; the 'collection_expression' is the
13217 expression of the collection that we iterate over (we need to make
13218 sure we evaluate this only once); the 'for_body' is the set of
13219 statements to be executed in each iteration; 'break_label' and
13220 'continue_label' are the break and continue labels which we need to
13221 emit since the <statements> may be jumping to 'break_label' (if they
13222 contain 'break') or to 'continue_label' (if they contain
13223 'continue').
13225 The syntax is
13227 for (<object expression> in <collection expression>)
13228 <statements>
13230 which is compiled into the following blurb:
13233 id __objc_foreach_collection;
13234 __objc_fast_enumeration_state __objc_foreach_enum_state;
13235 unsigned long __objc_foreach_batchsize;
13236 id __objc_foreach_items[16];
13237 __objc_foreach_collection = <collection expression>;
13238 __objc_foreach_enum_state = { 0 };
13239 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
13241 if (__objc_foreach_batchsize == 0)
13242 <object expression> = nil;
13243 else
13245 unsigned long __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr;
13246 next_batch:
13248 unsigned long __objc_foreach_index;
13249 __objc_foreach_index = 0;
13251 next_object:
13252 if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>);
13253 <object expression> = enumState.itemsPtr[__objc_foreach_index];
13254 <statements> [PS: inside <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label]
13256 continue_label:
13257 __objc_foreach_index++;
13258 if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object;
13259 __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16];
13261 if (__objc_foreach_batchsize != 0) goto next_batch;
13262 <object expression> = nil;
13263 break_label:
13267 'statements' may contain a 'continue' or 'break' instruction, which
13268 the user expects to 'continue' or 'break' the entire foreach loop.
13269 We are provided the labels that 'break' and 'continue' jump to, so
13270 we place them where we want them to jump to when they pick them.
13272 Optimization TODO: we could cache the IMP of
13273 countByEnumeratingWithState:objects:count:.
13276 /* If you need to debug objc_finish_foreach_loop(), uncomment the following line. */
13277 /* #define DEBUG_OBJC_FINISH_FOREACH_LOOP 1 */
13279 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
13280 #include "tree-pretty-print.h"
13281 #endif
13283 void
13284 objc_finish_foreach_loop (location_t location, tree object_expression, tree collection_expression, tree for_body,
13285 tree break_label, tree continue_label)
13287 /* A tree representing the __objcFastEnumerationState struct type,
13288 or NSFastEnumerationState struct, whatever we are using. */
13289 tree objc_fast_enumeration_state_type;
13291 /* The trees representing the declarations of each of the local variables. */
13292 tree objc_foreach_collection_decl;
13293 tree objc_foreach_enum_state_decl;
13294 tree objc_foreach_items_decl;
13295 tree objc_foreach_batchsize_decl;
13296 tree objc_foreach_mutations_pointer_decl;
13297 tree objc_foreach_index_decl;
13299 /* A tree representing the selector countByEnumeratingWithState:objects:count:. */
13300 tree selector_name;
13302 /* A tree representing the local bind. */
13303 tree bind;
13305 /* A tree representing the external 'if (__objc_foreach_batchsize)' */
13306 tree first_if;
13308 /* A tree representing the 'else' part of 'first_if' */
13309 tree first_else;
13311 /* A tree representing the 'next_batch' label. */
13312 tree next_batch_label_decl;
13314 /* A tree representing the binding after the 'next_batch' label. */
13315 tree next_batch_bind;
13317 /* A tree representing the 'next_object' label. */
13318 tree next_object_label_decl;
13320 /* Temporary variables. */
13321 tree t;
13322 int i;
13324 if (flag_objc1_only)
13325 error_at (location, "fast enumeration is not available in Objective-C 1.0");
13327 if (object_expression == error_mark_node)
13328 return;
13330 if (collection_expression == error_mark_node)
13331 return;
13333 if (!objc_type_valid_for_messaging (TREE_TYPE (object_expression), true))
13335 error_at (location, "iterating variable in fast enumeration is not an object");
13336 return;
13339 if (!objc_type_valid_for_messaging (TREE_TYPE (collection_expression), true))
13341 error_at (location, "collection in fast enumeration is not an object");
13342 return;
13345 /* TODO: Check that object_expression is either a variable
13346 declaration, or an lvalue. */
13348 /* This kludge is an idea from apple. We use the
13349 __objcFastEnumerationState struct implicitly defined by the
13350 compiler, unless a NSFastEnumerationState struct has been defined
13351 (by a Foundation library such as GNUstep Base) in which case, we
13352 use that one.
13354 objc_fast_enumeration_state_type = objc_fast_enumeration_state_template;
13356 tree objc_NSFastEnumeration_type = lookup_name (get_identifier ("NSFastEnumerationState"));
13358 if (objc_NSFastEnumeration_type)
13360 /* TODO: We really need to check that
13361 objc_NSFastEnumeration_type is the same as ours! */
13362 if (TREE_CODE (objc_NSFastEnumeration_type) == TYPE_DECL)
13364 /* If it's a typedef, use the original type. */
13365 if (DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type))
13366 objc_fast_enumeration_state_type = DECL_ORIGINAL_TYPE (objc_NSFastEnumeration_type);
13367 else
13368 objc_fast_enumeration_state_type = TREE_TYPE (objc_NSFastEnumeration_type);
13373 /* { */
13374 /* Done by c-parser.c. */
13376 /* type object; */
13377 /* Done by c-parser.c. */
13379 /* Disable warnings that 'object' is unused. For example the code
13381 for (id object in collection)
13382 i++;
13384 which can be used to count how many objects there are in the
13385 collection is fine and should generate no warnings even if
13386 'object' is technically unused. */
13387 TREE_USED (object_expression) = 1;
13388 if (DECL_P (object_expression))
13389 DECL_READ_P (object_expression) = 1;
13391 /* id __objc_foreach_collection */
13392 objc_foreach_collection_decl = objc_create_temporary_var (objc_object_type, "__objc_foreach_collection");
13394 /* __objcFastEnumerationState __objc_foreach_enum_state; */
13395 objc_foreach_enum_state_decl = objc_create_temporary_var (objc_fast_enumeration_state_type, "__objc_foreach_enum_state");
13396 TREE_CHAIN (objc_foreach_enum_state_decl) = objc_foreach_collection_decl;
13398 /* id __objc_foreach_items[16]; */
13399 objc_foreach_items_decl = objc_create_temporary_var (build_sized_array_type (objc_object_type, 16), "__objc_foreach_items");
13400 TREE_CHAIN (objc_foreach_items_decl) = objc_foreach_enum_state_decl;
13402 /* unsigned long __objc_foreach_batchsize; */
13403 objc_foreach_batchsize_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_batchsize");
13404 TREE_CHAIN (objc_foreach_batchsize_decl) = objc_foreach_items_decl;
13406 /* Generate the local variable binding. */
13407 bind = build3 (BIND_EXPR, void_type_node, objc_foreach_batchsize_decl, NULL, NULL);
13408 SET_EXPR_LOCATION (bind, location);
13409 TREE_SIDE_EFFECTS (bind) = 1;
13411 /* __objc_foreach_collection = <collection expression>; */
13412 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_collection_decl, collection_expression);
13413 SET_EXPR_LOCATION (t, location);
13414 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13416 /* __objc_foreach_enum_state.state = 0; */
13417 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
13418 get_identifier ("state")),
13419 build_int_cst (long_unsigned_type_node, 0));
13420 SET_EXPR_LOCATION (t, location);
13421 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13423 /* __objc_foreach_enum_state.itemsPtr = NULL; */
13424 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
13425 get_identifier ("itemsPtr")),
13426 null_pointer_node);
13427 SET_EXPR_LOCATION (t, location);
13428 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13430 /* __objc_foreach_enum_state.mutationsPtr = NULL; */
13431 t = build2 (MODIFY_EXPR, void_type_node, objc_build_component_ref (objc_foreach_enum_state_decl,
13432 get_identifier ("mutationsPtr")),
13433 null_pointer_node);
13434 SET_EXPR_LOCATION (t, location);
13435 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13437 /* __objc_foreach_enum_state.extra[0] = 0; */
13438 /* __objc_foreach_enum_state.extra[1] = 0; */
13439 /* __objc_foreach_enum_state.extra[2] = 0; */
13440 /* __objc_foreach_enum_state.extra[3] = 0; */
13441 /* __objc_foreach_enum_state.extra[4] = 0; */
13442 for (i = 0; i < 5 ; i++)
13444 t = build2 (MODIFY_EXPR, void_type_node,
13445 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
13446 get_identifier ("extra")),
13447 build_int_cst (NULL_TREE, i)),
13448 build_int_cst (long_unsigned_type_node, 0));
13449 SET_EXPR_LOCATION (t, location);
13450 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13453 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
13454 selector_name = get_identifier ("countByEnumeratingWithState:objects:count:");
13455 #ifdef OBJCPLUS
13456 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13457 /* Parameters. */
13458 tree_cons /* &__objc_foreach_enum_state */
13459 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13460 tree_cons /* __objc_foreach_items */
13461 (NULL_TREE, objc_foreach_items_decl,
13462 tree_cons /* 16 */
13463 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13464 #else
13465 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
13467 struct c_expr array;
13468 array.value = objc_foreach_items_decl;
13469 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13470 /* Parameters. */
13471 tree_cons /* &__objc_foreach_enum_state */
13472 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13473 tree_cons /* __objc_foreach_items */
13474 (NULL_TREE, default_function_array_conversion (location, array).value,
13475 tree_cons /* 16 */
13476 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13478 #endif
13479 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
13480 convert (long_unsigned_type_node, t));
13481 SET_EXPR_LOCATION (t, location);
13482 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
13484 /* if (__objc_foreach_batchsize == 0) */
13485 first_if = build3 (COND_EXPR, void_type_node,
13486 /* Condition. */
13487 c_fully_fold
13488 (c_common_truthvalue_conversion
13489 (location,
13490 build_binary_op (location,
13491 EQ_EXPR,
13492 objc_foreach_batchsize_decl,
13493 build_int_cst (long_unsigned_type_node, 0), 1)),
13494 false, NULL),
13495 /* Then block (we fill it in later). */
13496 NULL_TREE,
13497 /* Else block (we fill it in later). */
13498 NULL_TREE);
13499 SET_EXPR_LOCATION (first_if, location);
13500 append_to_statement_list (first_if, &BIND_EXPR_BODY (bind));
13502 /* then <object expression> = nil; */
13503 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13504 SET_EXPR_LOCATION (t, location);
13505 COND_EXPR_THEN (first_if) = t;
13507 /* Now we build the 'else' part of the if; once we finish building
13508 it, we attach it to first_if as the 'else' part. */
13510 /* else */
13511 /* { */
13513 /* unsigned long __objc_foreach_mutations_pointer; */
13514 objc_foreach_mutations_pointer_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_mutations_pointer");
13516 /* Generate the local variable binding. */
13517 first_else = build3 (BIND_EXPR, void_type_node, objc_foreach_mutations_pointer_decl, NULL, NULL);
13518 SET_EXPR_LOCATION (first_else, location);
13519 TREE_SIDE_EFFECTS (first_else) = 1;
13521 /* __objc_foreach_mutations_pointer = *__objc_foreach_enum_state.mutationsPtr; */
13522 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_mutations_pointer_decl,
13523 build_indirect_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
13524 get_identifier ("mutationsPtr")),
13525 RO_UNARY_STAR));
13526 SET_EXPR_LOCATION (t, location);
13527 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13529 /* next_batch: */
13530 next_batch_label_decl = create_artificial_label (location);
13531 t = build1 (LABEL_EXPR, void_type_node, next_batch_label_decl);
13532 SET_EXPR_LOCATION (t, location);
13533 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13535 /* { */
13537 /* unsigned long __objc_foreach_index; */
13538 objc_foreach_index_decl = objc_create_temporary_var (long_unsigned_type_node, "__objc_foreach_index");
13540 /* Generate the local variable binding. */
13541 next_batch_bind = build3 (BIND_EXPR, void_type_node, objc_foreach_index_decl, NULL, NULL);
13542 SET_EXPR_LOCATION (next_batch_bind, location);
13543 TREE_SIDE_EFFECTS (next_batch_bind) = 1;
13544 append_to_statement_list (next_batch_bind, &BIND_EXPR_BODY (first_else));
13546 /* __objc_foreach_index = 0; */
13547 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
13548 build_int_cst (long_unsigned_type_node, 0));
13549 SET_EXPR_LOCATION (t, location);
13550 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13552 /* next_object: */
13553 next_object_label_decl = create_artificial_label (location);
13554 t = build1 (LABEL_EXPR, void_type_node, next_object_label_decl);
13555 SET_EXPR_LOCATION (t, location);
13556 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13558 /* if (__objc_foreach_mutation_pointer != *__objc_foreach_enum_state.mutationsPtr) objc_enumeration_mutation (<collection expression>); */
13559 t = build3 (COND_EXPR, void_type_node,
13560 /* Condition. */
13561 c_fully_fold
13562 (c_common_truthvalue_conversion
13563 (location,
13564 build_binary_op
13565 (location,
13566 NE_EXPR,
13567 objc_foreach_mutations_pointer_decl,
13568 build_indirect_ref (location,
13569 objc_build_component_ref (objc_foreach_enum_state_decl,
13570 get_identifier ("mutationsPtr")),
13571 RO_UNARY_STAR), 1)),
13572 false, NULL),
13573 /* Then block. */
13574 build_function_call (input_location,
13575 objc_enumeration_mutation_decl,
13576 tree_cons (NULL, collection_expression, NULL)),
13577 /* Else block. */
13578 NULL_TREE);
13579 SET_EXPR_LOCATION (t, location);
13580 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13582 /* <object expression> = enumState.itemsPtr[__objc_foreach_index]; */
13583 t = build2 (MODIFY_EXPR, void_type_node, object_expression,
13584 build_array_ref (location, objc_build_component_ref (objc_foreach_enum_state_decl,
13585 get_identifier ("itemsPtr")),
13586 objc_foreach_index_decl));
13587 SET_EXPR_LOCATION (t, location);
13588 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13590 /* <statements> [PS: in <statments>, 'break' jumps to break_label and 'continue' jumps to continue_label] */
13591 append_to_statement_list (for_body, &BIND_EXPR_BODY (next_batch_bind));
13593 /* continue_label: */
13594 if (continue_label)
13596 t = build1 (LABEL_EXPR, void_type_node, continue_label);
13597 SET_EXPR_LOCATION (t, location);
13598 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13601 /* __objc_foreach_index++; */
13602 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_index_decl,
13603 build_binary_op (location,
13604 PLUS_EXPR,
13605 objc_foreach_index_decl,
13606 build_int_cst (long_unsigned_type_node, 1), 1));
13607 SET_EXPR_LOCATION (t, location);
13608 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13610 /* if (__objc_foreach_index < __objc_foreach_batchsize) goto next_object; */
13611 t = build3 (COND_EXPR, void_type_node,
13612 /* Condition. */
13613 c_fully_fold
13614 (c_common_truthvalue_conversion
13615 (location,
13616 build_binary_op (location,
13617 LT_EXPR,
13618 objc_foreach_index_decl,
13619 objc_foreach_batchsize_decl, 1)),
13620 false, NULL),
13621 /* Then block. */
13622 build1 (GOTO_EXPR, void_type_node, next_object_label_decl),
13623 /* Else block. */
13624 NULL_TREE);
13625 SET_EXPR_LOCATION (t, location);
13626 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13628 /* __objc_foreach_batchsize = [__objc_foreach_collection countByEnumeratingWithState: &__objc_foreach_enum_state objects: __objc_foreach_items count: 16]; */
13629 #ifdef OBJCPLUS
13630 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13631 /* Parameters. */
13632 tree_cons /* &__objc_foreach_enum_state */
13633 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13634 tree_cons /* __objc_foreach_items */
13635 (NULL_TREE, objc_foreach_items_decl,
13636 tree_cons /* 16 */
13637 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13638 #else
13639 /* In C, we need to decay the __objc_foreach_items array that we are passing. */
13641 struct c_expr array;
13642 array.value = objc_foreach_items_decl;
13643 t = objc_finish_message_expr (objc_foreach_collection_decl, selector_name,
13644 /* Parameters. */
13645 tree_cons /* &__objc_foreach_enum_state */
13646 (NULL_TREE, build_fold_addr_expr_loc (location, objc_foreach_enum_state_decl),
13647 tree_cons /* __objc_foreach_items */
13648 (NULL_TREE, default_function_array_conversion (location, array).value,
13649 tree_cons /* 16 */
13650 (NULL_TREE, build_int_cst (NULL_TREE, 16), NULL_TREE))));
13652 #endif
13653 t = build2 (MODIFY_EXPR, void_type_node, objc_foreach_batchsize_decl,
13654 convert (long_unsigned_type_node, t));
13655 SET_EXPR_LOCATION (t, location);
13656 append_to_statement_list (t, &BIND_EXPR_BODY (next_batch_bind));
13658 /* } */
13660 /* if (__objc_foreach_batchsize != 0) goto next_batch; */
13661 t = build3 (COND_EXPR, void_type_node,
13662 /* Condition. */
13663 c_fully_fold
13664 (c_common_truthvalue_conversion
13665 (location,
13666 build_binary_op (location,
13667 NE_EXPR,
13668 objc_foreach_batchsize_decl,
13669 build_int_cst (long_unsigned_type_node, 0), 1)),
13670 false, NULL),
13671 /* Then block. */
13672 build1 (GOTO_EXPR, void_type_node, next_batch_label_decl),
13673 /* Else block. */
13674 NULL_TREE);
13675 SET_EXPR_LOCATION (t, location);
13676 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13678 /* <object expression> = nil; */
13679 t = build2 (MODIFY_EXPR, void_type_node, object_expression, convert (objc_object_type, null_pointer_node));
13680 SET_EXPR_LOCATION (t, location);
13681 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13683 /* break_label: */
13684 if (break_label)
13686 t = build1 (LABEL_EXPR, void_type_node, break_label);
13687 SET_EXPR_LOCATION (t, location);
13688 append_to_statement_list (t, &BIND_EXPR_BODY (first_else));
13691 /* } */
13692 COND_EXPR_ELSE (first_if) = first_else;
13694 /* Do the whole thing. */
13695 add_stmt (bind);
13697 #ifdef DEBUG_OBJC_FINISH_FOREACH_LOOP
13698 /* This will print to stderr the whole blurb generated by the
13699 compiler while compiling (assuming the compiler doesn't crash
13700 before getting here).
13702 debug_generic_stmt (bind);
13703 #endif
13705 /* } */
13706 /* Done by c-parser.c */
13709 /* Return true if we have an NxString object pointer. */
13711 bool
13712 objc_string_ref_type_p (tree strp)
13714 tree tmv;
13715 if (!strp || TREE_CODE (strp) != POINTER_TYPE)
13716 return false;
13718 tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp));
13719 tmv = OBJC_TYPE_NAME (tmv);
13720 return (tmv
13721 && TREE_CODE (tmv) == IDENTIFIER_NODE
13722 && IDENTIFIER_POINTER (tmv)
13723 && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8));
13726 /* At present the behavior of this is undefined and it does nothing. */
13727 void
13728 objc_check_format_arg (tree ARG_UNUSED (format_arg),
13729 tree ARG_UNUSED (args_list))
13733 #include "gt-objc-objc-act.h"