In gcc/: 2010-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / gcc / objc / objc-act.c
blob5d76596479c148c9dbdcd81f0d5d9585f6003cb7
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Steve Naroff.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
29 #ifdef OBJCPLUS
30 #include "cp-tree.h"
31 #else
32 #include "c-tree.h"
33 #include "c-lang.h"
34 #endif
36 #include "c-family/c-common.h"
37 #include "c-family/c-pragma.h"
38 #include "flags.h"
39 #include "langhooks.h"
40 #include "objc-act.h"
41 #include "input.h"
42 #include "function.h"
43 #include "output.h"
44 #include "toplev.h"
45 #include "ggc.h"
46 #include "debug.h"
47 #include "target.h"
48 #include "diagnostic-core.h"
49 #include "intl.h"
50 #include "cgraph.h"
51 #include "tree-iterator.h"
52 #include "hashtab.h"
53 #include "langhooks-def.h"
55 /* For enum gimplify_status */
56 #include "gimple.h"
58 #define OBJC_VOID_AT_END void_list_node
60 static unsigned int should_call_super_dealloc = 0;
62 /* When building Objective-C++, we need in_late_binary_op. */
63 #ifdef OBJCPLUS
64 bool in_late_binary_op = false;
65 #endif /* OBJCPLUS */
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 /* I am not sure it is really correct.
76 Perhaps there's a danger that it will make name conflicts
77 if method names contain underscores. -- rms. */
78 #ifndef OBJC_GEN_METHOD_LABEL
79 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
80 do { \
81 char *temp; \
82 sprintf ((BUF), "_%s_%s_%s_%s", \
83 ((IS_INST) ? "i" : "c"), \
84 (CLASS_NAME), \
85 ((CAT_NAME)? (CAT_NAME) : ""), \
86 (SEL_NAME)); \
87 for (temp = (BUF); *temp; temp++) \
88 if (*temp == ':') *temp = '_'; \
89 } while (0)
90 #endif
92 /* These need specifying. */
93 #ifndef OBJC_FORWARDING_STACK_OFFSET
94 #define OBJC_FORWARDING_STACK_OFFSET 0
95 #endif
97 #ifndef OBJC_FORWARDING_MIN_OFFSET
98 #define OBJC_FORWARDING_MIN_OFFSET 0
99 #endif
101 /* Set up for use of obstacks. */
103 #include "obstack.h"
105 /* This obstack is used to accumulate the encoding of a data type. */
106 static struct obstack util_obstack;
108 /* This points to the beginning of obstack contents, so we can free
109 the whole contents. */
110 char *util_firstobj;
112 /* The version identifies which language generation and runtime
113 the module (file) was compiled for, and is recorded in the
114 module descriptor. */
116 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
117 #define PROTOCOL_VERSION 2
119 /* (Decide if these can ever be validly changed.) */
120 #define OBJC_ENCODE_INLINE_DEFS 0
121 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
123 /*** Private Interface (procedures) ***/
125 /* Used by compile_file. */
127 static void init_objc (void);
128 static void finish_objc (void);
130 /* Code generation. */
132 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
133 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
134 static tree get_proto_encoding (tree);
135 static tree lookup_interface (tree);
136 static tree objc_add_static_instance (tree, tree);
138 static tree start_class (enum tree_code, tree, tree, tree);
139 static tree continue_class (tree);
140 static void finish_class (tree);
141 static void start_method_def (tree);
142 #ifdef OBJCPLUS
143 static void objc_start_function (tree, tree, tree, tree);
144 #else
145 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
146 #endif
147 static tree start_protocol (enum tree_code, tree, tree);
148 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
149 static tree objc_add_method (tree, tree, int);
150 static tree add_instance_variable (tree, int, tree);
151 static tree build_ivar_reference (tree);
152 static tree is_ivar (tree, tree);
154 static void build_objc_exception_stuff (void);
155 static void build_next_objc_exception_stuff (void);
157 /* We only need the following for ObjC; ObjC++ will use C++'s definition
158 of DERIVED_FROM_P. */
159 #ifndef OBJCPLUS
160 static bool objc_derived_from_p (tree, tree);
161 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
162 #endif
163 static void objc_xref_basetypes (tree, tree);
165 static void build_class_template (void);
166 static void build_selector_template (void);
167 static void build_category_template (void);
168 static void build_super_template (void);
169 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
170 static tree get_class_ivars (tree, bool);
171 static tree generate_protocol_list (tree);
172 static void build_protocol_reference (tree);
174 #ifdef OBJCPLUS
175 static void objc_generate_cxx_cdtors (void);
176 #endif
178 static const char *synth_id_with_class_suffix (const char *, tree);
180 /* Hash tables to manage the global pool of method prototypes. */
182 hash *nst_method_hash_list = 0;
183 hash *cls_method_hash_list = 0;
185 static hash hash_lookup (hash *, tree);
186 static tree lookup_method (tree, tree);
187 static tree lookup_method_static (tree, tree, int);
189 enum string_section
191 class_names, /* class, category, protocol, module names */
192 meth_var_names, /* method and variable names */
193 meth_var_types /* method and variable type descriptors */
196 static tree add_objc_string (tree, enum string_section);
197 static void build_selector_table_decl (void);
199 /* Protocol additions. */
201 static tree lookup_protocol (tree);
202 static tree lookup_and_install_protocols (tree);
204 /* Type encoding. */
206 static void encode_type_qualifiers (tree);
207 static void encode_type (tree, int, int);
208 static void encode_field_decl (tree, int, int);
210 #ifdef OBJCPLUS
211 static void really_start_method (tree, tree);
212 #else
213 static void really_start_method (tree, struct c_arg_info *);
214 #endif
215 static int comp_proto_with_proto (tree, tree, int);
216 static void objc_push_parm (tree);
217 #ifdef OBJCPLUS
218 static tree objc_get_parm_info (int);
219 #else
220 static struct c_arg_info *objc_get_parm_info (int);
221 #endif
223 /* Utilities for debugging and error diagnostics. */
225 static char *gen_type_name (tree);
226 static char *gen_type_name_0 (tree);
227 static char *gen_method_decl (tree);
228 static char *gen_declaration (tree);
230 /* Everything else. */
232 static tree create_field_decl (tree, const char *);
233 static void add_class_reference (tree);
234 static void build_protocol_template (void);
235 static tree encode_method_prototype (tree);
236 static void generate_classref_translation_entry (tree);
237 static void handle_class_ref (tree);
238 static void generate_struct_by_value_array (void)
239 ATTRIBUTE_NORETURN;
240 static void mark_referenced_methods (void);
241 static void generate_objc_image_info (void);
243 /*** Private Interface (data) ***/
245 /* Reserved tag definitions. */
247 #define OBJECT_TYPEDEF_NAME "id"
248 #define CLASS_TYPEDEF_NAME "Class"
250 #define TAG_OBJECT "objc_object"
251 #define TAG_CLASS "objc_class"
252 #define TAG_SUPER "objc_super"
253 #define TAG_SELECTOR "objc_selector"
255 #define UTAG_CLASS "_objc_class"
256 #define UTAG_IVAR "_objc_ivar"
257 #define UTAG_IVAR_LIST "_objc_ivar_list"
258 #define UTAG_METHOD "_objc_method"
259 #define UTAG_METHOD_LIST "_objc_method_list"
260 #define UTAG_CATEGORY "_objc_category"
261 #define UTAG_MODULE "_objc_module"
262 #define UTAG_SYMTAB "_objc_symtab"
263 #define UTAG_SUPER "_objc_super"
264 #define UTAG_SELECTOR "_objc_selector"
266 #define UTAG_PROTOCOL "_objc_protocol"
267 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
268 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
270 /* Note that the string object global name is only needed for the
271 NeXT runtime. */
272 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
274 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
276 static const char *TAG_GETCLASS;
277 static const char *TAG_GETMETACLASS;
278 static const char *TAG_MSGSEND;
279 static const char *TAG_MSGSENDSUPER;
280 /* The NeXT Objective-C messenger may have two extra entry points, for use
281 when returning a structure. */
282 static const char *TAG_MSGSEND_STRET;
283 static const char *TAG_MSGSENDSUPER_STRET;
284 static const char *default_constant_string_class_name;
286 /* Runtime metadata flags. */
287 #define CLS_FACTORY 0x0001L
288 #define CLS_META 0x0002L
289 #define CLS_HAS_CXX_STRUCTORS 0x2000L
291 #define OBJC_MODIFIER_STATIC 0x00000001
292 #define OBJC_MODIFIER_FINAL 0x00000002
293 #define OBJC_MODIFIER_PUBLIC 0x00000004
294 #define OBJC_MODIFIER_PRIVATE 0x00000008
295 #define OBJC_MODIFIER_PROTECTED 0x00000010
296 #define OBJC_MODIFIER_NATIVE 0x00000020
297 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
298 #define OBJC_MODIFIER_ABSTRACT 0x00000080
299 #define OBJC_MODIFIER_VOLATILE 0x00000100
300 #define OBJC_MODIFIER_TRANSIENT 0x00000200
301 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
303 /* NeXT-specific tags. */
305 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
306 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
307 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
308 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
309 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
310 #define TAG_EXCEPTIONMATCH "objc_exception_match"
311 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
312 #define TAG_SYNCENTER "objc_sync_enter"
313 #define TAG_SYNCEXIT "objc_sync_exit"
314 #define TAG_SETJMP "_setjmp"
315 #define UTAG_EXCDATA "_objc_exception_data"
317 #define TAG_ASSIGNIVAR "objc_assign_ivar"
318 #define TAG_ASSIGNGLOBAL "objc_assign_global"
319 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
321 /* Branch entry points. All that matters here are the addresses;
322 functions with these names do not really exist in libobjc. */
324 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
325 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
327 #define TAG_CXX_CONSTRUCT ".cxx_construct"
328 #define TAG_CXX_DESTRUCT ".cxx_destruct"
330 /* GNU-specific tags. */
332 #define TAG_EXECCLASS "__objc_exec_class"
333 #define TAG_GNUINIT "__objc_gnu_init"
335 /* Flags for lookup_method_static(). */
336 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
337 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
339 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
340 tree objc_global_trees[OCTI_MAX];
342 static void handle_impent (struct imp_entry *);
344 struct imp_entry *imp_list = 0;
345 int imp_count = 0; /* `@implementation' */
346 int cat_count = 0; /* `@category' */
348 enum tree_code objc_inherit_code;
349 int objc_public_flag;
351 /* Use to generate method labels. */
352 static int method_slot = 0;
354 static int objc_collecting_ivars = 0;
356 #define BUFSIZE 1024
358 static char *errbuf; /* Buffer for error diagnostics */
360 /* Data imported from tree.c. */
362 extern enum debug_info_type write_symbols;
364 /* Data imported from toplev.c. */
366 extern const char *dump_base_name;
368 static int flag_typed_selectors;
370 /* Store all constructed constant strings in a hash table so that
371 they get uniqued properly. */
373 struct GTY(()) string_descriptor {
374 /* The literal argument . */
375 tree literal;
377 /* The resulting constant string. */
378 tree constructor;
381 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
383 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
384 struct GTY(()) volatilized_type {
385 tree type;
388 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
390 FILE *gen_declaration_file;
392 /* Tells "encode_pointer/encode_aggregate" whether we are generating
393 type descriptors for instance variables (as opposed to methods).
394 Type descriptors for instance variables contain more information
395 than methods (for static typing and embedded structures). */
397 static int generating_instance_variables = 0;
399 /* For building an objc struct. These may not be used when this file
400 is compiled as part of obj-c++. */
402 static bool objc_building_struct;
403 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
405 /* Start building a struct for objc. */
407 static tree
408 objc_start_struct (tree name)
410 gcc_assert (!objc_building_struct);
411 objc_building_struct = true;
412 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
415 /* Finish building a struct for objc. */
417 static tree
418 objc_finish_struct (tree type, tree fieldlist)
420 gcc_assert (objc_building_struct);
421 objc_building_struct = false;
422 return finish_struct (input_location, type, fieldlist, NULL_TREE,
423 objc_struct_info);
426 static tree
427 build_sized_array_type (tree base_type, int size)
429 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
430 return build_array_type (base_type, index_type);
433 static tree
434 add_field_decl (tree type, const char *name, tree **chain)
436 tree field = create_field_decl (type, name);
438 if (*chain != NULL)
439 **chain = field;
440 *chain = &DECL_CHAIN (field);
442 return field;
445 /* Some platforms pass small structures through registers versus
446 through an invisible pointer. Determine at what size structure is
447 the transition point between the two possibilities. */
449 static void
450 generate_struct_by_value_array (void)
452 tree type;
453 tree decls;
454 int i, j;
455 int aggregate_in_mem[32];
456 int found = 0;
458 /* Presumably no platform passes 32 byte structures in a register. */
459 for (i = 1; i < 32; i++)
461 char buffer[5];
462 tree *chain = NULL;
464 /* Create an unnamed struct that has `i' character components */
465 type = objc_start_struct (NULL_TREE);
467 strcpy (buffer, "c1");
468 decls = add_field_decl (char_type_node, buffer, &chain);
470 for (j = 1; j < i; j++)
472 sprintf (buffer, "c%d", j + 1);
473 add_field_decl (char_type_node, buffer, &chain);
475 objc_finish_struct (type, decls);
477 aggregate_in_mem[i] = aggregate_value_p (type, 0);
478 if (!aggregate_in_mem[i])
479 found = 1;
482 /* We found some structures that are returned in registers instead of memory
483 so output the necessary data. */
484 if (found)
486 for (i = 31; i >= 0; i--)
487 if (!aggregate_in_mem[i])
488 break;
489 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
491 /* The first member of the structure is always 0 because we don't handle
492 structures with 0 members */
493 printf ("static int struct_forward_array[] = {\n 0");
495 for (j = 1; j <= i; j++)
496 printf (", %d", aggregate_in_mem[j]);
497 printf ("\n};\n");
500 exit (0);
503 bool
504 objc_init (void)
506 #ifdef OBJCPLUS
507 if (cxx_init () == false)
508 #else
509 if (c_objc_common_init () == false)
510 #endif
511 return false;
513 /* If gen_declaration desired, open the output file. */
514 if (flag_gen_declaration)
516 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
517 gen_declaration_file = fopen (dumpname, "w");
518 if (gen_declaration_file == 0)
519 fatal_error ("can't open %s: %m", dumpname);
520 free (dumpname);
523 if (flag_next_runtime)
525 TAG_GETCLASS = "objc_getClass";
526 TAG_GETMETACLASS = "objc_getMetaClass";
527 TAG_MSGSEND = "objc_msgSend";
528 TAG_MSGSENDSUPER = "objc_msgSendSuper";
529 TAG_MSGSEND_STRET = "objc_msgSend_stret";
530 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
531 default_constant_string_class_name = "NSConstantString";
533 else
535 TAG_GETCLASS = "objc_get_class";
536 TAG_GETMETACLASS = "objc_get_meta_class";
537 TAG_MSGSEND = "objc_msg_lookup";
538 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
539 /* GNU runtime does not provide special functions to support
540 structure-returning methods. */
541 default_constant_string_class_name = "NXConstantString";
542 flag_typed_selectors = 1;
543 /* GNU runtime does not need the compiler to change code
544 in order to do GC. */
545 if (flag_objc_gc)
547 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
548 flag_objc_gc=0;
552 init_objc ();
554 if (print_struct_values && !flag_compare_debug)
555 generate_struct_by_value_array ();
557 return true;
560 void
561 objc_finish_file (void)
563 mark_referenced_methods ();
565 #ifdef OBJCPLUS
566 /* We need to instantiate templates _before_ we emit ObjC metadata;
567 if we do not, some metadata (such as selectors) may go missing. */
568 at_eof = 1;
569 instantiate_pending_templates (0);
570 #endif
572 /* Finalize Objective-C runtime data. No need to generate tables
573 and code if only checking syntax, or if generating a PCH file. */
574 if (!flag_syntax_only && !pch_file)
575 finish_objc ();
577 if (gen_declaration_file)
578 fclose (gen_declaration_file);
581 /* Return the first occurrence of a method declaration corresponding
582 to sel_name in rproto_list. Search rproto_list recursively.
583 If is_class is 0, search for instance methods, otherwise for class
584 methods. */
585 static tree
586 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
587 int is_class)
589 tree rproto, p;
590 tree fnd = 0;
592 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
594 p = TREE_VALUE (rproto);
596 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
598 if ((fnd = lookup_method (is_class
599 ? PROTOCOL_CLS_METHODS (p)
600 : PROTOCOL_NST_METHODS (p), sel_name)))
602 else if (PROTOCOL_LIST (p))
603 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
604 sel_name, is_class);
606 else
608 ; /* An identifier...if we could not find a protocol. */
611 if (fnd)
612 return fnd;
615 return 0;
618 static tree
619 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
621 tree rproto, p;
623 /* Make sure the protocol is supported by the object on the rhs. */
624 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
626 tree fnd = 0;
627 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
629 p = TREE_VALUE (rproto);
631 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
633 if (lproto == p)
634 fnd = lproto;
636 else if (PROTOCOL_LIST (p))
637 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
640 if (fnd)
641 return fnd;
644 else
646 ; /* An identifier...if we could not find a protocol. */
649 return 0;
652 void
653 objc_start_class_interface (tree klass, tree super_class, tree protos)
655 objc_interface_context
656 = objc_ivar_context
657 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
658 objc_public_flag = 0;
661 void
662 objc_start_category_interface (tree klass, tree categ, tree protos)
664 objc_interface_context
665 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
666 objc_ivar_chain
667 = continue_class (objc_interface_context);
670 void
671 objc_start_protocol (tree name, tree protos)
673 objc_interface_context
674 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
677 void
678 objc_continue_interface (void)
680 objc_ivar_chain
681 = continue_class (objc_interface_context);
684 void
685 objc_finish_interface (void)
687 finish_class (objc_interface_context);
688 objc_interface_context = NULL_TREE;
691 void
692 objc_start_class_implementation (tree klass, tree super_class)
694 objc_implementation_context
695 = objc_ivar_context
696 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
697 objc_public_flag = 0;
700 void
701 objc_start_category_implementation (tree klass, tree categ)
703 objc_implementation_context
704 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
705 objc_ivar_chain
706 = continue_class (objc_implementation_context);
709 void
710 objc_continue_implementation (void)
712 objc_ivar_chain
713 = continue_class (objc_implementation_context);
716 void
717 objc_finish_implementation (void)
719 #ifdef OBJCPLUS
720 if (flag_objc_call_cxx_cdtors)
721 objc_generate_cxx_cdtors ();
722 #endif
724 if (objc_implementation_context)
726 finish_class (objc_implementation_context);
727 objc_ivar_chain = NULL_TREE;
728 objc_implementation_context = NULL_TREE;
730 else
731 warning (0, "%<@end%> must appear in an @implementation context");
734 void
735 objc_set_visibility (int visibility)
737 objc_public_flag = visibility;
740 void
741 objc_set_method_type (enum tree_code type)
743 objc_inherit_code = (type == PLUS_EXPR
744 ? CLASS_METHOD_DECL
745 : INSTANCE_METHOD_DECL);
748 tree
749 objc_build_method_signature (tree rettype, tree selector,
750 tree optparms, bool ellipsis)
752 return build_method_decl (objc_inherit_code, rettype, selector,
753 optparms, ellipsis);
756 void
757 objc_add_method_declaration (tree decl)
759 if (!objc_interface_context)
761 /* PS: At the moment, due to how the parser works, it should be
762 impossible to get here. But it's good to have the check in
763 case the parser changes.
765 fatal_error ("method declaration not in @interface context");
768 objc_add_method (objc_interface_context,
769 decl,
770 objc_inherit_code == CLASS_METHOD_DECL);
773 /* Return 'true' if the method definition could be started, and
774 'false' if not (because we are outside an @implementation context).
776 bool
777 objc_start_method_definition (tree decl)
779 if (!objc_implementation_context)
781 error ("method definition not in @implementation context");
782 return false;
785 #ifndef OBJCPLUS
786 /* Indicate no valid break/continue context by setting these variables
787 to some non-null, non-label value. We'll notice and emit the proper
788 error message in c_finish_bc_stmt. */
789 c_break_label = c_cont_label = size_zero_node;
790 #endif
792 objc_add_method (objc_implementation_context,
793 decl,
794 objc_inherit_code == CLASS_METHOD_DECL);
795 start_method_def (decl);
796 return true;
799 void
800 objc_add_instance_variable (tree decl)
802 (void) add_instance_variable (objc_ivar_context,
803 objc_public_flag,
804 decl);
807 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
808 an '@'. */
811 objc_is_reserved_word (tree ident)
813 unsigned char code = C_RID_CODE (ident);
815 return (OBJC_IS_AT_KEYWORD (code)
816 || code == RID_CLASS || code == RID_PUBLIC
817 || code == RID_PROTECTED || code == RID_PRIVATE
818 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
821 /* Return true if TYPE is 'id'. */
823 static bool
824 objc_is_object_id (tree type)
826 return OBJC_TYPE_NAME (type) == objc_object_id;
829 static bool
830 objc_is_class_id (tree type)
832 return OBJC_TYPE_NAME (type) == objc_class_id;
835 /* Construct a C struct with same name as KLASS, a base struct with tag
836 SUPER_NAME (if any), and FIELDS indicated. */
838 static tree
839 objc_build_struct (tree klass, tree fields, tree super_name)
841 tree name = CLASS_NAME (klass);
842 tree s = objc_start_struct (name);
843 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
844 tree t;
845 VEC(tree,heap) *objc_info = NULL;
846 int i;
848 if (super)
850 /* Prepend a packed variant of the base class into the layout. This
851 is necessary to preserve ObjC ABI compatibility. */
852 tree base = build_decl (input_location,
853 FIELD_DECL, NULL_TREE, super);
854 tree field = TYPE_FIELDS (super);
856 while (field && DECL_CHAIN (field)
857 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
858 field = DECL_CHAIN (field);
860 /* For ObjC ABI purposes, the "packed" size of a base class is
861 the sum of the offset and the size (in bits) of the last field
862 in the class. */
863 DECL_SIZE (base)
864 = (field && TREE_CODE (field) == FIELD_DECL
865 ? size_binop (PLUS_EXPR,
866 size_binop (PLUS_EXPR,
867 size_binop
868 (MULT_EXPR,
869 convert (bitsizetype,
870 DECL_FIELD_OFFSET (field)),
871 bitsize_int (BITS_PER_UNIT)),
872 DECL_FIELD_BIT_OFFSET (field)),
873 DECL_SIZE (field))
874 : bitsize_zero_node);
875 DECL_SIZE_UNIT (base)
876 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
877 size_int (BITS_PER_UNIT));
878 DECL_ARTIFICIAL (base) = 1;
879 DECL_ALIGN (base) = 1;
880 DECL_FIELD_CONTEXT (base) = s;
881 #ifdef OBJCPLUS
882 DECL_FIELD_IS_BASE (base) = 1;
884 if (fields)
885 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
886 #endif /* are following the ObjC ABI here. */
887 DECL_CHAIN (base) = fields;
888 fields = base;
891 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
892 in all variants of this RECORD_TYPE to be clobbered, but it is therein
893 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
894 Hence, we must squirrel away the ObjC-specific information before calling
895 finish_struct(), and then reinstate it afterwards. */
897 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
899 if (!TYPE_HAS_OBJC_INFO (t))
901 INIT_TYPE_OBJC_INFO (t);
902 TYPE_OBJC_INTERFACE (t) = klass;
904 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
907 /* Point the struct at its related Objective-C class. */
908 INIT_TYPE_OBJC_INFO (s);
909 TYPE_OBJC_INTERFACE (s) = klass;
911 s = objc_finish_struct (s, fields);
913 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
915 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
916 /* Replace the IDENTIFIER_NODE with an actual @interface. */
917 TYPE_OBJC_INTERFACE (t) = klass;
919 VEC_free (tree, heap, objc_info);
921 /* Use TYPE_BINFO structures to point at the super class, if any. */
922 objc_xref_basetypes (s, super);
924 /* Mark this struct as a class template. */
925 CLASS_STATIC_TEMPLATE (klass) = s;
927 return s;
930 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
931 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
932 process. */
933 static tree
934 objc_build_volatilized_type (tree type)
936 tree t;
938 /* Check if we have not constructed the desired variant already. */
939 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
941 /* The type qualifiers must (obviously) match up. */
942 if (!TYPE_VOLATILE (t)
943 || (TYPE_READONLY (t) != TYPE_READONLY (type))
944 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
945 continue;
947 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
948 info, if any) must match up. */
949 if (POINTER_TYPE_P (t)
950 && (TREE_TYPE (t) != TREE_TYPE (type)))
951 continue;
953 /* Everything matches up! */
954 return t;
957 /* Ok, we could not re-use any of the pre-existing variants. Create
958 a new one. */
959 t = build_variant_type_copy (type);
960 TYPE_VOLATILE (t) = 1;
962 /* Set up the canonical type information. */
963 if (TYPE_STRUCTURAL_EQUALITY_P (type))
964 SET_TYPE_STRUCTURAL_EQUALITY (t);
965 else if (TYPE_CANONICAL (type) != type)
966 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
967 else
968 TYPE_CANONICAL (t) = t;
970 return t;
973 /* Mark DECL as being 'volatile' for purposes of Darwin
974 _setjmp()/_longjmp() exception handling. Called from
975 objc_mark_locals_volatile(). */
976 void
977 objc_volatilize_decl (tree decl)
979 /* Do not mess with variables that are 'static' or (already)
980 'volatile'. */
981 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
982 && (TREE_CODE (decl) == VAR_DECL
983 || TREE_CODE (decl) == PARM_DECL))
985 tree t = TREE_TYPE (decl);
986 struct volatilized_type key;
987 void **loc;
989 t = objc_build_volatilized_type (t);
990 key.type = t;
991 loc = htab_find_slot (volatilized_htab, &key, INSERT);
993 if (!*loc)
995 *loc = ggc_alloc_volatilized_type ();
996 ((struct volatilized_type *) *loc)->type = t;
999 TREE_TYPE (decl) = t;
1000 TREE_THIS_VOLATILE (decl) = 1;
1001 TREE_SIDE_EFFECTS (decl) = 1;
1002 DECL_REGISTER (decl) = 0;
1003 #ifndef OBJCPLUS
1004 C_DECL_REGISTER (decl) = 0;
1005 #endif
1009 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1010 (including its categories and superclasses) or by object type TYP.
1011 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1013 static bool
1014 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
1016 bool class_type = (cls != NULL_TREE);
1018 while (cls)
1020 tree c;
1022 /* Check protocols adopted by the class and its categories. */
1023 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1025 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1026 return true;
1029 /* Repeat for superclasses. */
1030 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1033 /* Check for any protocols attached directly to the object type. */
1034 if (TYPE_HAS_OBJC_INFO (typ))
1036 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1037 return true;
1040 if (warn)
1042 *errbuf = 0;
1043 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1044 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1045 "implementing" a given protocol, since they do not have an
1046 implementation. */
1047 if (class_type)
1048 warning (0, "class %qs does not implement the %qE protocol",
1049 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1050 else
1051 warning (0, "type %qs does not conform to the %qE protocol",
1052 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1055 return false;
1058 /* Check if class RCLS and instance struct type RTYP conform to at least the
1059 same protocols that LCLS and LTYP conform to. */
1061 static bool
1062 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1064 tree p;
1065 bool have_lproto = false;
1067 while (lcls)
1069 /* NB: We do _not_ look at categories defined for LCLS; these may or
1070 may not get loaded in, and therefore it is unreasonable to require
1071 that RCLS/RTYP must implement any of their protocols. */
1072 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1074 have_lproto = true;
1076 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1077 return warn;
1080 /* Repeat for superclasses. */
1081 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1084 /* Check for any protocols attached directly to the object type. */
1085 if (TYPE_HAS_OBJC_INFO (ltyp))
1087 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1089 have_lproto = true;
1091 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1092 return warn;
1096 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1097 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1098 away with simply checking for 'id' or 'Class' (!RCLS), since this
1099 routine will not get called in other cases. */
1100 return have_lproto || (rcls != NULL_TREE);
1103 /* Given two types TYPE1 and TYPE2, return their least common ancestor.
1104 Both TYPE1 and TYPE2 must be pointers, and already determined to be
1105 compatible by objc_compare_types() below. */
1107 tree
1108 objc_common_type (tree type1, tree type2)
1110 tree inner1 = TREE_TYPE (type1), inner2 = TREE_TYPE (type2);
1112 while (POINTER_TYPE_P (inner1))
1114 inner1 = TREE_TYPE (inner1);
1115 inner2 = TREE_TYPE (inner2);
1118 /* If one type is derived from another, return the base type. */
1119 if (DERIVED_FROM_P (inner1, inner2))
1120 return type1;
1121 else if (DERIVED_FROM_P (inner2, inner1))
1122 return type2;
1124 /* If both types are 'Class', return 'Class'. */
1125 if (objc_is_class_id (inner1) && objc_is_class_id (inner2))
1126 return objc_class_type;
1128 /* Otherwise, return 'id'. */
1129 return objc_object_type;
1132 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1133 an instance of RTYP to an instance of LTYP or to compare the two
1134 (if ARGNO is equal to -3), per ObjC type system rules. Before
1135 returning 'true', this routine may issue warnings related to, e.g.,
1136 protocol conformance. When returning 'false', the routine must
1137 produce absolutely no warnings; the C or C++ front-end will do so
1138 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1139 the routine must return 'false'.
1141 The ARGNO parameter is encoded as follows:
1142 >= 1 Parameter number (CALLEE contains function being called);
1143 0 Return value;
1144 -1 Assignment;
1145 -2 Initialization;
1146 -3 Comparison (LTYP and RTYP may match in either direction). */
1148 bool
1149 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1151 tree lcls, rcls, lproto, rproto;
1152 bool pointers_compatible;
1154 /* We must be dealing with pointer types */
1155 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1156 return false;
1160 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1161 rtyp = TREE_TYPE (rtyp);
1163 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1165 /* We must also handle function pointers, since ObjC is a bit more
1166 lenient than C or C++ on this. */
1167 if (TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE)
1169 /* Return types must be covariant. */
1170 if (!comptypes (TREE_TYPE (ltyp), TREE_TYPE (rtyp))
1171 && !objc_compare_types (TREE_TYPE (ltyp), TREE_TYPE (rtyp),
1172 argno, callee))
1173 return false;
1175 /* Argument types must be contravariant. */
1176 for (ltyp = TYPE_ARG_TYPES (ltyp), rtyp = TYPE_ARG_TYPES (rtyp);
1177 ltyp && rtyp; ltyp = TREE_CHAIN (ltyp), rtyp = TREE_CHAIN (rtyp))
1179 if (!comptypes (TREE_VALUE (rtyp), TREE_VALUE (ltyp))
1180 && !objc_compare_types (TREE_VALUE (rtyp), TREE_VALUE (ltyp),
1181 argno, callee))
1182 return false;
1185 return (ltyp == rtyp);
1188 /* Past this point, we are only interested in ObjC class instances,
1189 or 'id' or 'Class'. */
1190 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1191 return false;
1193 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1194 && !TYPE_HAS_OBJC_INFO (ltyp))
1195 return false;
1197 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1198 && !TYPE_HAS_OBJC_INFO (rtyp))
1199 return false;
1201 /* Past this point, we are committed to returning 'true' to the caller.
1202 However, we can still warn about type and/or protocol mismatches. */
1204 if (TYPE_HAS_OBJC_INFO (ltyp))
1206 lcls = TYPE_OBJC_INTERFACE (ltyp);
1207 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1209 else
1210 lcls = lproto = NULL_TREE;
1212 if (TYPE_HAS_OBJC_INFO (rtyp))
1214 rcls = TYPE_OBJC_INTERFACE (rtyp);
1215 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1217 else
1218 rcls = rproto = NULL_TREE;
1220 /* If we could not find an @interface declaration, we must have
1221 only seen a @class declaration; for purposes of type comparison,
1222 treat it as a stand-alone (root) class. */
1224 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1225 lcls = NULL_TREE;
1227 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1228 rcls = NULL_TREE;
1230 /* If either type is an unqualified 'id', we're done. */
1231 if ((!lproto && objc_is_object_id (ltyp))
1232 || (!rproto && objc_is_object_id (rtyp)))
1233 return true;
1235 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1237 /* If the underlying types are the same, and at most one of them has
1238 a protocol list, we do not need to issue any diagnostics. */
1239 if (pointers_compatible && (!lproto || !rproto))
1240 return true;
1242 /* If exactly one of the types is 'Class', issue a diagnostic; any
1243 exceptions of this rule have already been handled. */
1244 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1245 pointers_compatible = false;
1246 /* Otherwise, check for inheritance relations. */
1247 else
1249 if (!pointers_compatible)
1250 pointers_compatible
1251 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1253 if (!pointers_compatible)
1254 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1256 if (!pointers_compatible && argno == -3)
1257 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1260 /* If the pointers match modulo protocols, check for protocol conformance
1261 mismatches. */
1262 if (pointers_compatible)
1264 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1265 argno != -3);
1267 if (!pointers_compatible && argno == -3)
1268 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1269 argno != -3);
1272 if (!pointers_compatible)
1274 /* NB: For the time being, we shall make our warnings look like their
1275 C counterparts. In the future, we may wish to make them more
1276 ObjC-specific. */
1277 switch (argno)
1279 case -3:
1280 warning (0, "comparison of distinct Objective-C types lacks a cast");
1281 break;
1283 case -2:
1284 warning (0, "initialization from distinct Objective-C type");
1285 break;
1287 case -1:
1288 warning (0, "assignment from distinct Objective-C type");
1289 break;
1291 case 0:
1292 warning (0, "distinct Objective-C type in return");
1293 break;
1295 default:
1296 warning (0, "passing argument %d of %qE from distinct "
1297 "Objective-C type", argno, callee);
1298 break;
1302 return true;
1305 /* This routine is similar to objc_compare_types except that function-pointers are
1306 excluded. This is because, caller assumes that common types are of (id, Object*)
1307 variety and calls objc_common_type to obtain a common type. There is no commonolty
1308 between two function-pointers in this regard. */
1310 bool
1311 objc_have_common_type (tree ltyp, tree rtyp, int argno, tree callee)
1313 if (objc_compare_types (ltyp, rtyp, argno, callee))
1315 /* exclude function-pointer types. */
1318 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1319 rtyp = TREE_TYPE (rtyp);
1321 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1322 return !(TREE_CODE (ltyp) == FUNCTION_TYPE && TREE_CODE (rtyp) == FUNCTION_TYPE);
1324 return false;
1327 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1328 lives in the volatilized hash table, ignore the 'volatile' bit when
1329 making the comparison. */
1331 bool
1332 objc_type_quals_match (tree ltyp, tree rtyp)
1334 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1335 struct volatilized_type key;
1337 key.type = ltyp;
1339 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1340 lquals &= ~TYPE_QUAL_VOLATILE;
1342 key.type = rtyp;
1344 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1345 rquals &= ~TYPE_QUAL_VOLATILE;
1347 return (lquals == rquals);
1350 #ifndef OBJCPLUS
1351 /* Determine if CHILD is derived from PARENT. The routine assumes that
1352 both parameters are RECORD_TYPEs, and is non-reflexive. */
1354 static bool
1355 objc_derived_from_p (tree parent, tree child)
1357 parent = TYPE_MAIN_VARIANT (parent);
1359 for (child = TYPE_MAIN_VARIANT (child);
1360 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1362 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1363 (TYPE_BINFO (child),
1364 0)));
1366 if (child == parent)
1367 return true;
1370 return false;
1372 #endif
1374 static tree
1375 objc_build_component_ref (tree datum, tree component)
1377 /* If COMPONENT is NULL, the caller is referring to the anonymous
1378 base class field. */
1379 if (!component)
1381 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1383 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1386 /* The 'build_component_ref' routine has been removed from the C++
1387 front-end, but 'finish_class_member_access_expr' seems to be
1388 a worthy substitute. */
1389 #ifdef OBJCPLUS
1390 return finish_class_member_access_expr (datum, component, false,
1391 tf_warning_or_error);
1392 #else
1393 return build_component_ref (input_location, datum, component);
1394 #endif
1397 /* Recursively copy inheritance information rooted at BINFO. To do this,
1398 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1400 static tree
1401 objc_copy_binfo (tree binfo)
1403 tree btype = BINFO_TYPE (binfo);
1404 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1405 tree base_binfo;
1406 int ix;
1408 BINFO_TYPE (binfo2) = btype;
1409 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1410 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1412 /* Recursively copy base binfos of BINFO. */
1413 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1415 tree base_binfo2 = objc_copy_binfo (base_binfo);
1417 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1418 BINFO_BASE_APPEND (binfo2, base_binfo2);
1421 return binfo2;
1424 /* Record superclass information provided in BASETYPE for ObjC class REF.
1425 This is loosely based on cp/decl.c:xref_basetypes(). */
1427 static void
1428 objc_xref_basetypes (tree ref, tree basetype)
1430 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1432 TYPE_BINFO (ref) = binfo;
1433 BINFO_OFFSET (binfo) = size_zero_node;
1434 BINFO_TYPE (binfo) = ref;
1436 if (basetype)
1438 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1440 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1441 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1442 BINFO_BASE_APPEND (binfo, base_binfo);
1443 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1447 static hashval_t
1448 volatilized_hash (const void *ptr)
1450 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1452 return htab_hash_pointer(typ);
1455 static int
1456 volatilized_eq (const void *ptr1, const void *ptr2)
1458 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1459 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1461 return typ1 == typ2;
1464 /* Called from finish_decl. */
1466 void
1467 objc_check_decl (tree decl)
1469 tree type = TREE_TYPE (decl);
1471 if (TREE_CODE (type) != RECORD_TYPE)
1472 return;
1473 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1474 error ("statically allocated instance of Objective-C class %qE",
1475 type);
1478 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1479 either name an Objective-C class, or refer to the special 'id' or 'Class'
1480 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1482 tree
1483 objc_get_protocol_qualified_type (tree interface, tree protocols)
1485 /* If INTERFACE is not provided, default to 'id'. */
1486 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1487 bool is_ptr = (type != NULL_TREE);
1489 if (!is_ptr)
1491 type = objc_is_class_name (interface);
1493 if (type)
1495 /* If looking at a typedef, retrieve the precise type it
1496 describes. */
1497 if (TREE_CODE (interface) == IDENTIFIER_NODE)
1498 interface = identifier_global_value (interface);
1500 type = ((interface && TREE_CODE (interface) == TYPE_DECL
1501 && DECL_ORIGINAL_TYPE (interface))
1502 ? DECL_ORIGINAL_TYPE (interface)
1503 : xref_tag (RECORD_TYPE, type));
1505 else
1506 return interface;
1509 if (protocols)
1511 type = build_variant_type_copy (type);
1513 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1514 to the pointee. */
1515 if (is_ptr)
1517 tree orig_pointee_type = TREE_TYPE (type);
1518 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1520 /* Set up the canonical type information. */
1521 TYPE_CANONICAL (type)
1522 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1524 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1525 type = TREE_TYPE (type);
1528 /* Look up protocols and install in lang specific list. */
1529 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1530 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1532 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1533 return the pointer to the new pointee variant. */
1534 if (is_ptr)
1535 type = TYPE_POINTER_TO (type);
1536 else
1537 TYPE_OBJC_INTERFACE (type)
1538 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1541 return type;
1544 /* Check for circular dependencies in protocols. The arguments are
1545 PROTO, the protocol to check, and LIST, a list of protocol it
1546 conforms to. */
1548 static void
1549 check_protocol_recursively (tree proto, tree list)
1551 tree p;
1553 for (p = list; p; p = TREE_CHAIN (p))
1555 tree pp = TREE_VALUE (p);
1557 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1558 pp = lookup_protocol (pp);
1560 if (pp == proto)
1561 fatal_error ("protocol %qE has circular dependency",
1562 PROTOCOL_NAME (pp));
1563 if (pp)
1564 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1568 /* Look up PROTOCOLS, and return a list of those that are found.
1569 If none are found, return NULL. */
1571 static tree
1572 lookup_and_install_protocols (tree protocols)
1574 tree proto;
1575 tree return_value = NULL_TREE;
1577 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1579 tree ident = TREE_VALUE (proto);
1580 tree p = lookup_protocol (ident);
1582 if (p)
1583 return_value = chainon (return_value,
1584 build_tree_list (NULL_TREE, p));
1585 else if (ident != error_mark_node)
1586 error ("cannot find protocol declaration for %qE",
1587 ident);
1590 return return_value;
1593 /* Create a declaration for field NAME of a given TYPE. */
1595 static tree
1596 create_field_decl (tree type, const char *name)
1598 return build_decl (input_location,
1599 FIELD_DECL, get_identifier (name), type);
1602 /* Create a global, static declaration for variable NAME of a given TYPE. The
1603 finish_var_decl() routine will need to be called on it afterwards. */
1605 static tree
1606 start_var_decl (tree type, const char *name)
1608 tree var = build_decl (input_location,
1609 VAR_DECL, get_identifier (name), type);
1611 TREE_STATIC (var) = 1;
1612 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1613 DECL_IGNORED_P (var) = 1;
1614 DECL_ARTIFICIAL (var) = 1;
1615 DECL_CONTEXT (var) = NULL_TREE;
1616 #ifdef OBJCPLUS
1617 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1618 #endif
1620 return var;
1623 /* Finish off the variable declaration created by start_var_decl(). */
1625 static void
1626 finish_var_decl (tree var, tree initializer)
1628 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
1631 /* Find the decl for the constant string class reference. This is only
1632 used for the NeXT runtime. */
1634 static tree
1635 setup_string_decl (void)
1637 char *name;
1638 size_t length;
1640 /* %s in format will provide room for terminating null */
1641 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1642 + strlen (constant_string_class_name);
1643 name = XNEWVEC (char, length);
1644 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1645 constant_string_class_name);
1646 constant_string_global_id = get_identifier (name);
1647 string_class_decl = lookup_name (constant_string_global_id);
1649 return string_class_decl;
1652 /* Purpose: "play" parser, creating/installing representations
1653 of the declarations that are required by Objective-C.
1655 Model:
1657 type_spec--------->sc_spec
1658 (tree_list) (tree_list)
1661 identifier_node identifier_node */
1663 static void
1664 synth_module_prologue (void)
1666 tree type;
1667 enum debug_info_type save_write_symbols = write_symbols;
1668 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1670 /* Suppress outputting debug symbols, because
1671 dbxout_init hasn't been called yet. */
1672 write_symbols = NO_DEBUG;
1673 debug_hooks = &do_nothing_debug_hooks;
1675 #ifdef OBJCPLUS
1676 push_lang_context (lang_name_c); /* extern "C" */
1677 #endif
1679 /* The following are also defined in <objc/objc.h> and friends. */
1681 objc_object_id = get_identifier (TAG_OBJECT);
1682 objc_class_id = get_identifier (TAG_CLASS);
1684 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1685 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1687 objc_object_type = build_pointer_type (objc_object_reference);
1688 objc_class_type = build_pointer_type (objc_class_reference);
1690 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1691 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1693 /* Declare the 'id' and 'Class' typedefs. */
1695 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1696 TYPE_DECL,
1697 objc_object_name,
1698 objc_object_type));
1699 TREE_NO_WARNING (type) = 1;
1700 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1701 TYPE_DECL,
1702 objc_class_name,
1703 objc_class_type));
1704 TREE_NO_WARNING (type) = 1;
1706 /* Forward-declare '@interface Protocol'. */
1708 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1709 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1710 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1711 type));
1713 /* Declare type of selector-objects that represent an operation name. */
1715 if (flag_next_runtime)
1716 /* `struct objc_selector *' */
1717 objc_selector_type
1718 = build_pointer_type (xref_tag (RECORD_TYPE,
1719 get_identifier (TAG_SELECTOR)));
1720 else
1721 /* `const struct objc_selector *' */
1722 objc_selector_type
1723 = build_pointer_type
1724 (build_qualified_type (xref_tag (RECORD_TYPE,
1725 get_identifier (TAG_SELECTOR)),
1726 TYPE_QUAL_CONST));
1728 /* Declare receiver type used for dispatching messages to 'super'. */
1730 /* `struct objc_super *' */
1731 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1732 get_identifier (TAG_SUPER)));
1734 /* Declare pointers to method and ivar lists. */
1735 objc_method_list_ptr = build_pointer_type
1736 (xref_tag (RECORD_TYPE,
1737 get_identifier (UTAG_METHOD_LIST)));
1738 objc_method_proto_list_ptr
1739 = build_pointer_type (xref_tag (RECORD_TYPE,
1740 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1741 objc_ivar_list_ptr = build_pointer_type
1742 (xref_tag (RECORD_TYPE,
1743 get_identifier (UTAG_IVAR_LIST)));
1745 /* TREE_NOTHROW is cleared for the message-sending functions,
1746 because the function that gets called can throw in Obj-C++, or
1747 could itself call something that can throw even in Obj-C. */
1749 if (flag_next_runtime)
1751 /* NB: In order to call one of the ..._stret (struct-returning)
1752 functions, the function *MUST* first be cast to a signature that
1753 corresponds to the actual ObjC method being invoked. This is
1754 what is done by the build_objc_method_call() routine below. */
1756 /* id objc_msgSend (id, SEL, ...); */
1757 /* id objc_msgSendNonNil (id, SEL, ...); */
1758 /* id objc_msgSend_stret (id, SEL, ...); */
1759 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1760 type
1761 = build_varargs_function_type_list (objc_object_type,
1762 objc_object_type,
1763 objc_selector_type,
1764 NULL_TREE);
1765 umsg_decl = add_builtin_function (TAG_MSGSEND,
1766 type, 0, NOT_BUILT_IN,
1767 NULL, NULL_TREE);
1768 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1769 type, 0, NOT_BUILT_IN,
1770 NULL, NULL_TREE);
1771 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1772 type, 0, NOT_BUILT_IN,
1773 NULL, NULL_TREE);
1774 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1775 type, 0, NOT_BUILT_IN,
1776 NULL, NULL_TREE);
1778 /* These can throw, because the function that gets called can throw
1779 in Obj-C++, or could itself call something that can throw even
1780 in Obj-C. */
1781 TREE_NOTHROW (umsg_decl) = 0;
1782 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1783 TREE_NOTHROW (umsg_stret_decl) = 0;
1784 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1786 /* id objc_msgSend_Fast (id, SEL, ...)
1787 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1788 #ifdef OFFS_MSGSEND_FAST
1789 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1790 type, 0, NOT_BUILT_IN,
1791 NULL, NULL_TREE);
1792 TREE_NOTHROW (umsg_fast_decl) = 0;
1793 DECL_ATTRIBUTES (umsg_fast_decl)
1794 = tree_cons (get_identifier ("hard_coded_address"),
1795 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1796 NULL_TREE);
1797 #else
1798 /* No direct dispatch available. */
1799 umsg_fast_decl = umsg_decl;
1800 #endif
1802 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1803 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1804 type
1805 = build_varargs_function_type_list (objc_object_type,
1806 objc_super_type,
1807 objc_selector_type,
1808 NULL_TREE);
1809 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1810 type, 0, NOT_BUILT_IN,
1811 NULL, NULL_TREE);
1812 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1813 type, 0, NOT_BUILT_IN, 0,
1814 NULL_TREE);
1815 TREE_NOTHROW (umsg_super_decl) = 0;
1816 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1818 else
1820 /* GNU runtime messenger entry points. */
1822 /* typedef id (*IMP)(id, SEL, ...); */
1823 tree ftype =
1824 build_varargs_function_type_list (objc_object_type,
1825 objc_object_type,
1826 objc_selector_type,
1827 NULL_TREE);
1828 tree IMP_type = build_pointer_type (ftype);
1830 /* IMP objc_msg_lookup (id, SEL); */
1831 type = build_function_type_list (IMP_type,
1832 objc_object_type,
1833 objc_selector_type,
1834 NULL_TREE);
1835 umsg_decl = add_builtin_function (TAG_MSGSEND,
1836 type, 0, NOT_BUILT_IN,
1837 NULL, NULL_TREE);
1838 TREE_NOTHROW (umsg_decl) = 0;
1840 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1841 type
1842 = build_function_type_list (IMP_type,
1843 objc_super_type,
1844 objc_selector_type,
1845 NULL_TREE);
1846 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1847 type, 0, NOT_BUILT_IN,
1848 NULL, NULL_TREE);
1849 TREE_NOTHROW (umsg_super_decl) = 0;
1851 /* The following GNU runtime entry point is called to initialize
1852 each module:
1854 __objc_exec_class (void *); */
1855 type
1856 = build_function_type_list (void_type_node,
1857 ptr_type_node,
1858 NULL_TREE);
1859 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1860 type, 0, NOT_BUILT_IN,
1861 NULL, NULL_TREE);
1864 /* id objc_getClass (const char *); */
1866 type = build_function_type_list (objc_object_type,
1867 const_string_type_node,
1868 NULL_TREE);
1870 objc_get_class_decl
1871 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1872 NULL, NULL_TREE);
1874 /* id objc_getMetaClass (const char *); */
1876 objc_get_meta_class_decl
1877 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1879 build_class_template ();
1880 build_super_template ();
1881 build_protocol_template ();
1882 build_category_template ();
1883 build_objc_exception_stuff ();
1885 if (flag_next_runtime)
1886 build_next_objc_exception_stuff ();
1888 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1890 if (! flag_next_runtime)
1891 build_selector_table_decl ();
1893 /* Forward declare constant_string_id and constant_string_type. */
1894 if (!constant_string_class_name)
1895 constant_string_class_name = default_constant_string_class_name;
1897 constant_string_id = get_identifier (constant_string_class_name);
1898 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1900 /* Pre-build the following entities - for speed/convenience. */
1901 self_id = get_identifier ("self");
1902 ucmd_id = get_identifier ("_cmd");
1904 #ifdef OBJCPLUS
1905 pop_lang_context ();
1906 #endif
1908 write_symbols = save_write_symbols;
1909 debug_hooks = save_hooks;
1912 /* Ensure that the ivar list for NSConstantString/NXConstantString
1913 (or whatever was specified via `-fconstant-string-class')
1914 contains fields at least as large as the following three, so that
1915 the runtime can stomp on them with confidence:
1917 struct STRING_OBJECT_CLASS_NAME
1919 Object isa;
1920 char *cString;
1921 unsigned int length;
1922 }; */
1924 static int
1925 check_string_class_template (void)
1927 tree field_decl = objc_get_class_ivars (constant_string_id);
1929 #define AT_LEAST_AS_LARGE_AS(F, T) \
1930 (F && TREE_CODE (F) == FIELD_DECL \
1931 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1932 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1934 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1935 return 0;
1937 field_decl = DECL_CHAIN (field_decl);
1938 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1939 return 0;
1941 field_decl = DECL_CHAIN (field_decl);
1942 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1944 #undef AT_LEAST_AS_LARGE_AS
1947 /* Avoid calling `check_string_class_template ()' more than once. */
1948 static GTY(()) int string_layout_checked;
1950 /* Construct an internal string layout to be used as a template for
1951 creating NSConstantString/NXConstantString instances. */
1953 static tree
1954 objc_build_internal_const_str_type (void)
1956 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1957 tree fields = build_decl (input_location,
1958 FIELD_DECL, NULL_TREE, ptr_type_node);
1959 tree field = build_decl (input_location,
1960 FIELD_DECL, NULL_TREE, ptr_type_node);
1962 DECL_CHAIN (field) = fields; fields = field;
1963 field = build_decl (input_location,
1964 FIELD_DECL, NULL_TREE, unsigned_type_node);
1965 DECL_CHAIN (field) = fields; fields = field;
1966 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1967 reverse order! */
1968 finish_builtin_struct (type, "__builtin_ObjCString",
1969 fields, NULL_TREE);
1971 return type;
1974 /* Custom build_string which sets TREE_TYPE! */
1976 static tree
1977 my_build_string (int len, const char *str)
1979 return fix_string_type (build_string (len, str));
1982 /* Build a string with contents STR and length LEN and convert it to a
1983 pointer. */
1985 static tree
1986 my_build_string_pointer (int len, const char *str)
1988 tree string = my_build_string (len, str);
1989 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1990 return build1 (ADDR_EXPR, ptrtype, string);
1993 static hashval_t
1994 string_hash (const void *ptr)
1996 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1997 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1998 int i, len = TREE_STRING_LENGTH (str);
1999 hashval_t h = len;
2001 for (i = 0; i < len; i++)
2002 h = ((h * 613) + p[i]);
2004 return h;
2007 static int
2008 string_eq (const void *ptr1, const void *ptr2)
2010 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
2011 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
2012 int len1 = TREE_STRING_LENGTH (str1);
2014 return (len1 == TREE_STRING_LENGTH (str2)
2015 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
2016 len1));
2019 /* Given a chain of STRING_CST's, build a static instance of
2020 NXConstantString which points at the concatenation of those
2021 strings. We place the string object in the __string_objects
2022 section of the __OBJC segment. The Objective-C runtime will
2023 initialize the isa pointers of the string objects to point at the
2024 NXConstantString class object. */
2026 tree
2027 objc_build_string_object (tree string)
2029 tree constructor, constant_string_class;
2030 int length;
2031 tree fields, addr;
2032 struct string_descriptor *desc, key;
2033 void **loc;
2035 /* Prep the string argument. */
2036 string = fix_string_type (string);
2037 TREE_SET_CODE (string, STRING_CST);
2038 length = TREE_STRING_LENGTH (string) - 1;
2040 /* Check whether the string class being used actually exists and has the
2041 correct ivar layout. */
2042 if (!string_layout_checked)
2044 string_layout_checked = -1;
2045 constant_string_class = lookup_interface (constant_string_id);
2046 internal_const_str_type = objc_build_internal_const_str_type ();
2048 if (!constant_string_class
2049 || !(constant_string_type
2050 = CLASS_STATIC_TEMPLATE (constant_string_class)))
2051 error ("cannot find interface declaration for %qE",
2052 constant_string_id);
2053 /* The NSConstantString/NXConstantString ivar layout is now known. */
2054 else if (!check_string_class_template ())
2055 error ("interface %qE does not have valid constant string layout",
2056 constant_string_id);
2057 /* For the NeXT runtime, we can generate a literal reference
2058 to the string class, don't need to run a constructor. */
2059 else if (flag_next_runtime && !setup_string_decl ())
2060 error ("cannot find reference tag for class %qE",
2061 constant_string_id);
2062 else
2064 string_layout_checked = 1; /* Success! */
2065 add_class_reference (constant_string_id);
2069 if (string_layout_checked == -1)
2070 return error_mark_node;
2072 /* Perhaps we already constructed a constant string just like this one? */
2073 key.literal = string;
2074 loc = htab_find_slot (string_htab, &key, INSERT);
2075 desc = (struct string_descriptor *) *loc;
2077 if (!desc)
2079 tree var;
2080 VEC(constructor_elt,gc) *v = NULL;
2081 *loc = desc = ggc_alloc_string_descriptor ();
2082 desc->literal = string;
2084 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
2085 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2086 fields = TYPE_FIELDS (internal_const_str_type);
2087 CONSTRUCTOR_APPEND_ELT (v, fields,
2088 flag_next_runtime
2089 ? build_unary_op (input_location,
2090 ADDR_EXPR, string_class_decl, 0)
2091 : build_int_cst (NULL_TREE, 0));
2092 fields = DECL_CHAIN (fields);
2093 CONSTRUCTOR_APPEND_ELT (v, fields,
2094 build_unary_op (input_location,
2095 ADDR_EXPR, string, 1));
2096 fields = DECL_CHAIN (fields);
2097 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
2098 constructor = objc_build_constructor (internal_const_str_type, v);
2100 if (!flag_next_runtime)
2101 constructor
2102 = objc_add_static_instance (constructor, constant_string_type);
2103 else
2105 var = build_decl (input_location,
2106 CONST_DECL, NULL, TREE_TYPE (constructor));
2107 DECL_INITIAL (var) = constructor;
2108 TREE_STATIC (var) = 1;
2109 pushdecl_top_level (var);
2110 constructor = var;
2112 desc->constructor = constructor;
2115 addr = convert (build_pointer_type (constant_string_type),
2116 build_unary_op (input_location,
2117 ADDR_EXPR, desc->constructor, 1));
2119 return addr;
2122 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2124 static GTY(()) int num_static_inst;
2126 static tree
2127 objc_add_static_instance (tree constructor, tree class_decl)
2129 tree *chain, decl;
2130 char buf[256];
2132 /* Find the list of static instances for the CLASS_DECL. Create one if
2133 not found. */
2134 for (chain = &objc_static_instances;
2135 *chain && TREE_VALUE (*chain) != class_decl;
2136 chain = &TREE_CHAIN (*chain));
2137 if (!*chain)
2139 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2140 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2143 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2144 decl = build_decl (input_location,
2145 VAR_DECL, get_identifier (buf), class_decl);
2146 TREE_STATIC (decl) = 1;
2147 DECL_ARTIFICIAL (decl) = 1;
2148 TREE_USED (decl) = 1;
2149 DECL_INITIAL (decl) = constructor;
2151 /* We may be writing something else just now.
2152 Postpone till end of input. */
2153 DECL_DEFER_OUTPUT (decl) = 1;
2154 pushdecl_top_level (decl);
2155 rest_of_decl_compilation (decl, 1, 0);
2157 /* Add the DECL to the head of this CLASS' list. */
2158 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2160 return decl;
2163 /* Build a static constant CONSTRUCTOR
2164 with type TYPE and elements ELTS. */
2166 static tree
2167 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
2169 tree constructor = build_constructor (type, elts);
2171 TREE_CONSTANT (constructor) = 1;
2172 TREE_STATIC (constructor) = 1;
2173 TREE_READONLY (constructor) = 1;
2175 #ifdef OBJCPLUS
2176 /* Adjust for impedance mismatch. We should figure out how to build
2177 CONSTRUCTORs that consistently please both the C and C++ gods. */
2178 if (!VEC_index (constructor_elt, elts, 0)->index)
2179 TREE_TYPE (constructor) = init_list_type_node;
2180 #endif
2182 return constructor;
2185 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2187 /* Predefine the following data type:
2189 struct _objc_symtab
2191 long sel_ref_cnt;
2192 SEL *refs;
2193 short cls_def_cnt;
2194 short cat_def_cnt;
2195 void *defs[cls_def_cnt + cat_def_cnt];
2196 }; */
2198 static void
2199 build_objc_symtab_template (void)
2201 tree fields, *chain = NULL;
2203 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2205 /* long sel_ref_cnt; */
2206 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
2208 /* SEL *refs; */
2209 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
2211 /* short cls_def_cnt; */
2212 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
2214 /* short cat_def_cnt; */
2215 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2217 if (imp_count || cat_count || !flag_next_runtime)
2219 /* void *defs[imp_count + cat_count (+ 1)]; */
2220 /* NB: The index is one less than the size of the array. */
2221 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
2222 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
2223 add_field_decl (array_type, "defs", &chain);
2226 objc_finish_struct (objc_symtab_template, fields);
2229 /* Create the initial value for the `defs' field of _objc_symtab.
2230 This is a CONSTRUCTOR. */
2232 static tree
2233 init_def_list (tree type)
2235 tree expr;
2236 struct imp_entry *impent;
2237 VEC(constructor_elt,gc) *v = NULL;
2239 if (imp_count)
2240 for (impent = imp_list; impent; impent = impent->next)
2242 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2244 expr = build_unary_op (input_location,
2245 ADDR_EXPR, impent->class_decl, 0);
2246 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2250 if (cat_count)
2251 for (impent = imp_list; impent; impent = impent->next)
2253 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2255 expr = build_unary_op (input_location,
2256 ADDR_EXPR, impent->class_decl, 0);
2257 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2261 if (!flag_next_runtime)
2263 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2264 if (static_instances_decl)
2265 expr = build_unary_op (input_location,
2266 ADDR_EXPR, static_instances_decl, 0);
2267 else
2268 expr = integer_zero_node;
2270 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2273 return objc_build_constructor (type, v);
2276 /* Construct the initial value for all of _objc_symtab. */
2278 static tree
2279 init_objc_symtab (tree type)
2281 VEC(constructor_elt,gc) *v = NULL;
2283 /* sel_ref_cnt = { ..., 5, ... } */
2285 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2286 build_int_cst (long_integer_type_node, 0));
2288 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2290 if (flag_next_runtime || ! sel_ref_chain)
2291 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
2292 build_pointer_type (objc_selector_type),
2293 integer_zero_node));
2294 else
2296 tree expr = build_unary_op (input_location, ADDR_EXPR,
2297 UOBJC_SELECTOR_TABLE_decl, 1);
2299 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2300 convert (build_pointer_type (objc_selector_type),
2301 expr));
2304 /* cls_def_cnt = { ..., 5, ... } */
2306 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2307 build_int_cst (short_integer_type_node, imp_count));
2309 /* cat_def_cnt = { ..., 5, ... } */
2311 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2312 build_int_cst (short_integer_type_node, cat_count));
2314 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2316 if (imp_count || cat_count || !flag_next_runtime)
2319 tree field = TYPE_FIELDS (type);
2320 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2322 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2325 return objc_build_constructor (type, v);
2328 /* Generate forward declarations for metadata such as
2329 'OBJC_CLASS_...'. */
2331 static tree
2332 build_metadata_decl (const char *name, tree type)
2334 tree decl;
2336 /* struct TYPE NAME_<name>; */
2337 decl = start_var_decl (type, synth_id_with_class_suffix
2338 (name,
2339 objc_implementation_context));
2341 return decl;
2344 /* Push forward-declarations of all the categories so that
2345 init_def_list can use them in a CONSTRUCTOR. */
2347 static void
2348 forward_declare_categories (void)
2350 struct imp_entry *impent;
2351 tree sav = objc_implementation_context;
2353 for (impent = imp_list; impent; impent = impent->next)
2355 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2357 /* Set an invisible arg to synth_id_with_class_suffix. */
2358 objc_implementation_context = impent->imp_context;
2359 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2360 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2361 objc_category_template);
2364 objc_implementation_context = sav;
2367 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2368 and initialized appropriately. */
2370 static void
2371 generate_objc_symtab_decl (void)
2374 build_objc_symtab_template ();
2375 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2376 finish_var_decl (UOBJC_SYMBOLS_decl,
2377 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2380 static tree
2381 init_module_descriptor (tree type)
2383 tree expr;
2384 VEC(constructor_elt,gc) *v = NULL;
2386 /* version = { 1, ... } */
2388 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2389 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2391 /* size = { ..., sizeof (struct _objc_module), ... } */
2393 expr = convert (long_integer_type_node,
2394 size_in_bytes (objc_module_template));
2395 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2397 /* Don't provide any file name for security reasons. */
2398 /* name = { ..., "", ... } */
2400 expr = add_objc_string (get_identifier (""), class_names);
2401 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2403 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2405 if (UOBJC_SYMBOLS_decl)
2406 expr = build_unary_op (input_location,
2407 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2408 else
2409 expr = null_pointer_node;
2410 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2412 return objc_build_constructor (type, v);
2415 /* Write out the data structures to describe Objective C classes defined.
2417 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2419 static void
2420 build_module_descriptor (void)
2422 tree decls, *chain = NULL;
2424 #ifdef OBJCPLUS
2425 push_lang_context (lang_name_c); /* extern "C" */
2426 #endif
2428 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2430 /* long version; */
2431 decls = add_field_decl (long_integer_type_node, "version", &chain);
2433 /* long size; */
2434 add_field_decl (long_integer_type_node, "size", &chain);
2436 /* char *name; */
2437 add_field_decl (string_type_node, "name", &chain);
2439 /* struct _objc_symtab *symtab; */
2440 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
2441 get_identifier (UTAG_SYMTAB))),
2442 "symtab", &chain);
2444 objc_finish_struct (objc_module_template, decls);
2446 /* Create an instance of "_objc_module". */
2447 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2448 /* This is the root of the metadata for defined classes and categories, it
2449 is referenced by the runtime and, therefore, needed. */
2450 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
2451 finish_var_decl (UOBJC_MODULES_decl,
2452 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2454 #ifdef OBJCPLUS
2455 pop_lang_context ();
2456 #endif
2459 /* The GNU runtime requires us to provide a static initializer function
2460 for each module:
2462 static void __objc_gnu_init (void) {
2463 __objc_exec_class (&L_OBJC_MODULES);
2464 } */
2466 static void
2467 build_module_initializer_routine (void)
2469 tree body;
2471 #ifdef OBJCPLUS
2472 push_lang_context (lang_name_c); /* extern "C" */
2473 #endif
2475 objc_push_parm (build_decl (input_location,
2476 PARM_DECL, NULL_TREE, void_type_node));
2477 #ifdef OBJCPLUS
2478 objc_start_function (get_identifier (TAG_GNUINIT),
2479 build_function_type_list (void_type_node, NULL_TREE),
2480 NULL_TREE, NULL_TREE);
2481 #else
2482 objc_start_function (get_identifier (TAG_GNUINIT),
2483 build_function_type_list (void_type_node, NULL_TREE),
2484 NULL_TREE, objc_get_parm_info (0));
2485 #endif
2486 body = c_begin_compound_stmt (true);
2487 add_stmt (build_function_call
2488 (input_location,
2489 execclass_decl,
2490 build_tree_list
2491 (NULL_TREE,
2492 build_unary_op (input_location, ADDR_EXPR,
2493 UOBJC_MODULES_decl, 0))));
2494 add_stmt (c_end_compound_stmt (input_location, body, true));
2496 TREE_PUBLIC (current_function_decl) = 0;
2498 #ifndef OBJCPLUS
2499 /* For Objective-C++, we will need to call __objc_gnu_init
2500 from objc_generate_static_init_call() below. */
2501 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2502 #endif
2504 GNU_INIT_decl = current_function_decl;
2505 finish_function ();
2507 #ifdef OBJCPLUS
2508 pop_lang_context ();
2509 #endif
2512 #ifdef OBJCPLUS
2513 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2514 to be called by the module initializer routine. */
2517 objc_static_init_needed_p (void)
2519 return (GNU_INIT_decl != NULL_TREE);
2522 /* Generate a call to the __objc_gnu_init initializer function. */
2524 tree
2525 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2527 add_stmt (build_stmt (input_location, EXPR_STMT,
2528 build_function_call (input_location,
2529 GNU_INIT_decl, NULL_TREE)));
2531 return ctors;
2533 #endif /* OBJCPLUS */
2535 /* Return the DECL of the string IDENT in the SECTION. */
2537 static tree
2538 get_objc_string_decl (tree ident, enum string_section section)
2540 tree chain;
2542 if (section == class_names)
2543 chain = class_names_chain;
2544 else if (section == meth_var_names)
2545 chain = meth_var_names_chain;
2546 else if (section == meth_var_types)
2547 chain = meth_var_types_chain;
2548 else
2549 abort ();
2551 for (; chain != 0; chain = TREE_CHAIN (chain))
2552 if (TREE_VALUE (chain) == ident)
2553 return (TREE_PURPOSE (chain));
2555 abort ();
2556 return NULL_TREE;
2559 /* Output references to all statically allocated objects. Return the DECL
2560 for the array built. */
2562 static void
2563 generate_static_references (void)
2565 tree expr = NULL_TREE;
2566 tree class_name, klass, decl;
2567 tree cl_chain, in_chain, type
2568 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2569 int num_inst, num_class;
2570 char buf[256];
2571 VEC(constructor_elt,gc) *decls = NULL;
2573 if (flag_next_runtime)
2574 gcc_unreachable ();
2576 for (cl_chain = objc_static_instances, num_class = 0;
2577 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2579 VEC(constructor_elt,gc) *v = NULL;
2581 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2582 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2584 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2585 decl = start_var_decl (type, buf);
2587 /* Output {class_name, ...}. */
2588 klass = TREE_VALUE (cl_chain);
2589 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2590 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2591 build_unary_op (input_location,
2592 ADDR_EXPR, class_name, 1));
2594 /* Output {..., instance, ...}. */
2595 for (in_chain = TREE_PURPOSE (cl_chain);
2596 in_chain; in_chain = TREE_CHAIN (in_chain))
2598 expr = build_unary_op (input_location,
2599 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2600 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2603 /* Output {..., NULL}. */
2604 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
2606 expr = objc_build_constructor (TREE_TYPE (decl), v);
2607 finish_var_decl (decl, expr);
2608 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
2609 build_unary_op (input_location,
2610 ADDR_EXPR, decl, 1));
2613 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
2614 expr = objc_build_constructor (type, decls);
2615 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2616 finish_var_decl (static_instances_decl, expr);
2619 static GTY(()) int selector_reference_idx;
2621 static tree
2622 build_selector_reference_decl (void)
2624 tree decl;
2625 char buf[256];
2627 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2628 decl = start_var_decl (objc_selector_type, buf);
2630 return decl;
2633 static void
2634 build_selector_table_decl (void)
2636 tree temp;
2638 if (flag_typed_selectors)
2640 build_selector_template ();
2641 temp = build_array_type (objc_selector_template, NULL_TREE);
2643 else
2644 temp = build_array_type (objc_selector_type, NULL_TREE);
2646 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2649 /* Just a handy wrapper for add_objc_string. */
2651 static tree
2652 build_selector (tree ident)
2654 return convert (objc_selector_type,
2655 add_objc_string (ident, meth_var_names));
2658 /* Used only by build_*_selector_translation_table (). */
2659 static void
2660 diagnose_missing_method (tree meth, location_t here)
2662 tree method_chain;
2663 bool found = false;
2664 for (method_chain = meth_var_names_chain;
2665 method_chain;
2666 method_chain = TREE_CHAIN (method_chain))
2668 if (TREE_VALUE (method_chain) == meth)
2670 found = true;
2671 break;
2675 if (!found)
2676 warning_at (here, 0, "creating selector for nonexistent method %qE",
2677 meth);
2680 static void
2681 build_next_selector_translation_table (void)
2683 tree chain;
2684 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2686 tree expr;
2687 tree decl = TREE_PURPOSE (chain);
2688 if (warn_selector && objc_implementation_context)
2690 location_t loc;
2691 if (decl)
2692 loc = DECL_SOURCE_LOCATION (decl);
2693 else
2694 loc = input_location;
2695 diagnose_missing_method (TREE_VALUE (chain), loc);
2698 expr = build_selector (TREE_VALUE (chain));
2700 if (decl)
2702 /* Entries of this form are used for references to methods.
2703 The runtime re-writes these on start-up, but the compiler can't see
2704 that and optimizes it away unless we force it. */
2705 DECL_PRESERVE_P (decl) = 1;
2706 finish_var_decl (decl, expr);
2711 static void
2712 build_gnu_selector_translation_table (void)
2714 tree chain;
2715 /* int offset = 0;
2716 tree decl = NULL_TREE;*/
2717 VEC(constructor_elt,gc) *inits = NULL;
2719 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2721 tree expr;
2723 if (warn_selector && objc_implementation_context)
2724 diagnose_missing_method (TREE_VALUE (chain), input_location);
2726 expr = build_selector (TREE_VALUE (chain));
2727 /* add one for the '\0' character
2728 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
2731 if (flag_typed_selectors)
2733 VEC(constructor_elt,gc) *v = NULL;
2734 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2735 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2736 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
2737 expr = objc_build_constructor (objc_selector_template, v);
2740 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2742 } /* each element in the chain */
2745 /* Cause the selector table (previously forward-declared)
2746 to be actually output. */
2747 tree expr;
2749 if (flag_typed_selectors)
2751 VEC(constructor_elt,gc) *v = NULL;
2752 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
2753 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
2754 expr = objc_build_constructor (objc_selector_template, v);
2756 else
2757 expr = integer_zero_node;
2759 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2760 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2761 inits);
2762 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
2766 static tree
2767 get_proto_encoding (tree proto)
2769 tree encoding;
2770 if (proto)
2772 if (! METHOD_ENCODING (proto))
2774 encoding = encode_method_prototype (proto);
2775 METHOD_ENCODING (proto) = encoding;
2777 else
2778 encoding = METHOD_ENCODING (proto);
2780 return add_objc_string (encoding, meth_var_types);
2782 else
2783 return build_int_cst (NULL_TREE, 0);
2786 /* sel_ref_chain is a list whose "value" fields will be instances of
2787 identifier_node that represent the selector. LOC is the location of
2788 the @selector. */
2790 static tree
2791 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
2793 tree *chain = &sel_ref_chain;
2794 tree expr;
2795 int index = 0;
2797 while (*chain)
2799 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2800 goto return_at_index;
2802 index++;
2803 chain = &TREE_CHAIN (*chain);
2806 *chain = tree_cons (prototype, ident, NULL_TREE);
2808 return_at_index:
2809 expr = build_unary_op (loc, ADDR_EXPR,
2810 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2811 build_int_cst (NULL_TREE, index)),
2813 return convert (objc_selector_type, expr);
2816 static tree
2817 build_selector_reference (location_t loc, tree ident)
2819 tree *chain = &sel_ref_chain;
2820 tree expr;
2821 int index = 0;
2823 while (*chain)
2825 if (TREE_VALUE (*chain) == ident)
2826 return (flag_next_runtime
2827 ? TREE_PURPOSE (*chain)
2828 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2829 build_int_cst (NULL_TREE, index)));
2831 index++;
2832 chain = &TREE_CHAIN (*chain);
2835 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2837 *chain = tree_cons (expr, ident, NULL_TREE);
2839 return (flag_next_runtime
2840 ? expr
2841 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2842 build_int_cst (NULL_TREE, index)));
2845 static GTY(()) int class_reference_idx;
2847 static tree
2848 build_class_reference_decl (void)
2850 tree decl;
2851 char buf[256];
2853 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2854 decl = start_var_decl (objc_class_type, buf);
2856 return decl;
2859 /* Create a class reference, but don't create a variable to reference
2860 it. */
2862 static void
2863 add_class_reference (tree ident)
2865 tree chain;
2867 if ((chain = cls_ref_chain))
2869 tree tail;
2872 if (ident == TREE_VALUE (chain))
2873 return;
2875 tail = chain;
2876 chain = TREE_CHAIN (chain);
2878 while (chain);
2880 /* Append to the end of the list */
2881 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2883 else
2884 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2887 /* Get a class reference, creating it if necessary. Also create the
2888 reference variable. */
2890 tree
2891 objc_get_class_reference (tree ident)
2893 tree orig_ident = (DECL_P (ident)
2894 ? DECL_NAME (ident)
2895 : TYPE_P (ident)
2896 ? OBJC_TYPE_NAME (ident)
2897 : ident);
2898 bool local_scope = false;
2900 #ifdef OBJCPLUS
2901 if (processing_template_decl)
2902 /* Must wait until template instantiation time. */
2903 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2904 #endif
2906 if (TREE_CODE (ident) == TYPE_DECL)
2907 ident = (DECL_ORIGINAL_TYPE (ident)
2908 ? DECL_ORIGINAL_TYPE (ident)
2909 : TREE_TYPE (ident));
2911 #ifdef OBJCPLUS
2912 if (TYPE_P (ident)
2913 && CP_TYPE_CONTEXT (ident) != global_namespace)
2914 local_scope = true;
2915 #endif
2917 if (local_scope || !(ident = objc_is_class_name (ident)))
2919 error ("%qE is not an Objective-C class name or alias",
2920 orig_ident);
2921 return error_mark_node;
2924 if (flag_next_runtime && !flag_zero_link)
2926 tree *chain;
2927 tree decl;
2929 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2930 if (TREE_VALUE (*chain) == ident)
2932 if (! TREE_PURPOSE (*chain))
2933 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2935 return TREE_PURPOSE (*chain);
2938 decl = build_class_reference_decl ();
2939 *chain = tree_cons (decl, ident, NULL_TREE);
2940 return decl;
2942 else
2944 tree params;
2946 add_class_reference (ident);
2948 params = build_tree_list (NULL_TREE,
2949 my_build_string_pointer
2950 (IDENTIFIER_LENGTH (ident) + 1,
2951 IDENTIFIER_POINTER (ident)));
2953 assemble_external (objc_get_class_decl);
2954 return build_function_call (input_location, objc_get_class_decl, params);
2958 /* For each string section we have a chain which maps identifier nodes
2959 to decls for the strings. */
2961 static GTY(()) int class_names_idx;
2962 static GTY(()) int meth_var_names_idx;
2963 static GTY(()) int meth_var_types_idx;
2965 static tree
2966 add_objc_string (tree ident, enum string_section section)
2968 tree *chain, decl, type, string_expr;
2969 char buf[256];
2971 buf[0] = 0;
2972 if (section == class_names)
2974 chain = &class_names_chain;
2975 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2977 else if (section == meth_var_names)
2979 chain = &meth_var_names_chain;
2980 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2982 else if (section == meth_var_types)
2984 chain = &meth_var_types_chain;
2985 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2987 else
2988 gcc_unreachable ();
2990 while (*chain)
2992 if (TREE_VALUE (*chain) == ident)
2993 return convert (string_type_node,
2994 build_unary_op (input_location,
2995 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2997 chain = &TREE_CHAIN (*chain);
3000 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
3001 decl = start_var_decl (type, buf);
3002 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
3003 IDENTIFIER_POINTER (ident));
3004 TREE_CONSTANT (decl) = 1;
3005 finish_var_decl (decl, string_expr);
3007 *chain = tree_cons (decl, ident, NULL_TREE);
3009 return convert (string_type_node, build_unary_op (input_location,
3010 ADDR_EXPR, decl, 1));
3013 void
3014 objc_declare_alias (tree alias_ident, tree class_ident)
3016 tree underlying_class;
3018 #ifdef OBJCPLUS
3019 if (current_namespace != global_namespace) {
3020 error ("Objective-C declarations may only appear in global scope");
3022 #endif /* OBJCPLUS */
3024 if (!(underlying_class = objc_is_class_name (class_ident)))
3025 warning (0, "cannot find class %qE", class_ident);
3026 else if (objc_is_class_name (alias_ident))
3027 warning (0, "class %qE already exists", alias_ident);
3028 else
3030 /* Implement @compatibility_alias as a typedef. */
3031 #ifdef OBJCPLUS
3032 push_lang_context (lang_name_c); /* extern "C" */
3033 #endif
3034 lang_hooks.decls.pushdecl (build_decl
3035 (input_location,
3036 TYPE_DECL,
3037 alias_ident,
3038 xref_tag (RECORD_TYPE, underlying_class)));
3039 #ifdef OBJCPLUS
3040 pop_lang_context ();
3041 #endif
3042 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
3046 void
3047 objc_declare_class (tree ident_list)
3049 tree list;
3050 #ifdef OBJCPLUS
3051 if (current_namespace != global_namespace) {
3052 error ("Objective-C declarations may only appear in global scope");
3054 #endif /* OBJCPLUS */
3056 for (list = ident_list; list; list = TREE_CHAIN (list))
3058 tree ident = TREE_VALUE (list);
3060 if (! objc_is_class_name (ident))
3062 tree record = lookup_name (ident), type = record;
3064 if (record)
3066 if (TREE_CODE (record) == TYPE_DECL)
3067 type = DECL_ORIGINAL_TYPE (record);
3069 if (!TYPE_HAS_OBJC_INFO (type)
3070 || !TYPE_OBJC_INTERFACE (type))
3072 error ("%qE redeclared as different kind of symbol",
3073 ident);
3074 error ("previous declaration of %q+D",
3075 record);
3079 record = xref_tag (RECORD_TYPE, ident);
3080 INIT_TYPE_OBJC_INFO (record);
3081 TYPE_OBJC_INTERFACE (record) = ident;
3082 class_chain = tree_cons (NULL_TREE, ident, class_chain);
3087 tree
3088 objc_is_class_name (tree ident)
3090 tree chain;
3092 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3093 && identifier_global_value (ident))
3094 ident = identifier_global_value (ident);
3095 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3096 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3098 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3099 ident = OBJC_TYPE_NAME (ident);
3100 #ifdef OBJCPLUS
3101 if (ident && TREE_CODE (ident) == TYPE_DECL)
3102 ident = DECL_NAME (ident);
3103 #endif
3104 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3105 return NULL_TREE;
3107 if (lookup_interface (ident))
3108 return ident;
3110 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3112 if (ident == TREE_VALUE (chain))
3113 return ident;
3116 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3118 if (ident == TREE_VALUE (chain))
3119 return TREE_PURPOSE (chain);
3122 return 0;
3125 /* Check whether TYPE is either 'id' or 'Class'. */
3127 tree
3128 objc_is_id (tree type)
3130 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3131 && identifier_global_value (type))
3132 type = identifier_global_value (type);
3134 if (type && TREE_CODE (type) == TYPE_DECL)
3135 type = TREE_TYPE (type);
3137 /* NB: This function may be called before the ObjC front-end has
3138 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3139 return (objc_object_type && type
3140 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3141 ? type
3142 : NULL_TREE);
3145 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3146 class instance. This is needed by other parts of the compiler to
3147 handle ObjC types gracefully. */
3149 tree
3150 objc_is_object_ptr (tree type)
3152 tree ret;
3154 type = TYPE_MAIN_VARIANT (type);
3155 if (!POINTER_TYPE_P (type))
3156 return 0;
3158 ret = objc_is_id (type);
3159 if (!ret)
3160 ret = objc_is_class_name (TREE_TYPE (type));
3162 return ret;
3165 static int
3166 objc_is_gcable_type (tree type, int or_strong_p)
3168 tree name;
3170 if (!TYPE_P (type))
3171 return 0;
3172 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3173 return 1;
3174 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3175 return 1;
3176 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3177 return 0;
3178 type = TREE_TYPE (type);
3179 if (TREE_CODE (type) != RECORD_TYPE)
3180 return 0;
3181 name = TYPE_NAME (type);
3182 return (objc_is_class_name (name) != NULL_TREE);
3185 static tree
3186 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3188 if (expr == oldexpr)
3189 return newexpr;
3191 switch (TREE_CODE (expr))
3193 case COMPONENT_REF:
3194 return objc_build_component_ref
3195 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3196 oldexpr,
3197 newexpr),
3198 DECL_NAME (TREE_OPERAND (expr, 1)));
3199 case ARRAY_REF:
3200 return build_array_ref (input_location,
3201 objc_substitute_decl (TREE_OPERAND (expr, 0),
3202 oldexpr,
3203 newexpr),
3204 TREE_OPERAND (expr, 1));
3205 case INDIRECT_REF:
3206 return build_indirect_ref (input_location,
3207 objc_substitute_decl (TREE_OPERAND (expr, 0),
3208 oldexpr,
3209 newexpr), RO_ARROW);
3210 default:
3211 return expr;
3215 static tree
3216 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3218 tree func_params;
3219 /* The LHS parameter contains the expression 'outervar->memberspec';
3220 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3221 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3223 tree offs
3224 = objc_substitute_decl
3225 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3226 tree func
3227 = (flag_objc_direct_dispatch
3228 ? objc_assign_ivar_fast_decl
3229 : objc_assign_ivar_decl);
3231 offs = convert (integer_type_node, build_unary_op (input_location,
3232 ADDR_EXPR, offs, 0));
3233 offs = fold (offs);
3234 func_params = tree_cons (NULL_TREE,
3235 convert (objc_object_type, rhs),
3236 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3237 tree_cons (NULL_TREE, offs,
3238 NULL_TREE)));
3240 assemble_external (func);
3241 return build_function_call (input_location, func, func_params);
3244 static tree
3245 objc_build_global_assignment (tree lhs, tree rhs)
3247 tree func_params = tree_cons (NULL_TREE,
3248 convert (objc_object_type, rhs),
3249 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3250 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3251 NULL_TREE));
3253 assemble_external (objc_assign_global_decl);
3254 return build_function_call (input_location,
3255 objc_assign_global_decl, func_params);
3258 static tree
3259 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3261 tree func_params = tree_cons (NULL_TREE,
3262 convert (objc_object_type, rhs),
3263 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3264 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3265 NULL_TREE));
3267 assemble_external (objc_assign_strong_cast_decl);
3268 return build_function_call (input_location,
3269 objc_assign_strong_cast_decl, func_params);
3272 static int
3273 objc_is_gcable_p (tree expr)
3275 return (TREE_CODE (expr) == COMPONENT_REF
3276 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3277 : TREE_CODE (expr) == ARRAY_REF
3278 ? (objc_is_gcable_p (TREE_TYPE (expr))
3279 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3280 : TREE_CODE (expr) == ARRAY_TYPE
3281 ? objc_is_gcable_p (TREE_TYPE (expr))
3282 : TYPE_P (expr)
3283 ? objc_is_gcable_type (expr, 1)
3284 : (objc_is_gcable_p (TREE_TYPE (expr))
3285 || (DECL_P (expr)
3286 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3289 static int
3290 objc_is_ivar_reference_p (tree expr)
3292 return (TREE_CODE (expr) == ARRAY_REF
3293 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3294 : TREE_CODE (expr) == COMPONENT_REF
3295 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3296 : 0);
3299 static int
3300 objc_is_global_reference_p (tree expr)
3302 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3303 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3304 : DECL_P (expr)
3305 ? (DECL_FILE_SCOPE_P (expr) || TREE_STATIC (expr))
3306 : 0);
3309 tree
3310 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3312 tree result = NULL_TREE, outer;
3313 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3315 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3316 will have been transformed to the form '*(type *)&expr'. */
3317 if (TREE_CODE (lhs) == INDIRECT_REF)
3319 outer = TREE_OPERAND (lhs, 0);
3321 while (!strong_cast_p
3322 && (CONVERT_EXPR_P (outer)
3323 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3325 tree lhstype = TREE_TYPE (outer);
3327 /* Descend down the cast chain, and record the first objc_gc
3328 attribute found. */
3329 if (POINTER_TYPE_P (lhstype))
3331 tree attr
3332 = lookup_attribute ("objc_gc",
3333 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3335 if (attr)
3336 strong_cast_p = 1;
3339 outer = TREE_OPERAND (outer, 0);
3343 /* If we have a __strong cast, it trumps all else. */
3344 if (strong_cast_p)
3346 if (modifycode != NOP_EXPR)
3347 goto invalid_pointer_arithmetic;
3349 if (warn_assign_intercept)
3350 warning (0, "strong-cast assignment has been intercepted");
3352 result = objc_build_strong_cast_assignment (lhs, rhs);
3354 goto exit_point;
3357 /* the lhs must be of a suitable type, regardless of its underlying
3358 structure. */
3359 if (!objc_is_gcable_p (lhs))
3360 goto exit_point;
3362 outer = lhs;
3364 while (outer
3365 && (TREE_CODE (outer) == COMPONENT_REF
3366 || TREE_CODE (outer) == ARRAY_REF))
3367 outer = TREE_OPERAND (outer, 0);
3369 if (TREE_CODE (outer) == INDIRECT_REF)
3371 outer = TREE_OPERAND (outer, 0);
3372 indirect_p = 1;
3375 outer_gc_p = objc_is_gcable_p (outer);
3377 /* Handle ivar assignments. */
3378 if (objc_is_ivar_reference_p (lhs))
3380 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3381 doesn't cut it here), the best we can do here is suggest a cast. */
3382 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3384 /* We may still be able to use the global write barrier... */
3385 if (!indirect_p && objc_is_global_reference_p (outer))
3386 goto global_reference;
3388 suggest_cast:
3389 if (modifycode == NOP_EXPR)
3391 if (warn_assign_intercept)
3392 warning (0, "strong-cast may possibly be needed");
3395 goto exit_point;
3398 if (modifycode != NOP_EXPR)
3399 goto invalid_pointer_arithmetic;
3401 if (warn_assign_intercept)
3402 warning (0, "instance variable assignment has been intercepted");
3404 result = objc_build_ivar_assignment (outer, lhs, rhs);
3406 goto exit_point;
3409 /* Likewise, intercept assignment to global/static variables if their type is
3410 GC-marked. */
3411 if (objc_is_global_reference_p (outer))
3413 if (indirect_p)
3414 goto suggest_cast;
3416 global_reference:
3417 if (modifycode != NOP_EXPR)
3419 invalid_pointer_arithmetic:
3420 if (outer_gc_p)
3421 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3423 goto exit_point;
3426 if (warn_assign_intercept)
3427 warning (0, "global/static variable assignment has been intercepted");
3429 result = objc_build_global_assignment (lhs, rhs);
3432 /* In all other cases, fall back to the normal mechanism. */
3433 exit_point:
3434 return result;
3437 struct GTY(()) interface_tuple {
3438 tree id;
3439 tree class_name;
3442 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3444 static hashval_t
3445 hash_interface (const void *p)
3447 const struct interface_tuple *d = (const struct interface_tuple *) p;
3448 return IDENTIFIER_HASH_VALUE (d->id);
3451 static int
3452 eq_interface (const void *p1, const void *p2)
3454 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3455 return d->id == p2;
3458 static tree
3459 lookup_interface (tree ident)
3461 #ifdef OBJCPLUS
3462 if (ident && TREE_CODE (ident) == TYPE_DECL)
3463 ident = DECL_NAME (ident);
3464 #endif
3466 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3467 return NULL_TREE;
3470 struct interface_tuple **slot;
3471 tree i = NULL_TREE;
3473 if (interface_htab)
3475 slot = (struct interface_tuple **)
3476 htab_find_slot_with_hash (interface_htab, ident,
3477 IDENTIFIER_HASH_VALUE (ident),
3478 NO_INSERT);
3479 if (slot && *slot)
3480 i = (*slot)->class_name;
3482 return i;
3486 /* Implement @defs (<classname>) within struct bodies. */
3488 tree
3489 objc_get_class_ivars (tree class_name)
3491 tree interface = lookup_interface (class_name);
3493 if (interface)
3494 return get_class_ivars (interface, true);
3496 error ("cannot find interface declaration for %qE",
3497 class_name);
3499 return error_mark_node;
3502 /* Called when checking the variables in a struct. If we are not
3503 doing the ivars list inside an @interface context, then returns
3504 fieldlist unchanged. Else, returns the list of class ivars.
3506 tree
3507 objc_get_interface_ivars (tree fieldlist)
3509 if (!objc_collecting_ivars || !objc_interface_context
3510 || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
3511 || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
3512 return fieldlist;
3514 return get_class_ivars (objc_interface_context, true);
3517 /* Used by: build_private_template, continue_class,
3518 and for @defs constructs. */
3520 static tree
3521 get_class_ivars (tree interface, bool inherited)
3523 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3525 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3526 by the current class (i.e., they do not include super-class ivars).
3527 However, the CLASS_IVARS list will be side-effected by a call to
3528 finish_struct(), which will fill in field offsets. */
3529 if (!CLASS_IVARS (interface))
3530 CLASS_IVARS (interface) = ivar_chain;
3532 if (!inherited)
3533 return ivar_chain;
3535 while (CLASS_SUPER_NAME (interface))
3537 /* Prepend super-class ivars. */
3538 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3539 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3540 ivar_chain);
3543 return ivar_chain;
3546 static tree
3547 objc_create_temporary_var (tree type)
3549 tree decl;
3551 decl = build_decl (input_location,
3552 VAR_DECL, NULL_TREE, type);
3553 TREE_USED (decl) = 1;
3554 DECL_ARTIFICIAL (decl) = 1;
3555 DECL_IGNORED_P (decl) = 1;
3556 DECL_CONTEXT (decl) = current_function_decl;
3558 return decl;
3561 /* Exception handling constructs. We begin by having the parser do most
3562 of the work and passing us blocks. What we do next depends on whether
3563 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3564 We abstract all of this in a handful of appropriately named routines. */
3566 /* Stack of open try blocks. */
3568 struct objc_try_context
3570 struct objc_try_context *outer;
3572 /* Statements (or statement lists) as processed by the parser. */
3573 tree try_body;
3574 tree finally_body;
3576 /* Some file position locations. */
3577 location_t try_locus;
3578 location_t end_try_locus;
3579 location_t end_catch_locus;
3580 location_t finally_locus;
3581 location_t end_finally_locus;
3583 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3584 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3585 tree catch_list;
3587 /* The CATCH_EXPR of an open @catch clause. */
3588 tree current_catch;
3590 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
3591 tree caught_decl;
3592 tree stack_decl;
3593 tree rethrow_decl;
3596 static struct objc_try_context *cur_try_context;
3598 static GTY(()) tree objc_eh_personality_decl;
3600 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3601 that represents TYPE. For Objective-C, this is just the class name. */
3602 /* ??? Isn't there a class object or some such? Is it easy to get? */
3604 #ifndef OBJCPLUS
3605 tree
3606 objc_eh_runtime_type (tree type)
3608 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3611 tree
3612 objc_eh_personality (void)
3614 if (!flag_objc_sjlj_exceptions
3615 && !objc_eh_personality_decl)
3616 objc_eh_personality_decl
3617 = build_personality_function (USING_SJLJ_EXCEPTIONS
3618 ? "__gnu_objc_personality_sj0"
3619 : "__gnu_objc_personality_v0");
3621 return objc_eh_personality_decl;
3623 #endif
3625 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
3626 of Darwin, we'll arrange for it to be initialized (and associated
3627 with a binding) later. */
3629 static tree
3630 objc_build_exc_ptr (void)
3632 if (flag_objc_sjlj_exceptions)
3634 tree var = cur_try_context->caught_decl;
3635 if (!var)
3637 var = objc_create_temporary_var (objc_object_type);
3638 cur_try_context->caught_decl = var;
3640 return var;
3642 else
3644 tree t;
3645 t = built_in_decls[BUILT_IN_EH_POINTER];
3646 t = build_call_expr (t, 1, integer_zero_node);
3647 return fold_convert (objc_object_type, t);
3651 /* Build "objc_exception_try_exit(&_stack)". */
3653 static tree
3654 next_sjlj_build_try_exit (void)
3656 tree t;
3657 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3658 t = tree_cons (NULL, t, NULL);
3659 t = build_function_call (input_location,
3660 objc_exception_try_exit_decl, t);
3661 return t;
3664 /* Build
3665 objc_exception_try_enter (&_stack);
3666 if (_setjmp(&_stack.buf))
3668 else
3670 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3671 empty, ready for the caller to fill them in. */
3673 static tree
3674 next_sjlj_build_enter_and_setjmp (void)
3676 tree t, enter, sj, cond;
3678 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3679 t = tree_cons (NULL, t, NULL);
3680 enter = build_function_call (input_location,
3681 objc_exception_try_enter_decl, t);
3683 t = objc_build_component_ref (cur_try_context->stack_decl,
3684 get_identifier ("buf"));
3685 t = build_fold_addr_expr_loc (input_location, t);
3686 #ifdef OBJCPLUS
3687 /* Convert _setjmp argument to type that is expected. */
3688 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3689 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3690 else
3691 t = convert (ptr_type_node, t);
3692 #else
3693 t = convert (ptr_type_node, t);
3694 #endif
3695 t = tree_cons (NULL, t, NULL);
3696 sj = build_function_call (input_location,
3697 objc_setjmp_decl, t);
3699 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3700 cond = c_common_truthvalue_conversion (input_location, cond);
3702 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3705 /* Build:
3707 DECL = objc_exception_extract(&_stack); */
3709 static tree
3710 next_sjlj_build_exc_extract (tree decl)
3712 tree t;
3714 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3715 t = tree_cons (NULL, t, NULL);
3716 t = build_function_call (input_location,
3717 objc_exception_extract_decl, t);
3718 t = convert (TREE_TYPE (decl), t);
3719 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3721 return t;
3724 /* Build
3725 if (objc_exception_match(obj_get_class(TYPE), _caught)
3726 BODY
3727 else if (...)
3729 else
3731 _rethrow = _caught;
3732 objc_exception_try_exit(&_stack);
3734 from the sequence of CATCH_EXPRs in the current try context. */
3736 static tree
3737 next_sjlj_build_catch_list (void)
3739 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3740 tree catch_seq, t;
3741 tree *last = &catch_seq;
3742 bool saw_id = false;
3744 for (; !tsi_end_p (i); tsi_next (&i))
3746 tree stmt = tsi_stmt (i);
3747 tree type = CATCH_TYPES (stmt);
3748 tree body = CATCH_BODY (stmt);
3750 if (type == NULL)
3752 *last = body;
3753 saw_id = true;
3754 break;
3756 else
3758 tree args, cond;
3760 if (type == error_mark_node)
3761 cond = error_mark_node;
3762 else
3764 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3765 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3766 args = tree_cons (NULL, t, args);
3767 t = build_function_call (input_location,
3768 objc_exception_match_decl, args);
3769 cond = c_common_truthvalue_conversion (input_location, t);
3771 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3772 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
3774 *last = t;
3775 last = &COND_EXPR_ELSE (t);
3779 if (!saw_id)
3781 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3782 cur_try_context->caught_decl);
3783 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3784 append_to_statement_list (t, last);
3786 t = next_sjlj_build_try_exit ();
3787 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3788 append_to_statement_list (t, last);
3791 return catch_seq;
3794 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3795 exception handling. We aim to build:
3798 struct _objc_exception_data _stack;
3799 id _rethrow = 0;
3802 objc_exception_try_enter (&_stack);
3803 if (_setjmp(&_stack.buf))
3805 id _caught = objc_exception_extract(&_stack);
3806 objc_exception_try_enter (&_stack);
3807 if (_setjmp(&_stack.buf))
3808 _rethrow = objc_exception_extract(&_stack);
3809 else
3810 CATCH-LIST
3812 else
3813 TRY-BLOCK
3815 finally
3817 if (!_rethrow)
3818 objc_exception_try_exit(&_stack);
3819 FINALLY-BLOCK
3820 if (_rethrow)
3821 objc_exception_throw(_rethrow);
3825 If CATCH-LIST is empty, we can omit all of the block containing
3826 "_caught" except for the setting of _rethrow. Note the use of
3827 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3828 but handles goto and other exits from the block. */
3830 static tree
3831 next_sjlj_build_try_catch_finally (void)
3833 tree rethrow_decl, stack_decl, t;
3834 tree catch_seq, try_fin, bind;
3836 /* Create the declarations involved. */
3837 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3838 stack_decl = objc_create_temporary_var (t);
3839 cur_try_context->stack_decl = stack_decl;
3841 rethrow_decl = objc_create_temporary_var (objc_object_type);
3842 cur_try_context->rethrow_decl = rethrow_decl;
3843 TREE_CHAIN (rethrow_decl) = stack_decl;
3845 /* Build the outermost variable binding level. */
3846 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3847 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3848 TREE_SIDE_EFFECTS (bind) = 1;
3850 /* Initialize rethrow_decl. */
3851 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3852 convert (objc_object_type, null_pointer_node));
3853 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3854 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3856 /* Build the outermost TRY_FINALLY_EXPR. */
3857 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3858 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3859 TREE_SIDE_EFFECTS (try_fin) = 1;
3860 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3862 /* Create the complete catch sequence. */
3863 if (cur_try_context->catch_list)
3865 tree caught_decl = objc_build_exc_ptr ();
3866 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
3867 TREE_SIDE_EFFECTS (catch_seq) = 1;
3869 t = next_sjlj_build_exc_extract (caught_decl);
3870 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3872 t = next_sjlj_build_enter_and_setjmp ();
3873 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3874 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3875 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3877 else
3878 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3879 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3881 /* Build the main register-and-try if statement. */
3882 t = next_sjlj_build_enter_and_setjmp ();
3883 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3884 COND_EXPR_THEN (t) = catch_seq;
3885 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3886 TREE_OPERAND (try_fin, 0) = t;
3888 /* Build the complete FINALLY statement list. */
3889 t = next_sjlj_build_try_exit ();
3890 t = build_stmt (input_location, COND_EXPR,
3891 c_common_truthvalue_conversion
3892 (input_location, rethrow_decl),
3893 NULL, t);
3894 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3895 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3897 append_to_statement_list (cur_try_context->finally_body,
3898 &TREE_OPERAND (try_fin, 1));
3900 t = tree_cons (NULL, rethrow_decl, NULL);
3901 t = build_function_call (input_location,
3902 objc_exception_throw_decl, t);
3903 t = build_stmt (input_location, COND_EXPR,
3904 c_common_truthvalue_conversion (input_location,
3905 rethrow_decl),
3906 t, NULL);
3907 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3908 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3910 return bind;
3913 /* Called just after parsing the @try and its associated BODY. We now
3914 must prepare for the tricky bits -- handling the catches and finally. */
3916 void
3917 objc_begin_try_stmt (location_t try_locus, tree body)
3919 struct objc_try_context *c = XCNEW (struct objc_try_context);
3920 c->outer = cur_try_context;
3921 c->try_body = body;
3922 c->try_locus = try_locus;
3923 c->end_try_locus = input_location;
3924 cur_try_context = c;
3926 /* -fobjc-exceptions is required to enable Objective-C exceptions.
3927 For example, on Darwin, ObjC exceptions require a sufficiently
3928 recent version of the runtime, so the user must ask for them
3929 explicitly. On other platforms, at the moment -fobjc-exceptions
3930 triggers -fexceptions which again is required for exceptions to
3931 work.
3933 if (!flag_objc_exceptions)
3935 error_at (try_locus, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
3938 if (flag_objc_sjlj_exceptions)
3939 objc_mark_locals_volatile (NULL);
3942 /* Called just after parsing "@catch (parm)". Open a binding level,
3943 enter DECL into the binding level, and initialize it. Leave the
3944 binding level open while the body of the compound statement is parsed. */
3946 void
3947 objc_begin_catch_clause (tree decl)
3949 tree compound, type, t;
3951 /* Begin a new scope that the entire catch clause will live in. */
3952 compound = c_begin_compound_stmt (true);
3954 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3955 decl = build_decl (input_location,
3956 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3957 lang_hooks.decls.pushdecl (decl);
3959 /* Since a decl is required here by syntax, don't warn if its unused. */
3960 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3961 be what the previous objc implementation did. */
3962 TREE_USED (decl) = 1;
3963 DECL_READ_P (decl) = 1;
3965 /* Verify that the type of the catch is valid. It must be a pointer
3966 to an Objective-C class, or "id" (which is catch-all). */
3967 type = TREE_TYPE (decl);
3969 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3970 type = NULL;
3971 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3973 error ("@catch parameter is not a known Objective-C class type");
3974 type = error_mark_node;
3976 else if (cur_try_context->catch_list)
3978 /* Examine previous @catch clauses and see if we've already
3979 caught the type in question. */
3980 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3981 for (; !tsi_end_p (i); tsi_next (&i))
3983 tree stmt = tsi_stmt (i);
3984 t = CATCH_TYPES (stmt);
3985 if (t == error_mark_node)
3986 continue;
3987 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3989 warning (0, "exception of type %<%T%> will be caught",
3990 TREE_TYPE (type));
3991 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
3992 TREE_TYPE (t ? t : objc_object_type));
3993 break;
3998 /* Record the data for the catch in the try context so that we can
3999 finalize it later. */
4000 t = build_stmt (input_location, CATCH_EXPR, type, compound);
4001 cur_try_context->current_catch = t;
4003 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
4004 t = objc_build_exc_ptr ();
4005 t = convert (TREE_TYPE (decl), t);
4006 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4007 add_stmt (t);
4010 /* Called just after parsing the closing brace of a @catch clause. Close
4011 the open binding level, and record a CATCH_EXPR for it. */
4013 void
4014 objc_finish_catch_clause (void)
4016 tree c = cur_try_context->current_catch;
4017 cur_try_context->current_catch = NULL;
4018 cur_try_context->end_catch_locus = input_location;
4020 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
4021 append_to_statement_list (c, &cur_try_context->catch_list);
4024 /* Called after parsing a @finally clause and its associated BODY.
4025 Record the body for later placement. */
4027 void
4028 objc_build_finally_clause (location_t finally_locus, tree body)
4030 cur_try_context->finally_body = body;
4031 cur_try_context->finally_locus = finally_locus;
4032 cur_try_context->end_finally_locus = input_location;
4035 /* Called to finalize a @try construct. */
4037 tree
4038 objc_finish_try_stmt (void)
4040 struct objc_try_context *c = cur_try_context;
4041 tree stmt;
4043 if (c->catch_list == NULL && c->finally_body == NULL)
4044 error ("%<@try%> without %<@catch%> or %<@finally%>");
4046 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
4047 if (flag_objc_sjlj_exceptions)
4049 bool save = in_late_binary_op;
4050 in_late_binary_op = true;
4051 if (!cur_try_context->finally_body)
4053 cur_try_context->finally_locus = input_location;
4054 cur_try_context->end_finally_locus = input_location;
4056 stmt = next_sjlj_build_try_catch_finally ();
4057 in_late_binary_op = save;
4059 else
4061 /* Otherwise, nest the CATCH inside a FINALLY. */
4062 stmt = c->try_body;
4063 if (c->catch_list)
4065 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
4066 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4068 if (c->finally_body)
4070 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
4071 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
4074 add_stmt (stmt);
4076 cur_try_context = c->outer;
4077 free (c);
4078 return stmt;
4081 tree
4082 objc_build_throw_stmt (location_t loc, tree throw_expr)
4084 tree args;
4086 if (!flag_objc_exceptions)
4088 error_at (loc, "%<-fobjc-exceptions%> is required to enable Objective-C exception syntax");
4091 if (throw_expr == NULL)
4093 /* If we're not inside a @catch block, there is no "current
4094 exception" to be rethrown. */
4095 if (cur_try_context == NULL
4096 || cur_try_context->current_catch == NULL)
4098 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
4099 return NULL_TREE;
4102 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4103 value that we get from the runtime. */
4104 throw_expr = objc_build_exc_ptr ();
4107 /* A throw is just a call to the runtime throw function with the
4108 object as a parameter. */
4109 args = tree_cons (NULL, throw_expr, NULL);
4110 return add_stmt (build_function_call (loc,
4111 objc_exception_throw_decl, args));
4114 tree
4115 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4117 tree args, call;
4119 /* First lock the mutex. */
4120 mutex = save_expr (mutex);
4121 args = tree_cons (NULL, mutex, NULL);
4122 call = build_function_call (input_location,
4123 objc_sync_enter_decl, args);
4124 SET_EXPR_LOCATION (call, start_locus);
4125 add_stmt (call);
4127 /* Build the mutex unlock. */
4128 args = tree_cons (NULL, mutex, NULL);
4129 call = build_function_call (input_location,
4130 objc_sync_exit_decl, args);
4131 SET_EXPR_LOCATION (call, input_location);
4133 /* Put the that and the body in a TRY_FINALLY. */
4134 objc_begin_try_stmt (start_locus, body);
4135 objc_build_finally_clause (input_location, call);
4136 return objc_finish_try_stmt ();
4140 /* Predefine the following data type:
4142 struct _objc_exception_data
4144 int buf[OBJC_JBLEN];
4145 void *pointers[4];
4146 }; */
4148 /* The following yuckiness should prevent users from having to #include
4149 <setjmp.h> in their code... */
4151 /* Define to a harmless positive value so the below code doesn't die. */
4152 #ifndef OBJC_JBLEN
4153 #define OBJC_JBLEN 18
4154 #endif
4156 static void
4157 build_next_objc_exception_stuff (void)
4159 tree decls, temp_type, *chain = NULL;
4161 objc_exception_data_template
4162 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4164 /* int buf[OBJC_JBLEN]; */
4166 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
4167 decls = add_field_decl (temp_type, "buf", &chain);
4169 /* void *pointers[4]; */
4171 temp_type = build_sized_array_type (ptr_type_node, 4);
4172 add_field_decl (temp_type, "pointers", &chain);
4174 objc_finish_struct (objc_exception_data_template, decls);
4176 /* int _setjmp(...); */
4177 /* If the user includes <setjmp.h>, this shall be superseded by
4178 'int _setjmp(jmp_buf);' */
4179 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
4180 objc_setjmp_decl
4181 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4183 /* id objc_exception_extract(struct _objc_exception_data *); */
4184 temp_type
4185 = build_function_type_list (objc_object_type,
4186 build_pointer_type (objc_exception_data_template),
4187 NULL_TREE);
4188 objc_exception_extract_decl
4189 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4190 NULL_TREE);
4191 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4192 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4193 temp_type
4194 = build_function_type_list (void_type_node,
4195 build_pointer_type (objc_exception_data_template),
4196 NULL_TREE);
4197 objc_exception_try_enter_decl
4198 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4199 NULL_TREE);
4200 objc_exception_try_exit_decl
4201 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4202 NULL_TREE);
4204 /* int objc_exception_match(id, id); */
4205 temp_type
4206 = build_function_type_list (integer_type_node,
4207 objc_object_type, objc_object_type, NULL_TREE);
4208 objc_exception_match_decl
4209 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4210 NULL_TREE);
4212 /* id objc_assign_ivar (id, id, unsigned int); */
4213 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4214 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4215 temp_type
4216 = build_function_type_list (objc_object_type,
4217 objc_object_type,
4218 objc_object_type,
4219 unsigned_type_node,
4220 NULL_TREE);
4221 objc_assign_ivar_decl
4222 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4223 NULL, NULL_TREE);
4224 #ifdef OFFS_ASSIGNIVAR_FAST
4225 objc_assign_ivar_fast_decl
4226 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4227 NOT_BUILT_IN, NULL, NULL_TREE);
4228 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4229 = tree_cons (get_identifier ("hard_coded_address"),
4230 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4231 NULL_TREE);
4232 #else
4233 /* Default to slower ivar method. */
4234 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4235 #endif
4237 /* id objc_assign_global (id, id *); */
4238 /* id objc_assign_strongCast (id, id *); */
4239 temp_type = build_function_type_list (objc_object_type,
4240 objc_object_type,
4241 build_pointer_type (objc_object_type),
4242 NULL_TREE);
4243 objc_assign_global_decl
4244 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4245 NULL_TREE);
4246 objc_assign_strong_cast_decl
4247 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4248 NULL_TREE);
4251 static void
4252 build_objc_exception_stuff (void)
4254 tree noreturn_list, nothrow_list, temp_type;
4256 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4257 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4259 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4260 /* void objc_sync_enter(id); */
4261 /* void objc_sync_exit(id); */
4262 temp_type = build_function_type_list (void_type_node,
4263 objc_object_type,
4264 NULL_TREE);
4265 objc_exception_throw_decl
4266 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4267 noreturn_list);
4268 objc_sync_enter_decl
4269 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4270 NULL, nothrow_list);
4271 objc_sync_exit_decl
4272 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4273 NULL, nothrow_list);
4276 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4277 name as the class:
4279 struct <classname> {
4280 struct _objc_class *isa;
4282 }; */
4284 static void
4285 build_private_template (tree klass)
4287 if (!CLASS_STATIC_TEMPLATE (klass))
4289 tree record = objc_build_struct (klass,
4290 get_class_ivars (klass, false),
4291 CLASS_SUPER_NAME (klass));
4293 /* Set the TREE_USED bit for this struct, so that stab generator
4294 can emit stabs for this struct type. */
4295 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4296 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4300 /* Begin code generation for protocols... */
4302 /* struct _objc_protocol {
4303 struct _objc_class *isa;
4304 char *protocol_name;
4305 struct _objc_protocol **protocol_list;
4306 struct _objc__method_prototype_list *instance_methods;
4307 struct _objc__method_prototype_list *class_methods;
4308 }; */
4310 static void
4311 build_protocol_template (void)
4313 tree ptype, decls, *chain = NULL;
4315 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4317 /* struct _objc_class *isa; */
4318 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4319 get_identifier (UTAG_CLASS)));
4320 decls = add_field_decl (ptype, "isa", &chain);
4322 /* char *protocol_name; */
4323 add_field_decl (string_type_node, "protocol_name", &chain);
4325 /* struct _objc_protocol **protocol_list; */
4326 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4327 add_field_decl (ptype, "protocol_list", &chain);
4329 /* struct _objc__method_prototype_list *instance_methods; */
4330 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
4332 /* struct _objc__method_prototype_list *class_methods; */
4333 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
4335 objc_finish_struct (objc_protocol_template, decls);
4338 static tree
4339 build_descriptor_table_initializer (tree type, tree entries)
4341 VEC(constructor_elt,gc) *inits = NULL;
4345 VEC(constructor_elt,gc) *elts = NULL;
4347 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4348 build_selector (METHOD_SEL_NAME (entries)));
4349 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4350 add_objc_string (METHOD_ENCODING (entries),
4351 meth_var_types));
4353 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
4354 objc_build_constructor (type, elts));
4356 entries = DECL_CHAIN (entries);
4358 while (entries);
4360 return objc_build_constructor (build_array_type (type, 0), inits);
4363 /* struct objc_method_prototype_list {
4364 int count;
4365 struct objc_method_prototype {
4366 SEL name;
4367 char *types;
4368 } list[1];
4369 }; */
4371 static tree
4372 build_method_prototype_list_template (tree list_type, int size)
4374 tree objc_ivar_list_record;
4375 tree array_type, decls, *chain = NULL;
4377 /* Generate an unnamed struct definition. */
4379 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4381 /* int method_count; */
4382 decls = add_field_decl (integer_type_node, "method_count", &chain);
4384 /* struct objc_method method_list[]; */
4385 array_type = build_sized_array_type (list_type, size);
4386 add_field_decl (array_type, "method_list", &chain);
4388 objc_finish_struct (objc_ivar_list_record, decls);
4390 return objc_ivar_list_record;
4393 static tree
4394 build_method_prototype_template (void)
4396 tree proto_record;
4397 tree decls, *chain = NULL;
4399 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4401 /* SEL _cmd; */
4402 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
4404 /* char *method_types; */
4405 add_field_decl (string_type_node, "method_types", &chain);
4407 objc_finish_struct (proto_record, decls);
4409 return proto_record;
4412 static tree
4413 objc_method_parm_type (tree type)
4415 type = TREE_VALUE (TREE_TYPE (type));
4416 if (TREE_CODE (type) == TYPE_DECL)
4417 type = TREE_TYPE (type);
4418 return type;
4421 static int
4422 objc_encoded_type_size (tree type)
4424 int sz = int_size_in_bytes (type);
4426 /* Make all integer and enum types at least as large
4427 as an int. */
4428 if (sz > 0 && INTEGRAL_TYPE_P (type))
4429 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4430 /* Treat arrays as pointers, since that's how they're
4431 passed in. */
4432 else if (TREE_CODE (type) == ARRAY_TYPE)
4433 sz = int_size_in_bytes (ptr_type_node);
4434 return sz;
4437 static tree
4438 encode_method_prototype (tree method_decl)
4440 tree parms;
4441 int parm_offset, i;
4442 char buf[40];
4443 tree result;
4445 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4446 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4448 /* Encode return type. */
4449 encode_type (objc_method_parm_type (method_decl),
4450 obstack_object_size (&util_obstack),
4451 OBJC_ENCODE_INLINE_DEFS);
4453 /* Stack size. */
4454 /* The first two arguments (self and _cmd) are pointers; account for
4455 their size. */
4456 i = int_size_in_bytes (ptr_type_node);
4457 parm_offset = 2 * i;
4458 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4459 parms = DECL_CHAIN (parms))
4461 tree type = objc_method_parm_type (parms);
4462 int sz = objc_encoded_type_size (type);
4464 /* If a type size is not known, bail out. */
4465 if (sz < 0)
4467 error ("type %q+D does not have a known size",
4468 type);
4469 /* Pretend that the encoding succeeded; the compilation will
4470 fail nevertheless. */
4471 goto finish_encoding;
4473 parm_offset += sz;
4476 sprintf (buf, "%d@0:%d", parm_offset, i);
4477 obstack_grow (&util_obstack, buf, strlen (buf));
4479 /* Argument types. */
4480 parm_offset = 2 * i;
4481 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4482 parms = DECL_CHAIN (parms))
4484 tree type = objc_method_parm_type (parms);
4486 /* Process argument qualifiers for user supplied arguments. */
4487 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4489 /* Type. */
4490 encode_type (type, obstack_object_size (&util_obstack),
4491 OBJC_ENCODE_INLINE_DEFS);
4493 /* Compute offset. */
4494 sprintf (buf, "%d", parm_offset);
4495 parm_offset += objc_encoded_type_size (type);
4497 obstack_grow (&util_obstack, buf, strlen (buf));
4500 finish_encoding:
4501 obstack_1grow (&util_obstack, '\0');
4502 result = get_identifier (XOBFINISH (&util_obstack, char *));
4503 obstack_free (&util_obstack, util_firstobj);
4504 return result;
4507 static tree
4508 generate_descriptor_table (tree type, const char *name, int size, tree list,
4509 tree proto)
4511 tree decl;
4512 VEC(constructor_elt,gc) *v = NULL;
4514 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4516 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
4517 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
4519 finish_var_decl (decl, objc_build_constructor (type, v));
4521 return decl;
4524 static void
4525 generate_method_descriptors (tree protocol)
4527 tree initlist, chain, method_list_template;
4528 int size;
4530 if (!objc_method_prototype_template)
4531 objc_method_prototype_template = build_method_prototype_template ();
4533 chain = PROTOCOL_CLS_METHODS (protocol);
4534 if (chain)
4536 size = list_length (chain);
4538 method_list_template
4539 = build_method_prototype_list_template (objc_method_prototype_template,
4540 size);
4542 initlist
4543 = build_descriptor_table_initializer (objc_method_prototype_template,
4544 chain);
4546 UOBJC_CLASS_METHODS_decl
4547 = generate_descriptor_table (method_list_template,
4548 "_OBJC_PROTOCOL_CLASS_METHODS",
4549 size, initlist, protocol);
4551 else
4552 UOBJC_CLASS_METHODS_decl = 0;
4554 chain = PROTOCOL_NST_METHODS (protocol);
4555 if (chain)
4557 size = list_length (chain);
4559 method_list_template
4560 = build_method_prototype_list_template (objc_method_prototype_template,
4561 size);
4562 initlist
4563 = build_descriptor_table_initializer (objc_method_prototype_template,
4564 chain);
4566 UOBJC_INSTANCE_METHODS_decl
4567 = generate_descriptor_table (method_list_template,
4568 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4569 size, initlist, protocol);
4571 else
4572 UOBJC_INSTANCE_METHODS_decl = 0;
4575 static void
4576 generate_protocol_references (tree plist)
4578 tree lproto;
4580 /* Forward declare protocols referenced. */
4581 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4583 tree proto = TREE_VALUE (lproto);
4585 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4586 && PROTOCOL_NAME (proto))
4588 if (! PROTOCOL_FORWARD_DECL (proto))
4589 build_protocol_reference (proto);
4591 if (PROTOCOL_LIST (proto))
4592 generate_protocol_references (PROTOCOL_LIST (proto));
4597 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4598 current class. */
4599 #ifdef OBJCPLUS
4600 static void
4601 objc_generate_cxx_ctor_or_dtor (bool dtor)
4603 tree fn, body, compound_stmt, ivar;
4605 /* - (id) .cxx_construct { ... return self; } */
4606 /* - (void) .cxx_construct { ... } */
4608 objc_set_method_type (MINUS_EXPR);
4609 objc_start_method_definition
4610 (objc_build_method_signature (build_tree_list (NULL_TREE,
4611 dtor
4612 ? void_type_node
4613 : objc_object_type),
4614 get_identifier (dtor
4615 ? TAG_CXX_DESTRUCT
4616 : TAG_CXX_CONSTRUCT),
4617 make_node (TREE_LIST),
4618 false));
4619 body = begin_function_body ();
4620 compound_stmt = begin_compound_stmt (0);
4622 ivar = CLASS_IVARS (implementation_template);
4623 /* Destroy ivars in reverse order. */
4624 if (dtor)
4625 ivar = nreverse (copy_list (ivar));
4627 for (; ivar; ivar = TREE_CHAIN (ivar))
4629 if (TREE_CODE (ivar) == FIELD_DECL)
4631 tree type = TREE_TYPE (ivar);
4633 /* Call the ivar's default constructor or destructor. Do not
4634 call the destructor unless a corresponding constructor call
4635 has also been made (or is not needed). */
4636 if (MAYBE_CLASS_TYPE_P (type)
4637 && (dtor
4638 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4639 && (!TYPE_NEEDS_CONSTRUCTING (type)
4640 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4641 : (TYPE_NEEDS_CONSTRUCTING (type)
4642 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4643 finish_expr_stmt
4644 (build_special_member_call
4645 (build_ivar_reference (DECL_NAME (ivar)),
4646 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4647 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
4651 /* The constructor returns 'self'. */
4652 if (!dtor)
4653 finish_return_stmt (self_decl);
4655 finish_compound_stmt (compound_stmt);
4656 finish_function_body (body);
4657 fn = current_function_decl;
4658 finish_function ();
4659 objc_finish_method_definition (fn);
4662 /* The following routine will examine the current @interface for any
4663 non-POD C++ ivars requiring non-trivial construction and/or
4664 destruction, and then synthesize special '- .cxx_construct' and/or
4665 '- .cxx_destruct' methods which will run the appropriate
4666 construction or destruction code. Note that ivars inherited from
4667 super-classes are _not_ considered. */
4668 static void
4669 objc_generate_cxx_cdtors (void)
4671 bool need_ctor = false, need_dtor = false;
4672 tree ivar;
4674 /* We do not want to do this for categories, since they do not have
4675 their own ivars. */
4677 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4678 return;
4680 /* First, determine if we even need a constructor and/or destructor. */
4682 for (ivar = CLASS_IVARS (implementation_template); ivar;
4683 ivar = TREE_CHAIN (ivar))
4685 if (TREE_CODE (ivar) == FIELD_DECL)
4687 tree type = TREE_TYPE (ivar);
4689 if (MAYBE_CLASS_TYPE_P (type))
4691 if (TYPE_NEEDS_CONSTRUCTING (type)
4692 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4693 /* NB: If a default constructor is not available, we will not
4694 be able to initialize this ivar; the add_instance_variable()
4695 routine will already have warned about this. */
4696 need_ctor = true;
4698 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4699 && (!TYPE_NEEDS_CONSTRUCTING (type)
4700 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4701 /* NB: If a default constructor is not available, we will not
4702 call the destructor either, for symmetry. */
4703 need_dtor = true;
4708 /* Generate '- .cxx_construct' if needed. */
4710 if (need_ctor)
4711 objc_generate_cxx_ctor_or_dtor (false);
4713 /* Generate '- .cxx_destruct' if needed. */
4715 if (need_dtor)
4716 objc_generate_cxx_ctor_or_dtor (true);
4718 /* The 'imp_list' variable points at an imp_entry record for the current
4719 @implementation. Record the existence of '- .cxx_construct' and/or
4720 '- .cxx_destruct' methods therein; it will be included in the
4721 metadata for the class. */
4722 if (flag_next_runtime)
4723 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4725 #endif
4727 /* For each protocol which was referenced either from a @protocol()
4728 expression, or because a class/category implements it (then a
4729 pointer to the protocol is stored in the struct describing the
4730 class/category), we create a statically allocated instance of the
4731 Protocol class. The code is written in such a way as to generate
4732 as few Protocol objects as possible; we generate a unique Protocol
4733 instance for each protocol, and we don't generate a Protocol
4734 instance if the protocol is never referenced (either from a
4735 @protocol() or from a class/category implementation). These
4736 statically allocated objects can be referred to via the static
4737 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4739 The statically allocated Protocol objects that we generate here
4740 need to be fixed up at runtime in order to be used: the 'isa'
4741 pointer of the objects need to be set up to point to the 'Protocol'
4742 class, as known at runtime.
4744 The NeXT runtime fixes up all protocols at program startup time,
4745 before main() is entered. It uses a low-level trick to look up all
4746 those symbols, then loops on them and fixes them up.
4748 The GNU runtime as well fixes up all protocols before user code
4749 from the module is executed; it requires pointers to those symbols
4750 to be put in the objc_symtab (which is then passed as argument to
4751 the function __objc_exec_class() which the compiler sets up to be
4752 executed automatically when the module is loaded); setup of those
4753 Protocol objects happen in two ways in the GNU runtime: all
4754 Protocol objects referred to by a class or category implementation
4755 are fixed up when the class/category is loaded; all Protocol
4756 objects referred to by a @protocol() expression are added by the
4757 compiler to the list of statically allocated instances to fixup
4758 (the same list holding the statically allocated constant string
4759 objects). Because, as explained above, the compiler generates as
4760 few Protocol objects as possible, some Protocol object might end up
4761 being referenced multiple times when compiled with the GNU runtime,
4762 and end up being fixed up multiple times at runtime initialization.
4763 But that doesn't hurt, it's just a little inefficient. */
4765 static void
4766 generate_protocols (void)
4768 tree p, encoding;
4769 tree decl;
4770 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4772 /* If a protocol was directly referenced, pull in indirect references. */
4773 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4774 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4775 generate_protocol_references (PROTOCOL_LIST (p));
4777 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4779 tree nst_methods = PROTOCOL_NST_METHODS (p);
4780 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4782 /* If protocol wasn't referenced, don't generate any code. */
4783 decl = PROTOCOL_FORWARD_DECL (p);
4785 if (!decl)
4786 continue;
4788 /* Make sure we link in the Protocol class. */
4789 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4791 while (nst_methods)
4793 if (! METHOD_ENCODING (nst_methods))
4795 encoding = encode_method_prototype (nst_methods);
4796 METHOD_ENCODING (nst_methods) = encoding;
4798 nst_methods = DECL_CHAIN (nst_methods);
4801 while (cls_methods)
4803 if (! METHOD_ENCODING (cls_methods))
4805 encoding = encode_method_prototype (cls_methods);
4806 METHOD_ENCODING (cls_methods) = encoding;
4809 cls_methods = DECL_CHAIN (cls_methods);
4811 generate_method_descriptors (p);
4813 if (PROTOCOL_LIST (p))
4814 refs_decl = generate_protocol_list (p);
4815 else
4816 refs_decl = 0;
4818 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4819 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4821 if (refs_decl)
4822 refs_expr = convert (build_pointer_type (build_pointer_type
4823 (objc_protocol_template)),
4824 build_unary_op (input_location,
4825 ADDR_EXPR, refs_decl, 0));
4826 else
4827 refs_expr = build_int_cst (NULL_TREE, 0);
4829 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4830 by generate_method_descriptors, which is called above. */
4831 initlist = build_protocol_initializer (TREE_TYPE (decl),
4832 protocol_name_expr, refs_expr,
4833 UOBJC_INSTANCE_METHODS_decl,
4834 UOBJC_CLASS_METHODS_decl);
4835 finish_var_decl (decl, initlist);
4839 static tree
4840 build_protocol_initializer (tree type, tree protocol_name,
4841 tree protocol_list, tree instance_methods,
4842 tree class_methods)
4844 tree expr;
4845 tree cast_type = build_pointer_type
4846 (xref_tag (RECORD_TYPE,
4847 get_identifier (UTAG_CLASS)));
4848 VEC(constructor_elt,gc) *inits = NULL;
4850 /* Filling the "isa" in with one allows the runtime system to
4851 detect that the version change...should remove before final release. */
4853 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4854 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4855 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
4856 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
4858 if (!instance_methods)
4859 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
4860 else
4862 expr = convert (objc_method_proto_list_ptr,
4863 build_unary_op (input_location,
4864 ADDR_EXPR, instance_methods, 0));
4865 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4868 if (!class_methods)
4869 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
4870 else
4872 expr = convert (objc_method_proto_list_ptr,
4873 build_unary_op (input_location,
4874 ADDR_EXPR, class_methods, 0));
4875 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4878 return objc_build_constructor (type, inits);
4881 /* struct _objc_category {
4882 char *category_name;
4883 char *class_name;
4884 struct _objc_method_list *instance_methods;
4885 struct _objc_method_list *class_methods;
4886 struct _objc_protocol_list *protocols;
4887 }; */
4889 static void
4890 build_category_template (void)
4892 tree ptype, decls, *chain = NULL;
4894 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
4896 /* char *category_name; */
4897 decls = add_field_decl (string_type_node, "category_name", &chain);
4899 /* char *class_name; */
4900 add_field_decl (string_type_node, "class_name", &chain);
4902 /* struct _objc_method_list *instance_methods; */
4903 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
4905 /* struct _objc_method_list *class_methods; */
4906 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
4908 /* struct _objc_protocol **protocol_list; */
4909 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4910 add_field_decl (ptype, "protocol_list", &chain);
4912 objc_finish_struct (objc_category_template, decls);
4915 /* struct _objc_selector {
4916 SEL sel_id;
4917 char *sel_type;
4918 }; */
4920 static void
4921 build_selector_template (void)
4923 tree decls, *chain = NULL;
4925 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
4927 /* SEL sel_id; */
4928 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
4930 /* char *sel_type; */
4931 add_field_decl (string_type_node, "sel_type", &chain);
4933 objc_finish_struct (objc_selector_template, decls);
4936 /* struct _objc_class {
4937 struct _objc_class *isa;
4938 struct _objc_class *super_class;
4939 char *name;
4940 long version;
4941 long info;
4942 long instance_size;
4943 struct _objc_ivar_list *ivars;
4944 struct _objc_method_list *methods;
4945 #ifdef __NEXT_RUNTIME__
4946 struct objc_cache *cache;
4947 #else
4948 struct sarray *dtable;
4949 struct _objc_class *subclass_list;
4950 struct _objc_class *sibling_class;
4951 #endif
4952 struct _objc_protocol_list *protocols;
4953 #ifdef __NEXT_RUNTIME__
4954 void *sel_id;
4955 #endif
4956 void *gc_object_type;
4957 }; */
4959 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4960 the NeXT/Apple runtime; still, the compiler must generate them to
4961 maintain backward binary compatibility (and to allow for future
4962 expansion). */
4964 static void
4965 build_class_template (void)
4967 tree ptype, decls, *chain = NULL;
4969 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
4971 /* struct _objc_class *isa; */
4972 decls = add_field_decl (build_pointer_type (objc_class_template),
4973 "isa", &chain);
4975 /* struct _objc_class *super_class; */
4976 add_field_decl (build_pointer_type (objc_class_template),
4977 "super_class", &chain);
4979 /* char *name; */
4980 add_field_decl (string_type_node, "name", &chain);
4982 /* long version; */
4983 add_field_decl (long_integer_type_node, "version", &chain);
4985 /* long info; */
4986 add_field_decl (long_integer_type_node, "info", &chain);
4988 /* long instance_size; */
4989 add_field_decl (long_integer_type_node, "instance_size", &chain);
4991 /* struct _objc_ivar_list *ivars; */
4992 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
4994 /* struct _objc_method_list *methods; */
4995 add_field_decl (objc_method_list_ptr, "methods", &chain);
4997 if (flag_next_runtime)
4999 /* struct objc_cache *cache; */
5000 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
5001 get_identifier ("objc_cache")));
5002 add_field_decl (ptype, "cache", &chain);
5004 else
5006 /* struct sarray *dtable; */
5007 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
5008 get_identifier ("sarray")));
5009 add_field_decl (ptype, "dtable", &chain);
5011 /* struct objc_class *subclass_list; */
5012 ptype = build_pointer_type (objc_class_template);
5013 add_field_decl (ptype, "subclass_list", &chain);
5015 /* struct objc_class *sibling_class; */
5016 ptype = build_pointer_type (objc_class_template);
5017 add_field_decl (ptype, "sibling_class", &chain);
5020 /* struct _objc_protocol **protocol_list; */
5021 ptype = build_pointer_type (build_pointer_type
5022 (xref_tag (RECORD_TYPE,
5023 get_identifier (UTAG_PROTOCOL))));
5024 add_field_decl (ptype, "protocol_list", &chain);
5026 if (flag_next_runtime)
5028 /* void *sel_id; */
5029 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
5032 /* void *gc_object_type; */
5033 add_field_decl (build_pointer_type (void_type_node),
5034 "gc_object_type", &chain);
5036 objc_finish_struct (objc_class_template, decls);
5039 /* Generate appropriate forward declarations for an implementation. */
5041 static void
5042 synth_forward_declarations (void)
5044 tree an_id;
5046 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5047 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5048 objc_class_template);
5050 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5051 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5052 objc_class_template);
5054 /* Pre-build the following entities - for speed/convenience. */
5056 an_id = get_identifier ("super_class");
5057 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5058 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5061 static void
5062 error_with_ivar (const char *message, tree decl)
5064 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5065 message, identifier_to_locale (gen_declaration (decl)));
5069 static void
5070 check_ivars (tree inter, tree imp)
5072 tree intdecls = CLASS_RAW_IVARS (inter);
5073 tree impdecls = CLASS_RAW_IVARS (imp);
5075 while (1)
5077 tree t1, t2;
5079 #ifdef OBJCPLUS
5080 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5081 intdecls = TREE_CHAIN (intdecls);
5082 #endif
5083 if (intdecls == 0 && impdecls == 0)
5084 break;
5085 if (intdecls == 0 || impdecls == 0)
5087 error ("inconsistent instance variable specification");
5088 break;
5091 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5093 if (!comptypes (t1, t2)
5094 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5095 DECL_INITIAL (impdecls)))
5097 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5099 error_with_ivar ("conflicting instance variable type",
5100 impdecls);
5101 error_with_ivar ("previous declaration of",
5102 intdecls);
5104 else /* both the type and the name don't match */
5106 error ("inconsistent instance variable specification");
5107 break;
5111 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5113 error_with_ivar ("conflicting instance variable name",
5114 impdecls);
5115 error_with_ivar ("previous declaration of",
5116 intdecls);
5119 intdecls = DECL_CHAIN (intdecls);
5120 impdecls = DECL_CHAIN (impdecls);
5124 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5125 This needs to be done just once per compilation. */
5127 /* struct _objc_super {
5128 struct _objc_object *self;
5129 struct _objc_class *super_class;
5130 }; */
5132 static void
5133 build_super_template (void)
5135 tree decls, *chain = NULL;
5137 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5139 /* struct _objc_object *self; */
5140 decls = add_field_decl (objc_object_type, "self", &chain);
5142 /* struct _objc_class *super_class; */
5143 add_field_decl (build_pointer_type (objc_class_template),
5144 "super_class", &chain);
5146 objc_finish_struct (objc_super_template, decls);
5149 /* struct _objc_ivar {
5150 char *ivar_name;
5151 char *ivar_type;
5152 int ivar_offset;
5153 }; */
5155 static tree
5156 build_ivar_template (void)
5158 tree objc_ivar_id, objc_ivar_record;
5159 tree decls, *chain = NULL;
5161 objc_ivar_id = get_identifier (UTAG_IVAR);
5162 objc_ivar_record = objc_start_struct (objc_ivar_id);
5164 /* char *ivar_name; */
5165 decls = add_field_decl (string_type_node, "ivar_name", &chain);
5167 /* char *ivar_type; */
5168 add_field_decl (string_type_node, "ivar_type", &chain);
5170 /* int ivar_offset; */
5171 add_field_decl (integer_type_node, "ivar_offset", &chain);
5173 objc_finish_struct (objc_ivar_record, decls);
5175 return objc_ivar_record;
5178 /* struct {
5179 int ivar_count;
5180 struct objc_ivar ivar_list[ivar_count];
5181 }; */
5183 static tree
5184 build_ivar_list_template (tree list_type, int size)
5186 tree objc_ivar_list_record;
5187 tree array_type, decls, *chain = NULL;
5189 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5191 /* int ivar_count; */
5192 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
5194 /* struct objc_ivar ivar_list[]; */
5195 array_type = build_sized_array_type (list_type, size);
5196 add_field_decl (array_type, "ivar_list", &chain);
5198 objc_finish_struct (objc_ivar_list_record, decls);
5200 return objc_ivar_list_record;
5203 /* struct {
5204 struct _objc__method_prototype_list *method_next;
5205 int method_count;
5206 struct objc_method method_list[method_count];
5207 }; */
5209 static tree
5210 build_method_list_template (tree list_type, int size)
5212 tree objc_ivar_list_record;
5213 tree array_type, decls, *chain = NULL;
5215 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5217 /* struct _objc__method_prototype_list *method_next; */
5218 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
5220 /* int method_count; */
5221 add_field_decl (integer_type_node, "method_count", &chain);
5223 /* struct objc_method method_list[]; */
5224 array_type = build_sized_array_type (list_type, size);
5225 add_field_decl (array_type, "method_list", &chain);
5227 objc_finish_struct (objc_ivar_list_record, decls);
5229 return objc_ivar_list_record;
5232 static tree
5233 build_ivar_list_initializer (tree type, tree field_decl)
5235 VEC(constructor_elt,gc) *inits = NULL;
5239 VEC(constructor_elt,gc) *ivar = NULL;
5240 tree id;
5242 /* Set name. */
5243 if (DECL_NAME (field_decl))
5244 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
5245 add_objc_string (DECL_NAME (field_decl),
5246 meth_var_names));
5247 else
5248 /* Unnamed bit-field ivar (yuck). */
5249 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
5251 /* Set type. */
5252 encode_field_decl (field_decl,
5253 obstack_object_size (&util_obstack),
5254 OBJC_ENCODE_DONT_INLINE_DEFS);
5256 /* Null terminate string. */
5257 obstack_1grow (&util_obstack, 0);
5258 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5259 meth_var_types);
5260 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
5261 obstack_free (&util_obstack, util_firstobj);
5263 /* Set offset. */
5264 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
5265 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5266 objc_build_constructor (type, ivar));
5268 field_decl = DECL_CHAIN (field_decl);
5269 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5271 while (field_decl);
5273 return objc_build_constructor (build_array_type (type, 0), inits);
5276 static tree
5277 generate_ivars_list (tree type, const char *name, int size, tree list)
5279 tree decl;
5280 VEC(constructor_elt,gc) *inits = NULL;
5282 decl = start_var_decl (type, synth_id_with_class_suffix
5283 (name, objc_implementation_context));
5285 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
5286 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
5288 finish_var_decl (decl,
5289 objc_build_constructor (TREE_TYPE (decl), inits));
5291 return decl;
5294 /* Count only the fields occurring in T. */
5296 static int
5297 ivar_list_length (tree t)
5299 int count = 0;
5301 for (; t; t = DECL_CHAIN (t))
5302 if (TREE_CODE (t) == FIELD_DECL)
5303 ++count;
5305 return count;
5308 static void
5309 generate_ivar_lists (void)
5311 tree initlist, ivar_list_template, chain;
5312 int size;
5314 generating_instance_variables = 1;
5316 if (!objc_ivar_template)
5317 objc_ivar_template = build_ivar_template ();
5319 /* Only generate class variables for the root of the inheritance
5320 hierarchy since these will be the same for every class. */
5322 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5323 && (chain = TYPE_FIELDS (objc_class_template)))
5325 size = ivar_list_length (chain);
5327 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5328 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5330 UOBJC_CLASS_VARIABLES_decl
5331 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5332 size, initlist);
5334 else
5335 UOBJC_CLASS_VARIABLES_decl = 0;
5337 chain = CLASS_IVARS (implementation_template);
5338 if (chain)
5340 size = ivar_list_length (chain);
5341 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5342 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5344 UOBJC_INSTANCE_VARIABLES_decl
5345 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5346 size, initlist);
5348 else
5349 UOBJC_INSTANCE_VARIABLES_decl = 0;
5351 generating_instance_variables = 0;
5354 static tree
5355 build_dispatch_table_initializer (tree type, tree entries)
5357 VEC(constructor_elt,gc) *inits = NULL;
5361 VEC(constructor_elt,gc) *elems = NULL;
5362 tree expr;
5364 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5365 build_selector (METHOD_SEL_NAME (entries)));
5367 /* Generate the method encoding if we don't have one already. */
5368 if (! METHOD_ENCODING (entries))
5369 METHOD_ENCODING (entries) =
5370 encode_method_prototype (entries);
5372 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5373 add_objc_string (METHOD_ENCODING (entries),
5374 meth_var_types));
5376 expr = convert (ptr_type_node,
5377 build_unary_op (input_location, ADDR_EXPR,
5378 METHOD_DEFINITION (entries), 1));
5379 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
5381 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5382 objc_build_constructor (type, elems));
5384 entries = DECL_CHAIN (entries);
5386 while (entries);
5388 return objc_build_constructor (build_array_type (type, 0), inits);
5391 /* To accomplish method prototyping without generating all kinds of
5392 inane warnings, the definition of the dispatch table entries were
5393 changed from:
5395 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5397 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5399 static tree
5400 build_method_template (void)
5402 tree _SLT_record;
5403 tree decls, *chain = NULL;
5405 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5407 /* SEL _cmd; */
5408 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5410 /* char *method_types; */
5411 add_field_decl (string_type_node, "method_types", &chain);
5413 /* void *_imp; */
5414 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
5416 objc_finish_struct (_SLT_record, decls);
5418 return _SLT_record;
5422 static tree
5423 generate_dispatch_table (tree type, const char *name, int size, tree list)
5425 tree decl;
5426 VEC(constructor_elt,gc) *v = NULL;
5428 decl = start_var_decl (type, synth_id_with_class_suffix
5429 (name, objc_implementation_context));
5431 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
5432 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
5433 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5435 finish_var_decl (decl,
5436 objc_build_constructor (TREE_TYPE (decl), v));
5438 return decl;
5441 static void
5442 mark_referenced_methods (void)
5444 struct imp_entry *impent;
5445 tree chain;
5447 for (impent = imp_list; impent; impent = impent->next)
5449 chain = CLASS_CLS_METHODS (impent->imp_context);
5450 while (chain)
5452 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5453 chain = DECL_CHAIN (chain);
5456 chain = CLASS_NST_METHODS (impent->imp_context);
5457 while (chain)
5459 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5460 chain = DECL_CHAIN (chain);
5465 static void
5466 generate_dispatch_tables (void)
5468 tree initlist, chain, method_list_template;
5469 int size;
5471 if (!objc_method_template)
5472 objc_method_template = build_method_template ();
5474 chain = CLASS_CLS_METHODS (objc_implementation_context);
5475 if (chain)
5477 size = list_length (chain);
5479 method_list_template
5480 = build_method_list_template (objc_method_template, size);
5481 initlist
5482 = build_dispatch_table_initializer (objc_method_template, chain);
5484 UOBJC_CLASS_METHODS_decl
5485 = generate_dispatch_table (method_list_template,
5486 ((TREE_CODE (objc_implementation_context)
5487 == CLASS_IMPLEMENTATION_TYPE)
5488 ? "_OBJC_CLASS_METHODS"
5489 : "_OBJC_CATEGORY_CLASS_METHODS"),
5490 size, initlist);
5492 else
5493 UOBJC_CLASS_METHODS_decl = 0;
5495 chain = CLASS_NST_METHODS (objc_implementation_context);
5496 if (chain)
5498 size = list_length (chain);
5500 method_list_template
5501 = build_method_list_template (objc_method_template, size);
5502 initlist
5503 = build_dispatch_table_initializer (objc_method_template, chain);
5505 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5506 UOBJC_INSTANCE_METHODS_decl
5507 = generate_dispatch_table (method_list_template,
5508 "_OBJC_INSTANCE_METHODS",
5509 size, initlist);
5510 else
5511 /* We have a category. */
5512 UOBJC_INSTANCE_METHODS_decl
5513 = generate_dispatch_table (method_list_template,
5514 "_OBJC_CATEGORY_INSTANCE_METHODS",
5515 size, initlist);
5517 else
5518 UOBJC_INSTANCE_METHODS_decl = 0;
5521 static tree
5522 generate_protocol_list (tree i_or_p)
5524 tree array_type, ptype, refs_decl, lproto, e, plist;
5525 int size = 0;
5526 const char *ref_name;
5527 VEC(constructor_elt,gc) *v = NULL;
5529 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5530 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5531 plist = CLASS_PROTOCOL_LIST (i_or_p);
5532 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5533 plist = PROTOCOL_LIST (i_or_p);
5534 else
5535 abort ();
5537 /* Compute size. */
5538 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5539 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5540 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5541 size++;
5543 /* Build initializer. */
5544 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5545 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5546 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
5548 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5550 tree pval = TREE_VALUE (lproto);
5552 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5553 && PROTOCOL_FORWARD_DECL (pval))
5555 e = build_unary_op (input_location, ADDR_EXPR,
5556 PROTOCOL_FORWARD_DECL (pval), 0);
5557 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
5561 /* static struct objc_protocol *refs[n]; */
5563 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5564 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5565 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5566 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5567 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5568 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5569 else
5570 abort ();
5572 ptype = build_pointer_type (objc_protocol_template);
5573 array_type = build_sized_array_type (ptype, size + 3);
5574 refs_decl = start_var_decl (array_type, ref_name);
5576 finish_var_decl (refs_decl,
5577 objc_build_constructor (TREE_TYPE (refs_decl), v));
5579 return refs_decl;
5582 static tree
5583 build_category_initializer (tree type, tree cat_name, tree class_name,
5584 tree instance_methods, tree class_methods,
5585 tree protocol_list)
5587 tree expr;
5588 VEC(constructor_elt,gc) *v = NULL;
5590 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
5591 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
5593 if (!instance_methods)
5594 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5595 else
5597 expr = convert (objc_method_list_ptr,
5598 build_unary_op (input_location, ADDR_EXPR,
5599 instance_methods, 0));
5600 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5602 if (!class_methods)
5603 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5604 else
5606 expr = convert (objc_method_list_ptr,
5607 build_unary_op (input_location, ADDR_EXPR,
5608 class_methods, 0));
5609 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5612 /* protocol_list = */
5613 if (!protocol_list)
5614 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5615 else
5617 expr = convert (build_pointer_type
5618 (build_pointer_type
5619 (objc_protocol_template)),
5620 build_unary_op (input_location, ADDR_EXPR,
5621 protocol_list, 0));
5622 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5625 return objc_build_constructor (type, v);
5628 /* struct _objc_class {
5629 struct objc_class *isa;
5630 struct objc_class *super_class;
5631 char *name;
5632 long version;
5633 long info;
5634 long instance_size;
5635 struct objc_ivar_list *ivars;
5636 struct objc_method_list *methods;
5637 if (flag_next_runtime)
5638 struct objc_cache *cache;
5639 else {
5640 struct sarray *dtable;
5641 struct objc_class *subclass_list;
5642 struct objc_class *sibling_class;
5644 struct objc_protocol_list *protocols;
5645 if (flag_next_runtime)
5646 void *sel_id;
5647 void *gc_object_type;
5648 }; */
5650 static tree
5651 build_shared_structure_initializer (tree type, tree isa, tree super,
5652 tree name, tree size, int status,
5653 tree dispatch_table, tree ivar_list,
5654 tree protocol_list)
5656 tree expr;
5657 VEC(constructor_elt,gc) *v = NULL;
5659 /* isa = */
5660 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
5662 /* super_class = */
5663 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
5665 /* name = */
5666 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
5668 /* version = */
5669 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
5670 build_int_cst (long_integer_type_node, 0));
5672 /* info = */
5673 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
5674 build_int_cst (long_integer_type_node, status));
5676 /* instance_size = */
5677 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
5678 convert (long_integer_type_node, size));
5680 /* objc_ivar_list = */
5681 if (!ivar_list)
5682 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5683 else
5685 expr = convert (objc_ivar_list_ptr,
5686 build_unary_op (input_location, ADDR_EXPR,
5687 ivar_list, 0));
5688 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5691 /* objc_method_list = */
5692 if (!dispatch_table)
5693 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5694 else
5696 expr = convert (objc_method_list_ptr,
5697 build_unary_op (input_location, ADDR_EXPR,
5698 dispatch_table, 0));
5699 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5702 if (flag_next_runtime)
5703 /* method_cache = */
5704 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5705 else
5707 /* dtable = */
5708 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5710 /* subclass_list = */
5711 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5713 /* sibling_class = */
5714 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5717 /* protocol_list = */
5718 if (! protocol_list)
5719 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5720 else
5722 expr = convert (build_pointer_type
5723 (build_pointer_type
5724 (objc_protocol_template)),
5725 build_unary_op (input_location, ADDR_EXPR,
5726 protocol_list, 0));
5727 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5730 if (flag_next_runtime)
5731 /* sel_id = NULL */
5732 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5734 /* gc_object_type = NULL */
5735 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5737 return objc_build_constructor (type, v);
5740 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5742 static inline tree
5743 lookup_category (tree klass, tree cat_name)
5745 tree category = CLASS_CATEGORY_LIST (klass);
5747 while (category && CLASS_SUPER_NAME (category) != cat_name)
5748 category = CLASS_CATEGORY_LIST (category);
5749 return category;
5752 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5754 static void
5755 generate_category (struct imp_entry *impent)
5757 tree initlist, cat_name_expr, class_name_expr;
5758 tree protocol_decl, category;
5759 tree cat = impent->imp_context;
5761 implementation_template = impent->imp_template;
5762 UOBJC_CLASS_decl = impent->class_decl;
5763 UOBJC_METACLASS_decl = impent->meta_decl;
5765 add_class_reference (CLASS_NAME (cat));
5766 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5768 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5770 category = lookup_category (implementation_template,
5771 CLASS_SUPER_NAME (cat));
5773 if (category && CLASS_PROTOCOL_LIST (category))
5775 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5776 protocol_decl = generate_protocol_list (category);
5778 else
5779 protocol_decl = 0;
5781 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
5782 cat_name_expr, class_name_expr,
5783 UOBJC_INSTANCE_METHODS_decl,
5784 UOBJC_CLASS_METHODS_decl,
5785 protocol_decl);
5786 /* Finish and initialize the forward decl. */
5787 finish_var_decl (UOBJC_CLASS_decl, initlist);
5790 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5791 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5793 static void
5794 generate_shared_structures (struct imp_entry *impent)
5796 tree name_expr, super_expr, root_expr;
5797 tree my_root_id, my_super_id;
5798 tree cast_type, initlist, protocol_decl;
5799 int cls_flags;
5801 objc_implementation_context = impent->imp_context;
5802 implementation_template = impent->imp_template;
5803 UOBJC_CLASS_decl = impent->class_decl;
5804 UOBJC_METACLASS_decl = impent->meta_decl;
5805 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
5807 my_super_id = CLASS_SUPER_NAME (implementation_template);
5808 if (my_super_id)
5810 add_class_reference (my_super_id);
5812 /* Compute "my_root_id" - this is required for code generation.
5813 the "isa" for all meta class structures points to the root of
5814 the inheritance hierarchy (e.g. "__Object")... */
5815 my_root_id = my_super_id;
5818 tree my_root_int = lookup_interface (my_root_id);
5820 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5821 my_root_id = CLASS_SUPER_NAME (my_root_int);
5822 else
5823 break;
5825 while (1);
5827 else
5828 /* No super class. */
5829 my_root_id = CLASS_NAME (implementation_template);
5831 cast_type = build_pointer_type (objc_class_template);
5832 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5833 class_names);
5835 /* Install class `isa' and `super' pointers at runtime. */
5836 if (my_super_id)
5837 super_expr = add_objc_string (my_super_id, class_names);
5838 else
5839 super_expr = integer_zero_node;
5841 super_expr = build_c_cast (input_location,
5842 cast_type, super_expr); /* cast! */
5844 root_expr = add_objc_string (my_root_id, class_names);
5845 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
5847 if (CLASS_PROTOCOL_LIST (implementation_template))
5849 generate_protocol_references
5850 (CLASS_PROTOCOL_LIST (implementation_template));
5851 protocol_decl = generate_protocol_list (implementation_template);
5853 else
5854 protocol_decl = 0;
5856 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5858 initlist
5859 = build_shared_structure_initializer
5860 (TREE_TYPE (UOBJC_METACLASS_decl),
5861 root_expr, super_expr, name_expr,
5862 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5863 2 /*CLS_META*/,
5864 UOBJC_CLASS_METHODS_decl,
5865 UOBJC_CLASS_VARIABLES_decl,
5866 protocol_decl);
5868 finish_var_decl (UOBJC_METACLASS_decl, initlist);
5870 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5872 initlist
5873 = build_shared_structure_initializer
5874 (TREE_TYPE (UOBJC_CLASS_decl),
5875 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5876 super_expr, name_expr,
5877 convert (integer_type_node,
5878 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5879 (implementation_template))),
5880 1 /*CLS_FACTORY*/ | cls_flags,
5881 UOBJC_INSTANCE_METHODS_decl,
5882 UOBJC_INSTANCE_VARIABLES_decl,
5883 protocol_decl);
5885 finish_var_decl (UOBJC_CLASS_decl, initlist);
5889 static const char *
5890 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5892 static char string[BUFSIZE];
5894 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5895 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5897 sprintf (string, "%s_%s", preamble,
5898 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5900 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5901 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5903 /* We have a category. */
5904 const char *const class_name
5905 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5906 const char *const class_super_name
5907 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5908 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5910 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5912 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5913 sprintf (string, "%s_%s", preamble, protocol_name);
5915 else
5916 abort ();
5918 return string;
5921 /* If type is empty or only type qualifiers are present, add default
5922 type of id (otherwise grokdeclarator will default to int). */
5924 static tree
5925 adjust_type_for_id_default (tree type)
5927 if (!type)
5928 type = make_node (TREE_LIST);
5930 if (!TREE_VALUE (type))
5931 TREE_VALUE (type) = objc_object_type;
5932 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5933 && TYPED_OBJECT (TREE_VALUE (type)))
5934 error ("can not use an object as parameter to a method");
5936 return type;
5939 /* Usage:
5940 keyworddecl:
5941 selector ':' '(' typename ')' identifier
5943 Purpose:
5944 Transform an Objective-C keyword argument into
5945 the C equivalent parameter declarator.
5947 In: key_name, an "identifier_node" (optional).
5948 arg_type, a "tree_list" (optional).
5949 arg_name, an "identifier_node".
5951 Note: It would be really nice to strongly type the preceding
5952 arguments in the function prototype; however, then I
5953 could not use the "accessor" macros defined in "tree.h".
5955 Out: an instance of "keyword_decl". */
5957 tree
5958 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5960 tree keyword_decl;
5962 /* If no type is specified, default to "id". */
5963 arg_type = adjust_type_for_id_default (arg_type);
5965 keyword_decl = make_node (KEYWORD_DECL);
5967 TREE_TYPE (keyword_decl) = arg_type;
5968 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5969 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5971 return keyword_decl;
5974 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5976 static tree
5977 build_keyword_selector (tree selector)
5979 int len = 0;
5980 tree key_chain, key_name;
5981 char *buf;
5983 /* Scan the selector to see how much space we'll need. */
5984 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5986 if (TREE_CODE (selector) == KEYWORD_DECL)
5987 key_name = KEYWORD_KEY_NAME (key_chain);
5988 else if (TREE_CODE (selector) == TREE_LIST)
5989 key_name = TREE_PURPOSE (key_chain);
5990 else
5991 abort ();
5993 if (key_name)
5994 len += IDENTIFIER_LENGTH (key_name) + 1;
5995 else
5996 /* Just a ':' arg. */
5997 len++;
6000 buf = (char *) alloca (len + 1);
6001 /* Start the buffer out as an empty string. */
6002 buf[0] = '\0';
6004 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6006 if (TREE_CODE (selector) == KEYWORD_DECL)
6007 key_name = KEYWORD_KEY_NAME (key_chain);
6008 else if (TREE_CODE (selector) == TREE_LIST)
6010 key_name = TREE_PURPOSE (key_chain);
6011 /* The keyword decl chain will later be used as a function argument
6012 chain. Unhook the selector itself so as to not confuse other
6013 parts of the compiler. */
6014 TREE_PURPOSE (key_chain) = NULL_TREE;
6016 else
6017 abort ();
6019 if (key_name)
6020 strcat (buf, IDENTIFIER_POINTER (key_name));
6021 strcat (buf, ":");
6024 return get_identifier (buf);
6027 /* Used for declarations and definitions. */
6029 static tree
6030 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6031 tree add_args, bool ellipsis)
6033 tree method_decl;
6035 /* If no type is specified, default to "id". */
6036 ret_type = adjust_type_for_id_default (ret_type);
6038 method_decl = make_node (code);
6039 TREE_TYPE (method_decl) = ret_type;
6041 /* If we have a keyword selector, create an identifier_node that
6042 represents the full selector name (`:' included)... */
6043 if (TREE_CODE (selector) == KEYWORD_DECL)
6045 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6046 METHOD_SEL_ARGS (method_decl) = selector;
6047 METHOD_ADD_ARGS (method_decl) = add_args;
6048 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6050 else
6052 METHOD_SEL_NAME (method_decl) = selector;
6053 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6054 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6057 return method_decl;
6060 #define METHOD_DEF 0
6061 #define METHOD_REF 1
6063 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6064 an argument list for method METH. CONTEXT is either METHOD_DEF or
6065 METHOD_REF, saying whether we are trying to define a method or call
6066 one. SUPERFLAG says this is for a send to super; this makes a
6067 difference for the NeXT calling sequence in which the lookup and
6068 the method call are done together. If METH is null, user-defined
6069 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6071 static tree
6072 get_arg_type_list (tree meth, int context, int superflag)
6074 tree arglist, akey;
6076 /* Receiver type. */
6077 if (flag_next_runtime && superflag)
6078 arglist = build_tree_list (NULL_TREE, objc_super_type);
6079 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6080 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6081 else
6082 arglist = build_tree_list (NULL_TREE, objc_object_type);
6084 /* Selector type - will eventually change to `int'. */
6085 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6087 /* No actual method prototype given -- assume that remaining arguments
6088 are `...'. */
6089 if (!meth)
6090 return arglist;
6092 /* Build a list of argument types. */
6093 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
6095 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6097 /* Decay arrays and functions into pointers. */
6098 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6099 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6100 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6101 arg_type = build_pointer_type (arg_type);
6103 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6106 if (METHOD_ADD_ARGS (meth))
6108 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6109 akey; akey = TREE_CHAIN (akey))
6111 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6113 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6116 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6117 goto lack_of_ellipsis;
6119 else
6121 lack_of_ellipsis:
6122 chainon (arglist, OBJC_VOID_AT_END);
6125 return arglist;
6128 static tree
6129 check_duplicates (hash hsh, int methods, int is_class)
6131 tree meth = NULL_TREE;
6133 if (hsh)
6135 meth = hsh->key;
6137 if (hsh->list)
6139 /* We have two or more methods with the same name but
6140 different types. */
6141 attr loop;
6143 /* But just how different are those types? If
6144 -Wno-strict-selector-match is specified, we shall not
6145 complain if the differences are solely among types with
6146 identical size and alignment. */
6147 if (!warn_strict_selector_match)
6149 for (loop = hsh->list; loop; loop = loop->next)
6150 if (!comp_proto_with_proto (meth, loop->value, 0))
6151 goto issue_warning;
6153 return meth;
6156 issue_warning:
6157 if (methods)
6159 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6161 warning_at (input_location, 0,
6162 "multiple methods named %<%c%E%> found",
6163 (is_class ? '+' : '-'),
6164 METHOD_SEL_NAME (meth));
6165 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6166 (type ? '-' : '+'),
6167 identifier_to_locale (gen_method_decl (meth)));
6169 else
6171 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6173 warning_at (input_location, 0,
6174 "multiple selectors named %<%c%E%> found",
6175 (is_class ? '+' : '-'),
6176 METHOD_SEL_NAME (meth));
6177 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6178 (type ? '-' : '+'),
6179 identifier_to_locale (gen_method_decl (meth)));
6182 for (loop = hsh->list; loop; loop = loop->next)
6184 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6186 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6187 (type ? '-' : '+'),
6188 identifier_to_locale (gen_method_decl (loop->value)));
6192 return meth;
6195 /* If RECEIVER is a class reference, return the identifier node for
6196 the referenced class. RECEIVER is created by objc_get_class_reference,
6197 so we check the exact form created depending on which runtimes are
6198 used. */
6200 static tree
6201 receiver_is_class_object (tree receiver, int self, int super)
6203 tree chain, exp, arg;
6205 /* The receiver is 'self' or 'super' in the context of a class method. */
6206 if (objc_method_context
6207 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6208 && (self || super))
6209 return (super
6210 ? CLASS_SUPER_NAME (implementation_template)
6211 : CLASS_NAME (implementation_template));
6213 if (flag_next_runtime)
6215 /* The receiver is a variable created by
6216 build_class_reference_decl. */
6217 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6218 /* Look up the identifier. */
6219 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6220 if (TREE_PURPOSE (chain) == receiver)
6221 return TREE_VALUE (chain);
6224 /* The receiver is a function call that returns an id. Check if
6225 it is a call to objc_getClass, if so, pick up the class name. */
6226 if (TREE_CODE (receiver) == CALL_EXPR
6227 && (exp = CALL_EXPR_FN (receiver))
6228 && TREE_CODE (exp) == ADDR_EXPR
6229 && (exp = TREE_OPERAND (exp, 0))
6230 && TREE_CODE (exp) == FUNCTION_DECL
6231 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6232 prototypes for objc_get_class(). Thankfully, they seem to share the
6233 same function type. */
6234 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6235 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6236 /* We have a call to objc_get_class/objc_getClass! */
6237 && (arg = CALL_EXPR_ARG (receiver, 0)))
6239 STRIP_NOPS (arg);
6240 if (TREE_CODE (arg) == ADDR_EXPR
6241 && (arg = TREE_OPERAND (arg, 0))
6242 && TREE_CODE (arg) == STRING_CST)
6243 /* Finally, we have the class name. */
6244 return get_identifier (TREE_STRING_POINTER (arg));
6246 return 0;
6249 /* If we are currently building a message expr, this holds
6250 the identifier of the selector of the message. This is
6251 used when printing warnings about argument mismatches. */
6253 static tree current_objc_message_selector = 0;
6255 tree
6256 objc_message_selector (void)
6258 return current_objc_message_selector;
6261 /* Construct an expression for sending a message.
6262 MESS has the object to send to in TREE_PURPOSE
6263 and the argument list (including selector) in TREE_VALUE.
6265 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6266 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6268 tree
6269 objc_build_message_expr (tree mess)
6271 tree receiver = TREE_PURPOSE (mess);
6272 tree sel_name;
6273 #ifdef OBJCPLUS
6274 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6275 #else
6276 tree args = TREE_VALUE (mess);
6277 #endif
6278 tree method_params = NULL_TREE;
6280 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6281 return error_mark_node;
6283 /* Obtain the full selector name. */
6284 if (TREE_CODE (args) == IDENTIFIER_NODE)
6285 /* A unary selector. */
6286 sel_name = args;
6287 else if (TREE_CODE (args) == TREE_LIST)
6288 sel_name = build_keyword_selector (args);
6289 else
6290 abort ();
6292 /* Build the parameter list to give to the method. */
6293 if (TREE_CODE (args) == TREE_LIST)
6294 #ifdef OBJCPLUS
6295 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6296 #else
6298 tree chain = args, prev = NULL_TREE;
6300 /* We have a keyword selector--check for comma expressions. */
6301 while (chain)
6303 tree element = TREE_VALUE (chain);
6305 /* We have a comma expression, must collapse... */
6306 if (TREE_CODE (element) == TREE_LIST)
6308 if (prev)
6309 TREE_CHAIN (prev) = element;
6310 else
6311 args = element;
6313 prev = chain;
6314 chain = TREE_CHAIN (chain);
6316 method_params = args;
6318 #endif
6320 #ifdef OBJCPLUS
6321 if (processing_template_decl)
6322 /* Must wait until template instantiation time. */
6323 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6324 method_params);
6325 #endif
6327 return objc_finish_message_expr (receiver, sel_name, method_params);
6330 /* Look up method SEL_NAME that would be suitable for receiver
6331 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6332 nonzero), and report on any duplicates. */
6334 static tree
6335 lookup_method_in_hash_lists (tree sel_name, int is_class)
6337 hash method_prototype = NULL;
6339 if (!is_class)
6340 method_prototype = hash_lookup (nst_method_hash_list,
6341 sel_name);
6343 if (!method_prototype)
6345 method_prototype = hash_lookup (cls_method_hash_list,
6346 sel_name);
6347 is_class = 1;
6350 return check_duplicates (method_prototype, 1, is_class);
6353 /* The 'objc_finish_message_expr' routine is called from within
6354 'objc_build_message_expr' for non-template functions. In the case of
6355 C++ template functions, it is called from 'build_expr_from_tree'
6356 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6358 tree
6359 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6361 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6362 tree selector, retval, class_tree;
6363 int self, super, have_cast;
6365 /* Extract the receiver of the message, as well as its type
6366 (where the latter may take the form of a cast or be inferred
6367 from the implementation context). */
6368 rtype = receiver;
6369 while (TREE_CODE (rtype) == COMPOUND_EXPR
6370 || TREE_CODE (rtype) == MODIFY_EXPR
6371 || CONVERT_EXPR_P (rtype)
6372 || TREE_CODE (rtype) == COMPONENT_REF)
6373 rtype = TREE_OPERAND (rtype, 0);
6374 self = (rtype == self_decl);
6375 super = (rtype == UOBJC_SUPER_decl);
6376 rtype = TREE_TYPE (receiver);
6377 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6378 || (TREE_CODE (receiver) == COMPOUND_EXPR
6379 && !IS_SUPER (rtype)));
6381 /* If we are calling [super dealloc], reset our warning flag. */
6382 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6383 should_call_super_dealloc = 0;
6385 /* If the receiver is a class object, retrieve the corresponding
6386 @interface, if one exists. */
6387 class_tree = receiver_is_class_object (receiver, self, super);
6389 /* Now determine the receiver type (if an explicit cast has not been
6390 provided). */
6391 if (!have_cast)
6393 if (class_tree)
6394 rtype = lookup_interface (class_tree);
6395 /* Handle `self' and `super'. */
6396 else if (super)
6398 if (!CLASS_SUPER_NAME (implementation_template))
6400 error ("no super class declared in @interface for %qE",
6401 CLASS_NAME (implementation_template));
6402 return error_mark_node;
6404 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6406 else if (self)
6407 rtype = lookup_interface (CLASS_NAME (implementation_template));
6410 /* If receiver is of type `id' or `Class' (or if the @interface for a
6411 class is not visible), we shall be satisfied with the existence of
6412 any instance or class method. */
6413 if (objc_is_id (rtype))
6415 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6416 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6417 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6418 : NULL_TREE);
6419 rtype = NULL_TREE;
6421 if (rprotos)
6423 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6424 in protocols themselves for the method prototype. */
6425 method_prototype
6426 = lookup_method_in_protocol_list (rprotos, sel_name,
6427 class_tree != NULL_TREE);
6429 /* If messaging 'Class <Proto>' but did not find a class method
6430 prototype, search for an instance method instead, and warn
6431 about having done so. */
6432 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6434 method_prototype
6435 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6437 if (method_prototype)
6438 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
6439 sel_name, sel_name);
6443 else if (rtype)
6445 tree orig_rtype = rtype;
6447 if (TREE_CODE (rtype) == POINTER_TYPE)
6448 rtype = TREE_TYPE (rtype);
6449 /* Traverse typedef aliases */
6450 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6451 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6452 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6453 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6454 if (TYPED_OBJECT (rtype))
6456 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6457 rtype = TYPE_OBJC_INTERFACE (rtype);
6459 /* If we could not find an @interface declaration, we must have
6460 only seen a @class declaration; so, we cannot say anything
6461 more intelligent about which methods the receiver will
6462 understand. */
6463 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6465 rtype = NULL_TREE;
6466 /* We could not find an @interface declaration, yet Message maybe in a
6467 @class's protocol. */
6468 if (!method_prototype && rprotos)
6469 method_prototype
6470 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6472 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6473 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6475 /* We have a valid ObjC class name. Look up the method name
6476 in the published @interface for the class (and its
6477 superclasses). */
6478 method_prototype
6479 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6481 /* If the method was not found in the @interface, it may still
6482 exist locally as part of the @implementation. */
6483 if (!method_prototype && objc_implementation_context
6484 && CLASS_NAME (objc_implementation_context)
6485 == OBJC_TYPE_NAME (rtype))
6486 method_prototype
6487 = lookup_method
6488 ((class_tree
6489 ? CLASS_CLS_METHODS (objc_implementation_context)
6490 : CLASS_NST_METHODS (objc_implementation_context)),
6491 sel_name);
6493 /* If we haven't found a candidate method by now, try looking for
6494 it in the protocol list. */
6495 if (!method_prototype && rprotos)
6496 method_prototype
6497 = lookup_method_in_protocol_list (rprotos, sel_name,
6498 class_tree != NULL_TREE);
6500 else
6502 warning (0, "invalid receiver type %qs",
6503 identifier_to_locale (gen_type_name (orig_rtype)));
6504 /* After issuing the "invalid receiver" warning, perform method
6505 lookup as if we were messaging 'id'. */
6506 rtype = rprotos = NULL_TREE;
6511 /* For 'id' or 'Class' receivers, search in the global hash table
6512 as a last resort. For all receivers, warn if protocol searches
6513 have failed. */
6514 if (!method_prototype)
6516 if (rprotos)
6517 warning (0, "%<%c%E%> not found in protocol(s)",
6518 (class_tree ? '+' : '-'),
6519 sel_name);
6521 if (!rtype)
6522 method_prototype
6523 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6526 if (!method_prototype)
6528 static bool warn_missing_methods = false;
6530 if (rtype)
6531 warning (0, "%qE may not respond to %<%c%E%>",
6532 OBJC_TYPE_NAME (rtype),
6533 (class_tree ? '+' : '-'),
6534 sel_name);
6535 /* If we are messaging an 'id' or 'Class' object and made it here,
6536 then we have failed to find _any_ instance or class method,
6537 respectively. */
6538 else
6539 warning (0, "no %<%c%E%> method found",
6540 (class_tree ? '+' : '-'),
6541 sel_name);
6543 if (!warn_missing_methods)
6545 warning_at (input_location,
6546 0, "(Messages without a matching method signature");
6547 warning_at (input_location,
6548 0, "will be assumed to return %<id%> and accept");
6549 warning_at (input_location,
6550 0, "%<...%> as arguments.)");
6551 warn_missing_methods = true;
6555 /* Save the selector name for printing error messages. */
6556 current_objc_message_selector = sel_name;
6558 /* Build the parameters list for looking up the method.
6559 These are the object itself and the selector. */
6561 if (flag_typed_selectors)
6562 selector = build_typed_selector_reference (input_location,
6563 sel_name, method_prototype);
6564 else
6565 selector = build_selector_reference (input_location, sel_name);
6567 retval = build_objc_method_call (input_location, super, method_prototype,
6568 receiver,
6569 selector, method_params);
6571 current_objc_message_selector = 0;
6573 return retval;
6576 /* Build a tree expression to send OBJECT the operation SELECTOR,
6577 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6578 assuming the method has prototype METHOD_PROTOTYPE.
6579 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6580 LOC is the location of the expression to build.
6581 Use METHOD_PARAMS as list of args to pass to the method.
6582 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6584 static tree
6585 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
6586 tree lookup_object, tree selector,
6587 tree method_params)
6589 tree sender = (super_flag ? umsg_super_decl :
6590 (!flag_next_runtime || flag_nil_receivers
6591 ? (flag_objc_direct_dispatch
6592 ? umsg_fast_decl
6593 : umsg_decl)
6594 : umsg_nonnil_decl));
6595 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6597 /* If a prototype for the method to be called exists, then cast
6598 the sender's return type and arguments to match that of the method.
6599 Otherwise, leave sender as is. */
6600 tree ret_type
6601 = (method_prototype
6602 ? TREE_VALUE (TREE_TYPE (method_prototype))
6603 : objc_object_type);
6604 tree sender_cast
6605 = build_pointer_type
6606 (build_function_type
6607 (ret_type,
6608 get_arg_type_list
6609 (method_prototype, METHOD_REF, super_flag)));
6610 tree method, t;
6612 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
6614 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6615 lookup_object = save_expr (lookup_object);
6617 if (flag_next_runtime)
6619 /* If we are returning a struct in memory, and the address
6620 of that memory location is passed as a hidden first
6621 argument, then change which messenger entry point this
6622 expr will call. NB: Note that sender_cast remains
6623 unchanged (it already has a struct return type). */
6624 if (!targetm.calls.struct_value_rtx (0, 0)
6625 && (TREE_CODE (ret_type) == RECORD_TYPE
6626 || TREE_CODE (ret_type) == UNION_TYPE)
6627 && targetm.calls.return_in_memory (ret_type, 0))
6628 sender = (super_flag ? umsg_super_stret_decl :
6629 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6631 method_params = tree_cons (NULL_TREE, lookup_object,
6632 tree_cons (NULL_TREE, selector,
6633 method_params));
6634 method = build_fold_addr_expr_loc (input_location, sender);
6636 else
6638 /* This is the portable (GNU) way. */
6639 tree object;
6641 /* First, call the lookup function to get a pointer to the method,
6642 then cast the pointer, then call it with the method arguments. */
6644 object = (super_flag ? self_decl : lookup_object);
6646 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6647 t = tree_cons (NULL_TREE, lookup_object, t);
6648 method = build_function_call (loc, sender, t);
6650 /* Pass the object to the method. */
6651 method_params = tree_cons (NULL_TREE, object,
6652 tree_cons (NULL_TREE, selector,
6653 method_params));
6656 /* ??? Selector is not at this point something we can use inside
6657 the compiler itself. Set it to garbage for the nonce. */
6658 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6659 return build_function_call (loc,
6660 t, method_params);
6663 static void
6664 build_protocol_reference (tree p)
6666 tree decl;
6667 const char *proto_name;
6669 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6671 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6672 decl = start_var_decl (objc_protocol_template, proto_name);
6674 PROTOCOL_FORWARD_DECL (p) = decl;
6677 /* This function is called by the parser when (and only when) a
6678 @protocol() expression is found, in order to compile it. */
6679 tree
6680 objc_build_protocol_expr (tree protoname)
6682 tree expr;
6683 tree p = lookup_protocol (protoname);
6685 if (!p)
6687 error ("cannot find protocol declaration for %qE",
6688 protoname);
6689 return error_mark_node;
6692 if (!PROTOCOL_FORWARD_DECL (p))
6693 build_protocol_reference (p);
6695 expr = build_unary_op (input_location,
6696 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6698 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6699 if we have it, rather than converting it here. */
6700 expr = convert (objc_protocol_type, expr);
6702 /* The @protocol() expression is being compiled into a pointer to a
6703 statically allocated instance of the Protocol class. To become
6704 usable at runtime, the 'isa' pointer of the instance need to be
6705 fixed up at runtime by the runtime library, to point to the
6706 actual 'Protocol' class. */
6708 /* For the GNU runtime, put the static Protocol instance in the list
6709 of statically allocated instances, so that we make sure that its
6710 'isa' pointer is fixed up at runtime by the GNU runtime library
6711 to point to the Protocol class (at runtime, when loading the
6712 module, the GNU runtime library loops on the statically allocated
6713 instances (as found in the defs field in objc_symtab) and fixups
6714 all the 'isa' pointers of those objects). */
6715 if (! flag_next_runtime)
6717 /* This type is a struct containing the fields of a Protocol
6718 object. (Cfr. objc_protocol_type instead is the type of a pointer
6719 to such a struct). */
6720 tree protocol_struct_type = xref_tag
6721 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6722 tree *chain;
6724 /* Look for the list of Protocol statically allocated instances
6725 to fixup at runtime. Create a new list to hold Protocol
6726 statically allocated instances, if the list is not found. At
6727 present there is only another list, holding NSConstantString
6728 static instances to be fixed up at runtime. */
6729 for (chain = &objc_static_instances;
6730 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6731 chain = &TREE_CHAIN (*chain));
6732 if (!*chain)
6734 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6735 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6736 class_names);
6739 /* Add this statically allocated instance to the Protocol list. */
6740 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6741 PROTOCOL_FORWARD_DECL (p),
6742 TREE_PURPOSE (*chain));
6746 return expr;
6749 /* This function is called by the parser when a @selector() expression
6750 is found, in order to compile it. It is only called by the parser
6751 and only to compile a @selector(). LOC is the location of the
6752 @selector. */
6753 tree
6754 objc_build_selector_expr (location_t loc, tree selnamelist)
6756 tree selname;
6758 /* Obtain the full selector name. */
6759 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6760 /* A unary selector. */
6761 selname = selnamelist;
6762 else if (TREE_CODE (selnamelist) == TREE_LIST)
6763 selname = build_keyword_selector (selnamelist);
6764 else
6765 abort ();
6767 /* If we are required to check @selector() expressions as they
6768 are found, check that the selector has been declared. */
6769 if (warn_undeclared_selector)
6771 /* Look the selector up in the list of all known class and
6772 instance methods (up to this line) to check that the selector
6773 exists. */
6774 hash hsh;
6776 /* First try with instance methods. */
6777 hsh = hash_lookup (nst_method_hash_list, selname);
6779 /* If not found, try with class methods. */
6780 if (!hsh)
6782 hsh = hash_lookup (cls_method_hash_list, selname);
6785 /* If still not found, print out a warning. */
6786 if (!hsh)
6788 warning (0, "undeclared selector %qE", selname);
6793 if (flag_typed_selectors)
6794 return build_typed_selector_reference (loc, selname, 0);
6795 else
6796 return build_selector_reference (loc, selname);
6799 tree
6800 objc_build_encode_expr (tree type)
6802 tree result;
6803 const char *string;
6805 encode_type (type, obstack_object_size (&util_obstack),
6806 OBJC_ENCODE_INLINE_DEFS);
6807 obstack_1grow (&util_obstack, 0); /* null terminate string */
6808 string = XOBFINISH (&util_obstack, const char *);
6810 /* Synthesize a string that represents the encoded struct/union. */
6811 result = my_build_string (strlen (string) + 1, string);
6812 obstack_free (&util_obstack, util_firstobj);
6813 return result;
6816 static tree
6817 build_ivar_reference (tree id)
6819 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6821 /* Historically, a class method that produced objects (factory
6822 method) would assign `self' to the instance that it
6823 allocated. This would effectively turn the class method into
6824 an instance method. Following this assignment, the instance
6825 variables could be accessed. That practice, while safe,
6826 violates the simple rule that a class method should not refer
6827 to an instance variable. It's better to catch the cases
6828 where this is done unknowingly than to support the above
6829 paradigm. */
6830 warning (0, "instance variable %qE accessed in class method",
6831 id);
6832 self_decl = convert (objc_instance_type, self_decl); /* cast */
6835 return objc_build_component_ref (build_indirect_ref (input_location,
6836 self_decl, RO_ARROW),
6837 id);
6840 /* Compute a hash value for a given method SEL_NAME. */
6842 static size_t
6843 hash_func (tree sel_name)
6845 const unsigned char *s
6846 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6847 size_t h = 0;
6849 while (*s)
6850 h = h * 67 + *s++ - 113;
6851 return h;
6854 static void
6855 hash_init (void)
6857 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
6858 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
6860 /* Initialize the hash table used to hold the constant string objects. */
6861 string_htab = htab_create_ggc (31, string_hash,
6862 string_eq, NULL);
6864 /* Initialize the hash table used to hold EH-volatilized types. */
6865 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6866 volatilized_eq, NULL);
6869 /* WARNING!!!! hash_enter is called with a method, and will peek
6870 inside to find its selector! But hash_lookup is given a selector
6871 directly, and looks for the selector that's inside the found
6872 entry's key (method) for comparison. */
6874 static void
6875 hash_enter (hash *hashlist, tree method)
6877 hash obj;
6878 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6880 obj = ggc_alloc_hashed_entry ();
6881 obj->list = 0;
6882 obj->next = hashlist[slot];
6883 obj->key = method;
6885 hashlist[slot] = obj; /* append to front */
6888 static hash
6889 hash_lookup (hash *hashlist, tree sel_name)
6891 hash target;
6893 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6895 while (target)
6897 if (sel_name == METHOD_SEL_NAME (target->key))
6898 return target;
6900 target = target->next;
6902 return 0;
6905 static void
6906 hash_add_attr (hash entry, tree value)
6908 attr obj;
6910 obj = ggc_alloc_hashed_attribute ();
6911 obj->next = entry->list;
6912 obj->value = value;
6914 entry->list = obj; /* append to front */
6917 static tree
6918 lookup_method (tree mchain, tree method)
6920 tree key;
6922 if (TREE_CODE (method) == IDENTIFIER_NODE)
6923 key = method;
6924 else
6925 key = METHOD_SEL_NAME (method);
6927 while (mchain)
6929 if (METHOD_SEL_NAME (mchain) == key)
6930 return mchain;
6932 mchain = DECL_CHAIN (mchain);
6934 return NULL_TREE;
6937 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6938 in INTERFACE, along with any categories and protocols attached thereto.
6939 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6940 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6941 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6942 be found in INTERFACE or any of its superclasses, look for an _instance_
6943 method of the same name in the root class as a last resort.
6945 If a suitable method cannot be found, return NULL_TREE. */
6947 static tree
6948 lookup_method_static (tree interface, tree ident, int flags)
6950 tree meth = NULL_TREE, root_inter = NULL_TREE;
6951 tree inter = interface;
6952 int is_class = (flags & OBJC_LOOKUP_CLASS);
6953 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6955 while (inter)
6957 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6958 tree category = inter;
6960 /* First, look up the method in the class itself. */
6961 if ((meth = lookup_method (chain, ident)))
6962 return meth;
6964 /* Failing that, look for the method in each category of the class. */
6965 while ((category = CLASS_CATEGORY_LIST (category)))
6967 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6969 /* Check directly in each category. */
6970 if ((meth = lookup_method (chain, ident)))
6971 return meth;
6973 /* Failing that, check in each category's protocols. */
6974 if (CLASS_PROTOCOL_LIST (category))
6976 if ((meth = (lookup_method_in_protocol_list
6977 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6978 return meth;
6982 /* If not found in categories, check in protocols of the main class. */
6983 if (CLASS_PROTOCOL_LIST (inter))
6985 if ((meth = (lookup_method_in_protocol_list
6986 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6987 return meth;
6990 /* If we were instructed not to look in superclasses, don't. */
6991 if (no_superclasses)
6992 return NULL_TREE;
6994 /* Failing that, climb up the inheritance hierarchy. */
6995 root_inter = inter;
6996 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6998 while (inter);
7000 /* If no class (factory) method was found, check if an _instance_
7001 method of the same name exists in the root class. This is what
7002 the Objective-C runtime will do. If an instance method was not
7003 found, return 0. */
7004 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
7007 /* Add the method to the hash list if it doesn't contain an identical
7008 method already. */
7010 static void
7011 add_method_to_hash_list (hash *hash_list, tree method)
7013 hash hsh;
7015 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7017 /* Install on a global chain. */
7018 hash_enter (hash_list, method);
7020 else
7022 /* Check types against those; if different, add to a list. */
7023 attr loop;
7024 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7025 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7026 already_there |= comp_proto_with_proto (method, loop->value, 1);
7027 if (!already_there)
7028 hash_add_attr (hsh, method);
7032 static tree
7033 objc_add_method (tree klass, tree method, int is_class)
7035 tree mth;
7037 if (!(mth = lookup_method (is_class
7038 ? CLASS_CLS_METHODS (klass)
7039 : CLASS_NST_METHODS (klass), method)))
7041 /* put method on list in reverse order */
7042 if (is_class)
7044 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
7045 CLASS_CLS_METHODS (klass) = method;
7047 else
7049 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
7050 CLASS_NST_METHODS (klass) = method;
7053 else
7055 /* When processing an @interface for a class or category, give hard
7056 errors on methods with identical selectors but differing argument
7057 and/or return types. We do not do this for @implementations, because
7058 C/C++ will do it for us (i.e., there will be duplicate function
7059 definition errors). */
7060 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7061 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7062 && !comp_proto_with_proto (method, mth, 1))
7063 error ("duplicate declaration of method %<%c%E%>",
7064 is_class ? '+' : '-',
7065 METHOD_SEL_NAME (mth));
7068 if (is_class)
7069 add_method_to_hash_list (cls_method_hash_list, method);
7070 else
7072 add_method_to_hash_list (nst_method_hash_list, method);
7074 /* Instance methods in root classes (and categories thereof)
7075 may act as class methods as a last resort. We also add
7076 instance methods listed in @protocol declarations to
7077 the class hash table, on the assumption that @protocols
7078 may be adopted by root classes or categories. */
7079 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7080 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7081 klass = lookup_interface (CLASS_NAME (klass));
7083 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7084 || !CLASS_SUPER_NAME (klass))
7085 add_method_to_hash_list (cls_method_hash_list, method);
7088 return method;
7091 static tree
7092 add_class (tree class_name, tree name)
7094 struct interface_tuple **slot;
7096 /* Put interfaces on list in reverse order. */
7097 TREE_CHAIN (class_name) = interface_chain;
7098 interface_chain = class_name;
7100 if (interface_htab == NULL)
7101 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7102 slot = (struct interface_tuple **)
7103 htab_find_slot_with_hash (interface_htab, name,
7104 IDENTIFIER_HASH_VALUE (name),
7105 INSERT);
7106 if (!*slot)
7108 *slot = ggc_alloc_cleared_interface_tuple ();
7109 (*slot)->id = name;
7111 (*slot)->class_name = class_name;
7113 return interface_chain;
7116 static void
7117 add_category (tree klass, tree category)
7119 /* Put categories on list in reverse order. */
7120 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7122 if (cat)
7124 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7125 CLASS_NAME (klass),
7126 CLASS_SUPER_NAME (category));
7128 else
7130 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7131 CLASS_CATEGORY_LIST (klass) = category;
7135 /* Called after parsing each instance variable declaration. Necessary to
7136 preserve typedefs and implement public/private...
7138 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7140 static tree
7141 add_instance_variable (tree klass, int visibility, tree field_decl)
7143 tree field_type = TREE_TYPE (field_decl);
7144 const char *ivar_name = DECL_NAME (field_decl)
7145 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7146 : _("<unnamed>");
7148 #ifdef OBJCPLUS
7149 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7151 error ("illegal reference type specified for instance variable %qs",
7152 ivar_name);
7153 /* Return class as is without adding this ivar. */
7154 return klass;
7156 #endif
7158 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7159 || TYPE_SIZE (field_type) == error_mark_node)
7160 /* 'type[0]' is allowed, but 'type[]' is not! */
7162 error ("instance variable %qs has unknown size", ivar_name);
7163 /* Return class as is without adding this ivar. */
7164 return klass;
7167 #ifdef OBJCPLUS
7168 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7169 need to either (1) warn the user about it or (2) generate suitable
7170 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7171 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7172 if (MAYBE_CLASS_TYPE_P (field_type)
7173 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7174 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7175 || TYPE_POLYMORPHIC_P (field_type)))
7177 tree type_name = OBJC_TYPE_NAME (field_type);
7179 if (flag_objc_call_cxx_cdtors)
7181 /* Since the ObjC runtime will be calling the constructors and
7182 destructors for us, the only thing we can't handle is the lack
7183 of a default constructor. */
7184 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7185 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7187 warning (0, "type %qE has no default constructor to call",
7188 type_name);
7190 /* If we cannot call a constructor, we should also avoid
7191 calling the destructor, for symmetry. */
7192 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7193 warning (0, "destructor for %qE shall not be run either",
7194 type_name);
7197 else
7199 static bool warn_cxx_ivars = false;
7201 if (TYPE_POLYMORPHIC_P (field_type))
7203 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7204 initialize them. */
7205 error ("type %qE has virtual member functions", type_name);
7206 error ("illegal aggregate type %qE specified "
7207 "for instance variable %qs",
7208 type_name, ivar_name);
7209 /* Return class as is without adding this ivar. */
7210 return klass;
7213 /* User-defined constructors and destructors are not known to Obj-C
7214 and hence will not be called. This may or may not be a problem. */
7215 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7216 warning (0, "type %qE has a user-defined constructor", type_name);
7217 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7218 warning (0, "type %qE has a user-defined destructor", type_name);
7220 if (!warn_cxx_ivars)
7222 warning (0, "C++ constructors and destructors will not "
7223 "be invoked for Objective-C fields");
7224 warn_cxx_ivars = true;
7228 #endif
7230 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7231 switch (visibility)
7233 case 0:
7234 TREE_PUBLIC (field_decl) = 0;
7235 TREE_PRIVATE (field_decl) = 0;
7236 TREE_PROTECTED (field_decl) = 1;
7237 break;
7239 case 1:
7240 TREE_PUBLIC (field_decl) = 1;
7241 TREE_PRIVATE (field_decl) = 0;
7242 TREE_PROTECTED (field_decl) = 0;
7243 break;
7245 case 2:
7246 TREE_PUBLIC (field_decl) = 0;
7247 TREE_PRIVATE (field_decl) = 1;
7248 TREE_PROTECTED (field_decl) = 0;
7249 break;
7253 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7255 return klass;
7258 static tree
7259 is_ivar (tree decl_chain, tree ident)
7261 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
7262 if (DECL_NAME (decl_chain) == ident)
7263 return decl_chain;
7264 return NULL_TREE;
7267 /* True if the ivar is private and we are not in its implementation. */
7269 static int
7270 is_private (tree decl)
7272 return (TREE_PRIVATE (decl)
7273 && ! is_ivar (CLASS_IVARS (implementation_template),
7274 DECL_NAME (decl)));
7277 /* We have an instance variable reference;, check to see if it is public. */
7280 objc_is_public (tree expr, tree identifier)
7282 tree basetype, decl;
7284 #ifdef OBJCPLUS
7285 if (processing_template_decl)
7286 return 1;
7287 #endif
7289 if (TREE_TYPE (expr) == error_mark_node)
7290 return 1;
7292 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7294 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7296 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7298 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7300 if (!klass)
7302 error ("cannot find interface declaration for %qE",
7303 OBJC_TYPE_NAME (basetype));
7304 return 0;
7307 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7309 if (TREE_PUBLIC (decl))
7310 return 1;
7312 /* Important difference between the Stepstone translator:
7313 all instance variables should be public within the context
7314 of the implementation. */
7315 if (objc_implementation_context
7316 && ((TREE_CODE (objc_implementation_context)
7317 == CLASS_IMPLEMENTATION_TYPE)
7318 || (TREE_CODE (objc_implementation_context)
7319 == CATEGORY_IMPLEMENTATION_TYPE)))
7321 tree curtype = TYPE_MAIN_VARIANT
7322 (CLASS_STATIC_TEMPLATE
7323 (implementation_template));
7325 if (basetype == curtype
7326 || DERIVED_FROM_P (basetype, curtype))
7328 int priv = is_private (decl);
7330 if (priv)
7331 error ("instance variable %qE is declared private",
7332 DECL_NAME (decl));
7334 return !priv;
7338 /* The 2.95.2 compiler sometimes allowed C functions to access
7339 non-@public ivars. We will let this slide for now... */
7340 if (!objc_method_context)
7342 warning (0, "instance variable %qE is %s; "
7343 "this will be a hard error in the future",
7344 identifier,
7345 TREE_PRIVATE (decl) ? "@private" : "@protected");
7346 return 1;
7349 error ("instance variable %qE is declared %s",
7350 identifier,
7351 TREE_PRIVATE (decl) ? "private" : "protected");
7352 return 0;
7357 return 1;
7360 /* Make sure all entries in CHAIN are also in LIST. */
7362 static int
7363 check_methods (tree chain, tree list, int mtype)
7365 int first = 1;
7367 while (chain)
7369 if (!lookup_method (list, chain))
7371 if (first)
7373 if (TREE_CODE (objc_implementation_context)
7374 == CLASS_IMPLEMENTATION_TYPE)
7375 warning (0, "incomplete implementation of class %qE",
7376 CLASS_NAME (objc_implementation_context));
7377 else if (TREE_CODE (objc_implementation_context)
7378 == CATEGORY_IMPLEMENTATION_TYPE)
7379 warning (0, "incomplete implementation of category %qE",
7380 CLASS_SUPER_NAME (objc_implementation_context));
7381 first = 0;
7384 warning (0, "method definition for %<%c%E%> not found",
7385 mtype, METHOD_SEL_NAME (chain));
7388 chain = DECL_CHAIN (chain);
7391 return first;
7394 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7396 static int
7397 conforms_to_protocol (tree klass, tree protocol)
7399 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7401 tree p = CLASS_PROTOCOL_LIST (klass);
7402 while (p && TREE_VALUE (p) != protocol)
7403 p = TREE_CHAIN (p);
7405 if (!p)
7407 tree super = (CLASS_SUPER_NAME (klass)
7408 ? lookup_interface (CLASS_SUPER_NAME (klass))
7409 : NULL_TREE);
7410 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7411 if (!tmp)
7412 return 0;
7416 return 1;
7419 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7420 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7422 static int
7423 check_methods_accessible (tree chain, tree context, int mtype)
7425 int first = 1;
7426 tree list;
7427 tree base_context = context;
7429 while (chain)
7431 context = base_context;
7432 while (context)
7434 if (mtype == '+')
7435 list = CLASS_CLS_METHODS (context);
7436 else
7437 list = CLASS_NST_METHODS (context);
7439 if (lookup_method (list, chain))
7440 break;
7442 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7443 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7444 context = (CLASS_SUPER_NAME (context)
7445 ? lookup_interface (CLASS_SUPER_NAME (context))
7446 : NULL_TREE);
7448 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7449 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7450 context = (CLASS_NAME (context)
7451 ? lookup_interface (CLASS_NAME (context))
7452 : NULL_TREE);
7453 else
7454 abort ();
7457 if (context == NULL_TREE)
7459 if (first)
7461 if (TREE_CODE (objc_implementation_context)
7462 == CLASS_IMPLEMENTATION_TYPE)
7463 warning (0, "incomplete implementation of class %qE",
7464 CLASS_NAME (objc_implementation_context));
7465 else if (TREE_CODE (objc_implementation_context)
7466 == CATEGORY_IMPLEMENTATION_TYPE)
7467 warning (0, "incomplete implementation of category %qE",
7468 CLASS_SUPER_NAME (objc_implementation_context));
7469 first = 0;
7471 warning (0, "method definition for %<%c%E%> not found",
7472 mtype, METHOD_SEL_NAME (chain));
7475 chain = TREE_CHAIN (chain); /* next method... */
7477 return first;
7480 /* Check whether the current interface (accessible via
7481 'objc_implementation_context') actually implements protocol P, along
7482 with any protocols that P inherits. */
7484 static void
7485 check_protocol (tree p, const char *type, tree name)
7487 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7489 int f1, f2;
7491 /* Ensure that all protocols have bodies! */
7492 if (warn_protocol)
7494 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7495 CLASS_CLS_METHODS (objc_implementation_context),
7496 '+');
7497 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7498 CLASS_NST_METHODS (objc_implementation_context),
7499 '-');
7501 else
7503 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7504 objc_implementation_context,
7505 '+');
7506 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7507 objc_implementation_context,
7508 '-');
7511 if (!f1 || !f2)
7512 warning (0, "%s %qE does not fully implement the %qE protocol",
7513 type, name, PROTOCOL_NAME (p));
7516 /* Check protocols recursively. */
7517 if (PROTOCOL_LIST (p))
7519 tree subs = PROTOCOL_LIST (p);
7520 tree super_class =
7521 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7523 while (subs)
7525 tree sub = TREE_VALUE (subs);
7527 /* If the superclass does not conform to the protocols
7528 inherited by P, then we must! */
7529 if (!super_class || !conforms_to_protocol (super_class, sub))
7530 check_protocol (sub, type, name);
7531 subs = TREE_CHAIN (subs);
7536 /* Check whether the current interface (accessible via
7537 'objc_implementation_context') actually implements the protocols listed
7538 in PROTO_LIST. */
7540 static void
7541 check_protocols (tree proto_list, const char *type, tree name)
7543 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7545 tree p = TREE_VALUE (proto_list);
7547 check_protocol (p, type, name);
7551 /* Make sure that the class CLASS_NAME is defined
7552 CODE says which kind of thing CLASS_NAME ought to be.
7553 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7554 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7556 static tree
7557 start_class (enum tree_code code, tree class_name, tree super_name,
7558 tree protocol_list)
7560 tree klass, decl;
7562 #ifdef OBJCPLUS
7563 if (current_namespace != global_namespace) {
7564 error ("Objective-C declarations may only appear in global scope");
7566 #endif /* OBJCPLUS */
7568 if (objc_implementation_context)
7570 warning (0, "%<@end%> missing in implementation context");
7571 finish_class (objc_implementation_context);
7572 objc_ivar_chain = NULL_TREE;
7573 objc_implementation_context = NULL_TREE;
7576 klass = make_node (code);
7577 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7579 /* Check for existence of the super class, if one was specified. Note
7580 that we must have seen an @interface, not just a @class. If we
7581 are looking at a @compatibility_alias, traverse it first. */
7582 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7583 && super_name)
7585 tree super = objc_is_class_name (super_name);
7587 if (!super || !lookup_interface (super))
7589 error ("cannot find interface declaration for %qE, superclass of %qE",
7590 super ? super : super_name,
7591 class_name);
7592 super_name = NULL_TREE;
7594 else
7595 super_name = super;
7598 CLASS_NAME (klass) = class_name;
7599 CLASS_SUPER_NAME (klass) = super_name;
7600 CLASS_CLS_METHODS (klass) = NULL_TREE;
7602 if (! objc_is_class_name (class_name)
7603 && (decl = lookup_name (class_name)))
7605 error ("%qE redeclared as different kind of symbol",
7606 class_name);
7607 error ("previous declaration of %q+D",
7608 decl);
7611 if (code == CLASS_IMPLEMENTATION_TYPE)
7614 tree chain;
7616 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7617 if (TREE_VALUE (chain) == class_name)
7619 error ("reimplementation of class %qE",
7620 class_name);
7621 return error_mark_node;
7623 implemented_classes = tree_cons (NULL_TREE, class_name,
7624 implemented_classes);
7627 /* Reset for multiple classes per file. */
7628 method_slot = 0;
7630 objc_implementation_context = klass;
7632 /* Lookup the interface for this implementation. */
7634 if (!(implementation_template = lookup_interface (class_name)))
7636 warning (0, "cannot find interface declaration for %qE",
7637 class_name);
7638 add_class (implementation_template = objc_implementation_context,
7639 class_name);
7642 /* If a super class has been specified in the implementation,
7643 insure it conforms to the one specified in the interface. */
7645 if (super_name
7646 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7648 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7649 error ("conflicting super class name %qE",
7650 super_name);
7651 if (previous_name)
7652 error ("previous declaration of %qE", previous_name);
7653 else
7654 error ("previous declaration");
7657 else if (! super_name)
7659 CLASS_SUPER_NAME (objc_implementation_context)
7660 = CLASS_SUPER_NAME (implementation_template);
7664 else if (code == CLASS_INTERFACE_TYPE)
7666 if (lookup_interface (class_name))
7667 #ifdef OBJCPLUS
7668 error ("duplicate interface declaration for class %qE",
7669 #else
7670 warning (0, "duplicate interface declaration for class %qE",
7671 #endif
7672 class_name);
7673 else
7674 add_class (klass, class_name);
7676 if (protocol_list)
7677 CLASS_PROTOCOL_LIST (klass)
7678 = lookup_and_install_protocols (protocol_list);
7681 else if (code == CATEGORY_INTERFACE_TYPE)
7683 tree class_category_is_assoc_with;
7685 /* For a category, class_name is really the name of the class that
7686 the following set of methods will be associated with. We must
7687 find the interface so that can derive the objects template. */
7689 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7691 error ("cannot find interface declaration for %qE",
7692 class_name);
7693 exit (FATAL_EXIT_CODE);
7695 else
7696 add_category (class_category_is_assoc_with, klass);
7698 if (protocol_list)
7699 CLASS_PROTOCOL_LIST (klass)
7700 = lookup_and_install_protocols (protocol_list);
7703 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7705 /* Reset for multiple classes per file. */
7706 method_slot = 0;
7708 objc_implementation_context = klass;
7710 /* For a category, class_name is really the name of the class that
7711 the following set of methods will be associated with. We must
7712 find the interface so that can derive the objects template. */
7714 if (!(implementation_template = lookup_interface (class_name)))
7716 error ("cannot find interface declaration for %qE",
7717 class_name);
7718 exit (FATAL_EXIT_CODE);
7721 return klass;
7724 static tree
7725 continue_class (tree klass)
7727 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7728 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7730 struct imp_entry *imp_entry;
7732 /* Check consistency of the instance variables. */
7734 if (CLASS_RAW_IVARS (klass))
7735 check_ivars (implementation_template, klass);
7737 /* code generation */
7739 #ifdef OBJCPLUS
7740 push_lang_context (lang_name_c);
7741 #endif
7743 build_private_template (implementation_template);
7744 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7745 objc_instance_type = build_pointer_type (uprivate_record);
7747 imp_entry = ggc_alloc_imp_entry ();
7749 imp_entry->next = imp_list;
7750 imp_entry->imp_context = klass;
7751 imp_entry->imp_template = implementation_template;
7753 synth_forward_declarations ();
7754 imp_entry->class_decl = UOBJC_CLASS_decl;
7755 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7756 imp_entry->has_cxx_cdtors = 0;
7758 /* Append to front and increment count. */
7759 imp_list = imp_entry;
7760 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7761 imp_count++;
7762 else
7763 cat_count++;
7765 #ifdef OBJCPLUS
7766 pop_lang_context ();
7767 #endif /* OBJCPLUS */
7769 return get_class_ivars (implementation_template, true);
7772 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7774 #ifdef OBJCPLUS
7775 push_lang_context (lang_name_c);
7776 #endif /* OBJCPLUS */
7778 objc_collecting_ivars = 1;
7779 build_private_template (klass);
7780 objc_collecting_ivars = 0;
7782 #ifdef OBJCPLUS
7783 pop_lang_context ();
7784 #endif /* OBJCPLUS */
7786 return NULL_TREE;
7789 else
7790 return error_mark_node;
7793 /* This is called once we see the "@end" in an interface/implementation. */
7795 static void
7796 finish_class (tree klass)
7798 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7800 /* All code generation is done in finish_objc. */
7802 if (implementation_template != objc_implementation_context)
7804 /* Ensure that all method listed in the interface contain bodies. */
7805 check_methods (CLASS_CLS_METHODS (implementation_template),
7806 CLASS_CLS_METHODS (objc_implementation_context), '+');
7807 check_methods (CLASS_NST_METHODS (implementation_template),
7808 CLASS_NST_METHODS (objc_implementation_context), '-');
7810 if (CLASS_PROTOCOL_LIST (implementation_template))
7811 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7812 "class",
7813 CLASS_NAME (objc_implementation_context));
7817 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7819 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7821 if (category)
7823 /* Ensure all method listed in the interface contain bodies. */
7824 check_methods (CLASS_CLS_METHODS (category),
7825 CLASS_CLS_METHODS (objc_implementation_context), '+');
7826 check_methods (CLASS_NST_METHODS (category),
7827 CLASS_NST_METHODS (objc_implementation_context), '-');
7829 if (CLASS_PROTOCOL_LIST (category))
7830 check_protocols (CLASS_PROTOCOL_LIST (category),
7831 "category",
7832 CLASS_SUPER_NAME (objc_implementation_context));
7837 static tree
7838 add_protocol (tree protocol)
7840 /* Put protocol on list in reverse order. */
7841 TREE_CHAIN (protocol) = protocol_chain;
7842 protocol_chain = protocol;
7843 return protocol_chain;
7846 static tree
7847 lookup_protocol (tree ident)
7849 tree chain;
7851 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7852 if (ident == PROTOCOL_NAME (chain))
7853 return chain;
7855 return NULL_TREE;
7858 /* This function forward declares the protocols named by NAMES. If
7859 they are already declared or defined, the function has no effect. */
7861 void
7862 objc_declare_protocols (tree names)
7864 tree list;
7866 #ifdef OBJCPLUS
7867 if (current_namespace != global_namespace) {
7868 error ("Objective-C declarations may only appear in global scope");
7870 #endif /* OBJCPLUS */
7872 for (list = names; list; list = TREE_CHAIN (list))
7874 tree name = TREE_VALUE (list);
7876 if (lookup_protocol (name) == NULL_TREE)
7878 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7880 TYPE_LANG_SLOT_1 (protocol)
7881 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7882 PROTOCOL_NAME (protocol) = name;
7883 PROTOCOL_LIST (protocol) = NULL_TREE;
7884 add_protocol (protocol);
7885 PROTOCOL_DEFINED (protocol) = 0;
7886 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7891 static tree
7892 start_protocol (enum tree_code code, tree name, tree list)
7894 tree protocol;
7896 #ifdef OBJCPLUS
7897 if (current_namespace != global_namespace) {
7898 error ("Objective-C declarations may only appear in global scope");
7900 #endif /* OBJCPLUS */
7902 protocol = lookup_protocol (name);
7904 if (!protocol)
7906 protocol = make_node (code);
7907 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7909 PROTOCOL_NAME (protocol) = name;
7910 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7911 add_protocol (protocol);
7912 PROTOCOL_DEFINED (protocol) = 1;
7913 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7915 check_protocol_recursively (protocol, list);
7917 else if (! PROTOCOL_DEFINED (protocol))
7919 PROTOCOL_DEFINED (protocol) = 1;
7920 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7922 check_protocol_recursively (protocol, list);
7924 else
7926 warning (0, "duplicate declaration for protocol %qE",
7927 name);
7929 return protocol;
7933 /* "Encode" a data type into a string, which grows in util_obstack.
7934 ??? What is the FORMAT? Someone please document this! */
7936 static void
7937 encode_type_qualifiers (tree declspecs)
7939 tree spec;
7941 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7943 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7944 obstack_1grow (&util_obstack, 'n');
7945 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7946 obstack_1grow (&util_obstack, 'N');
7947 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7948 obstack_1grow (&util_obstack, 'o');
7949 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7950 obstack_1grow (&util_obstack, 'O');
7951 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7952 obstack_1grow (&util_obstack, 'R');
7953 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7954 obstack_1grow (&util_obstack, 'V');
7958 /* Encode a pointer type. */
7960 static void
7961 encode_pointer (tree type, int curtype, int format)
7963 tree pointer_to = TREE_TYPE (type);
7965 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7967 if (OBJC_TYPE_NAME (pointer_to)
7968 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7970 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7972 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7974 obstack_1grow (&util_obstack, '@');
7975 return;
7977 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7978 && TYPE_OBJC_INTERFACE (pointer_to))
7980 if (generating_instance_variables)
7982 obstack_1grow (&util_obstack, '@');
7983 obstack_1grow (&util_obstack, '"');
7984 obstack_grow (&util_obstack, name, strlen (name));
7985 obstack_1grow (&util_obstack, '"');
7986 return;
7988 else
7990 obstack_1grow (&util_obstack, '@');
7991 return;
7994 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7996 obstack_1grow (&util_obstack, '#');
7997 return;
7999 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
8001 obstack_1grow (&util_obstack, ':');
8002 return;
8006 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
8007 && TYPE_MODE (pointer_to) == QImode)
8009 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
8010 ? OBJC_TYPE_NAME (pointer_to)
8011 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
8013 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
8015 /* It appears that "r*" means "const char *" rather than
8016 "char *const". */
8017 if (TYPE_READONLY (pointer_to))
8018 obstack_1grow (&util_obstack, 'r');
8020 obstack_1grow (&util_obstack, '*');
8021 return;
8025 /* We have a type that does not get special treatment. */
8027 /* NeXT extension */
8028 obstack_1grow (&util_obstack, '^');
8029 encode_type (pointer_to, curtype, format);
8032 static void
8033 encode_array (tree type, int curtype, int format)
8035 tree an_int_cst = TYPE_SIZE (type);
8036 tree array_of = TREE_TYPE (type);
8037 char buffer[40];
8039 /* An incomplete array is treated like a pointer. */
8040 if (an_int_cst == NULL)
8042 encode_pointer (type, curtype, format);
8043 return;
8046 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
8047 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
8048 else
8049 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
8050 TREE_INT_CST_LOW (an_int_cst)
8051 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
8053 obstack_grow (&util_obstack, buffer, strlen (buffer));
8054 encode_type (array_of, curtype, format);
8055 obstack_1grow (&util_obstack, ']');
8056 return;
8059 static void
8060 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
8062 tree field = TYPE_FIELDS (type);
8064 for (; field; field = DECL_CHAIN (field))
8066 #ifdef OBJCPLUS
8067 /* C++ static members, and things that are not field at all,
8068 should not appear in the encoding. */
8069 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
8070 continue;
8071 #endif
8073 /* Recursively encode fields of embedded base classes. */
8074 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
8075 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
8077 encode_aggregate_fields (TREE_TYPE (field),
8078 pointed_to, curtype, format);
8079 continue;
8082 if (generating_instance_variables && !pointed_to)
8084 tree fname = DECL_NAME (field);
8086 obstack_1grow (&util_obstack, '"');
8088 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
8089 obstack_grow (&util_obstack,
8090 IDENTIFIER_POINTER (fname),
8091 strlen (IDENTIFIER_POINTER (fname)));
8093 obstack_1grow (&util_obstack, '"');
8096 encode_field_decl (field, curtype, format);
8100 static void
8101 encode_aggregate_within (tree type, int curtype, int format, int left,
8102 int right)
8104 tree name;
8105 /* NB: aggregates that are pointed to have slightly different encoding
8106 rules in that you never encode the names of instance variables. */
8107 int ob_size = obstack_object_size (&util_obstack);
8108 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8109 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8110 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8111 int inline_contents
8112 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8113 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8115 /* Traverse struct aliases; it is important to get the
8116 original struct and its tag name (if any). */
8117 type = TYPE_MAIN_VARIANT (type);
8118 name = OBJC_TYPE_NAME (type);
8119 /* Open parenth/bracket. */
8120 obstack_1grow (&util_obstack, left);
8122 /* Encode the struct/union tag name, or '?' if a tag was
8123 not provided. Typedef aliases do not qualify. */
8124 #ifdef OBJCPLUS
8125 /* For compatibility with the NeXT runtime, ObjC++ encodes template
8126 args as a composite struct tag name. */
8127 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8128 /* Did this struct have a tag? */
8129 && !TYPE_WAS_ANONYMOUS (type))
8130 obstack_grow (&util_obstack,
8131 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
8132 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
8133 #else
8134 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
8135 obstack_grow (&util_obstack,
8136 IDENTIFIER_POINTER (name),
8137 strlen (IDENTIFIER_POINTER (name)));
8138 #endif
8139 else
8140 obstack_1grow (&util_obstack, '?');
8142 /* Encode the types (and possibly names) of the inner fields,
8143 if required. */
8144 if (inline_contents)
8146 obstack_1grow (&util_obstack, '=');
8147 encode_aggregate_fields (type, pointed_to, curtype, format);
8149 /* Close parenth/bracket. */
8150 obstack_1grow (&util_obstack, right);
8153 static void
8154 encode_aggregate (tree type, int curtype, int format)
8156 enum tree_code code = TREE_CODE (type);
8158 switch (code)
8160 case RECORD_TYPE:
8162 encode_aggregate_within (type, curtype, format, '{', '}');
8163 break;
8165 case UNION_TYPE:
8167 encode_aggregate_within (type, curtype, format, '(', ')');
8168 break;
8171 case ENUMERAL_TYPE:
8172 obstack_1grow (&util_obstack, 'i');
8173 break;
8175 default:
8176 break;
8180 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8181 field type. */
8183 static void
8184 encode_next_bitfield (int width)
8186 char buffer[40];
8187 sprintf (buffer, "b%d", width);
8188 obstack_grow (&util_obstack, buffer, strlen (buffer));
8191 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8192 static void
8193 encode_type (tree type, int curtype, int format)
8195 enum tree_code code = TREE_CODE (type);
8196 char c;
8198 if (type == error_mark_node)
8199 return;
8201 if (TYPE_READONLY (type))
8202 obstack_1grow (&util_obstack, 'r');
8204 if (code == INTEGER_TYPE)
8206 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8208 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8209 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8210 case 32:
8211 if (type == long_unsigned_type_node
8212 || type == long_integer_type_node)
8213 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8214 else
8215 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8216 break;
8217 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8218 default: abort ();
8220 obstack_1grow (&util_obstack, c);
8223 else if (code == REAL_TYPE)
8225 /* Floating point types. */
8226 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8228 case 32: c = 'f'; break;
8229 case 64:
8230 case 96:
8231 case 128: c = 'd'; break;
8232 default: abort ();
8234 obstack_1grow (&util_obstack, c);
8237 else if (code == VOID_TYPE)
8238 obstack_1grow (&util_obstack, 'v');
8240 else if (code == BOOLEAN_TYPE)
8241 obstack_1grow (&util_obstack, 'B');
8243 else if (code == ARRAY_TYPE)
8244 encode_array (type, curtype, format);
8246 else if (code == POINTER_TYPE)
8247 encode_pointer (type, curtype, format);
8249 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8250 encode_aggregate (type, curtype, format);
8252 else if (code == FUNCTION_TYPE) /* '?' */
8253 obstack_1grow (&util_obstack, '?');
8255 else if (code == COMPLEX_TYPE)
8257 obstack_1grow (&util_obstack, 'j');
8258 encode_type (TREE_TYPE (type), curtype, format);
8262 static void
8263 encode_gnu_bitfield (int position, tree type, int size)
8265 enum tree_code code = TREE_CODE (type);
8266 char buffer[40];
8267 char charType = '?';
8269 if (code == INTEGER_TYPE)
8271 if (integer_zerop (TYPE_MIN_VALUE (type)))
8273 /* Unsigned integer types. */
8275 if (TYPE_MODE (type) == QImode)
8276 charType = 'C';
8277 else if (TYPE_MODE (type) == HImode)
8278 charType = 'S';
8279 else if (TYPE_MODE (type) == SImode)
8281 if (type == long_unsigned_type_node)
8282 charType = 'L';
8283 else
8284 charType = 'I';
8286 else if (TYPE_MODE (type) == DImode)
8287 charType = 'Q';
8290 else
8291 /* Signed integer types. */
8293 if (TYPE_MODE (type) == QImode)
8294 charType = 'c';
8295 else if (TYPE_MODE (type) == HImode)
8296 charType = 's';
8297 else if (TYPE_MODE (type) == SImode)
8299 if (type == long_integer_type_node)
8300 charType = 'l';
8301 else
8302 charType = 'i';
8305 else if (TYPE_MODE (type) == DImode)
8306 charType = 'q';
8309 else if (code == ENUMERAL_TYPE)
8310 charType = 'i';
8311 else
8312 abort ();
8314 sprintf (buffer, "b%d%c%d", position, charType, size);
8315 obstack_grow (&util_obstack, buffer, strlen (buffer));
8318 static void
8319 encode_field_decl (tree field_decl, int curtype, int format)
8321 #ifdef OBJCPLUS
8322 /* C++ static members, and things that are not fields at all,
8323 should not appear in the encoding. */
8324 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8325 return;
8326 #endif
8328 /* Generate the bitfield typing information, if needed. Note the difference
8329 between GNU and NeXT runtimes. */
8330 if (DECL_BIT_FIELD_TYPE (field_decl))
8332 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8334 if (flag_next_runtime)
8335 encode_next_bitfield (size);
8336 else
8337 encode_gnu_bitfield (int_bit_position (field_decl),
8338 DECL_BIT_FIELD_TYPE (field_decl), size);
8340 else
8341 encode_type (TREE_TYPE (field_decl), curtype, format);
8344 static GTY(()) tree objc_parmlist = NULL_TREE;
8346 /* Append PARM to a list of formal parameters of a method, making a necessary
8347 array-to-pointer adjustment along the way. */
8349 static void
8350 objc_push_parm (tree parm)
8352 bool relayout_needed = false;
8354 if (TREE_TYPE (parm) == error_mark_node)
8356 objc_parmlist = chainon (objc_parmlist, parm);
8357 return;
8360 /* Decay arrays and functions into pointers. */
8361 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8363 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8364 relayout_needed = true;
8366 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8368 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8369 relayout_needed = true;
8372 if (relayout_needed)
8373 relayout_decl (parm);
8376 DECL_ARG_TYPE (parm)
8377 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8379 /* Record constancy and volatility. */
8380 c_apply_type_quals_to_decl
8381 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8382 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8383 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8385 objc_parmlist = chainon (objc_parmlist, parm);
8388 /* Retrieve the formal parameter list constructed via preceding calls to
8389 objc_push_parm(). */
8391 #ifdef OBJCPLUS
8392 static tree
8393 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8394 #else
8395 static struct c_arg_info *
8396 objc_get_parm_info (int have_ellipsis)
8397 #endif
8399 #ifdef OBJCPLUS
8400 tree parm_info = objc_parmlist;
8401 objc_parmlist = NULL_TREE;
8403 return parm_info;
8404 #else
8405 tree parm_info = objc_parmlist;
8406 struct c_arg_info *arg_info;
8407 /* The C front-end requires an elaborate song and dance at
8408 this point. */
8409 push_scope ();
8410 declare_parm_level ();
8411 while (parm_info)
8413 tree next = DECL_CHAIN (parm_info);
8415 DECL_CHAIN (parm_info) = NULL_TREE;
8416 parm_info = pushdecl (parm_info);
8417 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
8418 parm_info = next;
8420 arg_info = get_parm_info (have_ellipsis);
8421 pop_scope ();
8422 objc_parmlist = NULL_TREE;
8423 return arg_info;
8424 #endif
8427 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8428 method definitions. In the case of instance methods, we can be more
8429 specific as to the type of 'self'. */
8431 static void
8432 synth_self_and_ucmd_args (void)
8434 tree self_type;
8436 if (objc_method_context
8437 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8438 self_type = objc_instance_type;
8439 else
8440 /* Really a `struct objc_class *'. However, we allow people to
8441 assign to self, which changes its type midstream. */
8442 self_type = objc_object_type;
8444 /* id self; */
8445 objc_push_parm (build_decl (input_location,
8446 PARM_DECL, self_id, self_type));
8448 /* SEL _cmd; */
8449 objc_push_parm (build_decl (input_location,
8450 PARM_DECL, ucmd_id, objc_selector_type));
8453 /* Transform an Objective-C method definition into a static C function
8454 definition, synthesizing the first two arguments, "self" and "_cmd",
8455 in the process. */
8457 static void
8458 start_method_def (tree method)
8460 tree parmlist;
8461 #ifdef OBJCPLUS
8462 tree parm_info;
8463 #else
8464 struct c_arg_info *parm_info;
8465 #endif
8466 int have_ellipsis = 0;
8468 /* If we are defining a "dealloc" method in a non-root class, we
8469 will need to check if a [super dealloc] is missing, and warn if
8470 it is. */
8471 if(CLASS_SUPER_NAME (objc_implementation_context)
8472 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8473 should_call_super_dealloc = 1;
8474 else
8475 should_call_super_dealloc = 0;
8477 /* Required to implement _msgSuper. */
8478 objc_method_context = method;
8479 UOBJC_SUPER_decl = NULL_TREE;
8481 /* Generate prototype declarations for arguments..."new-style". */
8482 synth_self_and_ucmd_args ();
8484 /* Generate argument declarations if a keyword_decl. */
8485 parmlist = METHOD_SEL_ARGS (method);
8486 while (parmlist)
8488 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8490 parm = build_decl (input_location,
8491 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8492 objc_push_parm (parm);
8493 parmlist = DECL_CHAIN (parmlist);
8496 if (METHOD_ADD_ARGS (method))
8498 tree akey;
8500 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8501 akey; akey = TREE_CHAIN (akey))
8503 objc_push_parm (TREE_VALUE (akey));
8506 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8507 have_ellipsis = 1;
8510 parm_info = objc_get_parm_info (have_ellipsis);
8512 really_start_method (objc_method_context, parm_info);
8515 /* Return 1 if TYPE1 is equivalent to TYPE2
8516 for purposes of method overloading. */
8518 static int
8519 objc_types_are_equivalent (tree type1, tree type2)
8521 if (type1 == type2)
8522 return 1;
8524 /* Strip away indirections. */
8525 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8526 && (TREE_CODE (type1) == TREE_CODE (type2)))
8527 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8528 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8529 return 0;
8531 type1 = (TYPE_HAS_OBJC_INFO (type1)
8532 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8533 : NULL_TREE);
8534 type2 = (TYPE_HAS_OBJC_INFO (type2)
8535 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8536 : NULL_TREE);
8538 if (list_length (type1) == list_length (type2))
8540 for (; type2; type2 = TREE_CHAIN (type2))
8541 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8542 return 0;
8543 return 1;
8545 return 0;
8548 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8550 static int
8551 objc_types_share_size_and_alignment (tree type1, tree type2)
8553 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8554 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8557 /* Return 1 if PROTO1 is equivalent to PROTO2
8558 for purposes of method overloading. Ordinarily, the type signatures
8559 should match up exactly, unless STRICT is zero, in which case we
8560 shall allow differences in which the size and alignment of a type
8561 is the same. */
8563 static int
8564 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8566 tree type1, type2;
8568 /* The following test is needed in case there are hashing
8569 collisions. */
8570 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8571 return 0;
8573 /* Compare return types. */
8574 type1 = TREE_VALUE (TREE_TYPE (proto1));
8575 type2 = TREE_VALUE (TREE_TYPE (proto2));
8577 if (!objc_types_are_equivalent (type1, type2)
8578 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8579 return 0;
8581 /* Compare argument types. */
8582 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8583 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8584 type1 && type2;
8585 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8587 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8588 && (strict
8589 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8590 TREE_VALUE (type2))))
8591 return 0;
8594 return (!type1 && !type2);
8597 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8598 this occurs. ObjC method dispatches are _not_ like C++ virtual
8599 member function dispatches, and we account for the difference here. */
8600 tree
8601 #ifdef OBJCPLUS
8602 objc_fold_obj_type_ref (tree ref, tree known_type)
8603 #else
8604 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8605 tree known_type ATTRIBUTE_UNUSED)
8606 #endif
8608 #ifdef OBJCPLUS
8609 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8611 /* If the receiver does not have virtual member functions, there
8612 is nothing we can (or need to) do here. */
8613 if (!v)
8614 return NULL_TREE;
8616 /* Let C++ handle C++ virtual functions. */
8617 return cp_fold_obj_type_ref (ref, known_type);
8618 #else
8619 /* For plain ObjC, we currently do not need to do anything. */
8620 return NULL_TREE;
8621 #endif
8624 static void
8625 objc_start_function (tree name, tree type, tree attrs,
8626 #ifdef OBJCPLUS
8627 tree params
8628 #else
8629 struct c_arg_info *params
8630 #endif
8633 tree fndecl = build_decl (input_location,
8634 FUNCTION_DECL, name, type);
8636 #ifdef OBJCPLUS
8637 DECL_ARGUMENTS (fndecl) = params;
8638 DECL_INITIAL (fndecl) = error_mark_node;
8639 DECL_EXTERNAL (fndecl) = 0;
8640 TREE_STATIC (fndecl) = 1;
8641 retrofit_lang_decl (fndecl);
8642 cplus_decl_attributes (&fndecl, attrs, 0);
8643 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8644 #else
8645 current_function_returns_value = 0; /* Assume, until we see it does. */
8646 current_function_returns_null = 0;
8648 decl_attributes (&fndecl, attrs, 0);
8649 announce_function (fndecl);
8650 DECL_INITIAL (fndecl) = error_mark_node;
8651 DECL_EXTERNAL (fndecl) = 0;
8652 TREE_STATIC (fndecl) = 1;
8653 current_function_decl = pushdecl (fndecl);
8654 push_scope ();
8655 declare_parm_level ();
8656 DECL_RESULT (current_function_decl)
8657 = build_decl (input_location,
8658 RESULT_DECL, NULL_TREE,
8659 TREE_TYPE (TREE_TYPE (current_function_decl)));
8660 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8661 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8662 start_fname_decls ();
8663 store_parm_decls_from (params);
8664 #endif
8666 TREE_USED (current_function_decl) = 1;
8669 /* - Generate an identifier for the function. the format is "_n_cls",
8670 where 1 <= n <= nMethods, and cls is the name the implementation we
8671 are processing.
8672 - Install the return type from the method declaration.
8673 - If we have a prototype, check for type consistency. */
8675 static void
8676 really_start_method (tree method,
8677 #ifdef OBJCPLUS
8678 tree parmlist
8679 #else
8680 struct c_arg_info *parmlist
8681 #endif
8684 tree ret_type, meth_type;
8685 tree method_id;
8686 const char *sel_name, *class_name, *cat_name;
8687 char *buf;
8689 /* Synth the storage class & assemble the return type. */
8690 ret_type = TREE_VALUE (TREE_TYPE (method));
8692 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8693 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8694 cat_name = ((TREE_CODE (objc_implementation_context)
8695 == CLASS_IMPLEMENTATION_TYPE)
8696 ? NULL
8697 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8698 method_slot++;
8700 /* Make sure this is big enough for any plausible method label. */
8701 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8702 + (cat_name ? strlen (cat_name) : 0));
8704 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8705 class_name, cat_name, sel_name, method_slot);
8707 method_id = get_identifier (buf);
8709 #ifdef OBJCPLUS
8710 /* Objective-C methods cannot be overloaded, so we don't need
8711 the type encoding appended. It looks bad anyway... */
8712 push_lang_context (lang_name_c);
8713 #endif
8715 meth_type
8716 = build_function_type (ret_type,
8717 get_arg_type_list (method, METHOD_DEF, 0));
8718 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8720 /* Set self_decl from the first argument. */
8721 self_decl = DECL_ARGUMENTS (current_function_decl);
8723 /* Suppress unused warnings. */
8724 TREE_USED (self_decl) = 1;
8725 DECL_READ_P (self_decl) = 1;
8726 TREE_USED (DECL_CHAIN (self_decl)) = 1;
8727 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
8728 #ifdef OBJCPLUS
8729 pop_lang_context ();
8730 #endif
8732 METHOD_DEFINITION (method) = current_function_decl;
8734 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8736 if (implementation_template != objc_implementation_context)
8738 tree proto
8739 = lookup_method_static (implementation_template,
8740 METHOD_SEL_NAME (method),
8741 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8742 | OBJC_LOOKUP_NO_SUPER));
8744 if (proto)
8746 if (!comp_proto_with_proto (method, proto, 1))
8748 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8750 warning_at (DECL_SOURCE_LOCATION (method), 0,
8751 "conflicting types for %<%c%s%>",
8752 (type ? '-' : '+'),
8753 identifier_to_locale (gen_method_decl (method)));
8754 inform (DECL_SOURCE_LOCATION (proto),
8755 "previous declaration of %<%c%s%>",
8756 (type ? '-' : '+'),
8757 identifier_to_locale (gen_method_decl (proto)));
8760 else
8762 /* We have a method @implementation even though we did not
8763 see a corresponding @interface declaration (which is allowed
8764 by Objective-C rules). Go ahead and place the method in
8765 the @interface anyway, so that message dispatch lookups
8766 will see it. */
8767 tree interface = implementation_template;
8769 if (TREE_CODE (objc_implementation_context)
8770 == CATEGORY_IMPLEMENTATION_TYPE)
8771 interface = lookup_category
8772 (interface,
8773 CLASS_SUPER_NAME (objc_implementation_context));
8775 if (interface)
8776 objc_add_method (interface, copy_node (method),
8777 TREE_CODE (method) == CLASS_METHOD_DECL);
8782 static void *UOBJC_SUPER_scope = 0;
8784 /* _n_Method (id self, SEL sel, ...)
8786 struct objc_super _S;
8787 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8788 } */
8790 static tree
8791 get_super_receiver (void)
8793 if (objc_method_context)
8795 tree super_expr, super_expr_list;
8797 if (!UOBJC_SUPER_decl)
8799 UOBJC_SUPER_decl = build_decl (input_location,
8800 VAR_DECL, get_identifier (TAG_SUPER),
8801 objc_super_template);
8802 /* This prevents `unused variable' warnings when compiling with -Wall. */
8803 TREE_USED (UOBJC_SUPER_decl) = 1;
8804 DECL_READ_P (UOBJC_SUPER_decl) = 1;
8805 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8806 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
8807 NULL_TREE);
8808 UOBJC_SUPER_scope = objc_get_current_scope ();
8811 /* Set receiver to self. */
8812 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8813 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8814 NOP_EXPR, input_location, self_decl,
8815 NULL_TREE);
8816 super_expr_list = super_expr;
8818 /* Set class to begin searching. */
8819 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8820 get_identifier ("super_class"));
8822 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8824 /* [_cls, __cls]Super are "pre-built" in
8825 synth_forward_declarations. */
8827 super_expr = build_modify_expr (input_location, super_expr,
8828 NULL_TREE, NOP_EXPR,
8829 input_location,
8830 ((TREE_CODE (objc_method_context)
8831 == INSTANCE_METHOD_DECL)
8832 ? ucls_super_ref
8833 : uucls_super_ref),
8834 NULL_TREE);
8837 else
8838 /* We have a category. */
8840 tree super_name = CLASS_SUPER_NAME (implementation_template);
8841 tree super_class;
8843 /* Barf if super used in a category of Object. */
8844 if (!super_name)
8846 error ("no super class declared in interface for %qE",
8847 CLASS_NAME (implementation_template));
8848 return error_mark_node;
8851 if (flag_next_runtime && !flag_zero_link)
8853 super_class = objc_get_class_reference (super_name);
8854 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8855 /* If we are in a class method, we must retrieve the
8856 _metaclass_ for the current class, pointed at by
8857 the class's "isa" pointer. The following assumes that
8858 "isa" is the first ivar in a class (which it must be). */
8859 super_class
8860 = build_indirect_ref
8861 (input_location,
8862 build_c_cast (input_location,
8863 build_pointer_type (objc_class_type),
8864 super_class), RO_UNARY_STAR);
8866 else
8868 add_class_reference (super_name);
8869 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8870 ? objc_get_class_decl : objc_get_meta_class_decl);
8871 assemble_external (super_class);
8872 super_class
8873 = build_function_call
8874 (input_location,
8875 super_class,
8876 build_tree_list
8877 (NULL_TREE,
8878 my_build_string_pointer
8879 (IDENTIFIER_LENGTH (super_name) + 1,
8880 IDENTIFIER_POINTER (super_name))));
8883 super_expr
8884 = build_modify_expr (input_location, super_expr, NULL_TREE,
8885 NOP_EXPR,
8886 input_location,
8887 build_c_cast (input_location,
8888 TREE_TYPE (super_expr),
8889 super_class),
8890 NULL_TREE);
8893 super_expr_list = build_compound_expr (input_location,
8894 super_expr_list, super_expr);
8896 super_expr = build_unary_op (input_location,
8897 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8898 super_expr_list = build_compound_expr (input_location,
8899 super_expr_list, super_expr);
8901 return super_expr_list;
8903 else
8905 error ("[super ...] must appear in a method context");
8906 return error_mark_node;
8910 /* When exiting a scope, sever links to a 'super' declaration (if any)
8911 therein contained. */
8913 void
8914 objc_clear_super_receiver (void)
8916 if (objc_method_context
8917 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8918 UOBJC_SUPER_decl = 0;
8919 UOBJC_SUPER_scope = 0;
8923 void
8924 objc_finish_method_definition (tree fndecl)
8926 /* We cannot validly inline ObjC methods, at least not without a language
8927 extension to declare that a method need not be dynamically
8928 dispatched, so suppress all thoughts of doing so. */
8929 DECL_UNINLINABLE (fndecl) = 1;
8931 #ifndef OBJCPLUS
8932 /* The C++ front-end will have called finish_function() for us. */
8933 finish_function ();
8934 #endif
8936 METHOD_ENCODING (objc_method_context)
8937 = encode_method_prototype (objc_method_context);
8939 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8940 since the optimizer may find "may be used before set" errors. */
8941 objc_method_context = NULL_TREE;
8943 if (should_call_super_dealloc)
8944 warning (0, "method possibly missing a [super dealloc] call");
8947 /* Given a tree DECL node, produce a printable description of it in the given
8948 buffer, overwriting the buffer. */
8950 static char *
8951 gen_declaration (tree decl)
8953 errbuf[0] = '\0';
8955 if (DECL_P (decl))
8957 gen_type_name_0 (TREE_TYPE (decl));
8959 if (DECL_NAME (decl))
8961 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8962 strcat (errbuf, " ");
8964 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8967 if (DECL_INITIAL (decl)
8968 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8969 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8970 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8973 return errbuf;
8976 /* Given a tree TYPE node, produce a printable description of it in the given
8977 buffer, overwriting the buffer. */
8979 static char *
8980 gen_type_name_0 (tree type)
8982 tree orig = type, proto;
8984 if (TYPE_P (type) && TYPE_NAME (type))
8985 type = TYPE_NAME (type);
8986 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8988 tree inner = TREE_TYPE (type);
8990 while (TREE_CODE (inner) == ARRAY_TYPE)
8991 inner = TREE_TYPE (inner);
8993 gen_type_name_0 (inner);
8995 if (!POINTER_TYPE_P (inner))
8996 strcat (errbuf, " ");
8998 if (POINTER_TYPE_P (type))
8999 strcat (errbuf, "*");
9000 else
9001 while (type != inner)
9003 strcat (errbuf, "[");
9005 if (TYPE_DOMAIN (type))
9007 char sz[20];
9009 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
9010 (TREE_INT_CST_LOW
9011 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
9012 strcat (errbuf, sz);
9015 strcat (errbuf, "]");
9016 type = TREE_TYPE (type);
9019 goto exit_function;
9022 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
9023 type = DECL_NAME (type);
9025 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
9026 ? IDENTIFIER_POINTER (type)
9027 : "");
9029 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
9030 if (objc_is_id (orig))
9031 orig = TREE_TYPE (orig);
9033 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
9035 if (proto)
9037 strcat (errbuf, " <");
9039 while (proto) {
9040 strcat (errbuf,
9041 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
9042 proto = TREE_CHAIN (proto);
9043 strcat (errbuf, proto ? ", " : ">");
9047 exit_function:
9048 return errbuf;
9051 static char *
9052 gen_type_name (tree type)
9054 errbuf[0] = '\0';
9056 return gen_type_name_0 (type);
9059 /* Given a method tree, put a printable description into the given
9060 buffer (overwriting) and return a pointer to the buffer. */
9062 static char *
9063 gen_method_decl (tree method)
9065 tree chain;
9067 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
9068 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
9069 strcat (errbuf, ")");
9070 chain = METHOD_SEL_ARGS (method);
9072 if (chain)
9074 /* We have a chain of keyword_decls. */
9077 if (KEYWORD_KEY_NAME (chain))
9078 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
9080 strcat (errbuf, ":(");
9081 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9082 strcat (errbuf, ")");
9084 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9085 if ((chain = DECL_CHAIN (chain)))
9086 strcat (errbuf, " ");
9088 while (chain);
9090 if (METHOD_ADD_ARGS (method))
9092 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9094 /* Know we have a chain of parm_decls. */
9095 while (chain)
9097 strcat (errbuf, ", ");
9098 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9099 chain = TREE_CHAIN (chain);
9102 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9103 strcat (errbuf, ", ...");
9107 else
9108 /* We have a unary selector. */
9109 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9111 return errbuf;
9114 /* Debug info. */
9117 /* Dump an @interface declaration of the supplied class CHAIN to the
9118 supplied file FP. Used to implement the -gen-decls option (which
9119 prints out an @interface declaration of all classes compiled in
9120 this run); potentially useful for debugging the compiler too. */
9121 static void
9122 dump_interface (FILE *fp, tree chain)
9124 /* FIXME: A heap overflow here whenever a method (or ivar)
9125 declaration is so long that it doesn't fit in the buffer. The
9126 code and all the related functions should be rewritten to avoid
9127 using fixed size buffers. */
9128 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9129 tree ivar_decls = CLASS_RAW_IVARS (chain);
9130 tree nst_methods = CLASS_NST_METHODS (chain);
9131 tree cls_methods = CLASS_CLS_METHODS (chain);
9133 fprintf (fp, "\n@interface %s", my_name);
9135 /* CLASS_SUPER_NAME is used to store the superclass name for
9136 classes, and the category name for categories. */
9137 if (CLASS_SUPER_NAME (chain))
9139 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9141 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9142 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9144 fprintf (fp, " (%s)\n", name);
9146 else
9148 fprintf (fp, " : %s\n", name);
9151 else
9152 fprintf (fp, "\n");
9154 /* FIXME - the following doesn't seem to work at the moment. */
9155 if (ivar_decls)
9157 fprintf (fp, "{\n");
9160 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9161 ivar_decls = TREE_CHAIN (ivar_decls);
9163 while (ivar_decls);
9164 fprintf (fp, "}\n");
9167 while (nst_methods)
9169 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9170 nst_methods = TREE_CHAIN (nst_methods);
9173 while (cls_methods)
9175 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9176 cls_methods = TREE_CHAIN (cls_methods);
9179 fprintf (fp, "@end\n");
9182 /* Demangle function for Objective-C */
9183 static const char *
9184 objc_demangle (const char *mangled)
9186 char *demangled, *cp;
9188 if (mangled[0] == '_' &&
9189 (mangled[1] == 'i' || mangled[1] == 'c') &&
9190 mangled[2] == '_')
9192 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9193 if (mangled[1] == 'i')
9194 *cp++ = '-'; /* for instance method */
9195 else
9196 *cp++ = '+'; /* for class method */
9197 *cp++ = '['; /* opening left brace */
9198 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9199 while (*cp && *cp == '_')
9200 cp++; /* skip any initial underbars in class name */
9201 cp = strchr(cp, '_'); /* find first non-initial underbar */
9202 if (cp == NULL)
9204 free(demangled); /* not mangled name */
9205 return mangled;
9207 if (cp[1] == '_') /* easy case: no category name */
9209 *cp++ = ' '; /* replace two '_' with one ' ' */
9210 strcpy(cp, mangled + (cp - demangled) + 2);
9212 else
9214 *cp++ = '('; /* less easy case: category name */
9215 cp = strchr(cp, '_');
9216 if (cp == 0)
9218 free(demangled); /* not mangled name */
9219 return mangled;
9221 *cp++ = ')';
9222 *cp++ = ' '; /* overwriting 1st char of method name... */
9223 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9225 while (*cp && *cp == '_')
9226 cp++; /* skip any initial underbars in method name */
9227 for (; *cp; cp++)
9228 if (*cp == '_')
9229 *cp = ':'; /* replace remaining '_' with ':' */
9230 *cp++ = ']'; /* closing right brace */
9231 *cp++ = 0; /* string terminator */
9232 return demangled;
9234 else
9235 return mangled; /* not an objc mangled name */
9238 const char *
9239 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9241 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9244 static void
9245 init_objc (void)
9247 gcc_obstack_init (&util_obstack);
9248 util_firstobj = (char *) obstack_finish (&util_obstack);
9250 errbuf = XNEWVEC (char, 1024 * 10);
9251 hash_init ();
9252 synth_module_prologue ();
9255 static void
9256 finish_objc (void)
9258 struct imp_entry *impent;
9259 tree chain;
9260 /* The internally generated initializers appear to have missing braces.
9261 Don't warn about this. */
9262 int save_warn_missing_braces = warn_missing_braces;
9263 warn_missing_braces = 0;
9265 /* A missing @end may not be detected by the parser. */
9266 if (objc_implementation_context)
9268 warning (0, "%<@end%> missing in implementation context");
9269 finish_class (objc_implementation_context);
9270 objc_ivar_chain = NULL_TREE;
9271 objc_implementation_context = NULL_TREE;
9274 /* Process the static instances here because initialization of objc_symtab
9275 depends on them. */
9276 if (objc_static_instances)
9277 generate_static_references ();
9279 /* forward declare categories */
9280 if (cat_count)
9281 forward_declare_categories ();
9283 for (impent = imp_list; impent; impent = impent->next)
9285 objc_implementation_context = impent->imp_context;
9286 implementation_template = impent->imp_template;
9288 /* FIXME: This needs reworking to be more obvious. */
9290 UOBJC_CLASS_decl = impent->class_decl;
9291 UOBJC_METACLASS_decl = impent->meta_decl;
9293 /* Dump the @interface of each class as we compile it, if the
9294 -gen-decls option is in use. TODO: Dump the classes in the
9295 order they were found, rather than in reverse order as we
9296 are doing now. */
9297 if (flag_gen_declaration)
9299 dump_interface (gen_declaration_file, objc_implementation_context);
9302 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9304 /* all of the following reference the string pool... */
9305 generate_ivar_lists ();
9306 generate_dispatch_tables ();
9307 generate_shared_structures (impent);
9309 else
9311 generate_dispatch_tables ();
9312 generate_category (impent);
9315 impent->class_decl = UOBJC_CLASS_decl;
9316 impent->meta_decl = UOBJC_METACLASS_decl;
9319 /* If we are using an array of selectors, we must always
9320 finish up the array decl even if no selectors were used. */
9321 if (flag_next_runtime)
9322 build_next_selector_translation_table ();
9323 else
9324 build_gnu_selector_translation_table ();
9326 if (protocol_chain)
9327 generate_protocols ();
9329 if (flag_next_runtime)
9330 generate_objc_image_info ();
9332 if (imp_list || class_names_chain
9333 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9334 generate_objc_symtab_decl ();
9336 /* Arrange for ObjC data structures to be initialized at run time. */
9337 if (objc_implementation_context || class_names_chain || objc_static_instances
9338 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9340 build_module_descriptor ();
9342 if (!flag_next_runtime)
9343 build_module_initializer_routine ();
9346 /* Dump the class references. This forces the appropriate classes
9347 to be linked into the executable image, preserving unix archive
9348 semantics. This can be removed when we move to a more dynamically
9349 linked environment. */
9351 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9353 handle_class_ref (chain);
9354 if (TREE_PURPOSE (chain))
9355 generate_classref_translation_entry (chain);
9358 for (impent = imp_list; impent; impent = impent->next)
9359 handle_impent (impent);
9361 if (warn_selector)
9363 int slot;
9364 hash hsh;
9366 /* Run through the selector hash tables and print a warning for any
9367 selector which has multiple methods. */
9369 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9371 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9372 check_duplicates (hsh, 0, 1);
9373 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9374 check_duplicates (hsh, 0, 1);
9378 warn_missing_braces = save_warn_missing_braces;
9381 /* Subroutines of finish_objc. */
9383 static void
9384 generate_classref_translation_entry (tree chain)
9386 tree expr, decl, type;
9388 decl = TREE_PURPOSE (chain);
9389 type = TREE_TYPE (decl);
9391 expr = add_objc_string (TREE_VALUE (chain), class_names);
9392 expr = convert (type, expr); /* cast! */
9394 /* This is a class reference. It is re-written by the runtime,
9395 but will be optimized away unless we force it. */
9396 DECL_PRESERVE_P (decl) = 1;
9397 finish_var_decl (decl, expr);
9398 return;
9401 static void
9402 handle_class_ref (tree chain)
9404 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9405 char *string = (char *) alloca (strlen (name) + 30);
9406 tree decl;
9407 tree exp;
9409 sprintf (string, "%sobjc_class_name_%s",
9410 (flag_next_runtime ? "." : "__"), name);
9412 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9413 if (flag_next_runtime)
9415 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9416 return;
9418 #endif
9420 /* Make a decl for this name, so we can use its address in a tree. */
9421 decl = build_decl (input_location,
9422 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
9423 DECL_EXTERNAL (decl) = 1;
9424 TREE_PUBLIC (decl) = 1;
9425 pushdecl (decl);
9426 finish_var_decl (decl, 0);
9428 /* Make a decl for the address. */
9429 sprintf (string, "%sobjc_class_ref_%s",
9430 (flag_next_runtime ? "." : "__"), name);
9431 exp = build1 (ADDR_EXPR, string_type_node, decl);
9432 decl = build_decl (input_location,
9433 VAR_DECL, get_identifier (string), string_type_node);
9434 TREE_STATIC (decl) = 1;
9435 TREE_USED (decl) = 1;
9436 DECL_READ_P (decl) = 1;
9437 DECL_ARTIFICIAL (decl) = 1;
9438 DECL_INITIAL (decl) = error_mark_node;
9440 /* We must force the reference. */
9441 DECL_PRESERVE_P (decl) = 1;
9443 pushdecl (decl);
9444 finish_var_decl (decl, exp);
9447 static void
9448 handle_impent (struct imp_entry *impent)
9450 char *string;
9452 objc_implementation_context = impent->imp_context;
9453 implementation_template = impent->imp_template;
9455 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9457 const char *const class_name =
9458 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9460 string = (char *) alloca (strlen (class_name) + 30);
9462 sprintf (string, "%sobjc_class_name_%s",
9463 (flag_next_runtime ? "." : "__"), class_name);
9465 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9467 const char *const class_name =
9468 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9469 const char *const class_super_name =
9470 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9472 string = (char *) alloca (strlen (class_name)
9473 + strlen (class_super_name) + 30);
9475 /* Do the same for categories. Even though no references to
9476 these symbols are generated automatically by the compiler, it
9477 gives you a handle to pull them into an archive by hand. */
9478 sprintf (string, "*%sobjc_category_name_%s_%s",
9479 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9481 else
9482 return;
9484 #ifdef ASM_DECLARE_CLASS_REFERENCE
9485 if (flag_next_runtime)
9487 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9488 return;
9490 else
9491 #endif
9493 tree decl, init;
9495 init = integer_zero_node;
9496 decl = build_decl (input_location,
9497 VAR_DECL, get_identifier (string), TREE_TYPE (init));
9498 TREE_PUBLIC (decl) = 1;
9499 TREE_READONLY (decl) = 1;
9500 TREE_USED (decl) = 1;
9501 TREE_CONSTANT (decl) = 1;
9502 DECL_CONTEXT (decl) = NULL_TREE;
9503 DECL_ARTIFICIAL (decl) = 1;
9504 TREE_STATIC (decl) = 1;
9505 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
9506 /* We must force the reference. */
9507 DECL_PRESERVE_P (decl) = 1;
9509 finish_var_decl(decl, init) ;
9513 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9514 later requires that ObjC translation units participating in F&C be
9515 specially marked. The following routine accomplishes this. */
9517 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9519 static void
9520 generate_objc_image_info (void)
9522 tree decl;
9523 int flags
9524 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
9525 | (flag_objc_gc ? 2 : 0));
9526 VEC(constructor_elt,gc) *v = NULL;
9527 tree array_type;
9529 if (!flags)
9530 return; /* No need for an image_info entry. */
9532 array_type = build_sized_array_type (integer_type_node, 2);
9534 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
9536 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
9537 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
9538 /* If we need this (determined above) it is because the runtime wants to
9539 refer to it in a manner hidden from the compiler. So we must force the
9540 output. */
9541 DECL_PRESERVE_P (decl) = 1;
9542 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
9545 /* Look up ID as an instance variable. OTHER contains the result of
9546 the C or C++ lookup, which we may want to use instead. */
9548 tree
9549 objc_lookup_ivar (tree other, tree id)
9551 tree ivar;
9553 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9554 if (!objc_method_context)
9555 return other;
9557 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9558 /* We have a message to super. */
9559 return get_super_receiver ();
9561 /* In a class method, look up an instance variable only as a last
9562 resort. */
9563 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9564 && other && other != error_mark_node)
9565 return other;
9567 /* Look up the ivar, but do not use it if it is not accessible. */
9568 ivar = is_ivar (objc_ivar_chain, id);
9570 if (!ivar || is_private (ivar))
9571 return other;
9573 /* In an instance method, a local variable (or parameter) may hide the
9574 instance variable. */
9575 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9576 && other && other != error_mark_node
9577 #ifdef OBJCPLUS
9578 && CP_DECL_CONTEXT (other) != global_namespace)
9579 #else
9580 && !DECL_FILE_SCOPE_P (other))
9581 #endif
9583 warning (0, "local declaration of %qE hides instance variable",
9584 id);
9586 return other;
9589 /* At this point, we are either in an instance method with no obscuring
9590 local definitions, or in a class method with no alternate definitions
9591 at all. */
9592 return build_ivar_reference (id);
9595 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9596 needs to be done if we are calling a function through a cast. */
9598 tree
9599 objc_rewrite_function_call (tree function, tree first_param)
9601 if (TREE_CODE (function) == NOP_EXPR
9602 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9603 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9604 == FUNCTION_DECL)
9606 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9607 TREE_OPERAND (function, 0),
9608 first_param, size_zero_node);
9611 return function;
9614 /* Look for the special case of OBJC_TYPE_REF with the address of
9615 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9616 of its cousins). */
9619 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9621 enum gimplify_status r0, r1;
9622 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9623 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9624 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9625 == FUNCTION_DECL)
9627 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9628 value of the OBJ_TYPE_REF, so force them to be emitted
9629 during subexpression evaluation rather than after the
9630 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9631 C to use direct rather than indirect calls when the
9632 object expression has a postincrement. */
9633 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9634 is_gimple_val, fb_rvalue);
9635 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9636 is_gimple_val, fb_rvalue);
9638 return MIN (r0, r1);
9641 #ifdef OBJCPLUS
9642 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9643 #else
9644 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9645 #endif
9648 #include "gt-objc-objc-act.h"