2010-07-27 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc/alias-decl.git] / gcc / objc / objc-act.c
blob81aba84eb9742b23432f30419fe6e88f11e804a2
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/>. */
24 /* Purpose: This module implements the Objective-C 4.0 language.
26 compatibility issues (with the Stepstone translator):
28 - does not recognize the following 3.3 constructs.
29 @requires, @classes, @messages, = (...)
30 - methods with variable arguments must conform to ANSI standard.
31 - tagged structure definitions that appear in BOTH the interface
32 and implementation are not allowed.
33 - public/private: all instance variables are public within the
34 context of the implementation...I consider this to be a bug in
35 the translator.
36 - statically allocated objects are not supported. the user will
37 receive an error if this service is requested.
39 code generation `options':
43 #include "config.h"
44 #include "system.h"
45 #include "coretypes.h"
46 #include "tm.h"
47 #include "tree.h"
49 #ifdef OBJCPLUS
50 #include "cp-tree.h"
51 #else
52 #include "c-tree.h"
53 #include "c-lang.h"
54 #endif
56 #include "c-family/c-common.h"
57 #include "c-family/c-pragma.h"
58 #include "flags.h"
59 #include "langhooks.h"
60 #include "objc-act.h"
61 #include "input.h"
62 #include "function.h"
63 #include "output.h"
64 #include "toplev.h"
65 #include "ggc.h"
66 #include "debug.h"
67 #include "target.h"
68 #include "diagnostic-core.h"
69 #include "intl.h"
70 #include "cgraph.h"
71 #include "tree-iterator.h"
72 #include "hashtab.h"
73 #include "langhooks-def.h"
75 /* For enum gimplify_status */
76 #include "gimple.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we need in_late_binary_op. */
83 #ifdef OBJCPLUS
84 bool in_late_binary_op = false;
85 #endif /* OBJCPLUS */
87 /* When building Objective-C++, we are not linking against the C front-end
88 and so need to replicate the C tree-construction functions in some way. */
89 #ifdef OBJCPLUS
90 #define OBJCP_REMAP_FUNCTIONS
91 #include "objcp-decl.h"
92 #endif /* OBJCPLUS */
94 /* This is the default way of generating a method name. */
95 /* I am not sure it is really correct.
96 Perhaps there's a danger that it will make name conflicts
97 if method names contain underscores. -- rms. */
98 #ifndef OBJC_GEN_METHOD_LABEL
99 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
100 do { \
101 char *temp; \
102 sprintf ((BUF), "_%s_%s_%s_%s", \
103 ((IS_INST) ? "i" : "c"), \
104 (CLASS_NAME), \
105 ((CAT_NAME)? (CAT_NAME) : ""), \
106 (SEL_NAME)); \
107 for (temp = (BUF); *temp; temp++) \
108 if (*temp == ':') *temp = '_'; \
109 } while (0)
110 #endif
112 /* These need specifying. */
113 #ifndef OBJC_FORWARDING_STACK_OFFSET
114 #define OBJC_FORWARDING_STACK_OFFSET 0
115 #endif
117 #ifndef OBJC_FORWARDING_MIN_OFFSET
118 #define OBJC_FORWARDING_MIN_OFFSET 0
119 #endif
121 /* Set up for use of obstacks. */
123 #include "obstack.h"
125 /* This obstack is used to accumulate the encoding of a data type. */
126 static struct obstack util_obstack;
128 /* This points to the beginning of obstack contents, so we can free
129 the whole contents. */
130 char *util_firstobj;
132 /* The version identifies which language generation and runtime
133 the module (file) was compiled for, and is recorded in the
134 module descriptor. */
136 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
137 #define PROTOCOL_VERSION 2
139 /* (Decide if these can ever be validly changed.) */
140 #define OBJC_ENCODE_INLINE_DEFS 0
141 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
143 /*** Private Interface (procedures) ***/
145 /* Used by compile_file. */
147 static void init_objc (void);
148 static void finish_objc (void);
150 /* Code generation. */
152 static tree objc_build_constructor (tree, VEC(constructor_elt,gc) *);
153 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
154 static tree get_proto_encoding (tree);
155 static tree lookup_interface (tree);
156 static tree objc_add_static_instance (tree, tree);
158 static tree start_class (enum tree_code, tree, tree, tree);
159 static tree continue_class (tree);
160 static void finish_class (tree);
161 static void start_method_def (tree);
162 #ifdef OBJCPLUS
163 static void objc_start_function (tree, tree, tree, tree);
164 #else
165 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
166 #endif
167 static tree start_protocol (enum tree_code, tree, tree);
168 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
169 static tree objc_add_method (tree, tree, int);
170 static tree add_instance_variable (tree, int, tree);
171 static tree build_ivar_reference (tree);
172 static tree is_ivar (tree, tree);
174 static void build_objc_exception_stuff (void);
175 static void build_next_objc_exception_stuff (void);
177 /* We only need the following for ObjC; ObjC++ will use C++'s definition
178 of DERIVED_FROM_P. */
179 #ifndef OBJCPLUS
180 static bool objc_derived_from_p (tree, tree);
181 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
182 #endif
183 static void objc_xref_basetypes (tree, tree);
185 static void build_class_template (void);
186 static void build_selector_template (void);
187 static void build_category_template (void);
188 static void build_super_template (void);
189 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
190 static tree get_class_ivars (tree, bool);
191 static tree generate_protocol_list (tree);
192 static void build_protocol_reference (tree);
194 #ifdef OBJCPLUS
195 static void objc_generate_cxx_cdtors (void);
196 #endif
198 static const char *synth_id_with_class_suffix (const char *, tree);
200 /* Hash tables to manage the global pool of method prototypes. */
202 hash *nst_method_hash_list = 0;
203 hash *cls_method_hash_list = 0;
205 static hash hash_lookup (hash *, tree);
206 static tree lookup_method (tree, tree);
207 static tree lookup_method_static (tree, tree, int);
209 enum string_section
211 class_names, /* class, category, protocol, module names */
212 meth_var_names, /* method and variable names */
213 meth_var_types /* method and variable type descriptors */
216 static tree add_objc_string (tree, enum string_section);
217 static void build_selector_table_decl (void);
219 /* Protocol additions. */
221 static tree lookup_protocol (tree);
222 static tree lookup_and_install_protocols (tree);
224 /* Type encoding. */
226 static void encode_type_qualifiers (tree);
227 static void encode_type (tree, int, int);
228 static void encode_field_decl (tree, int, int);
230 #ifdef OBJCPLUS
231 static void really_start_method (tree, tree);
232 #else
233 static void really_start_method (tree, struct c_arg_info *);
234 #endif
235 static int comp_proto_with_proto (tree, tree, int);
236 static void objc_push_parm (tree);
237 #ifdef OBJCPLUS
238 static tree objc_get_parm_info (int);
239 #else
240 static struct c_arg_info *objc_get_parm_info (int);
241 #endif
243 /* Utilities for debugging and error diagnostics. */
245 static char *gen_type_name (tree);
246 static char *gen_type_name_0 (tree);
247 static char *gen_method_decl (tree);
248 static char *gen_declaration (tree);
250 /* Everything else. */
252 static tree create_field_decl (tree, const char *);
253 static void add_class_reference (tree);
254 static void build_protocol_template (void);
255 static tree encode_method_prototype (tree);
256 static void generate_classref_translation_entry (tree);
257 static void handle_class_ref (tree);
258 static void generate_struct_by_value_array (void)
259 ATTRIBUTE_NORETURN;
260 static void mark_referenced_methods (void);
261 static void generate_objc_image_info (void);
263 /*** Private Interface (data) ***/
265 /* Reserved tag definitions. */
267 #define OBJECT_TYPEDEF_NAME "id"
268 #define CLASS_TYPEDEF_NAME "Class"
270 #define TAG_OBJECT "objc_object"
271 #define TAG_CLASS "objc_class"
272 #define TAG_SUPER "objc_super"
273 #define TAG_SELECTOR "objc_selector"
275 #define UTAG_CLASS "_objc_class"
276 #define UTAG_IVAR "_objc_ivar"
277 #define UTAG_IVAR_LIST "_objc_ivar_list"
278 #define UTAG_METHOD "_objc_method"
279 #define UTAG_METHOD_LIST "_objc_method_list"
280 #define UTAG_CATEGORY "_objc_category"
281 #define UTAG_MODULE "_objc_module"
282 #define UTAG_SYMTAB "_objc_symtab"
283 #define UTAG_SUPER "_objc_super"
284 #define UTAG_SELECTOR "_objc_selector"
286 #define UTAG_PROTOCOL "_objc_protocol"
287 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
288 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
290 /* Note that the string object global name is only needed for the
291 NeXT runtime. */
292 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
294 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
296 static const char *TAG_GETCLASS;
297 static const char *TAG_GETMETACLASS;
298 static const char *TAG_MSGSEND;
299 static const char *TAG_MSGSENDSUPER;
300 /* The NeXT Objective-C messenger may have two extra entry points, for use
301 when returning a structure. */
302 static const char *TAG_MSGSEND_STRET;
303 static const char *TAG_MSGSENDSUPER_STRET;
304 static const char *default_constant_string_class_name;
306 /* Runtime metadata flags. */
307 #define CLS_FACTORY 0x0001L
308 #define CLS_META 0x0002L
309 #define CLS_HAS_CXX_STRUCTORS 0x2000L
311 #define OBJC_MODIFIER_STATIC 0x00000001
312 #define OBJC_MODIFIER_FINAL 0x00000002
313 #define OBJC_MODIFIER_PUBLIC 0x00000004
314 #define OBJC_MODIFIER_PRIVATE 0x00000008
315 #define OBJC_MODIFIER_PROTECTED 0x00000010
316 #define OBJC_MODIFIER_NATIVE 0x00000020
317 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
318 #define OBJC_MODIFIER_ABSTRACT 0x00000080
319 #define OBJC_MODIFIER_VOLATILE 0x00000100
320 #define OBJC_MODIFIER_TRANSIENT 0x00000200
321 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
323 /* NeXT-specific tags. */
325 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
326 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
327 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
328 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
329 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
330 #define TAG_EXCEPTIONMATCH "objc_exception_match"
331 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
332 #define TAG_SYNCENTER "objc_sync_enter"
333 #define TAG_SYNCEXIT "objc_sync_exit"
334 #define TAG_SETJMP "_setjmp"
335 #define UTAG_EXCDATA "_objc_exception_data"
337 #define TAG_ASSIGNIVAR "objc_assign_ivar"
338 #define TAG_ASSIGNGLOBAL "objc_assign_global"
339 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
341 /* Branch entry points. All that matters here are the addresses;
342 functions with these names do not really exist in libobjc. */
344 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
345 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
347 #define TAG_CXX_CONSTRUCT ".cxx_construct"
348 #define TAG_CXX_DESTRUCT ".cxx_destruct"
350 /* GNU-specific tags. */
352 #define TAG_EXECCLASS "__objc_exec_class"
353 #define TAG_GNUINIT "__objc_gnu_init"
355 /* Flags for lookup_method_static(). */
356 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
357 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
359 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
360 tree objc_global_trees[OCTI_MAX];
362 static void handle_impent (struct imp_entry *);
364 struct imp_entry *imp_list = 0;
365 int imp_count = 0; /* `@implementation' */
366 int cat_count = 0; /* `@category' */
368 enum tree_code objc_inherit_code;
369 int objc_public_flag;
371 /* Use to generate method labels. */
372 static int method_slot = 0;
374 #define BUFSIZE 1024
376 static char *errbuf; /* Buffer for error diagnostics */
378 /* Data imported from tree.c. */
380 extern enum debug_info_type write_symbols;
382 /* Data imported from toplev.c. */
384 extern const char *dump_base_name;
386 static int flag_typed_selectors;
388 /* Store all constructed constant strings in a hash table so that
389 they get uniqued properly. */
391 struct GTY(()) string_descriptor {
392 /* The literal argument . */
393 tree literal;
395 /* The resulting constant string. */
396 tree constructor;
399 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
401 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
402 struct GTY(()) volatilized_type {
403 tree type;
406 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
408 FILE *gen_declaration_file;
410 /* Tells "encode_pointer/encode_aggregate" whether we are generating
411 type descriptors for instance variables (as opposed to methods).
412 Type descriptors for instance variables contain more information
413 than methods (for static typing and embedded structures). */
415 static int generating_instance_variables = 0;
417 /* For building an objc struct. These may not be used when this file
418 is compiled as part of obj-c++. */
420 static bool objc_building_struct;
421 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
423 /* Start building a struct for objc. */
425 static tree
426 objc_start_struct (tree name)
428 gcc_assert (!objc_building_struct);
429 objc_building_struct = true;
430 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
433 /* Finish building a struct for objc. */
435 static tree
436 objc_finish_struct (tree type, tree fieldlist)
438 gcc_assert (objc_building_struct);
439 objc_building_struct = false;
440 return finish_struct (input_location, type, fieldlist, NULL_TREE,
441 objc_struct_info);
444 static tree
445 build_sized_array_type (tree base_type, int size)
447 tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
448 return build_array_type (base_type, index_type);
451 static tree
452 add_field_decl (tree type, const char *name, tree **chain)
454 tree field = create_field_decl (type, name);
456 if (*chain != NULL)
457 **chain = field;
458 *chain = &DECL_CHAIN (field);
460 return field;
463 /* Some platforms pass small structures through registers versus
464 through an invisible pointer. Determine at what size structure is
465 the transition point between the two possibilities. */
467 static void
468 generate_struct_by_value_array (void)
470 tree type;
471 tree decls;
472 int i, j;
473 int aggregate_in_mem[32];
474 int found = 0;
476 /* Presumably no platform passes 32 byte structures in a register. */
477 for (i = 1; i < 32; i++)
479 char buffer[5];
480 tree *chain = NULL;
482 /* Create an unnamed struct that has `i' character components */
483 type = objc_start_struct (NULL_TREE);
485 strcpy (buffer, "c1");
486 decls = add_field_decl (char_type_node, buffer, &chain);
488 for (j = 1; j < i; j++)
490 sprintf (buffer, "c%d", j + 1);
491 add_field_decl (char_type_node, buffer, &chain);
493 objc_finish_struct (type, decls);
495 aggregate_in_mem[i] = aggregate_value_p (type, 0);
496 if (!aggregate_in_mem[i])
497 found = 1;
500 /* We found some structures that are returned in registers instead of memory
501 so output the necessary data. */
502 if (found)
504 for (i = 31; i >= 0; i--)
505 if (!aggregate_in_mem[i])
506 break;
507 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
509 /* The first member of the structure is always 0 because we don't handle
510 structures with 0 members */
511 printf ("static int struct_forward_array[] = {\n 0");
513 for (j = 1; j <= i; j++)
514 printf (", %d", aggregate_in_mem[j]);
515 printf ("\n};\n");
518 exit (0);
521 bool
522 objc_init (void)
524 #ifdef OBJCPLUS
525 if (cxx_init () == false)
526 #else
527 if (c_objc_common_init () == false)
528 #endif
529 return false;
531 /* If gen_declaration desired, open the output file. */
532 if (flag_gen_declaration)
534 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
535 gen_declaration_file = fopen (dumpname, "w");
536 if (gen_declaration_file == 0)
537 fatal_error ("can't open %s: %m", dumpname);
538 free (dumpname);
541 if (flag_next_runtime)
543 TAG_GETCLASS = "objc_getClass";
544 TAG_GETMETACLASS = "objc_getMetaClass";
545 TAG_MSGSEND = "objc_msgSend";
546 TAG_MSGSENDSUPER = "objc_msgSendSuper";
547 TAG_MSGSEND_STRET = "objc_msgSend_stret";
548 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
549 default_constant_string_class_name = "NSConstantString";
551 else
553 TAG_GETCLASS = "objc_get_class";
554 TAG_GETMETACLASS = "objc_get_meta_class";
555 TAG_MSGSEND = "objc_msg_lookup";
556 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
557 /* GNU runtime does not provide special functions to support
558 structure-returning methods. */
559 default_constant_string_class_name = "NXConstantString";
560 flag_typed_selectors = 1;
561 /* GNU runtime does not need the compiler to change code
562 in order to do GC. */
563 if (flag_objc_gc)
565 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
566 flag_objc_gc=0;
570 init_objc ();
572 if (print_struct_values && !flag_compare_debug)
573 generate_struct_by_value_array ();
575 return true;
578 void
579 objc_finish_file (void)
581 mark_referenced_methods ();
583 #ifdef OBJCPLUS
584 /* We need to instantiate templates _before_ we emit ObjC metadata;
585 if we do not, some metadata (such as selectors) may go missing. */
586 at_eof = 1;
587 instantiate_pending_templates (0);
588 #endif
590 /* Finalize Objective-C runtime data. No need to generate tables
591 and code if only checking syntax, or if generating a PCH file. */
592 if (!flag_syntax_only && !pch_file)
593 finish_objc ();
595 if (gen_declaration_file)
596 fclose (gen_declaration_file);
599 /* Return the first occurrence of a method declaration corresponding
600 to sel_name in rproto_list. Search rproto_list recursively.
601 If is_class is 0, search for instance methods, otherwise for class
602 methods. */
603 static tree
604 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
605 int is_class)
607 tree rproto, p;
608 tree fnd = 0;
610 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
612 p = TREE_VALUE (rproto);
614 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
616 if ((fnd = lookup_method (is_class
617 ? PROTOCOL_CLS_METHODS (p)
618 : PROTOCOL_NST_METHODS (p), sel_name)))
620 else if (PROTOCOL_LIST (p))
621 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
622 sel_name, is_class);
624 else
626 ; /* An identifier...if we could not find a protocol. */
629 if (fnd)
630 return fnd;
633 return 0;
636 static tree
637 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
639 tree rproto, p;
641 /* Make sure the protocol is supported by the object on the rhs. */
642 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
644 tree fnd = 0;
645 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
647 p = TREE_VALUE (rproto);
649 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
651 if (lproto == p)
652 fnd = lproto;
654 else if (PROTOCOL_LIST (p))
655 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
658 if (fnd)
659 return fnd;
662 else
664 ; /* An identifier...if we could not find a protocol. */
667 return 0;
670 void
671 objc_start_class_interface (tree klass, tree super_class, tree protos)
673 objc_interface_context
674 = objc_ivar_context
675 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
676 objc_public_flag = 0;
679 void
680 objc_start_category_interface (tree klass, tree categ, tree protos)
682 objc_interface_context
683 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
684 objc_ivar_chain
685 = continue_class (objc_interface_context);
688 void
689 objc_start_protocol (tree name, tree protos)
691 objc_interface_context
692 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
695 void
696 objc_continue_interface (void)
698 objc_ivar_chain
699 = continue_class (objc_interface_context);
702 void
703 objc_finish_interface (void)
705 finish_class (objc_interface_context);
706 objc_interface_context = NULL_TREE;
709 void
710 objc_start_class_implementation (tree klass, tree super_class)
712 objc_implementation_context
713 = objc_ivar_context
714 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
715 objc_public_flag = 0;
718 void
719 objc_start_category_implementation (tree klass, tree categ)
721 objc_implementation_context
722 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
723 objc_ivar_chain
724 = continue_class (objc_implementation_context);
727 void
728 objc_continue_implementation (void)
730 objc_ivar_chain
731 = continue_class (objc_implementation_context);
734 void
735 objc_finish_implementation (void)
737 #ifdef OBJCPLUS
738 if (flag_objc_call_cxx_cdtors)
739 objc_generate_cxx_cdtors ();
740 #endif
742 if (objc_implementation_context)
744 finish_class (objc_implementation_context);
745 objc_ivar_chain = NULL_TREE;
746 objc_implementation_context = NULL_TREE;
748 else
749 warning (0, "%<@end%> must appear in an @implementation context");
752 void
753 objc_set_visibility (int visibility)
755 objc_public_flag = visibility;
758 void
759 objc_set_method_type (enum tree_code type)
761 objc_inherit_code = (type == PLUS_EXPR
762 ? CLASS_METHOD_DECL
763 : INSTANCE_METHOD_DECL);
766 tree
767 objc_build_method_signature (tree rettype, tree selector,
768 tree optparms, bool ellipsis)
770 return build_method_decl (objc_inherit_code, rettype, selector,
771 optparms, ellipsis);
774 void
775 objc_add_method_declaration (tree decl)
777 if (!objc_interface_context)
778 fatal_error ("method declaration not in @interface context");
780 objc_add_method (objc_interface_context,
781 decl,
782 objc_inherit_code == CLASS_METHOD_DECL);
785 void
786 objc_start_method_definition (tree decl)
788 if (!objc_implementation_context)
789 fatal_error ("method definition not in @implementation context");
791 objc_add_method (objc_implementation_context,
792 decl,
793 objc_inherit_code == CLASS_METHOD_DECL);
794 start_method_def (decl);
797 void
798 objc_add_instance_variable (tree decl)
800 (void) add_instance_variable (objc_ivar_context,
801 objc_public_flag,
802 decl);
805 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
806 an '@'. */
809 objc_is_reserved_word (tree ident)
811 unsigned char code = C_RID_CODE (ident);
813 return (OBJC_IS_AT_KEYWORD (code)
814 || code == RID_CLASS || code == RID_PUBLIC
815 || code == RID_PROTECTED || code == RID_PRIVATE
816 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
819 /* Return true if TYPE is 'id'. */
821 static bool
822 objc_is_object_id (tree type)
824 return OBJC_TYPE_NAME (type) == objc_object_id;
827 static bool
828 objc_is_class_id (tree type)
830 return OBJC_TYPE_NAME (type) == objc_class_id;
833 /* Construct a C struct with same name as KLASS, a base struct with tag
834 SUPER_NAME (if any), and FIELDS indicated. */
836 static tree
837 objc_build_struct (tree klass, tree fields, tree super_name)
839 tree name = CLASS_NAME (klass);
840 tree s = objc_start_struct (name);
841 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
842 tree t;
843 VEC(tree,heap) *objc_info = NULL;
844 int i;
846 if (super)
848 /* Prepend a packed variant of the base class into the layout. This
849 is necessary to preserve ObjC ABI compatibility. */
850 tree base = build_decl (input_location,
851 FIELD_DECL, NULL_TREE, super);
852 tree field = TYPE_FIELDS (super);
854 while (field && DECL_CHAIN (field)
855 && TREE_CODE (DECL_CHAIN (field)) == FIELD_DECL)
856 field = DECL_CHAIN (field);
858 /* For ObjC ABI purposes, the "packed" size of a base class is
859 the sum of the offset and the size (in bits) of the last field
860 in the class. */
861 DECL_SIZE (base)
862 = (field && TREE_CODE (field) == FIELD_DECL
863 ? size_binop (PLUS_EXPR,
864 size_binop (PLUS_EXPR,
865 size_binop
866 (MULT_EXPR,
867 convert (bitsizetype,
868 DECL_FIELD_OFFSET (field)),
869 bitsize_int (BITS_PER_UNIT)),
870 DECL_FIELD_BIT_OFFSET (field)),
871 DECL_SIZE (field))
872 : bitsize_zero_node);
873 DECL_SIZE_UNIT (base)
874 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
875 size_int (BITS_PER_UNIT));
876 DECL_ARTIFICIAL (base) = 1;
877 DECL_ALIGN (base) = 1;
878 DECL_FIELD_CONTEXT (base) = s;
879 #ifdef OBJCPLUS
880 DECL_FIELD_IS_BASE (base) = 1;
882 if (fields)
883 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
884 #endif /* are following the ObjC ABI here. */
885 DECL_CHAIN (base) = fields;
886 fields = base;
889 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
890 in all variants of this RECORD_TYPE to be clobbered, but it is therein
891 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
892 Hence, we must squirrel away the ObjC-specific information before calling
893 finish_struct(), and then reinstate it afterwards. */
895 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
897 if (!TYPE_HAS_OBJC_INFO (t))
899 INIT_TYPE_OBJC_INFO (t);
900 TYPE_OBJC_INTERFACE (t) = klass;
902 VEC_safe_push (tree, heap, objc_info, TYPE_OBJC_INFO (t));
905 /* Point the struct at its related Objective-C class. */
906 INIT_TYPE_OBJC_INFO (s);
907 TYPE_OBJC_INTERFACE (s) = klass;
909 s = objc_finish_struct (s, fields);
911 for (i = 0, t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t), i++)
913 TYPE_OBJC_INFO (t) = VEC_index (tree, objc_info, i);
914 /* Replace the IDENTIFIER_NODE with an actual @interface. */
915 TYPE_OBJC_INTERFACE (t) = klass;
917 VEC_free (tree, heap, objc_info);
919 /* Use TYPE_BINFO structures to point at the super class, if any. */
920 objc_xref_basetypes (s, super);
922 /* Mark this struct as a class template. */
923 CLASS_STATIC_TEMPLATE (klass) = s;
925 return s;
928 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
929 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
930 process. */
931 static tree
932 objc_build_volatilized_type (tree type)
934 tree t;
936 /* Check if we have not constructed the desired variant already. */
937 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
939 /* The type qualifiers must (obviously) match up. */
940 if (!TYPE_VOLATILE (t)
941 || (TYPE_READONLY (t) != TYPE_READONLY (type))
942 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
943 continue;
945 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
946 info, if any) must match up. */
947 if (POINTER_TYPE_P (t)
948 && (TREE_TYPE (t) != TREE_TYPE (type)))
949 continue;
951 /* Everything matches up! */
952 return t;
955 /* Ok, we could not re-use any of the pre-existing variants. Create
956 a new one. */
957 t = build_variant_type_copy (type);
958 TYPE_VOLATILE (t) = 1;
960 /* Set up the canonical type information. */
961 if (TYPE_STRUCTURAL_EQUALITY_P (type))
962 SET_TYPE_STRUCTURAL_EQUALITY (t);
963 else if (TYPE_CANONICAL (type) != type)
964 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
965 else
966 TYPE_CANONICAL (t) = t;
968 return t;
971 /* Mark DECL as being 'volatile' for purposes of Darwin
972 _setjmp()/_longjmp() exception handling. Called from
973 objc_mark_locals_volatile(). */
974 void
975 objc_volatilize_decl (tree decl)
977 /* Do not mess with variables that are 'static' or (already)
978 'volatile'. */
979 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
980 && (TREE_CODE (decl) == VAR_DECL
981 || TREE_CODE (decl) == PARM_DECL))
983 tree t = TREE_TYPE (decl);
984 struct volatilized_type key;
985 void **loc;
987 t = objc_build_volatilized_type (t);
988 key.type = t;
989 loc = htab_find_slot (volatilized_htab, &key, INSERT);
991 if (!*loc)
993 *loc = ggc_alloc_volatilized_type ();
994 ((struct volatilized_type *) *loc)->type = t;
997 TREE_TYPE (decl) = t;
998 TREE_THIS_VOLATILE (decl) = 1;
999 TREE_SIDE_EFFECTS (decl) = 1;
1000 DECL_REGISTER (decl) = 0;
1001 #ifndef OBJCPLUS
1002 C_DECL_REGISTER (decl) = 0;
1003 #endif
1007 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
1008 (including its categories and superclasses) or by object type TYP.
1009 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
1011 static bool
1012 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
1014 bool class_type = (cls != NULL_TREE);
1016 while (cls)
1018 tree c;
1020 /* Check protocols adopted by the class and its categories. */
1021 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1023 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1024 return true;
1027 /* Repeat for superclasses. */
1028 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1031 /* Check for any protocols attached directly to the object type. */
1032 if (TYPE_HAS_OBJC_INFO (typ))
1034 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1035 return true;
1038 if (warn)
1040 *errbuf = 0;
1041 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1042 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1043 "implementing" a given protocol, since they do not have an
1044 implementation. */
1045 if (class_type)
1046 warning (0, "class %qs does not implement the %qE protocol",
1047 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1048 else
1049 warning (0, "type %qs does not conform to the %qE protocol",
1050 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1053 return false;
1056 /* Check if class RCLS and instance struct type RTYP conform to at least the
1057 same protocols that LCLS and LTYP conform to. */
1059 static bool
1060 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1062 tree p;
1063 bool have_lproto = false;
1065 while (lcls)
1067 /* NB: We do _not_ look at categories defined for LCLS; these may or
1068 may not get loaded in, and therefore it is unreasonable to require
1069 that RCLS/RTYP must implement any of their protocols. */
1070 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1072 have_lproto = true;
1074 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1075 return warn;
1078 /* Repeat for superclasses. */
1079 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1082 /* Check for any protocols attached directly to the object type. */
1083 if (TYPE_HAS_OBJC_INFO (ltyp))
1085 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1087 have_lproto = true;
1089 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1090 return warn;
1094 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1095 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1096 away with simply checking for 'id' or 'Class' (!RCLS), since this
1097 routine will not get called in other cases. */
1098 return have_lproto || (rcls != NULL_TREE);
1101 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1102 an instance of RTYP to an instance of LTYP or to compare the two
1103 (if ARGNO is equal to -3), per ObjC type system rules. Before
1104 returning 'true', this routine may issue warnings related to, e.g.,
1105 protocol conformance. When returning 'false', the routine must
1106 produce absolutely no warnings; the C or C++ front-end will do so
1107 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1108 the routine must return 'false'.
1110 The ARGNO parameter is encoded as follows:
1111 >= 1 Parameter number (CALLEE contains function being called);
1112 0 Return value;
1113 -1 Assignment;
1114 -2 Initialization;
1115 -3 Comparison (LTYP and RTYP may match in either direction). */
1117 bool
1118 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1120 tree lcls, rcls, lproto, rproto;
1121 bool pointers_compatible;
1123 /* We must be dealing with pointer types */
1124 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1125 return false;
1129 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1130 rtyp = TREE_TYPE (rtyp);
1132 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1134 /* Past this point, we are only interested in ObjC class instances,
1135 or 'id' or 'Class'. */
1136 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1137 return false;
1139 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1140 && !TYPE_HAS_OBJC_INFO (ltyp))
1141 return false;
1143 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1144 && !TYPE_HAS_OBJC_INFO (rtyp))
1145 return false;
1147 /* Past this point, we are committed to returning 'true' to the caller.
1148 However, we can still warn about type and/or protocol mismatches. */
1150 if (TYPE_HAS_OBJC_INFO (ltyp))
1152 lcls = TYPE_OBJC_INTERFACE (ltyp);
1153 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1155 else
1156 lcls = lproto = NULL_TREE;
1158 if (TYPE_HAS_OBJC_INFO (rtyp))
1160 rcls = TYPE_OBJC_INTERFACE (rtyp);
1161 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1163 else
1164 rcls = rproto = NULL_TREE;
1166 /* If we could not find an @interface declaration, we must have
1167 only seen a @class declaration; for purposes of type comparison,
1168 treat it as a stand-alone (root) class. */
1170 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1171 lcls = NULL_TREE;
1173 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1174 rcls = NULL_TREE;
1176 /* If either type is an unqualified 'id', we're done. */
1177 if ((!lproto && objc_is_object_id (ltyp))
1178 || (!rproto && objc_is_object_id (rtyp)))
1179 return true;
1181 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1183 /* If the underlying types are the same, and at most one of them has
1184 a protocol list, we do not need to issue any diagnostics. */
1185 if (pointers_compatible && (!lproto || !rproto))
1186 return true;
1188 /* If exactly one of the types is 'Class', issue a diagnostic; any
1189 exceptions of this rule have already been handled. */
1190 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1191 pointers_compatible = false;
1192 /* Otherwise, check for inheritance relations. */
1193 else
1195 if (!pointers_compatible)
1196 pointers_compatible
1197 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1199 if (!pointers_compatible)
1200 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1202 if (!pointers_compatible && argno == -3)
1203 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1206 /* If the pointers match modulo protocols, check for protocol conformance
1207 mismatches. */
1208 if (pointers_compatible)
1210 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1211 argno != -3);
1213 if (!pointers_compatible && argno == -3)
1214 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1215 argno != -3);
1218 if (!pointers_compatible)
1220 /* NB: For the time being, we shall make our warnings look like their
1221 C counterparts. In the future, we may wish to make them more
1222 ObjC-specific. */
1223 switch (argno)
1225 case -3:
1226 warning (0, "comparison of distinct Objective-C types lacks a cast");
1227 break;
1229 case -2:
1230 warning (0, "initialization from distinct Objective-C type");
1231 break;
1233 case -1:
1234 warning (0, "assignment from distinct Objective-C type");
1235 break;
1237 case 0:
1238 warning (0, "distinct Objective-C type in return");
1239 break;
1241 default:
1242 warning (0, "passing argument %d of %qE from distinct "
1243 "Objective-C type", argno, callee);
1244 break;
1248 return true;
1251 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1252 lives in the volatilized hash table, ignore the 'volatile' bit when
1253 making the comparison. */
1255 bool
1256 objc_type_quals_match (tree ltyp, tree rtyp)
1258 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1259 struct volatilized_type key;
1261 key.type = ltyp;
1263 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1264 lquals &= ~TYPE_QUAL_VOLATILE;
1266 key.type = rtyp;
1268 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1269 rquals &= ~TYPE_QUAL_VOLATILE;
1271 return (lquals == rquals);
1274 #ifndef OBJCPLUS
1275 /* Determine if CHILD is derived from PARENT. The routine assumes that
1276 both parameters are RECORD_TYPEs, and is non-reflexive. */
1278 static bool
1279 objc_derived_from_p (tree parent, tree child)
1281 parent = TYPE_MAIN_VARIANT (parent);
1283 for (child = TYPE_MAIN_VARIANT (child);
1284 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1286 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1287 (TYPE_BINFO (child),
1288 0)));
1290 if (child == parent)
1291 return true;
1294 return false;
1296 #endif
1298 static tree
1299 objc_build_component_ref (tree datum, tree component)
1301 /* If COMPONENT is NULL, the caller is referring to the anonymous
1302 base class field. */
1303 if (!component)
1305 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1307 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1310 /* The 'build_component_ref' routine has been removed from the C++
1311 front-end, but 'finish_class_member_access_expr' seems to be
1312 a worthy substitute. */
1313 #ifdef OBJCPLUS
1314 return finish_class_member_access_expr (datum, component, false,
1315 tf_warning_or_error);
1316 #else
1317 return build_component_ref (input_location, datum, component);
1318 #endif
1321 /* Recursively copy inheritance information rooted at BINFO. To do this,
1322 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1324 static tree
1325 objc_copy_binfo (tree binfo)
1327 tree btype = BINFO_TYPE (binfo);
1328 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1329 tree base_binfo;
1330 int ix;
1332 BINFO_TYPE (binfo2) = btype;
1333 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1334 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1336 /* Recursively copy base binfos of BINFO. */
1337 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1339 tree base_binfo2 = objc_copy_binfo (base_binfo);
1341 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1342 BINFO_BASE_APPEND (binfo2, base_binfo2);
1345 return binfo2;
1348 /* Record superclass information provided in BASETYPE for ObjC class REF.
1349 This is loosely based on cp/decl.c:xref_basetypes(). */
1351 static void
1352 objc_xref_basetypes (tree ref, tree basetype)
1354 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1356 TYPE_BINFO (ref) = binfo;
1357 BINFO_OFFSET (binfo) = size_zero_node;
1358 BINFO_TYPE (binfo) = ref;
1360 if (basetype)
1362 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1364 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1365 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1366 BINFO_BASE_APPEND (binfo, base_binfo);
1367 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1371 static hashval_t
1372 volatilized_hash (const void *ptr)
1374 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1376 return htab_hash_pointer(typ);
1379 static int
1380 volatilized_eq (const void *ptr1, const void *ptr2)
1382 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1383 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1385 return typ1 == typ2;
1388 /* Called from finish_decl. */
1390 void
1391 objc_check_decl (tree decl)
1393 tree type = TREE_TYPE (decl);
1395 if (TREE_CODE (type) != RECORD_TYPE)
1396 return;
1397 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1398 error ("statically allocated instance of Objective-C class %qE",
1399 type);
1402 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1403 either name an Objective-C class, or refer to the special 'id' or 'Class'
1404 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1406 tree
1407 objc_get_protocol_qualified_type (tree interface, tree protocols)
1409 /* If INTERFACE is not provided, default to 'id'. */
1410 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1411 bool is_ptr = (type != NULL_TREE);
1413 if (!is_ptr)
1415 type = objc_is_class_name (interface);
1417 if (type)
1418 type = xref_tag (RECORD_TYPE, type);
1419 else
1420 return interface;
1423 if (protocols)
1425 type = build_variant_type_copy (type);
1427 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1428 to the pointee. */
1429 if (is_ptr)
1431 tree orig_pointee_type = TREE_TYPE (type);
1432 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1434 /* Set up the canonical type information. */
1435 TYPE_CANONICAL (type)
1436 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1438 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1439 type = TREE_TYPE (type);
1442 /* Look up protocols and install in lang specific list. */
1443 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1444 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1446 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1447 return the pointer to the new pointee variant. */
1448 if (is_ptr)
1449 type = TYPE_POINTER_TO (type);
1450 else
1451 TYPE_OBJC_INTERFACE (type)
1452 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1455 return type;
1458 /* Check for circular dependencies in protocols. The arguments are
1459 PROTO, the protocol to check, and LIST, a list of protocol it
1460 conforms to. */
1462 static void
1463 check_protocol_recursively (tree proto, tree list)
1465 tree p;
1467 for (p = list; p; p = TREE_CHAIN (p))
1469 tree pp = TREE_VALUE (p);
1471 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1472 pp = lookup_protocol (pp);
1474 if (pp == proto)
1475 fatal_error ("protocol %qE has circular dependency",
1476 PROTOCOL_NAME (pp));
1477 if (pp)
1478 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1482 /* Look up PROTOCOLS, and return a list of those that are found.
1483 If none are found, return NULL. */
1485 static tree
1486 lookup_and_install_protocols (tree protocols)
1488 tree proto;
1489 tree return_value = NULL_TREE;
1491 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1493 tree ident = TREE_VALUE (proto);
1494 tree p = lookup_protocol (ident);
1496 if (p)
1497 return_value = chainon (return_value,
1498 build_tree_list (NULL_TREE, p));
1499 else if (ident != error_mark_node)
1500 error ("cannot find protocol declaration for %qE",
1501 ident);
1504 return return_value;
1507 /* Create a declaration for field NAME of a given TYPE. */
1509 static tree
1510 create_field_decl (tree type, const char *name)
1512 return build_decl (input_location,
1513 FIELD_DECL, get_identifier (name), type);
1516 /* Create a global, static declaration for variable NAME of a given TYPE. The
1517 finish_var_decl() routine will need to be called on it afterwards. */
1519 static tree
1520 start_var_decl (tree type, const char *name)
1522 tree var = build_decl (input_location,
1523 VAR_DECL, get_identifier (name), type);
1525 TREE_STATIC (var) = 1;
1526 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1527 DECL_IGNORED_P (var) = 1;
1528 DECL_ARTIFICIAL (var) = 1;
1529 DECL_CONTEXT (var) = NULL_TREE;
1530 #ifdef OBJCPLUS
1531 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1532 #endif
1534 return var;
1537 /* Finish off the variable declaration created by start_var_decl(). */
1539 static void
1540 finish_var_decl (tree var, tree initializer)
1542 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
1545 /* Find the decl for the constant string class reference. This is only
1546 used for the NeXT runtime. */
1548 static tree
1549 setup_string_decl (void)
1551 char *name;
1552 size_t length;
1554 /* %s in format will provide room for terminating null */
1555 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1556 + strlen (constant_string_class_name);
1557 name = XNEWVEC (char, length);
1558 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1559 constant_string_class_name);
1560 constant_string_global_id = get_identifier (name);
1561 string_class_decl = lookup_name (constant_string_global_id);
1563 return string_class_decl;
1566 /* Purpose: "play" parser, creating/installing representations
1567 of the declarations that are required by Objective-C.
1569 Model:
1571 type_spec--------->sc_spec
1572 (tree_list) (tree_list)
1575 identifier_node identifier_node */
1577 static void
1578 synth_module_prologue (void)
1580 tree type;
1581 enum debug_info_type save_write_symbols = write_symbols;
1582 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1584 /* Suppress outputting debug symbols, because
1585 dbxout_init hasn't been called yet. */
1586 write_symbols = NO_DEBUG;
1587 debug_hooks = &do_nothing_debug_hooks;
1589 #ifdef OBJCPLUS
1590 push_lang_context (lang_name_c); /* extern "C" */
1591 #endif
1593 /* The following are also defined in <objc/objc.h> and friends. */
1595 objc_object_id = get_identifier (TAG_OBJECT);
1596 objc_class_id = get_identifier (TAG_CLASS);
1598 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1599 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1601 objc_object_type = build_pointer_type (objc_object_reference);
1602 objc_class_type = build_pointer_type (objc_class_reference);
1604 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1605 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1607 /* Declare the 'id' and 'Class' typedefs. */
1609 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1610 TYPE_DECL,
1611 objc_object_name,
1612 objc_object_type));
1613 TREE_NO_WARNING (type) = 1;
1614 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1615 TYPE_DECL,
1616 objc_class_name,
1617 objc_class_type));
1618 TREE_NO_WARNING (type) = 1;
1620 /* Forward-declare '@interface Protocol'. */
1622 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1623 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1624 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1625 type));
1627 /* Declare type of selector-objects that represent an operation name. */
1629 if (flag_next_runtime)
1630 /* `struct objc_selector *' */
1631 objc_selector_type
1632 = build_pointer_type (xref_tag (RECORD_TYPE,
1633 get_identifier (TAG_SELECTOR)));
1634 else
1635 /* `const struct objc_selector *' */
1636 objc_selector_type
1637 = build_pointer_type
1638 (build_qualified_type (xref_tag (RECORD_TYPE,
1639 get_identifier (TAG_SELECTOR)),
1640 TYPE_QUAL_CONST));
1642 /* Declare receiver type used for dispatching messages to 'super'. */
1644 /* `struct objc_super *' */
1645 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1646 get_identifier (TAG_SUPER)));
1648 /* Declare pointers to method and ivar lists. */
1649 objc_method_list_ptr = build_pointer_type
1650 (xref_tag (RECORD_TYPE,
1651 get_identifier (UTAG_METHOD_LIST)));
1652 objc_method_proto_list_ptr
1653 = build_pointer_type (xref_tag (RECORD_TYPE,
1654 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1655 objc_ivar_list_ptr = build_pointer_type
1656 (xref_tag (RECORD_TYPE,
1657 get_identifier (UTAG_IVAR_LIST)));
1659 /* TREE_NOTHROW is cleared for the message-sending functions,
1660 because the function that gets called can throw in Obj-C++, or
1661 could itself call something that can throw even in Obj-C. */
1663 if (flag_next_runtime)
1665 /* NB: In order to call one of the ..._stret (struct-returning)
1666 functions, the function *MUST* first be cast to a signature that
1667 corresponds to the actual ObjC method being invoked. This is
1668 what is done by the build_objc_method_call() routine below. */
1670 /* id objc_msgSend (id, SEL, ...); */
1671 /* id objc_msgSendNonNil (id, SEL, ...); */
1672 /* id objc_msgSend_stret (id, SEL, ...); */
1673 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1674 type
1675 = build_varargs_function_type_list (objc_object_type,
1676 objc_object_type,
1677 objc_selector_type,
1678 NULL_TREE);
1679 umsg_decl = add_builtin_function (TAG_MSGSEND,
1680 type, 0, NOT_BUILT_IN,
1681 NULL, NULL_TREE);
1682 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1683 type, 0, NOT_BUILT_IN,
1684 NULL, NULL_TREE);
1685 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1686 type, 0, NOT_BUILT_IN,
1687 NULL, NULL_TREE);
1688 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1689 type, 0, NOT_BUILT_IN,
1690 NULL, NULL_TREE);
1692 /* These can throw, because the function that gets called can throw
1693 in Obj-C++, or could itself call something that can throw even
1694 in Obj-C. */
1695 TREE_NOTHROW (umsg_decl) = 0;
1696 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1697 TREE_NOTHROW (umsg_stret_decl) = 0;
1698 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1700 /* id objc_msgSend_Fast (id, SEL, ...)
1701 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1702 #ifdef OFFS_MSGSEND_FAST
1703 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1704 type, 0, NOT_BUILT_IN,
1705 NULL, NULL_TREE);
1706 TREE_NOTHROW (umsg_fast_decl) = 0;
1707 DECL_ATTRIBUTES (umsg_fast_decl)
1708 = tree_cons (get_identifier ("hard_coded_address"),
1709 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1710 NULL_TREE);
1711 #else
1712 /* No direct dispatch available. */
1713 umsg_fast_decl = umsg_decl;
1714 #endif
1716 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1717 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1718 type
1719 = build_varargs_function_type_list (objc_object_type,
1720 objc_super_type,
1721 objc_selector_type,
1722 NULL_TREE);
1723 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1724 type, 0, NOT_BUILT_IN,
1725 NULL, NULL_TREE);
1726 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1727 type, 0, NOT_BUILT_IN, 0,
1728 NULL_TREE);
1729 TREE_NOTHROW (umsg_super_decl) = 0;
1730 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1732 else
1734 /* GNU runtime messenger entry points. */
1736 /* typedef id (*IMP)(id, SEL, ...); */
1737 tree ftype =
1738 build_varargs_function_type_list (objc_object_type,
1739 objc_object_type,
1740 objc_selector_type,
1741 NULL_TREE);
1742 tree IMP_type = build_pointer_type (ftype);
1744 /* IMP objc_msg_lookup (id, SEL); */
1745 type = build_function_type_list (IMP_type,
1746 objc_object_type,
1747 objc_selector_type,
1748 NULL_TREE);
1749 umsg_decl = add_builtin_function (TAG_MSGSEND,
1750 type, 0, NOT_BUILT_IN,
1751 NULL, NULL_TREE);
1752 TREE_NOTHROW (umsg_decl) = 0;
1754 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1755 type
1756 = build_function_type_list (IMP_type,
1757 objc_super_type,
1758 objc_selector_type,
1759 NULL_TREE);
1760 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1761 type, 0, NOT_BUILT_IN,
1762 NULL, NULL_TREE);
1763 TREE_NOTHROW (umsg_super_decl) = 0;
1765 /* The following GNU runtime entry point is called to initialize
1766 each module:
1768 __objc_exec_class (void *); */
1769 type
1770 = build_function_type_list (void_type_node,
1771 ptr_type_node,
1772 NULL_TREE);
1773 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1774 type, 0, NOT_BUILT_IN,
1775 NULL, NULL_TREE);
1778 /* id objc_getClass (const char *); */
1780 type = build_function_type_list (objc_object_type,
1781 const_string_type_node,
1782 NULL_TREE);
1784 objc_get_class_decl
1785 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1786 NULL, NULL_TREE);
1788 /* id objc_getMetaClass (const char *); */
1790 objc_get_meta_class_decl
1791 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1793 build_class_template ();
1794 build_super_template ();
1795 build_protocol_template ();
1796 build_category_template ();
1797 build_objc_exception_stuff ();
1799 if (flag_next_runtime)
1800 build_next_objc_exception_stuff ();
1802 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1804 if (! flag_next_runtime)
1805 build_selector_table_decl ();
1807 /* Forward declare constant_string_id and constant_string_type. */
1808 if (!constant_string_class_name)
1809 constant_string_class_name = default_constant_string_class_name;
1811 constant_string_id = get_identifier (constant_string_class_name);
1812 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1814 /* Pre-build the following entities - for speed/convenience. */
1815 self_id = get_identifier ("self");
1816 ucmd_id = get_identifier ("_cmd");
1818 #ifdef OBJCPLUS
1819 pop_lang_context ();
1820 #endif
1822 write_symbols = save_write_symbols;
1823 debug_hooks = save_hooks;
1826 /* Ensure that the ivar list for NSConstantString/NXConstantString
1827 (or whatever was specified via `-fconstant-string-class')
1828 contains fields at least as large as the following three, so that
1829 the runtime can stomp on them with confidence:
1831 struct STRING_OBJECT_CLASS_NAME
1833 Object isa;
1834 char *cString;
1835 unsigned int length;
1836 }; */
1838 static int
1839 check_string_class_template (void)
1841 tree field_decl = objc_get_class_ivars (constant_string_id);
1843 #define AT_LEAST_AS_LARGE_AS(F, T) \
1844 (F && TREE_CODE (F) == FIELD_DECL \
1845 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1846 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1848 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1849 return 0;
1851 field_decl = DECL_CHAIN (field_decl);
1852 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1853 return 0;
1855 field_decl = DECL_CHAIN (field_decl);
1856 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1858 #undef AT_LEAST_AS_LARGE_AS
1861 /* Avoid calling `check_string_class_template ()' more than once. */
1862 static GTY(()) int string_layout_checked;
1864 /* Construct an internal string layout to be used as a template for
1865 creating NSConstantString/NXConstantString instances. */
1867 static tree
1868 objc_build_internal_const_str_type (void)
1870 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1871 tree fields = build_decl (input_location,
1872 FIELD_DECL, NULL_TREE, ptr_type_node);
1873 tree field = build_decl (input_location,
1874 FIELD_DECL, NULL_TREE, ptr_type_node);
1876 DECL_CHAIN (field) = fields; fields = field;
1877 field = build_decl (input_location,
1878 FIELD_DECL, NULL_TREE, unsigned_type_node);
1879 DECL_CHAIN (field) = fields; fields = field;
1880 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1881 reverse order! */
1882 finish_builtin_struct (type, "__builtin_ObjCString",
1883 fields, NULL_TREE);
1885 return type;
1888 /* Custom build_string which sets TREE_TYPE! */
1890 static tree
1891 my_build_string (int len, const char *str)
1893 return fix_string_type (build_string (len, str));
1896 /* Build a string with contents STR and length LEN and convert it to a
1897 pointer. */
1899 static tree
1900 my_build_string_pointer (int len, const char *str)
1902 tree string = my_build_string (len, str);
1903 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1904 return build1 (ADDR_EXPR, ptrtype, string);
1907 static hashval_t
1908 string_hash (const void *ptr)
1910 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1911 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1912 int i, len = TREE_STRING_LENGTH (str);
1913 hashval_t h = len;
1915 for (i = 0; i < len; i++)
1916 h = ((h * 613) + p[i]);
1918 return h;
1921 static int
1922 string_eq (const void *ptr1, const void *ptr2)
1924 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1925 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1926 int len1 = TREE_STRING_LENGTH (str1);
1928 return (len1 == TREE_STRING_LENGTH (str2)
1929 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1930 len1));
1933 /* Given a chain of STRING_CST's, build a static instance of
1934 NXConstantString which points at the concatenation of those
1935 strings. We place the string object in the __string_objects
1936 section of the __OBJC segment. The Objective-C runtime will
1937 initialize the isa pointers of the string objects to point at the
1938 NXConstantString class object. */
1940 tree
1941 objc_build_string_object (tree string)
1943 tree constructor, constant_string_class;
1944 int length;
1945 tree fields, addr;
1946 struct string_descriptor *desc, key;
1947 void **loc;
1949 /* Prep the string argument. */
1950 string = fix_string_type (string);
1951 TREE_SET_CODE (string, STRING_CST);
1952 length = TREE_STRING_LENGTH (string) - 1;
1954 /* Check whether the string class being used actually exists and has the
1955 correct ivar layout. */
1956 if (!string_layout_checked)
1958 string_layout_checked = -1;
1959 constant_string_class = lookup_interface (constant_string_id);
1960 internal_const_str_type = objc_build_internal_const_str_type ();
1962 if (!constant_string_class
1963 || !(constant_string_type
1964 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1965 error ("cannot find interface declaration for %qE",
1966 constant_string_id);
1967 /* The NSConstantString/NXConstantString ivar layout is now known. */
1968 else if (!check_string_class_template ())
1969 error ("interface %qE does not have valid constant string layout",
1970 constant_string_id);
1971 /* For the NeXT runtime, we can generate a literal reference
1972 to the string class, don't need to run a constructor. */
1973 else if (flag_next_runtime && !setup_string_decl ())
1974 error ("cannot find reference tag for class %qE",
1975 constant_string_id);
1976 else
1978 string_layout_checked = 1; /* Success! */
1979 add_class_reference (constant_string_id);
1983 if (string_layout_checked == -1)
1984 return error_mark_node;
1986 /* Perhaps we already constructed a constant string just like this one? */
1987 key.literal = string;
1988 loc = htab_find_slot (string_htab, &key, INSERT);
1989 desc = (struct string_descriptor *) *loc;
1991 if (!desc)
1993 tree var;
1994 VEC(constructor_elt,gc) *v = NULL;
1995 *loc = desc = ggc_alloc_string_descriptor ();
1996 desc->literal = string;
1998 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1999 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
2000 fields = TYPE_FIELDS (internal_const_str_type);
2001 CONSTRUCTOR_APPEND_ELT (v, fields,
2002 flag_next_runtime
2003 ? build_unary_op (input_location,
2004 ADDR_EXPR, string_class_decl, 0)
2005 : build_int_cst (NULL_TREE, 0));
2006 fields = DECL_CHAIN (fields);
2007 CONSTRUCTOR_APPEND_ELT (v, fields,
2008 build_unary_op (input_location,
2009 ADDR_EXPR, string, 1));
2010 fields = DECL_CHAIN (fields);
2011 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
2012 constructor = objc_build_constructor (internal_const_str_type, v);
2014 if (!flag_next_runtime)
2015 constructor
2016 = objc_add_static_instance (constructor, constant_string_type);
2017 else
2019 var = build_decl (input_location,
2020 CONST_DECL, NULL, TREE_TYPE (constructor));
2021 DECL_INITIAL (var) = constructor;
2022 TREE_STATIC (var) = 1;
2023 pushdecl_top_level (var);
2024 constructor = var;
2026 desc->constructor = constructor;
2029 addr = convert (build_pointer_type (constant_string_type),
2030 build_unary_op (input_location,
2031 ADDR_EXPR, desc->constructor, 1));
2033 return addr;
2036 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2038 static GTY(()) int num_static_inst;
2040 static tree
2041 objc_add_static_instance (tree constructor, tree class_decl)
2043 tree *chain, decl;
2044 char buf[256];
2046 /* Find the list of static instances for the CLASS_DECL. Create one if
2047 not found. */
2048 for (chain = &objc_static_instances;
2049 *chain && TREE_VALUE (*chain) != class_decl;
2050 chain = &TREE_CHAIN (*chain));
2051 if (!*chain)
2053 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2054 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2057 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2058 decl = build_decl (input_location,
2059 VAR_DECL, get_identifier (buf), class_decl);
2060 TREE_STATIC (decl) = 1;
2061 DECL_ARTIFICIAL (decl) = 1;
2062 TREE_USED (decl) = 1;
2063 DECL_INITIAL (decl) = constructor;
2065 /* We may be writing something else just now.
2066 Postpone till end of input. */
2067 DECL_DEFER_OUTPUT (decl) = 1;
2068 pushdecl_top_level (decl);
2069 rest_of_decl_compilation (decl, 1, 0);
2071 /* Add the DECL to the head of this CLASS' list. */
2072 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2074 return decl;
2077 /* Build a static constant CONSTRUCTOR
2078 with type TYPE and elements ELTS. */
2080 static tree
2081 objc_build_constructor (tree type, VEC(constructor_elt,gc) *elts)
2083 tree constructor = build_constructor (type, elts);
2085 TREE_CONSTANT (constructor) = 1;
2086 TREE_STATIC (constructor) = 1;
2087 TREE_READONLY (constructor) = 1;
2089 #ifdef OBJCPLUS
2090 /* Adjust for impedance mismatch. We should figure out how to build
2091 CONSTRUCTORs that consistently please both the C and C++ gods. */
2092 if (!VEC_index (constructor_elt, elts, 0)->index)
2093 TREE_TYPE (constructor) = init_list_type_node;
2094 #endif
2096 return constructor;
2099 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2101 /* Predefine the following data type:
2103 struct _objc_symtab
2105 long sel_ref_cnt;
2106 SEL *refs;
2107 short cls_def_cnt;
2108 short cat_def_cnt;
2109 void *defs[cls_def_cnt + cat_def_cnt];
2110 }; */
2112 static void
2113 build_objc_symtab_template (void)
2115 tree fields, *chain = NULL;
2117 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2119 /* long sel_ref_cnt; */
2120 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
2122 /* SEL *refs; */
2123 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
2125 /* short cls_def_cnt; */
2126 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
2128 /* short cat_def_cnt; */
2129 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2131 if (imp_count || cat_count || !flag_next_runtime)
2133 /* void *defs[imp_count + cat_count (+ 1)]; */
2134 /* NB: The index is one less than the size of the array. */
2135 int index = imp_count + cat_count + (flag_next_runtime ? -1: 0);
2136 tree array_type = build_sized_array_type (ptr_type_node, index + 1);
2137 add_field_decl (array_type, "defs", &chain);
2140 objc_finish_struct (objc_symtab_template, fields);
2143 /* Create the initial value for the `defs' field of _objc_symtab.
2144 This is a CONSTRUCTOR. */
2146 static tree
2147 init_def_list (tree type)
2149 tree expr;
2150 struct imp_entry *impent;
2151 VEC(constructor_elt,gc) *v = NULL;
2153 if (imp_count)
2154 for (impent = imp_list; impent; impent = impent->next)
2156 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2158 expr = build_unary_op (input_location,
2159 ADDR_EXPR, impent->class_decl, 0);
2160 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2164 if (cat_count)
2165 for (impent = imp_list; impent; impent = impent->next)
2167 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2169 expr = build_unary_op (input_location,
2170 ADDR_EXPR, impent->class_decl, 0);
2171 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2175 if (!flag_next_runtime)
2177 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2178 if (static_instances_decl)
2179 expr = build_unary_op (input_location,
2180 ADDR_EXPR, static_instances_decl, 0);
2181 else
2182 expr = integer_zero_node;
2184 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2187 return objc_build_constructor (type, v);
2190 /* Construct the initial value for all of _objc_symtab. */
2192 static tree
2193 init_objc_symtab (tree type)
2195 VEC(constructor_elt,gc) *v = NULL;
2197 /* sel_ref_cnt = { ..., 5, ... } */
2199 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2200 build_int_cst (long_integer_type_node, 0));
2202 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2204 if (flag_next_runtime || ! sel_ref_chain)
2205 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (
2206 build_pointer_type (objc_selector_type),
2207 integer_zero_node));
2208 else
2210 tree expr = build_unary_op (input_location, ADDR_EXPR,
2211 UOBJC_SELECTOR_TABLE_decl, 1);
2213 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2214 convert (build_pointer_type (objc_selector_type),
2215 expr));
2218 /* cls_def_cnt = { ..., 5, ... } */
2220 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2221 build_int_cst (short_integer_type_node, imp_count));
2223 /* cat_def_cnt = { ..., 5, ... } */
2225 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2226 build_int_cst (short_integer_type_node, cat_count));
2228 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2230 if (imp_count || cat_count || !flag_next_runtime)
2233 tree field = TYPE_FIELDS (type);
2234 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2236 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2239 return objc_build_constructor (type, v);
2242 /* Generate forward declarations for metadata such as
2243 'OBJC_CLASS_...'. */
2245 static tree
2246 build_metadata_decl (const char *name, tree type)
2248 tree decl;
2250 /* struct TYPE NAME_<name>; */
2251 decl = start_var_decl (type, synth_id_with_class_suffix
2252 (name,
2253 objc_implementation_context));
2255 return decl;
2258 /* Push forward-declarations of all the categories so that
2259 init_def_list can use them in a CONSTRUCTOR. */
2261 static void
2262 forward_declare_categories (void)
2264 struct imp_entry *impent;
2265 tree sav = objc_implementation_context;
2267 for (impent = imp_list; impent; impent = impent->next)
2269 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2271 /* Set an invisible arg to synth_id_with_class_suffix. */
2272 objc_implementation_context = impent->imp_context;
2273 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2274 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2275 objc_category_template);
2278 objc_implementation_context = sav;
2281 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2282 and initialized appropriately. */
2284 static void
2285 generate_objc_symtab_decl (void)
2288 build_objc_symtab_template ();
2289 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2290 finish_var_decl (UOBJC_SYMBOLS_decl,
2291 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2294 static tree
2295 init_module_descriptor (tree type)
2297 tree expr;
2298 VEC(constructor_elt,gc) *v = NULL;
2300 /* version = { 1, ... } */
2302 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2303 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2305 /* size = { ..., sizeof (struct _objc_module), ... } */
2307 expr = convert (long_integer_type_node,
2308 size_in_bytes (objc_module_template));
2309 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2311 /* Don't provide any file name for security reasons. */
2312 /* name = { ..., "", ... } */
2314 expr = add_objc_string (get_identifier (""), class_names);
2315 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2317 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2319 if (UOBJC_SYMBOLS_decl)
2320 expr = build_unary_op (input_location,
2321 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2322 else
2323 expr = null_pointer_node;
2324 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2326 return objc_build_constructor (type, v);
2329 /* Write out the data structures to describe Objective C classes defined.
2331 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2333 static void
2334 build_module_descriptor (void)
2336 tree decls, *chain = NULL;
2338 #ifdef OBJCPLUS
2339 push_lang_context (lang_name_c); /* extern "C" */
2340 #endif
2342 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2344 /* long version; */
2345 decls = add_field_decl (long_integer_type_node, "version", &chain);
2347 /* long size; */
2348 add_field_decl (long_integer_type_node, "size", &chain);
2350 /* char *name; */
2351 add_field_decl (string_type_node, "name", &chain);
2353 /* struct _objc_symtab *symtab; */
2354 add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
2355 get_identifier (UTAG_SYMTAB))),
2356 "symtab", &chain);
2358 objc_finish_struct (objc_module_template, decls);
2360 /* Create an instance of "_objc_module". */
2361 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2362 /* This is the root of the metadata for defined classes and categories, it
2363 is referenced by the runtime and, therefore, needed. */
2364 DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
2365 finish_var_decl (UOBJC_MODULES_decl,
2366 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2368 #ifdef OBJCPLUS
2369 pop_lang_context ();
2370 #endif
2373 /* The GNU runtime requires us to provide a static initializer function
2374 for each module:
2376 static void __objc_gnu_init (void) {
2377 __objc_exec_class (&L_OBJC_MODULES);
2378 } */
2380 static void
2381 build_module_initializer_routine (void)
2383 tree body;
2385 #ifdef OBJCPLUS
2386 push_lang_context (lang_name_c); /* extern "C" */
2387 #endif
2389 objc_push_parm (build_decl (input_location,
2390 PARM_DECL, NULL_TREE, void_type_node));
2391 #ifdef OBJCPLUS
2392 objc_start_function (get_identifier (TAG_GNUINIT),
2393 build_function_type_list (void_type_node, NULL_TREE),
2394 NULL_TREE, NULL_TREE);
2395 #else
2396 objc_start_function (get_identifier (TAG_GNUINIT),
2397 build_function_type_list (void_type_node, NULL_TREE),
2398 NULL_TREE, objc_get_parm_info (0));
2399 #endif
2400 body = c_begin_compound_stmt (true);
2401 add_stmt (build_function_call
2402 (input_location,
2403 execclass_decl,
2404 build_tree_list
2405 (NULL_TREE,
2406 build_unary_op (input_location, ADDR_EXPR,
2407 UOBJC_MODULES_decl, 0))));
2408 add_stmt (c_end_compound_stmt (input_location, body, true));
2410 TREE_PUBLIC (current_function_decl) = 0;
2412 #ifndef OBJCPLUS
2413 /* For Objective-C++, we will need to call __objc_gnu_init
2414 from objc_generate_static_init_call() below. */
2415 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2416 #endif
2418 GNU_INIT_decl = current_function_decl;
2419 finish_function ();
2421 #ifdef OBJCPLUS
2422 pop_lang_context ();
2423 #endif
2426 #ifdef OBJCPLUS
2427 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2428 to be called by the module initializer routine. */
2431 objc_static_init_needed_p (void)
2433 return (GNU_INIT_decl != NULL_TREE);
2436 /* Generate a call to the __objc_gnu_init initializer function. */
2438 tree
2439 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2441 add_stmt (build_stmt (input_location, EXPR_STMT,
2442 build_function_call (input_location,
2443 GNU_INIT_decl, NULL_TREE)));
2445 return ctors;
2447 #endif /* OBJCPLUS */
2449 /* Return the DECL of the string IDENT in the SECTION. */
2451 static tree
2452 get_objc_string_decl (tree ident, enum string_section section)
2454 tree chain;
2456 if (section == class_names)
2457 chain = class_names_chain;
2458 else if (section == meth_var_names)
2459 chain = meth_var_names_chain;
2460 else if (section == meth_var_types)
2461 chain = meth_var_types_chain;
2462 else
2463 abort ();
2465 for (; chain != 0; chain = TREE_CHAIN (chain))
2466 if (TREE_VALUE (chain) == ident)
2467 return (TREE_PURPOSE (chain));
2469 abort ();
2470 return NULL_TREE;
2473 /* Output references to all statically allocated objects. Return the DECL
2474 for the array built. */
2476 static void
2477 generate_static_references (void)
2479 tree expr = NULL_TREE;
2480 tree class_name, klass, decl;
2481 tree cl_chain, in_chain, type
2482 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2483 int num_inst, num_class;
2484 char buf[256];
2485 VEC(constructor_elt,gc) *decls = NULL;
2487 if (flag_next_runtime)
2488 gcc_unreachable ();
2490 for (cl_chain = objc_static_instances, num_class = 0;
2491 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2493 VEC(constructor_elt,gc) *v = NULL;
2495 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2496 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2498 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2499 decl = start_var_decl (type, buf);
2501 /* Output {class_name, ...}. */
2502 klass = TREE_VALUE (cl_chain);
2503 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2504 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2505 build_unary_op (input_location,
2506 ADDR_EXPR, class_name, 1));
2508 /* Output {..., instance, ...}. */
2509 for (in_chain = TREE_PURPOSE (cl_chain);
2510 in_chain; in_chain = TREE_CHAIN (in_chain))
2512 expr = build_unary_op (input_location,
2513 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2514 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2517 /* Output {..., NULL}. */
2518 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
2520 expr = objc_build_constructor (TREE_TYPE (decl), v);
2521 finish_var_decl (decl, expr);
2522 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
2523 build_unary_op (input_location,
2524 ADDR_EXPR, decl, 1));
2527 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
2528 expr = objc_build_constructor (type, decls);
2529 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2530 finish_var_decl (static_instances_decl, expr);
2533 static GTY(()) int selector_reference_idx;
2535 static tree
2536 build_selector_reference_decl (void)
2538 tree decl;
2539 char buf[256];
2541 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2542 decl = start_var_decl (objc_selector_type, buf);
2544 return decl;
2547 static void
2548 build_selector_table_decl (void)
2550 tree temp;
2552 if (flag_typed_selectors)
2554 build_selector_template ();
2555 temp = build_array_type (objc_selector_template, NULL_TREE);
2557 else
2558 temp = build_array_type (objc_selector_type, NULL_TREE);
2560 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2563 /* Just a handy wrapper for add_objc_string. */
2565 static tree
2566 build_selector (tree ident)
2568 return convert (objc_selector_type,
2569 add_objc_string (ident, meth_var_names));
2572 /* Used only by build_*_selector_translation_table (). */
2573 static void
2574 diagnose_missing_method (tree meth, location_t here)
2576 tree method_chain;
2577 bool found = false;
2578 for (method_chain = meth_var_names_chain;
2579 method_chain;
2580 method_chain = TREE_CHAIN (method_chain))
2582 if (TREE_VALUE (method_chain) == meth)
2584 found = true;
2585 break;
2589 if (!found)
2590 warning_at (here, 0, "creating selector for nonexistent method %qE",
2591 meth);
2594 static void
2595 build_next_selector_translation_table (void)
2597 tree chain;
2598 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2600 tree expr;
2601 tree decl = TREE_PURPOSE (chain);
2602 if (warn_selector && objc_implementation_context)
2604 location_t loc;
2605 if (decl)
2606 loc = DECL_SOURCE_LOCATION (decl);
2607 else
2608 loc = input_location;
2609 diagnose_missing_method (TREE_VALUE (chain), loc);
2612 expr = build_selector (TREE_VALUE (chain));
2614 if (decl)
2616 /* Entries of this form are used for references to methods.
2617 The runtime re-writes these on start-up, but the compiler can't see
2618 that and optimizes it away unless we force it. */
2619 DECL_PRESERVE_P (decl) = 1;
2620 finish_var_decl (decl, expr);
2625 static void
2626 build_gnu_selector_translation_table (void)
2628 tree chain;
2629 /* int offset = 0;
2630 tree decl = NULL_TREE;*/
2631 VEC(constructor_elt,gc) *inits = NULL;
2633 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2635 tree expr;
2637 if (warn_selector && objc_implementation_context)
2638 diagnose_missing_method (TREE_VALUE (chain), input_location);
2640 expr = build_selector (TREE_VALUE (chain));
2641 /* add one for the '\0' character
2642 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;*/
2645 if (flag_typed_selectors)
2647 VEC(constructor_elt,gc) *v = NULL;
2648 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2649 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2650 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
2651 expr = objc_build_constructor (objc_selector_template, v);
2654 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2656 } /* each element in the chain */
2659 /* Cause the selector table (previously forward-declared)
2660 to be actually output. */
2661 tree expr;
2663 if (flag_typed_selectors)
2665 VEC(constructor_elt,gc) *v = NULL;
2666 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
2667 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
2668 expr = objc_build_constructor (objc_selector_template, v);
2670 else
2671 expr = integer_zero_node;
2673 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
2674 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2675 inits);
2676 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
2680 static tree
2681 get_proto_encoding (tree proto)
2683 tree encoding;
2684 if (proto)
2686 if (! METHOD_ENCODING (proto))
2688 encoding = encode_method_prototype (proto);
2689 METHOD_ENCODING (proto) = encoding;
2691 else
2692 encoding = METHOD_ENCODING (proto);
2694 return add_objc_string (encoding, meth_var_types);
2696 else
2697 return build_int_cst (NULL_TREE, 0);
2700 /* sel_ref_chain is a list whose "value" fields will be instances of
2701 identifier_node that represent the selector. LOC is the location of
2702 the @selector. */
2704 static tree
2705 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
2707 tree *chain = &sel_ref_chain;
2708 tree expr;
2709 int index = 0;
2711 while (*chain)
2713 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2714 goto return_at_index;
2716 index++;
2717 chain = &TREE_CHAIN (*chain);
2720 *chain = tree_cons (prototype, ident, NULL_TREE);
2722 return_at_index:
2723 expr = build_unary_op (loc, ADDR_EXPR,
2724 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2725 build_int_cst (NULL_TREE, index)),
2727 return convert (objc_selector_type, expr);
2730 static tree
2731 build_selector_reference (location_t loc, tree ident)
2733 tree *chain = &sel_ref_chain;
2734 tree expr;
2735 int index = 0;
2737 while (*chain)
2739 if (TREE_VALUE (*chain) == ident)
2740 return (flag_next_runtime
2741 ? TREE_PURPOSE (*chain)
2742 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2743 build_int_cst (NULL_TREE, index)));
2745 index++;
2746 chain = &TREE_CHAIN (*chain);
2749 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2751 *chain = tree_cons (expr, ident, NULL_TREE);
2753 return (flag_next_runtime
2754 ? expr
2755 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2756 build_int_cst (NULL_TREE, index)));
2759 static GTY(()) int class_reference_idx;
2761 static tree
2762 build_class_reference_decl (void)
2764 tree decl;
2765 char buf[256];
2767 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2768 decl = start_var_decl (objc_class_type, buf);
2770 return decl;
2773 /* Create a class reference, but don't create a variable to reference
2774 it. */
2776 static void
2777 add_class_reference (tree ident)
2779 tree chain;
2781 if ((chain = cls_ref_chain))
2783 tree tail;
2786 if (ident == TREE_VALUE (chain))
2787 return;
2789 tail = chain;
2790 chain = TREE_CHAIN (chain);
2792 while (chain);
2794 /* Append to the end of the list */
2795 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2797 else
2798 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2801 /* Get a class reference, creating it if necessary. Also create the
2802 reference variable. */
2804 tree
2805 objc_get_class_reference (tree ident)
2807 tree orig_ident = (DECL_P (ident)
2808 ? DECL_NAME (ident)
2809 : TYPE_P (ident)
2810 ? OBJC_TYPE_NAME (ident)
2811 : ident);
2812 bool local_scope = false;
2814 #ifdef OBJCPLUS
2815 if (processing_template_decl)
2816 /* Must wait until template instantiation time. */
2817 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2818 #endif
2820 if (TREE_CODE (ident) == TYPE_DECL)
2821 ident = (DECL_ORIGINAL_TYPE (ident)
2822 ? DECL_ORIGINAL_TYPE (ident)
2823 : TREE_TYPE (ident));
2825 #ifdef OBJCPLUS
2826 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2827 && TYPE_CONTEXT (ident) != global_namespace)
2828 local_scope = true;
2829 #endif
2831 if (local_scope || !(ident = objc_is_class_name (ident)))
2833 error ("%qE is not an Objective-C class name or alias",
2834 orig_ident);
2835 return error_mark_node;
2838 if (flag_next_runtime && !flag_zero_link)
2840 tree *chain;
2841 tree decl;
2843 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2844 if (TREE_VALUE (*chain) == ident)
2846 if (! TREE_PURPOSE (*chain))
2847 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2849 return TREE_PURPOSE (*chain);
2852 decl = build_class_reference_decl ();
2853 *chain = tree_cons (decl, ident, NULL_TREE);
2854 return decl;
2856 else
2858 tree params;
2860 add_class_reference (ident);
2862 params = build_tree_list (NULL_TREE,
2863 my_build_string_pointer
2864 (IDENTIFIER_LENGTH (ident) + 1,
2865 IDENTIFIER_POINTER (ident)));
2867 assemble_external (objc_get_class_decl);
2868 return build_function_call (input_location, objc_get_class_decl, params);
2872 /* For each string section we have a chain which maps identifier nodes
2873 to decls for the strings. */
2875 static GTY(()) int class_names_idx;
2876 static GTY(()) int meth_var_names_idx;
2877 static GTY(()) int meth_var_types_idx;
2879 static tree
2880 add_objc_string (tree ident, enum string_section section)
2882 tree *chain, decl, type, string_expr;
2883 char buf[256];
2885 buf[0] = 0;
2886 if (section == class_names)
2888 chain = &class_names_chain;
2889 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2891 else if (section == meth_var_names)
2893 chain = &meth_var_names_chain;
2894 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2896 else if (section == meth_var_types)
2898 chain = &meth_var_types_chain;
2899 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2901 else
2902 gcc_unreachable ();
2904 while (*chain)
2906 if (TREE_VALUE (*chain) == ident)
2907 return convert (string_type_node,
2908 build_unary_op (input_location,
2909 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2911 chain = &TREE_CHAIN (*chain);
2914 type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
2915 decl = start_var_decl (type, buf);
2916 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2917 IDENTIFIER_POINTER (ident));
2918 TREE_CONSTANT (decl) = 1;
2919 finish_var_decl (decl, string_expr);
2921 *chain = tree_cons (decl, ident, NULL_TREE);
2923 return convert (string_type_node, build_unary_op (input_location,
2924 ADDR_EXPR, decl, 1));
2927 void
2928 objc_declare_alias (tree alias_ident, tree class_ident)
2930 tree underlying_class;
2932 #ifdef OBJCPLUS
2933 if (current_namespace != global_namespace) {
2934 error ("Objective-C declarations may only appear in global scope");
2936 #endif /* OBJCPLUS */
2938 if (!(underlying_class = objc_is_class_name (class_ident)))
2939 warning (0, "cannot find class %qE", class_ident);
2940 else if (objc_is_class_name (alias_ident))
2941 warning (0, "class %qE already exists", alias_ident);
2942 else
2944 /* Implement @compatibility_alias as a typedef. */
2945 #ifdef OBJCPLUS
2946 push_lang_context (lang_name_c); /* extern "C" */
2947 #endif
2948 lang_hooks.decls.pushdecl (build_decl
2949 (input_location,
2950 TYPE_DECL,
2951 alias_ident,
2952 xref_tag (RECORD_TYPE, underlying_class)));
2953 #ifdef OBJCPLUS
2954 pop_lang_context ();
2955 #endif
2956 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2960 void
2961 objc_declare_class (tree ident_list)
2963 tree list;
2964 #ifdef OBJCPLUS
2965 if (current_namespace != global_namespace) {
2966 error ("Objective-C declarations may only appear in global scope");
2968 #endif /* OBJCPLUS */
2970 for (list = ident_list; list; list = TREE_CHAIN (list))
2972 tree ident = TREE_VALUE (list);
2974 if (! objc_is_class_name (ident))
2976 tree record = lookup_name (ident), type = record;
2978 if (record)
2980 if (TREE_CODE (record) == TYPE_DECL)
2981 type = DECL_ORIGINAL_TYPE (record);
2983 if (!TYPE_HAS_OBJC_INFO (type)
2984 || !TYPE_OBJC_INTERFACE (type))
2986 error ("%qE redeclared as different kind of symbol",
2987 ident);
2988 error ("previous declaration of %q+D",
2989 record);
2993 record = xref_tag (RECORD_TYPE, ident);
2994 INIT_TYPE_OBJC_INFO (record);
2995 TYPE_OBJC_INTERFACE (record) = ident;
2996 class_chain = tree_cons (NULL_TREE, ident, class_chain);
3001 tree
3002 objc_is_class_name (tree ident)
3004 tree chain;
3006 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3007 && identifier_global_value (ident))
3008 ident = identifier_global_value (ident);
3009 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3010 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3012 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3013 ident = OBJC_TYPE_NAME (ident);
3014 #ifdef OBJCPLUS
3015 if (ident && TREE_CODE (ident) == TYPE_DECL)
3016 ident = DECL_NAME (ident);
3017 #endif
3018 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3019 return NULL_TREE;
3021 if (lookup_interface (ident))
3022 return ident;
3024 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3026 if (ident == TREE_VALUE (chain))
3027 return ident;
3030 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3032 if (ident == TREE_VALUE (chain))
3033 return TREE_PURPOSE (chain);
3036 return 0;
3039 /* Check whether TYPE is either 'id' or 'Class'. */
3041 tree
3042 objc_is_id (tree type)
3044 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3045 && identifier_global_value (type))
3046 type = identifier_global_value (type);
3048 if (type && TREE_CODE (type) == TYPE_DECL)
3049 type = TREE_TYPE (type);
3051 /* NB: This function may be called before the ObjC front-end has
3052 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3053 return (objc_object_type && type
3054 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3055 ? type
3056 : NULL_TREE);
3059 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3060 class instance. This is needed by other parts of the compiler to
3061 handle ObjC types gracefully. */
3063 tree
3064 objc_is_object_ptr (tree type)
3066 tree ret;
3068 type = TYPE_MAIN_VARIANT (type);
3069 if (!POINTER_TYPE_P (type))
3070 return 0;
3072 ret = objc_is_id (type);
3073 if (!ret)
3074 ret = objc_is_class_name (TREE_TYPE (type));
3076 return ret;
3079 static int
3080 objc_is_gcable_type (tree type, int or_strong_p)
3082 tree name;
3084 if (!TYPE_P (type))
3085 return 0;
3086 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3087 return 1;
3088 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3089 return 1;
3090 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3091 return 0;
3092 type = TREE_TYPE (type);
3093 if (TREE_CODE (type) != RECORD_TYPE)
3094 return 0;
3095 name = TYPE_NAME (type);
3096 return (objc_is_class_name (name) != NULL_TREE);
3099 static tree
3100 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3102 if (expr == oldexpr)
3103 return newexpr;
3105 switch (TREE_CODE (expr))
3107 case COMPONENT_REF:
3108 return objc_build_component_ref
3109 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3110 oldexpr,
3111 newexpr),
3112 DECL_NAME (TREE_OPERAND (expr, 1)));
3113 case ARRAY_REF:
3114 return build_array_ref (input_location,
3115 objc_substitute_decl (TREE_OPERAND (expr, 0),
3116 oldexpr,
3117 newexpr),
3118 TREE_OPERAND (expr, 1));
3119 case INDIRECT_REF:
3120 return build_indirect_ref (input_location,
3121 objc_substitute_decl (TREE_OPERAND (expr, 0),
3122 oldexpr,
3123 newexpr), RO_ARROW);
3124 default:
3125 return expr;
3129 static tree
3130 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3132 tree func_params;
3133 /* The LHS parameter contains the expression 'outervar->memberspec';
3134 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3135 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3137 tree offs
3138 = objc_substitute_decl
3139 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3140 tree func
3141 = (flag_objc_direct_dispatch
3142 ? objc_assign_ivar_fast_decl
3143 : objc_assign_ivar_decl);
3145 offs = convert (integer_type_node, build_unary_op (input_location,
3146 ADDR_EXPR, offs, 0));
3147 offs = fold (offs);
3148 func_params = tree_cons (NULL_TREE,
3149 convert (objc_object_type, rhs),
3150 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3151 tree_cons (NULL_TREE, offs,
3152 NULL_TREE)));
3154 assemble_external (func);
3155 return build_function_call (input_location, func, func_params);
3158 static tree
3159 objc_build_global_assignment (tree lhs, tree rhs)
3161 tree func_params = tree_cons (NULL_TREE,
3162 convert (objc_object_type, rhs),
3163 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3164 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3165 NULL_TREE));
3167 assemble_external (objc_assign_global_decl);
3168 return build_function_call (input_location,
3169 objc_assign_global_decl, func_params);
3172 static tree
3173 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3175 tree func_params = tree_cons (NULL_TREE,
3176 convert (objc_object_type, rhs),
3177 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3178 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3179 NULL_TREE));
3181 assemble_external (objc_assign_strong_cast_decl);
3182 return build_function_call (input_location,
3183 objc_assign_strong_cast_decl, func_params);
3186 static int
3187 objc_is_gcable_p (tree expr)
3189 return (TREE_CODE (expr) == COMPONENT_REF
3190 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3191 : TREE_CODE (expr) == ARRAY_REF
3192 ? (objc_is_gcable_p (TREE_TYPE (expr))
3193 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3194 : TREE_CODE (expr) == ARRAY_TYPE
3195 ? objc_is_gcable_p (TREE_TYPE (expr))
3196 : TYPE_P (expr)
3197 ? objc_is_gcable_type (expr, 1)
3198 : (objc_is_gcable_p (TREE_TYPE (expr))
3199 || (DECL_P (expr)
3200 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3203 static int
3204 objc_is_ivar_reference_p (tree expr)
3206 return (TREE_CODE (expr) == ARRAY_REF
3207 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3208 : TREE_CODE (expr) == COMPONENT_REF
3209 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3210 : 0);
3213 static int
3214 objc_is_global_reference_p (tree expr)
3216 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3217 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3218 : DECL_P (expr)
3219 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3220 : 0);
3223 tree
3224 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3226 tree result = NULL_TREE, outer;
3227 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3229 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3230 will have been transformed to the form '*(type *)&expr'. */
3231 if (TREE_CODE (lhs) == INDIRECT_REF)
3233 outer = TREE_OPERAND (lhs, 0);
3235 while (!strong_cast_p
3236 && (CONVERT_EXPR_P (outer)
3237 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3239 tree lhstype = TREE_TYPE (outer);
3241 /* Descend down the cast chain, and record the first objc_gc
3242 attribute found. */
3243 if (POINTER_TYPE_P (lhstype))
3245 tree attr
3246 = lookup_attribute ("objc_gc",
3247 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3249 if (attr)
3250 strong_cast_p = 1;
3253 outer = TREE_OPERAND (outer, 0);
3257 /* If we have a __strong cast, it trumps all else. */
3258 if (strong_cast_p)
3260 if (modifycode != NOP_EXPR)
3261 goto invalid_pointer_arithmetic;
3263 if (warn_assign_intercept)
3264 warning (0, "strong-cast assignment has been intercepted");
3266 result = objc_build_strong_cast_assignment (lhs, rhs);
3268 goto exit_point;
3271 /* the lhs must be of a suitable type, regardless of its underlying
3272 structure. */
3273 if (!objc_is_gcable_p (lhs))
3274 goto exit_point;
3276 outer = lhs;
3278 while (outer
3279 && (TREE_CODE (outer) == COMPONENT_REF
3280 || TREE_CODE (outer) == ARRAY_REF))
3281 outer = TREE_OPERAND (outer, 0);
3283 if (TREE_CODE (outer) == INDIRECT_REF)
3285 outer = TREE_OPERAND (outer, 0);
3286 indirect_p = 1;
3289 outer_gc_p = objc_is_gcable_p (outer);
3291 /* Handle ivar assignments. */
3292 if (objc_is_ivar_reference_p (lhs))
3294 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3295 doesn't cut it here), the best we can do here is suggest a cast. */
3296 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3298 /* We may still be able to use the global write barrier... */
3299 if (!indirect_p && objc_is_global_reference_p (outer))
3300 goto global_reference;
3302 suggest_cast:
3303 if (modifycode == NOP_EXPR)
3305 if (warn_assign_intercept)
3306 warning (0, "strong-cast may possibly be needed");
3309 goto exit_point;
3312 if (modifycode != NOP_EXPR)
3313 goto invalid_pointer_arithmetic;
3315 if (warn_assign_intercept)
3316 warning (0, "instance variable assignment has been intercepted");
3318 result = objc_build_ivar_assignment (outer, lhs, rhs);
3320 goto exit_point;
3323 /* Likewise, intercept assignment to global/static variables if their type is
3324 GC-marked. */
3325 if (objc_is_global_reference_p (outer))
3327 if (indirect_p)
3328 goto suggest_cast;
3330 global_reference:
3331 if (modifycode != NOP_EXPR)
3333 invalid_pointer_arithmetic:
3334 if (outer_gc_p)
3335 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3337 goto exit_point;
3340 if (warn_assign_intercept)
3341 warning (0, "global/static variable assignment has been intercepted");
3343 result = objc_build_global_assignment (lhs, rhs);
3346 /* In all other cases, fall back to the normal mechanism. */
3347 exit_point:
3348 return result;
3351 struct GTY(()) interface_tuple {
3352 tree id;
3353 tree class_name;
3356 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3358 static hashval_t
3359 hash_interface (const void *p)
3361 const struct interface_tuple *d = (const struct interface_tuple *) p;
3362 return IDENTIFIER_HASH_VALUE (d->id);
3365 static int
3366 eq_interface (const void *p1, const void *p2)
3368 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3369 return d->id == p2;
3372 static tree
3373 lookup_interface (tree ident)
3375 #ifdef OBJCPLUS
3376 if (ident && TREE_CODE (ident) == TYPE_DECL)
3377 ident = DECL_NAME (ident);
3378 #endif
3380 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3381 return NULL_TREE;
3384 struct interface_tuple **slot;
3385 tree i = NULL_TREE;
3387 if (interface_htab)
3389 slot = (struct interface_tuple **)
3390 htab_find_slot_with_hash (interface_htab, ident,
3391 IDENTIFIER_HASH_VALUE (ident),
3392 NO_INSERT);
3393 if (slot && *slot)
3394 i = (*slot)->class_name;
3396 return i;
3400 /* Implement @defs (<classname>) within struct bodies. */
3402 tree
3403 objc_get_class_ivars (tree class_name)
3405 tree interface = lookup_interface (class_name);
3407 if (interface)
3408 return get_class_ivars (interface, true);
3410 error ("cannot find interface declaration for %qE",
3411 class_name);
3413 return error_mark_node;
3416 /* Used by: build_private_template, continue_class,
3417 and for @defs constructs. */
3419 static tree
3420 get_class_ivars (tree interface, bool inherited)
3422 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3424 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3425 by the current class (i.e., they do not include super-class ivars).
3426 However, the CLASS_IVARS list will be side-effected by a call to
3427 finish_struct(), which will fill in field offsets. */
3428 if (!CLASS_IVARS (interface))
3429 CLASS_IVARS (interface) = ivar_chain;
3431 if (!inherited)
3432 return ivar_chain;
3434 while (CLASS_SUPER_NAME (interface))
3436 /* Prepend super-class ivars. */
3437 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3438 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3439 ivar_chain);
3442 return ivar_chain;
3445 static tree
3446 objc_create_temporary_var (tree type)
3448 tree decl;
3450 decl = build_decl (input_location,
3451 VAR_DECL, NULL_TREE, type);
3452 TREE_USED (decl) = 1;
3453 DECL_ARTIFICIAL (decl) = 1;
3454 DECL_IGNORED_P (decl) = 1;
3455 DECL_CONTEXT (decl) = current_function_decl;
3457 return decl;
3460 /* Exception handling constructs. We begin by having the parser do most
3461 of the work and passing us blocks. What we do next depends on whether
3462 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3463 We abstract all of this in a handful of appropriately named routines. */
3465 /* Stack of open try blocks. */
3467 struct objc_try_context
3469 struct objc_try_context *outer;
3471 /* Statements (or statement lists) as processed by the parser. */
3472 tree try_body;
3473 tree finally_body;
3475 /* Some file position locations. */
3476 location_t try_locus;
3477 location_t end_try_locus;
3478 location_t end_catch_locus;
3479 location_t finally_locus;
3480 location_t end_finally_locus;
3482 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3483 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3484 tree catch_list;
3486 /* The CATCH_EXPR of an open @catch clause. */
3487 tree current_catch;
3489 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
3490 tree caught_decl;
3491 tree stack_decl;
3492 tree rethrow_decl;
3495 static struct objc_try_context *cur_try_context;
3497 static GTY(()) tree objc_eh_personality_decl;
3499 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3500 that represents TYPE. For Objective-C, this is just the class name. */
3501 /* ??? Isn't there a class object or some such? Is it easy to get? */
3503 #ifndef OBJCPLUS
3504 tree
3505 objc_eh_runtime_type (tree type)
3507 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3510 tree
3511 objc_eh_personality (void)
3513 if (!flag_objc_sjlj_exceptions
3514 && !objc_eh_personality_decl)
3515 objc_eh_personality_decl
3516 = build_personality_function (USING_SJLJ_EXCEPTIONS
3517 ? "__gnu_objc_personality_sj0"
3518 : "__gnu_objc_personality_v0");
3520 return objc_eh_personality_decl;
3522 #endif
3524 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
3525 of Darwin, we'll arrange for it to be initialized (and associated
3526 with a binding) later. */
3528 static tree
3529 objc_build_exc_ptr (void)
3531 if (flag_objc_sjlj_exceptions)
3533 tree var = cur_try_context->caught_decl;
3534 if (!var)
3536 var = objc_create_temporary_var (objc_object_type);
3537 cur_try_context->caught_decl = var;
3539 return var;
3541 else
3543 tree t;
3544 t = built_in_decls[BUILT_IN_EH_POINTER];
3545 t = build_call_expr (t, 1, integer_zero_node);
3546 return fold_convert (objc_object_type, t);
3550 /* Build "objc_exception_try_exit(&_stack)". */
3552 static tree
3553 next_sjlj_build_try_exit (void)
3555 tree t;
3556 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3557 t = tree_cons (NULL, t, NULL);
3558 t = build_function_call (input_location,
3559 objc_exception_try_exit_decl, t);
3560 return t;
3563 /* Build
3564 objc_exception_try_enter (&_stack);
3565 if (_setjmp(&_stack.buf))
3567 else
3569 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3570 empty, ready for the caller to fill them in. */
3572 static tree
3573 next_sjlj_build_enter_and_setjmp (void)
3575 tree t, enter, sj, cond;
3577 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3578 t = tree_cons (NULL, t, NULL);
3579 enter = build_function_call (input_location,
3580 objc_exception_try_enter_decl, t);
3582 t = objc_build_component_ref (cur_try_context->stack_decl,
3583 get_identifier ("buf"));
3584 t = build_fold_addr_expr_loc (input_location, t);
3585 #ifdef OBJCPLUS
3586 /* Convert _setjmp argument to type that is expected. */
3587 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3588 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3589 else
3590 t = convert (ptr_type_node, t);
3591 #else
3592 t = convert (ptr_type_node, t);
3593 #endif
3594 t = tree_cons (NULL, t, NULL);
3595 sj = build_function_call (input_location,
3596 objc_setjmp_decl, t);
3598 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3599 cond = c_common_truthvalue_conversion (input_location, cond);
3601 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3604 /* Build:
3606 DECL = objc_exception_extract(&_stack); */
3608 static tree
3609 next_sjlj_build_exc_extract (tree decl)
3611 tree t;
3613 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3614 t = tree_cons (NULL, t, NULL);
3615 t = build_function_call (input_location,
3616 objc_exception_extract_decl, t);
3617 t = convert (TREE_TYPE (decl), t);
3618 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3620 return t;
3623 /* Build
3624 if (objc_exception_match(obj_get_class(TYPE), _caught)
3625 BODY
3626 else if (...)
3628 else
3630 _rethrow = _caught;
3631 objc_exception_try_exit(&_stack);
3633 from the sequence of CATCH_EXPRs in the current try context. */
3635 static tree
3636 next_sjlj_build_catch_list (void)
3638 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3639 tree catch_seq, t;
3640 tree *last = &catch_seq;
3641 bool saw_id = false;
3643 for (; !tsi_end_p (i); tsi_next (&i))
3645 tree stmt = tsi_stmt (i);
3646 tree type = CATCH_TYPES (stmt);
3647 tree body = CATCH_BODY (stmt);
3649 if (type == NULL)
3651 *last = body;
3652 saw_id = true;
3653 break;
3655 else
3657 tree args, cond;
3659 if (type == error_mark_node)
3660 cond = error_mark_node;
3661 else
3663 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3664 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3665 args = tree_cons (NULL, t, args);
3666 t = build_function_call (input_location,
3667 objc_exception_match_decl, args);
3668 cond = c_common_truthvalue_conversion (input_location, t);
3670 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3671 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
3673 *last = t;
3674 last = &COND_EXPR_ELSE (t);
3678 if (!saw_id)
3680 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3681 cur_try_context->caught_decl);
3682 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3683 append_to_statement_list (t, last);
3685 t = next_sjlj_build_try_exit ();
3686 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3687 append_to_statement_list (t, last);
3690 return catch_seq;
3693 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3694 exception handling. We aim to build:
3697 struct _objc_exception_data _stack;
3698 id _rethrow = 0;
3701 objc_exception_try_enter (&_stack);
3702 if (_setjmp(&_stack.buf))
3704 id _caught = objc_exception_extract(&_stack);
3705 objc_exception_try_enter (&_stack);
3706 if (_setjmp(&_stack.buf))
3707 _rethrow = objc_exception_extract(&_stack);
3708 else
3709 CATCH-LIST
3711 else
3712 TRY-BLOCK
3714 finally
3716 if (!_rethrow)
3717 objc_exception_try_exit(&_stack);
3718 FINALLY-BLOCK
3719 if (_rethrow)
3720 objc_exception_throw(_rethrow);
3724 If CATCH-LIST is empty, we can omit all of the block containing
3725 "_caught" except for the setting of _rethrow. Note the use of
3726 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3727 but handles goto and other exits from the block. */
3729 static tree
3730 next_sjlj_build_try_catch_finally (void)
3732 tree rethrow_decl, stack_decl, t;
3733 tree catch_seq, try_fin, bind;
3735 /* Create the declarations involved. */
3736 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3737 stack_decl = objc_create_temporary_var (t);
3738 cur_try_context->stack_decl = stack_decl;
3740 rethrow_decl = objc_create_temporary_var (objc_object_type);
3741 cur_try_context->rethrow_decl = rethrow_decl;
3742 TREE_CHAIN (rethrow_decl) = stack_decl;
3744 /* Build the outermost variable binding level. */
3745 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3746 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3747 TREE_SIDE_EFFECTS (bind) = 1;
3749 /* Initialize rethrow_decl. */
3750 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3751 convert (objc_object_type, null_pointer_node));
3752 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3753 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3755 /* Build the outermost TRY_FINALLY_EXPR. */
3756 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3757 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3758 TREE_SIDE_EFFECTS (try_fin) = 1;
3759 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3761 /* Create the complete catch sequence. */
3762 if (cur_try_context->catch_list)
3764 tree caught_decl = objc_build_exc_ptr ();
3765 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
3766 TREE_SIDE_EFFECTS (catch_seq) = 1;
3768 t = next_sjlj_build_exc_extract (caught_decl);
3769 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3771 t = next_sjlj_build_enter_and_setjmp ();
3772 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3773 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3774 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3776 else
3777 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3778 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3780 /* Build the main register-and-try if statement. */
3781 t = next_sjlj_build_enter_and_setjmp ();
3782 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3783 COND_EXPR_THEN (t) = catch_seq;
3784 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3785 TREE_OPERAND (try_fin, 0) = t;
3787 /* Build the complete FINALLY statement list. */
3788 t = next_sjlj_build_try_exit ();
3789 t = build_stmt (input_location, COND_EXPR,
3790 c_common_truthvalue_conversion
3791 (input_location, rethrow_decl),
3792 NULL, t);
3793 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3794 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3796 append_to_statement_list (cur_try_context->finally_body,
3797 &TREE_OPERAND (try_fin, 1));
3799 t = tree_cons (NULL, rethrow_decl, NULL);
3800 t = build_function_call (input_location,
3801 objc_exception_throw_decl, t);
3802 t = build_stmt (input_location, COND_EXPR,
3803 c_common_truthvalue_conversion (input_location,
3804 rethrow_decl),
3805 t, NULL);
3806 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3807 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3809 return bind;
3812 /* Called just after parsing the @try and its associated BODY. We now
3813 must prepare for the tricky bits -- handling the catches and finally. */
3815 void
3816 objc_begin_try_stmt (location_t try_locus, tree body)
3818 struct objc_try_context *c = XCNEW (struct objc_try_context);
3819 c->outer = cur_try_context;
3820 c->try_body = body;
3821 c->try_locus = try_locus;
3822 c->end_try_locus = input_location;
3823 cur_try_context = c;
3825 if (flag_objc_sjlj_exceptions)
3827 /* On Darwin, ObjC exceptions require a sufficiently recent
3828 version of the runtime, so the user must ask for them explicitly. */
3829 if (!flag_objc_exceptions)
3830 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3831 "exception syntax");
3834 if (flag_objc_sjlj_exceptions)
3835 objc_mark_locals_volatile (NULL);
3838 /* Called just after parsing "@catch (parm)". Open a binding level,
3839 enter DECL into the binding level, and initialize it. Leave the
3840 binding level open while the body of the compound statement is parsed. */
3842 void
3843 objc_begin_catch_clause (tree decl)
3845 tree compound, type, t;
3847 /* Begin a new scope that the entire catch clause will live in. */
3848 compound = c_begin_compound_stmt (true);
3850 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3851 decl = build_decl (input_location,
3852 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3853 lang_hooks.decls.pushdecl (decl);
3855 /* Since a decl is required here by syntax, don't warn if its unused. */
3856 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3857 be what the previous objc implementation did. */
3858 TREE_USED (decl) = 1;
3859 DECL_READ_P (decl) = 1;
3861 /* Verify that the type of the catch is valid. It must be a pointer
3862 to an Objective-C class, or "id" (which is catch-all). */
3863 type = TREE_TYPE (decl);
3865 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3866 type = NULL;
3867 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3869 error ("@catch parameter is not a known Objective-C class type");
3870 type = error_mark_node;
3872 else if (cur_try_context->catch_list)
3874 /* Examine previous @catch clauses and see if we've already
3875 caught the type in question. */
3876 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3877 for (; !tsi_end_p (i); tsi_next (&i))
3879 tree stmt = tsi_stmt (i);
3880 t = CATCH_TYPES (stmt);
3881 if (t == error_mark_node)
3882 continue;
3883 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3885 warning (0, "exception of type %<%T%> will be caught",
3886 TREE_TYPE (type));
3887 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
3888 TREE_TYPE (t ? t : objc_object_type));
3889 break;
3894 /* Record the data for the catch in the try context so that we can
3895 finalize it later. */
3896 t = build_stmt (input_location, CATCH_EXPR, type, compound);
3897 cur_try_context->current_catch = t;
3899 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3900 t = objc_build_exc_ptr ();
3901 t = convert (TREE_TYPE (decl), t);
3902 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3903 add_stmt (t);
3906 /* Called just after parsing the closing brace of a @catch clause. Close
3907 the open binding level, and record a CATCH_EXPR for it. */
3909 void
3910 objc_finish_catch_clause (void)
3912 tree c = cur_try_context->current_catch;
3913 cur_try_context->current_catch = NULL;
3914 cur_try_context->end_catch_locus = input_location;
3916 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
3917 append_to_statement_list (c, &cur_try_context->catch_list);
3920 /* Called after parsing a @finally clause and its associated BODY.
3921 Record the body for later placement. */
3923 void
3924 objc_build_finally_clause (location_t finally_locus, tree body)
3926 cur_try_context->finally_body = body;
3927 cur_try_context->finally_locus = finally_locus;
3928 cur_try_context->end_finally_locus = input_location;
3931 /* Called to finalize a @try construct. */
3933 tree
3934 objc_finish_try_stmt (void)
3936 struct objc_try_context *c = cur_try_context;
3937 tree stmt;
3939 if (c->catch_list == NULL && c->finally_body == NULL)
3940 error ("%<@try%> without %<@catch%> or %<@finally%>");
3942 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3943 if (flag_objc_sjlj_exceptions)
3945 bool save = in_late_binary_op;
3946 in_late_binary_op = true;
3947 if (!cur_try_context->finally_body)
3949 cur_try_context->finally_locus = input_location;
3950 cur_try_context->end_finally_locus = input_location;
3952 stmt = next_sjlj_build_try_catch_finally ();
3953 in_late_binary_op = save;
3955 else
3957 /* Otherwise, nest the CATCH inside a FINALLY. */
3958 stmt = c->try_body;
3959 if (c->catch_list)
3961 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
3962 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3964 if (c->finally_body)
3966 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
3967 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3970 add_stmt (stmt);
3972 cur_try_context = c->outer;
3973 free (c);
3974 return stmt;
3977 tree
3978 objc_build_throw_stmt (location_t loc, tree throw_expr)
3980 tree args;
3982 if (flag_objc_sjlj_exceptions)
3984 /* On Darwin, ObjC exceptions require a sufficiently recent
3985 version of the runtime, so the user must ask for them explicitly. */
3986 if (!flag_objc_exceptions)
3987 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3988 "exception syntax");
3991 if (throw_expr == NULL)
3993 /* If we're not inside a @catch block, there is no "current
3994 exception" to be rethrown. */
3995 if (cur_try_context == NULL
3996 || cur_try_context->current_catch == NULL)
3998 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
3999 return NULL_TREE;
4002 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
4003 value that we get from the runtime. */
4004 throw_expr = objc_build_exc_ptr ();
4007 /* A throw is just a call to the runtime throw function with the
4008 object as a parameter. */
4009 args = tree_cons (NULL, throw_expr, NULL);
4010 return add_stmt (build_function_call (loc,
4011 objc_exception_throw_decl, args));
4014 tree
4015 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4017 tree args, call;
4019 /* First lock the mutex. */
4020 mutex = save_expr (mutex);
4021 args = tree_cons (NULL, mutex, NULL);
4022 call = build_function_call (input_location,
4023 objc_sync_enter_decl, args);
4024 SET_EXPR_LOCATION (call, start_locus);
4025 add_stmt (call);
4027 /* Build the mutex unlock. */
4028 args = tree_cons (NULL, mutex, NULL);
4029 call = build_function_call (input_location,
4030 objc_sync_exit_decl, args);
4031 SET_EXPR_LOCATION (call, input_location);
4033 /* Put the that and the body in a TRY_FINALLY. */
4034 objc_begin_try_stmt (start_locus, body);
4035 objc_build_finally_clause (input_location, call);
4036 return objc_finish_try_stmt ();
4040 /* Predefine the following data type:
4042 struct _objc_exception_data
4044 int buf[OBJC_JBLEN];
4045 void *pointers[4];
4046 }; */
4048 /* The following yuckiness should prevent users from having to #include
4049 <setjmp.h> in their code... */
4051 /* Define to a harmless positive value so the below code doesn't die. */
4052 #ifndef OBJC_JBLEN
4053 #define OBJC_JBLEN 18
4054 #endif
4056 static void
4057 build_next_objc_exception_stuff (void)
4059 tree decls, temp_type, *chain = NULL;
4061 objc_exception_data_template
4062 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4064 /* int buf[OBJC_JBLEN]; */
4066 temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN);
4067 decls = add_field_decl (temp_type, "buf", &chain);
4069 /* void *pointers[4]; */
4071 temp_type = build_sized_array_type (ptr_type_node, 4);
4072 add_field_decl (temp_type, "pointers", &chain);
4074 objc_finish_struct (objc_exception_data_template, decls);
4076 /* int _setjmp(...); */
4077 /* If the user includes <setjmp.h>, this shall be superseded by
4078 'int _setjmp(jmp_buf);' */
4079 temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE);
4080 objc_setjmp_decl
4081 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4083 /* id objc_exception_extract(struct _objc_exception_data *); */
4084 temp_type
4085 = build_function_type_list (objc_object_type,
4086 build_pointer_type (objc_exception_data_template),
4087 NULL_TREE);
4088 objc_exception_extract_decl
4089 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4090 NULL_TREE);
4091 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4092 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4093 temp_type
4094 = build_function_type_list (void_type_node,
4095 build_pointer_type (objc_exception_data_template),
4096 NULL_TREE);
4097 objc_exception_try_enter_decl
4098 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4099 NULL_TREE);
4100 objc_exception_try_exit_decl
4101 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4102 NULL_TREE);
4104 /* int objc_exception_match(id, id); */
4105 temp_type
4106 = build_function_type_list (integer_type_node,
4107 objc_object_type, objc_object_type, NULL_TREE);
4108 objc_exception_match_decl
4109 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4110 NULL_TREE);
4112 /* id objc_assign_ivar (id, id, unsigned int); */
4113 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4114 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4115 temp_type
4116 = build_function_type_list (objc_object_type,
4117 objc_object_type,
4118 objc_object_type,
4119 unsigned_type_node,
4120 NULL_TREE);
4121 objc_assign_ivar_decl
4122 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4123 NULL, NULL_TREE);
4124 #ifdef OFFS_ASSIGNIVAR_FAST
4125 objc_assign_ivar_fast_decl
4126 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4127 NOT_BUILT_IN, NULL, NULL_TREE);
4128 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4129 = tree_cons (get_identifier ("hard_coded_address"),
4130 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4131 NULL_TREE);
4132 #else
4133 /* Default to slower ivar method. */
4134 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4135 #endif
4137 /* id objc_assign_global (id, id *); */
4138 /* id objc_assign_strongCast (id, id *); */
4139 temp_type = build_function_type_list (objc_object_type,
4140 objc_object_type,
4141 build_pointer_type (objc_object_type),
4142 NULL_TREE);
4143 objc_assign_global_decl
4144 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4145 NULL_TREE);
4146 objc_assign_strong_cast_decl
4147 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4148 NULL_TREE);
4151 static void
4152 build_objc_exception_stuff (void)
4154 tree noreturn_list, nothrow_list, temp_type;
4156 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4157 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4159 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4160 /* void objc_sync_enter(id); */
4161 /* void objc_sync_exit(id); */
4162 temp_type = build_function_type_list (void_type_node,
4163 objc_object_type,
4164 NULL_TREE);
4165 objc_exception_throw_decl
4166 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4167 noreturn_list);
4168 objc_sync_enter_decl
4169 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4170 NULL, nothrow_list);
4171 objc_sync_exit_decl
4172 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4173 NULL, nothrow_list);
4176 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4177 name as the class:
4179 struct <classname> {
4180 struct _objc_class *isa;
4182 }; */
4184 static void
4185 build_private_template (tree klass)
4187 if (!CLASS_STATIC_TEMPLATE (klass))
4189 tree record = objc_build_struct (klass,
4190 get_class_ivars (klass, false),
4191 CLASS_SUPER_NAME (klass));
4193 /* Set the TREE_USED bit for this struct, so that stab generator
4194 can emit stabs for this struct type. */
4195 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4196 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4200 /* Begin code generation for protocols... */
4202 /* struct _objc_protocol {
4203 struct _objc_class *isa;
4204 char *protocol_name;
4205 struct _objc_protocol **protocol_list;
4206 struct _objc__method_prototype_list *instance_methods;
4207 struct _objc__method_prototype_list *class_methods;
4208 }; */
4210 static void
4211 build_protocol_template (void)
4213 tree ptype, decls, *chain = NULL;
4215 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4217 /* struct _objc_class *isa; */
4218 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4219 get_identifier (UTAG_CLASS)));
4220 decls = add_field_decl (ptype, "isa", &chain);
4222 /* char *protocol_name; */
4223 add_field_decl (string_type_node, "protocol_name", &chain);
4225 /* struct _objc_protocol **protocol_list; */
4226 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4227 add_field_decl (ptype, "protocol_list", &chain);
4229 /* struct _objc__method_prototype_list *instance_methods; */
4230 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
4232 /* struct _objc__method_prototype_list *class_methods; */
4233 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
4235 objc_finish_struct (objc_protocol_template, decls);
4238 static tree
4239 build_descriptor_table_initializer (tree type, tree entries)
4241 VEC(constructor_elt,gc) *inits = NULL;
4245 VEC(constructor_elt,gc) *elts = NULL;
4247 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4248 build_selector (METHOD_SEL_NAME (entries)));
4249 CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
4250 add_objc_string (METHOD_ENCODING (entries),
4251 meth_var_types));
4253 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
4254 objc_build_constructor (type, elts));
4256 entries = DECL_CHAIN (entries);
4258 while (entries);
4260 return objc_build_constructor (build_array_type (type, 0), inits);
4263 /* struct objc_method_prototype_list {
4264 int count;
4265 struct objc_method_prototype {
4266 SEL name;
4267 char *types;
4268 } list[1];
4269 }; */
4271 static tree
4272 build_method_prototype_list_template (tree list_type, int size)
4274 tree objc_ivar_list_record;
4275 tree array_type, decls, *chain = NULL;
4277 /* Generate an unnamed struct definition. */
4279 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4281 /* int method_count; */
4282 decls = add_field_decl (integer_type_node, "method_count", &chain);
4284 /* struct objc_method method_list[]; */
4285 array_type = build_sized_array_type (list_type, size);
4286 add_field_decl (array_type, "method_list", &chain);
4288 objc_finish_struct (objc_ivar_list_record, decls);
4290 return objc_ivar_list_record;
4293 static tree
4294 build_method_prototype_template (void)
4296 tree proto_record;
4297 tree decls, *chain = NULL;
4299 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4301 /* SEL _cmd; */
4302 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
4304 /* char *method_types; */
4305 add_field_decl (string_type_node, "method_types", &chain);
4307 objc_finish_struct (proto_record, decls);
4309 return proto_record;
4312 static tree
4313 objc_method_parm_type (tree type)
4315 type = TREE_VALUE (TREE_TYPE (type));
4316 if (TREE_CODE (type) == TYPE_DECL)
4317 type = TREE_TYPE (type);
4318 return type;
4321 static int
4322 objc_encoded_type_size (tree type)
4324 int sz = int_size_in_bytes (type);
4326 /* Make all integer and enum types at least as large
4327 as an int. */
4328 if (sz > 0 && INTEGRAL_TYPE_P (type))
4329 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4330 /* Treat arrays as pointers, since that's how they're
4331 passed in. */
4332 else if (TREE_CODE (type) == ARRAY_TYPE)
4333 sz = int_size_in_bytes (ptr_type_node);
4334 return sz;
4337 static tree
4338 encode_method_prototype (tree method_decl)
4340 tree parms;
4341 int parm_offset, i;
4342 char buf[40];
4343 tree result;
4345 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4346 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4348 /* Encode return type. */
4349 encode_type (objc_method_parm_type (method_decl),
4350 obstack_object_size (&util_obstack),
4351 OBJC_ENCODE_INLINE_DEFS);
4353 /* Stack size. */
4354 /* The first two arguments (self and _cmd) are pointers; account for
4355 their size. */
4356 i = int_size_in_bytes (ptr_type_node);
4357 parm_offset = 2 * i;
4358 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4359 parms = DECL_CHAIN (parms))
4361 tree type = objc_method_parm_type (parms);
4362 int sz = objc_encoded_type_size (type);
4364 /* If a type size is not known, bail out. */
4365 if (sz < 0)
4367 error ("type %q+D does not have a known size",
4368 type);
4369 /* Pretend that the encoding succeeded; the compilation will
4370 fail nevertheless. */
4371 goto finish_encoding;
4373 parm_offset += sz;
4376 sprintf (buf, "%d@0:%d", parm_offset, i);
4377 obstack_grow (&util_obstack, buf, strlen (buf));
4379 /* Argument types. */
4380 parm_offset = 2 * i;
4381 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4382 parms = DECL_CHAIN (parms))
4384 tree type = objc_method_parm_type (parms);
4386 /* Process argument qualifiers for user supplied arguments. */
4387 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4389 /* Type. */
4390 encode_type (type, obstack_object_size (&util_obstack),
4391 OBJC_ENCODE_INLINE_DEFS);
4393 /* Compute offset. */
4394 sprintf (buf, "%d", parm_offset);
4395 parm_offset += objc_encoded_type_size (type);
4397 obstack_grow (&util_obstack, buf, strlen (buf));
4400 finish_encoding:
4401 obstack_1grow (&util_obstack, '\0');
4402 result = get_identifier (XOBFINISH (&util_obstack, char *));
4403 obstack_free (&util_obstack, util_firstobj);
4404 return result;
4407 static tree
4408 generate_descriptor_table (tree type, const char *name, int size, tree list,
4409 tree proto)
4411 tree decl;
4412 VEC(constructor_elt,gc) *v = NULL;
4414 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4416 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
4417 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
4419 finish_var_decl (decl, objc_build_constructor (type, v));
4421 return decl;
4424 static void
4425 generate_method_descriptors (tree protocol)
4427 tree initlist, chain, method_list_template;
4428 int size;
4430 if (!objc_method_prototype_template)
4431 objc_method_prototype_template = build_method_prototype_template ();
4433 chain = PROTOCOL_CLS_METHODS (protocol);
4434 if (chain)
4436 size = list_length (chain);
4438 method_list_template
4439 = build_method_prototype_list_template (objc_method_prototype_template,
4440 size);
4442 initlist
4443 = build_descriptor_table_initializer (objc_method_prototype_template,
4444 chain);
4446 UOBJC_CLASS_METHODS_decl
4447 = generate_descriptor_table (method_list_template,
4448 "_OBJC_PROTOCOL_CLASS_METHODS",
4449 size, initlist, protocol);
4451 else
4452 UOBJC_CLASS_METHODS_decl = 0;
4454 chain = PROTOCOL_NST_METHODS (protocol);
4455 if (chain)
4457 size = list_length (chain);
4459 method_list_template
4460 = build_method_prototype_list_template (objc_method_prototype_template,
4461 size);
4462 initlist
4463 = build_descriptor_table_initializer (objc_method_prototype_template,
4464 chain);
4466 UOBJC_INSTANCE_METHODS_decl
4467 = generate_descriptor_table (method_list_template,
4468 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4469 size, initlist, protocol);
4471 else
4472 UOBJC_INSTANCE_METHODS_decl = 0;
4475 static void
4476 generate_protocol_references (tree plist)
4478 tree lproto;
4480 /* Forward declare protocols referenced. */
4481 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4483 tree proto = TREE_VALUE (lproto);
4485 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4486 && PROTOCOL_NAME (proto))
4488 if (! PROTOCOL_FORWARD_DECL (proto))
4489 build_protocol_reference (proto);
4491 if (PROTOCOL_LIST (proto))
4492 generate_protocol_references (PROTOCOL_LIST (proto));
4497 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4498 current class. */
4499 #ifdef OBJCPLUS
4500 static void
4501 objc_generate_cxx_ctor_or_dtor (bool dtor)
4503 tree fn, body, compound_stmt, ivar;
4505 /* - (id) .cxx_construct { ... return self; } */
4506 /* - (void) .cxx_construct { ... } */
4508 objc_set_method_type (MINUS_EXPR);
4509 objc_start_method_definition
4510 (objc_build_method_signature (build_tree_list (NULL_TREE,
4511 dtor
4512 ? void_type_node
4513 : objc_object_type),
4514 get_identifier (dtor
4515 ? TAG_CXX_DESTRUCT
4516 : TAG_CXX_CONSTRUCT),
4517 make_node (TREE_LIST),
4518 false));
4519 body = begin_function_body ();
4520 compound_stmt = begin_compound_stmt (0);
4522 ivar = CLASS_IVARS (implementation_template);
4523 /* Destroy ivars in reverse order. */
4524 if (dtor)
4525 ivar = nreverse (copy_list (ivar));
4527 for (; ivar; ivar = TREE_CHAIN (ivar))
4529 if (TREE_CODE (ivar) == FIELD_DECL)
4531 tree type = TREE_TYPE (ivar);
4533 /* Call the ivar's default constructor or destructor. Do not
4534 call the destructor unless a corresponding constructor call
4535 has also been made (or is not needed). */
4536 if (MAYBE_CLASS_TYPE_P (type)
4537 && (dtor
4538 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4539 && (!TYPE_NEEDS_CONSTRUCTING (type)
4540 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4541 : (TYPE_NEEDS_CONSTRUCTING (type)
4542 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4543 finish_expr_stmt
4544 (build_special_member_call
4545 (build_ivar_reference (DECL_NAME (ivar)),
4546 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4547 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
4551 /* The constructor returns 'self'. */
4552 if (!dtor)
4553 finish_return_stmt (self_decl);
4555 finish_compound_stmt (compound_stmt);
4556 finish_function_body (body);
4557 fn = current_function_decl;
4558 finish_function ();
4559 objc_finish_method_definition (fn);
4562 /* The following routine will examine the current @interface for any
4563 non-POD C++ ivars requiring non-trivial construction and/or
4564 destruction, and then synthesize special '- .cxx_construct' and/or
4565 '- .cxx_destruct' methods which will run the appropriate
4566 construction or destruction code. Note that ivars inherited from
4567 super-classes are _not_ considered. */
4568 static void
4569 objc_generate_cxx_cdtors (void)
4571 bool need_ctor = false, need_dtor = false;
4572 tree ivar;
4574 /* We do not want to do this for categories, since they do not have
4575 their own ivars. */
4577 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4578 return;
4580 /* First, determine if we even need a constructor and/or destructor. */
4582 for (ivar = CLASS_IVARS (implementation_template); ivar;
4583 ivar = TREE_CHAIN (ivar))
4585 if (TREE_CODE (ivar) == FIELD_DECL)
4587 tree type = TREE_TYPE (ivar);
4589 if (MAYBE_CLASS_TYPE_P (type))
4591 if (TYPE_NEEDS_CONSTRUCTING (type)
4592 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4593 /* NB: If a default constructor is not available, we will not
4594 be able to initialize this ivar; the add_instance_variable()
4595 routine will already have warned about this. */
4596 need_ctor = true;
4598 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4599 && (!TYPE_NEEDS_CONSTRUCTING (type)
4600 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4601 /* NB: If a default constructor is not available, we will not
4602 call the destructor either, for symmetry. */
4603 need_dtor = true;
4608 /* Generate '- .cxx_construct' if needed. */
4610 if (need_ctor)
4611 objc_generate_cxx_ctor_or_dtor (false);
4613 /* Generate '- .cxx_destruct' if needed. */
4615 if (need_dtor)
4616 objc_generate_cxx_ctor_or_dtor (true);
4618 /* The 'imp_list' variable points at an imp_entry record for the current
4619 @implementation. Record the existence of '- .cxx_construct' and/or
4620 '- .cxx_destruct' methods therein; it will be included in the
4621 metadata for the class. */
4622 if (flag_next_runtime)
4623 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4625 #endif
4627 /* For each protocol which was referenced either from a @protocol()
4628 expression, or because a class/category implements it (then a
4629 pointer to the protocol is stored in the struct describing the
4630 class/category), we create a statically allocated instance of the
4631 Protocol class. The code is written in such a way as to generate
4632 as few Protocol objects as possible; we generate a unique Protocol
4633 instance for each protocol, and we don't generate a Protocol
4634 instance if the protocol is never referenced (either from a
4635 @protocol() or from a class/category implementation). These
4636 statically allocated objects can be referred to via the static
4637 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4639 The statically allocated Protocol objects that we generate here
4640 need to be fixed up at runtime in order to be used: the 'isa'
4641 pointer of the objects need to be set up to point to the 'Protocol'
4642 class, as known at runtime.
4644 The NeXT runtime fixes up all protocols at program startup time,
4645 before main() is entered. It uses a low-level trick to look up all
4646 those symbols, then loops on them and fixes them up.
4648 The GNU runtime as well fixes up all protocols before user code
4649 from the module is executed; it requires pointers to those symbols
4650 to be put in the objc_symtab (which is then passed as argument to
4651 the function __objc_exec_class() which the compiler sets up to be
4652 executed automatically when the module is loaded); setup of those
4653 Protocol objects happen in two ways in the GNU runtime: all
4654 Protocol objects referred to by a class or category implementation
4655 are fixed up when the class/category is loaded; all Protocol
4656 objects referred to by a @protocol() expression are added by the
4657 compiler to the list of statically allocated instances to fixup
4658 (the same list holding the statically allocated constant string
4659 objects). Because, as explained above, the compiler generates as
4660 few Protocol objects as possible, some Protocol object might end up
4661 being referenced multiple times when compiled with the GNU runtime,
4662 and end up being fixed up multiple times at runtime initialization.
4663 But that doesn't hurt, it's just a little inefficient. */
4665 static void
4666 generate_protocols (void)
4668 tree p, encoding;
4669 tree decl;
4670 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4672 /* If a protocol was directly referenced, pull in indirect references. */
4673 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4674 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4675 generate_protocol_references (PROTOCOL_LIST (p));
4677 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4679 tree nst_methods = PROTOCOL_NST_METHODS (p);
4680 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4682 /* If protocol wasn't referenced, don't generate any code. */
4683 decl = PROTOCOL_FORWARD_DECL (p);
4685 if (!decl)
4686 continue;
4688 /* Make sure we link in the Protocol class. */
4689 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4691 while (nst_methods)
4693 if (! METHOD_ENCODING (nst_methods))
4695 encoding = encode_method_prototype (nst_methods);
4696 METHOD_ENCODING (nst_methods) = encoding;
4698 nst_methods = DECL_CHAIN (nst_methods);
4701 while (cls_methods)
4703 if (! METHOD_ENCODING (cls_methods))
4705 encoding = encode_method_prototype (cls_methods);
4706 METHOD_ENCODING (cls_methods) = encoding;
4709 cls_methods = DECL_CHAIN (cls_methods);
4711 generate_method_descriptors (p);
4713 if (PROTOCOL_LIST (p))
4714 refs_decl = generate_protocol_list (p);
4715 else
4716 refs_decl = 0;
4718 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4719 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4721 if (refs_decl)
4722 refs_expr = convert (build_pointer_type (build_pointer_type
4723 (objc_protocol_template)),
4724 build_unary_op (input_location,
4725 ADDR_EXPR, refs_decl, 0));
4726 else
4727 refs_expr = build_int_cst (NULL_TREE, 0);
4729 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4730 by generate_method_descriptors, which is called above. */
4731 initlist = build_protocol_initializer (TREE_TYPE (decl),
4732 protocol_name_expr, refs_expr,
4733 UOBJC_INSTANCE_METHODS_decl,
4734 UOBJC_CLASS_METHODS_decl);
4735 finish_var_decl (decl, initlist);
4739 static tree
4740 build_protocol_initializer (tree type, tree protocol_name,
4741 tree protocol_list, tree instance_methods,
4742 tree class_methods)
4744 tree expr;
4745 tree cast_type = build_pointer_type
4746 (xref_tag (RECORD_TYPE,
4747 get_identifier (UTAG_CLASS)));
4748 VEC(constructor_elt,gc) *inits = NULL;
4750 /* Filling the "isa" in with one allows the runtime system to
4751 detect that the version change...should remove before final release. */
4753 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4754 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4755 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
4756 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
4758 if (!instance_methods)
4759 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
4760 else
4762 expr = convert (objc_method_proto_list_ptr,
4763 build_unary_op (input_location,
4764 ADDR_EXPR, instance_methods, 0));
4765 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4768 if (!class_methods)
4769 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, 0));
4770 else
4772 expr = convert (objc_method_proto_list_ptr,
4773 build_unary_op (input_location,
4774 ADDR_EXPR, class_methods, 0));
4775 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
4778 return objc_build_constructor (type, inits);
4781 /* struct _objc_category {
4782 char *category_name;
4783 char *class_name;
4784 struct _objc_method_list *instance_methods;
4785 struct _objc_method_list *class_methods;
4786 struct _objc_protocol_list *protocols;
4787 }; */
4789 static void
4790 build_category_template (void)
4792 tree ptype, decls, *chain = NULL;
4794 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
4796 /* char *category_name; */
4797 decls = add_field_decl (string_type_node, "category_name", &chain);
4799 /* char *class_name; */
4800 add_field_decl (string_type_node, "class_name", &chain);
4802 /* struct _objc_method_list *instance_methods; */
4803 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
4805 /* struct _objc_method_list *class_methods; */
4806 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
4808 /* struct _objc_protocol **protocol_list; */
4809 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
4810 add_field_decl (ptype, "protocol_list", &chain);
4812 objc_finish_struct (objc_category_template, decls);
4815 /* struct _objc_selector {
4816 SEL sel_id;
4817 char *sel_type;
4818 }; */
4820 static void
4821 build_selector_template (void)
4823 tree decls, *chain = NULL;
4825 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
4827 /* SEL sel_id; */
4828 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
4830 /* char *sel_type; */
4831 add_field_decl (string_type_node, "sel_type", &chain);
4833 objc_finish_struct (objc_selector_template, decls);
4836 /* struct _objc_class {
4837 struct _objc_class *isa;
4838 struct _objc_class *super_class;
4839 char *name;
4840 long version;
4841 long info;
4842 long instance_size;
4843 struct _objc_ivar_list *ivars;
4844 struct _objc_method_list *methods;
4845 #ifdef __NEXT_RUNTIME__
4846 struct objc_cache *cache;
4847 #else
4848 struct sarray *dtable;
4849 struct _objc_class *subclass_list;
4850 struct _objc_class *sibling_class;
4851 #endif
4852 struct _objc_protocol_list *protocols;
4853 #ifdef __NEXT_RUNTIME__
4854 void *sel_id;
4855 #endif
4856 void *gc_object_type;
4857 }; */
4859 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4860 the NeXT/Apple runtime; still, the compiler must generate them to
4861 maintain backward binary compatibility (and to allow for future
4862 expansion). */
4864 static void
4865 build_class_template (void)
4867 tree ptype, decls, *chain = NULL;
4869 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
4871 /* struct _objc_class *isa; */
4872 decls = add_field_decl (build_pointer_type (objc_class_template),
4873 "isa", &chain);
4875 /* struct _objc_class *super_class; */
4876 add_field_decl (build_pointer_type (objc_class_template),
4877 "super_class", &chain);
4879 /* char *name; */
4880 add_field_decl (string_type_node, "name", &chain);
4882 /* long version; */
4883 add_field_decl (long_integer_type_node, "version", &chain);
4885 /* long info; */
4886 add_field_decl (long_integer_type_node, "info", &chain);
4888 /* long instance_size; */
4889 add_field_decl (long_integer_type_node, "instance_size", &chain);
4891 /* struct _objc_ivar_list *ivars; */
4892 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
4894 /* struct _objc_method_list *methods; */
4895 add_field_decl (objc_method_list_ptr, "methods", &chain);
4897 if (flag_next_runtime)
4899 /* struct objc_cache *cache; */
4900 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
4901 get_identifier ("objc_cache")));
4902 add_field_decl (ptype, "cache", &chain);
4904 else
4906 /* struct sarray *dtable; */
4907 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
4908 get_identifier ("sarray")));
4909 add_field_decl (ptype, "dtable", &chain);
4911 /* struct objc_class *subclass_list; */
4912 ptype = build_pointer_type (objc_class_template);
4913 add_field_decl (ptype, "subclass_list", &chain);
4915 /* struct objc_class *sibling_class; */
4916 ptype = build_pointer_type (objc_class_template);
4917 add_field_decl (ptype, "sibling_class", &chain);
4920 /* struct _objc_protocol **protocol_list; */
4921 ptype = build_pointer_type (build_pointer_type
4922 (xref_tag (RECORD_TYPE,
4923 get_identifier (UTAG_PROTOCOL))));
4924 add_field_decl (ptype, "protocol_list", &chain);
4926 if (flag_next_runtime)
4928 /* void *sel_id; */
4929 add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain);
4932 /* void *gc_object_type; */
4933 add_field_decl (build_pointer_type (void_type_node),
4934 "gc_object_type", &chain);
4936 objc_finish_struct (objc_class_template, decls);
4939 /* Generate appropriate forward declarations for an implementation. */
4941 static void
4942 synth_forward_declarations (void)
4944 tree an_id;
4946 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4947 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4948 objc_class_template);
4950 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4951 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4952 objc_class_template);
4954 /* Pre-build the following entities - for speed/convenience. */
4956 an_id = get_identifier ("super_class");
4957 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4958 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4961 static void
4962 error_with_ivar (const char *message, tree decl)
4964 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
4965 message, identifier_to_locale (gen_declaration (decl)));
4969 static void
4970 check_ivars (tree inter, tree imp)
4972 tree intdecls = CLASS_RAW_IVARS (inter);
4973 tree impdecls = CLASS_RAW_IVARS (imp);
4975 while (1)
4977 tree t1, t2;
4979 #ifdef OBJCPLUS
4980 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4981 intdecls = TREE_CHAIN (intdecls);
4982 #endif
4983 if (intdecls == 0 && impdecls == 0)
4984 break;
4985 if (intdecls == 0 || impdecls == 0)
4987 error ("inconsistent instance variable specification");
4988 break;
4991 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4993 if (!comptypes (t1, t2)
4994 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4995 DECL_INITIAL (impdecls)))
4997 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4999 error_with_ivar ("conflicting instance variable type",
5000 impdecls);
5001 error_with_ivar ("previous declaration of",
5002 intdecls);
5004 else /* both the type and the name don't match */
5006 error ("inconsistent instance variable specification");
5007 break;
5011 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5013 error_with_ivar ("conflicting instance variable name",
5014 impdecls);
5015 error_with_ivar ("previous declaration of",
5016 intdecls);
5019 intdecls = DECL_CHAIN (intdecls);
5020 impdecls = DECL_CHAIN (impdecls);
5024 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5025 This needs to be done just once per compilation. */
5027 /* struct _objc_super {
5028 struct _objc_object *self;
5029 struct _objc_class *super_class;
5030 }; */
5032 static void
5033 build_super_template (void)
5035 tree decls, *chain = NULL;
5037 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5039 /* struct _objc_object *self; */
5040 decls = add_field_decl (objc_object_type, "self", &chain);
5042 /* struct _objc_class *super_class; */
5043 add_field_decl (build_pointer_type (objc_class_template),
5044 "super_class", &chain);
5046 objc_finish_struct (objc_super_template, decls);
5049 /* struct _objc_ivar {
5050 char *ivar_name;
5051 char *ivar_type;
5052 int ivar_offset;
5053 }; */
5055 static tree
5056 build_ivar_template (void)
5058 tree objc_ivar_id, objc_ivar_record;
5059 tree decls, *chain = NULL;
5061 objc_ivar_id = get_identifier (UTAG_IVAR);
5062 objc_ivar_record = objc_start_struct (objc_ivar_id);
5064 /* char *ivar_name; */
5065 decls = add_field_decl (string_type_node, "ivar_name", &chain);
5067 /* char *ivar_type; */
5068 add_field_decl (string_type_node, "ivar_type", &chain);
5070 /* int ivar_offset; */
5071 add_field_decl (integer_type_node, "ivar_offset", &chain);
5073 objc_finish_struct (objc_ivar_record, decls);
5075 return objc_ivar_record;
5078 /* struct {
5079 int ivar_count;
5080 struct objc_ivar ivar_list[ivar_count];
5081 }; */
5083 static tree
5084 build_ivar_list_template (tree list_type, int size)
5086 tree objc_ivar_list_record;
5087 tree array_type, decls, *chain = NULL;
5089 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5091 /* int ivar_count; */
5092 decls = add_field_decl (integer_type_node, "ivar_count", &chain);
5094 /* struct objc_ivar ivar_list[]; */
5095 array_type = build_sized_array_type (list_type, size);
5096 add_field_decl (array_type, "ivar_list", &chain);
5098 objc_finish_struct (objc_ivar_list_record, decls);
5100 return objc_ivar_list_record;
5103 /* struct {
5104 struct _objc__method_prototype_list *method_next;
5105 int method_count;
5106 struct objc_method method_list[method_count];
5107 }; */
5109 static tree
5110 build_method_list_template (tree list_type, int size)
5112 tree objc_ivar_list_record;
5113 tree array_type, decls, *chain = NULL;
5115 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5117 /* struct _objc__method_prototype_list *method_next; */
5118 decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
5120 /* int method_count; */
5121 add_field_decl (integer_type_node, "method_count", &chain);
5123 /* struct objc_method method_list[]; */
5124 array_type = build_sized_array_type (list_type, size);
5125 add_field_decl (array_type, "method_list", &chain);
5127 objc_finish_struct (objc_ivar_list_record, decls);
5129 return objc_ivar_list_record;
5132 static tree
5133 build_ivar_list_initializer (tree type, tree field_decl)
5135 VEC(constructor_elt,gc) *inits = NULL;
5139 VEC(constructor_elt,gc) *ivar = NULL;
5140 tree id;
5142 /* Set name. */
5143 if (DECL_NAME (field_decl))
5144 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
5145 add_objc_string (DECL_NAME (field_decl),
5146 meth_var_names));
5147 else
5148 /* Unnamed bit-field ivar (yuck). */
5149 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
5151 /* Set type. */
5152 encode_field_decl (field_decl,
5153 obstack_object_size (&util_obstack),
5154 OBJC_ENCODE_DONT_INLINE_DEFS);
5156 /* Null terminate string. */
5157 obstack_1grow (&util_obstack, 0);
5158 id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5159 meth_var_types);
5160 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
5161 obstack_free (&util_obstack, util_firstobj);
5163 /* Set offset. */
5164 CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
5165 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5166 objc_build_constructor (type, ivar));
5168 field_decl = DECL_CHAIN (field_decl);
5169 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5171 while (field_decl);
5173 return objc_build_constructor (build_array_type (type, 0), inits);
5176 static tree
5177 generate_ivars_list (tree type, const char *name, int size, tree list)
5179 tree decl;
5180 VEC(constructor_elt,gc) *inits = NULL;
5182 decl = start_var_decl (type, synth_id_with_class_suffix
5183 (name, objc_implementation_context));
5185 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
5186 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, list);
5188 finish_var_decl (decl,
5189 objc_build_constructor (TREE_TYPE (decl), inits));
5191 return decl;
5194 /* Count only the fields occurring in T. */
5196 static int
5197 ivar_list_length (tree t)
5199 int count = 0;
5201 for (; t; t = DECL_CHAIN (t))
5202 if (TREE_CODE (t) == FIELD_DECL)
5203 ++count;
5205 return count;
5208 static void
5209 generate_ivar_lists (void)
5211 tree initlist, ivar_list_template, chain;
5212 int size;
5214 generating_instance_variables = 1;
5216 if (!objc_ivar_template)
5217 objc_ivar_template = build_ivar_template ();
5219 /* Only generate class variables for the root of the inheritance
5220 hierarchy since these will be the same for every class. */
5222 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5223 && (chain = TYPE_FIELDS (objc_class_template)))
5225 size = ivar_list_length (chain);
5227 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5228 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5230 UOBJC_CLASS_VARIABLES_decl
5231 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5232 size, initlist);
5234 else
5235 UOBJC_CLASS_VARIABLES_decl = 0;
5237 chain = CLASS_IVARS (implementation_template);
5238 if (chain)
5240 size = ivar_list_length (chain);
5241 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5242 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5244 UOBJC_INSTANCE_VARIABLES_decl
5245 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5246 size, initlist);
5248 else
5249 UOBJC_INSTANCE_VARIABLES_decl = 0;
5251 generating_instance_variables = 0;
5254 static tree
5255 build_dispatch_table_initializer (tree type, tree entries)
5257 VEC(constructor_elt,gc) *inits = NULL;
5261 VEC(constructor_elt,gc) *elems = NULL;
5262 tree expr;
5264 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5265 build_selector (METHOD_SEL_NAME (entries)));
5267 /* Generate the method encoding if we don't have one already. */
5268 if (! METHOD_ENCODING (entries))
5269 METHOD_ENCODING (entries) =
5270 encode_method_prototype (entries);
5272 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
5273 add_objc_string (METHOD_ENCODING (entries),
5274 meth_var_types));
5276 expr = convert (ptr_type_node,
5277 build_unary_op (input_location, ADDR_EXPR,
5278 METHOD_DEFINITION (entries), 1));
5279 CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
5281 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
5282 objc_build_constructor (type, elems));
5284 entries = DECL_CHAIN (entries);
5286 while (entries);
5288 return objc_build_constructor (build_array_type (type, 0), inits);
5291 /* To accomplish method prototyping without generating all kinds of
5292 inane warnings, the definition of the dispatch table entries were
5293 changed from:
5295 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5297 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5299 static tree
5300 build_method_template (void)
5302 tree _SLT_record;
5303 tree decls, *chain = NULL;
5305 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5307 /* SEL _cmd; */
5308 decls = add_field_decl (objc_selector_type, "_cmd", &chain);
5310 /* char *method_types; */
5311 add_field_decl (string_type_node, "method_types", &chain);
5313 /* void *_imp; */
5314 add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
5316 objc_finish_struct (_SLT_record, decls);
5318 return _SLT_record;
5322 static tree
5323 generate_dispatch_table (tree type, const char *name, int size, tree list)
5325 tree decl;
5326 VEC(constructor_elt,gc) *v = NULL;
5328 decl = start_var_decl (type, synth_id_with_class_suffix
5329 (name, objc_implementation_context));
5331 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
5332 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, size));
5333 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, list);
5335 finish_var_decl (decl,
5336 objc_build_constructor (TREE_TYPE (decl), v));
5338 return decl;
5341 static void
5342 mark_referenced_methods (void)
5344 struct imp_entry *impent;
5345 tree chain;
5347 for (impent = imp_list; impent; impent = impent->next)
5349 chain = CLASS_CLS_METHODS (impent->imp_context);
5350 while (chain)
5352 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5353 chain = DECL_CHAIN (chain);
5356 chain = CLASS_NST_METHODS (impent->imp_context);
5357 while (chain)
5359 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5360 chain = DECL_CHAIN (chain);
5365 static void
5366 generate_dispatch_tables (void)
5368 tree initlist, chain, method_list_template;
5369 int size;
5371 if (!objc_method_template)
5372 objc_method_template = build_method_template ();
5374 chain = CLASS_CLS_METHODS (objc_implementation_context);
5375 if (chain)
5377 size = list_length (chain);
5379 method_list_template
5380 = build_method_list_template (objc_method_template, size);
5381 initlist
5382 = build_dispatch_table_initializer (objc_method_template, chain);
5384 UOBJC_CLASS_METHODS_decl
5385 = generate_dispatch_table (method_list_template,
5386 ((TREE_CODE (objc_implementation_context)
5387 == CLASS_IMPLEMENTATION_TYPE)
5388 ? "_OBJC_CLASS_METHODS"
5389 : "_OBJC_CATEGORY_CLASS_METHODS"),
5390 size, initlist);
5392 else
5393 UOBJC_CLASS_METHODS_decl = 0;
5395 chain = CLASS_NST_METHODS (objc_implementation_context);
5396 if (chain)
5398 size = list_length (chain);
5400 method_list_template
5401 = build_method_list_template (objc_method_template, size);
5402 initlist
5403 = build_dispatch_table_initializer (objc_method_template, chain);
5405 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5406 UOBJC_INSTANCE_METHODS_decl
5407 = generate_dispatch_table (method_list_template,
5408 "_OBJC_INSTANCE_METHODS",
5409 size, initlist);
5410 else
5411 /* We have a category. */
5412 UOBJC_INSTANCE_METHODS_decl
5413 = generate_dispatch_table (method_list_template,
5414 "_OBJC_CATEGORY_INSTANCE_METHODS",
5415 size, initlist);
5417 else
5418 UOBJC_INSTANCE_METHODS_decl = 0;
5421 static tree
5422 generate_protocol_list (tree i_or_p)
5424 tree array_type, ptype, refs_decl, lproto, e, plist;
5425 int size = 0;
5426 const char *ref_name;
5427 VEC(constructor_elt,gc) *v = NULL;
5429 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5430 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5431 plist = CLASS_PROTOCOL_LIST (i_or_p);
5432 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5433 plist = PROTOCOL_LIST (i_or_p);
5434 else
5435 abort ();
5437 /* Compute size. */
5438 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5439 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5440 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5441 size++;
5443 /* Build initializer. */
5444 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5445 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5446 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
5448 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5450 tree pval = TREE_VALUE (lproto);
5452 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5453 && PROTOCOL_FORWARD_DECL (pval))
5455 e = build_unary_op (input_location, ADDR_EXPR,
5456 PROTOCOL_FORWARD_DECL (pval), 0);
5457 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
5461 /* static struct objc_protocol *refs[n]; */
5463 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5464 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5465 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5466 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5467 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5468 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5469 else
5470 abort ();
5472 ptype = build_pointer_type (objc_protocol_template);
5473 array_type = build_sized_array_type (ptype, size + 3);
5474 refs_decl = start_var_decl (array_type, ref_name);
5476 finish_var_decl (refs_decl,
5477 objc_build_constructor (TREE_TYPE (refs_decl), v));
5479 return refs_decl;
5482 static tree
5483 build_category_initializer (tree type, tree cat_name, tree class_name,
5484 tree instance_methods, tree class_methods,
5485 tree protocol_list)
5487 tree expr;
5488 VEC(constructor_elt,gc) *v = NULL;
5490 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
5491 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
5493 if (!instance_methods)
5494 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5495 else
5497 expr = convert (objc_method_list_ptr,
5498 build_unary_op (input_location, ADDR_EXPR,
5499 instance_methods, 0));
5500 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5502 if (!class_methods)
5503 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5504 else
5506 expr = convert (objc_method_list_ptr,
5507 build_unary_op (input_location, ADDR_EXPR,
5508 class_methods, 0));
5509 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5512 /* protocol_list = */
5513 if (!protocol_list)
5514 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5515 else
5517 expr = convert (build_pointer_type
5518 (build_pointer_type
5519 (objc_protocol_template)),
5520 build_unary_op (input_location, ADDR_EXPR,
5521 protocol_list, 0));
5522 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5525 return objc_build_constructor (type, v);
5528 /* struct _objc_class {
5529 struct objc_class *isa;
5530 struct objc_class *super_class;
5531 char *name;
5532 long version;
5533 long info;
5534 long instance_size;
5535 struct objc_ivar_list *ivars;
5536 struct objc_method_list *methods;
5537 if (flag_next_runtime)
5538 struct objc_cache *cache;
5539 else {
5540 struct sarray *dtable;
5541 struct objc_class *subclass_list;
5542 struct objc_class *sibling_class;
5544 struct objc_protocol_list *protocols;
5545 if (flag_next_runtime)
5546 void *sel_id;
5547 void *gc_object_type;
5548 }; */
5550 static tree
5551 build_shared_structure_initializer (tree type, tree isa, tree super,
5552 tree name, tree size, int status,
5553 tree dispatch_table, tree ivar_list,
5554 tree protocol_list)
5556 tree expr;
5557 VEC(constructor_elt,gc) *v = NULL;
5559 /* isa = */
5560 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
5562 /* super_class = */
5563 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
5565 /* name = */
5566 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
5568 /* version = */
5569 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
5570 build_int_cst (long_integer_type_node, 0));
5572 /* info = */
5573 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
5574 build_int_cst (long_integer_type_node, status));
5576 /* instance_size = */
5577 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
5578 convert (long_integer_type_node, size));
5580 /* objc_ivar_list = */
5581 if (!ivar_list)
5582 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5583 else
5585 expr = convert (objc_ivar_list_ptr,
5586 build_unary_op (input_location, ADDR_EXPR,
5587 ivar_list, 0));
5588 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5591 /* objc_method_list = */
5592 if (!dispatch_table)
5593 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5594 else
5596 expr = convert (objc_method_list_ptr,
5597 build_unary_op (input_location, ADDR_EXPR,
5598 dispatch_table, 0));
5599 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5602 if (flag_next_runtime)
5603 /* method_cache = */
5604 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5605 else
5607 /* dtable = */
5608 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5610 /* subclass_list = */
5611 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5613 /* sibling_class = */
5614 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5617 /* protocol_list = */
5618 if (! protocol_list)
5619 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5620 else
5622 expr = convert (build_pointer_type
5623 (build_pointer_type
5624 (objc_protocol_template)),
5625 build_unary_op (input_location, ADDR_EXPR,
5626 protocol_list, 0));
5627 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
5630 if (flag_next_runtime)
5631 /* sel_id = NULL */
5632 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5634 /* gc_object_type = NULL */
5635 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
5637 return objc_build_constructor (type, v);
5640 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5642 static inline tree
5643 lookup_category (tree klass, tree cat_name)
5645 tree category = CLASS_CATEGORY_LIST (klass);
5647 while (category && CLASS_SUPER_NAME (category) != cat_name)
5648 category = CLASS_CATEGORY_LIST (category);
5649 return category;
5652 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5654 static void
5655 generate_category (struct imp_entry *impent)
5657 tree initlist, cat_name_expr, class_name_expr;
5658 tree protocol_decl, category;
5659 tree cat = impent->imp_context;
5661 implementation_template = impent->imp_template;
5662 UOBJC_CLASS_decl = impent->class_decl;
5663 UOBJC_METACLASS_decl = impent->meta_decl;
5665 add_class_reference (CLASS_NAME (cat));
5666 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5668 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5670 category = lookup_category (implementation_template,
5671 CLASS_SUPER_NAME (cat));
5673 if (category && CLASS_PROTOCOL_LIST (category))
5675 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5676 protocol_decl = generate_protocol_list (category);
5678 else
5679 protocol_decl = 0;
5681 initlist = build_category_initializer (TREE_TYPE (UOBJC_CLASS_decl),
5682 cat_name_expr, class_name_expr,
5683 UOBJC_INSTANCE_METHODS_decl,
5684 UOBJC_CLASS_METHODS_decl,
5685 protocol_decl);
5686 /* Finish and initialize the forward decl. */
5687 finish_var_decl (UOBJC_CLASS_decl, initlist);
5690 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5691 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5693 static void
5694 generate_shared_structures (struct imp_entry *impent)
5696 tree name_expr, super_expr, root_expr;
5697 tree my_root_id, my_super_id;
5698 tree cast_type, initlist, protocol_decl;
5699 int cls_flags;
5701 objc_implementation_context = impent->imp_context;
5702 implementation_template = impent->imp_template;
5703 UOBJC_CLASS_decl = impent->class_decl;
5704 UOBJC_METACLASS_decl = impent->meta_decl;
5705 cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ;
5707 my_super_id = CLASS_SUPER_NAME (implementation_template);
5708 if (my_super_id)
5710 add_class_reference (my_super_id);
5712 /* Compute "my_root_id" - this is required for code generation.
5713 the "isa" for all meta class structures points to the root of
5714 the inheritance hierarchy (e.g. "__Object")... */
5715 my_root_id = my_super_id;
5718 tree my_root_int = lookup_interface (my_root_id);
5720 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5721 my_root_id = CLASS_SUPER_NAME (my_root_int);
5722 else
5723 break;
5725 while (1);
5727 else
5728 /* No super class. */
5729 my_root_id = CLASS_NAME (implementation_template);
5731 cast_type = build_pointer_type (objc_class_template);
5732 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5733 class_names);
5735 /* Install class `isa' and `super' pointers at runtime. */
5736 if (my_super_id)
5737 super_expr = add_objc_string (my_super_id, class_names);
5738 else
5739 super_expr = integer_zero_node;
5741 super_expr = build_c_cast (input_location,
5742 cast_type, super_expr); /* cast! */
5744 root_expr = add_objc_string (my_root_id, class_names);
5745 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
5747 if (CLASS_PROTOCOL_LIST (implementation_template))
5749 generate_protocol_references
5750 (CLASS_PROTOCOL_LIST (implementation_template));
5751 protocol_decl = generate_protocol_list (implementation_template);
5753 else
5754 protocol_decl = 0;
5756 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5758 initlist
5759 = build_shared_structure_initializer
5760 (TREE_TYPE (UOBJC_METACLASS_decl),
5761 root_expr, super_expr, name_expr,
5762 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5763 2 /*CLS_META*/,
5764 UOBJC_CLASS_METHODS_decl,
5765 UOBJC_CLASS_VARIABLES_decl,
5766 protocol_decl);
5768 finish_var_decl (UOBJC_METACLASS_decl, initlist);
5770 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5772 initlist
5773 = build_shared_structure_initializer
5774 (TREE_TYPE (UOBJC_CLASS_decl),
5775 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5776 super_expr, name_expr,
5777 convert (integer_type_node,
5778 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5779 (implementation_template))),
5780 1 /*CLS_FACTORY*/ | cls_flags,
5781 UOBJC_INSTANCE_METHODS_decl,
5782 UOBJC_INSTANCE_VARIABLES_decl,
5783 protocol_decl);
5785 finish_var_decl (UOBJC_CLASS_decl, initlist);
5789 static const char *
5790 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5792 static char string[BUFSIZE];
5794 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5795 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5797 sprintf (string, "%s_%s", preamble,
5798 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5800 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5801 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5803 /* We have a category. */
5804 const char *const class_name
5805 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5806 const char *const class_super_name
5807 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5808 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5810 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5812 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5813 sprintf (string, "%s_%s", preamble, protocol_name);
5815 else
5816 abort ();
5818 return string;
5821 /* If type is empty or only type qualifiers are present, add default
5822 type of id (otherwise grokdeclarator will default to int). */
5824 static tree
5825 adjust_type_for_id_default (tree type)
5827 if (!type)
5828 type = make_node (TREE_LIST);
5830 if (!TREE_VALUE (type))
5831 TREE_VALUE (type) = objc_object_type;
5832 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5833 && TYPED_OBJECT (TREE_VALUE (type)))
5834 error ("can not use an object as parameter to a method");
5836 return type;
5839 /* Usage:
5840 keyworddecl:
5841 selector ':' '(' typename ')' identifier
5843 Purpose:
5844 Transform an Objective-C keyword argument into
5845 the C equivalent parameter declarator.
5847 In: key_name, an "identifier_node" (optional).
5848 arg_type, a "tree_list" (optional).
5849 arg_name, an "identifier_node".
5851 Note: It would be really nice to strongly type the preceding
5852 arguments in the function prototype; however, then I
5853 could not use the "accessor" macros defined in "tree.h".
5855 Out: an instance of "keyword_decl". */
5857 tree
5858 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5860 tree keyword_decl;
5862 /* If no type is specified, default to "id". */
5863 arg_type = adjust_type_for_id_default (arg_type);
5865 keyword_decl = make_node (KEYWORD_DECL);
5867 TREE_TYPE (keyword_decl) = arg_type;
5868 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5869 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5871 return keyword_decl;
5874 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5876 static tree
5877 build_keyword_selector (tree selector)
5879 int len = 0;
5880 tree key_chain, key_name;
5881 char *buf;
5883 /* Scan the selector to see how much space we'll need. */
5884 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5886 if (TREE_CODE (selector) == KEYWORD_DECL)
5887 key_name = KEYWORD_KEY_NAME (key_chain);
5888 else if (TREE_CODE (selector) == TREE_LIST)
5889 key_name = TREE_PURPOSE (key_chain);
5890 else
5891 abort ();
5893 if (key_name)
5894 len += IDENTIFIER_LENGTH (key_name) + 1;
5895 else
5896 /* Just a ':' arg. */
5897 len++;
5900 buf = (char *) alloca (len + 1);
5901 /* Start the buffer out as an empty string. */
5902 buf[0] = '\0';
5904 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5906 if (TREE_CODE (selector) == KEYWORD_DECL)
5907 key_name = KEYWORD_KEY_NAME (key_chain);
5908 else if (TREE_CODE (selector) == TREE_LIST)
5910 key_name = TREE_PURPOSE (key_chain);
5911 /* The keyword decl chain will later be used as a function argument
5912 chain. Unhook the selector itself so as to not confuse other
5913 parts of the compiler. */
5914 TREE_PURPOSE (key_chain) = NULL_TREE;
5916 else
5917 abort ();
5919 if (key_name)
5920 strcat (buf, IDENTIFIER_POINTER (key_name));
5921 strcat (buf, ":");
5924 return get_identifier (buf);
5927 /* Used for declarations and definitions. */
5929 static tree
5930 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5931 tree add_args, bool ellipsis)
5933 tree method_decl;
5935 /* If no type is specified, default to "id". */
5936 ret_type = adjust_type_for_id_default (ret_type);
5938 method_decl = make_node (code);
5939 TREE_TYPE (method_decl) = ret_type;
5941 /* If we have a keyword selector, create an identifier_node that
5942 represents the full selector name (`:' included)... */
5943 if (TREE_CODE (selector) == KEYWORD_DECL)
5945 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5946 METHOD_SEL_ARGS (method_decl) = selector;
5947 METHOD_ADD_ARGS (method_decl) = add_args;
5948 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5950 else
5952 METHOD_SEL_NAME (method_decl) = selector;
5953 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5954 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5957 return method_decl;
5960 #define METHOD_DEF 0
5961 #define METHOD_REF 1
5963 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5964 an argument list for method METH. CONTEXT is either METHOD_DEF or
5965 METHOD_REF, saying whether we are trying to define a method or call
5966 one. SUPERFLAG says this is for a send to super; this makes a
5967 difference for the NeXT calling sequence in which the lookup and
5968 the method call are done together. If METH is null, user-defined
5969 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5971 static tree
5972 get_arg_type_list (tree meth, int context, int superflag)
5974 tree arglist, akey;
5976 /* Receiver type. */
5977 if (flag_next_runtime && superflag)
5978 arglist = build_tree_list (NULL_TREE, objc_super_type);
5979 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5980 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5981 else
5982 arglist = build_tree_list (NULL_TREE, objc_object_type);
5984 /* Selector type - will eventually change to `int'. */
5985 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5987 /* No actual method prototype given -- assume that remaining arguments
5988 are `...'. */
5989 if (!meth)
5990 return arglist;
5992 /* Build a list of argument types. */
5993 for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
5995 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5997 /* Decay arrays and functions into pointers. */
5998 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5999 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6000 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6001 arg_type = build_pointer_type (arg_type);
6003 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6006 if (METHOD_ADD_ARGS (meth))
6008 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6009 akey; akey = TREE_CHAIN (akey))
6011 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6013 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6016 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6017 goto lack_of_ellipsis;
6019 else
6021 lack_of_ellipsis:
6022 chainon (arglist, OBJC_VOID_AT_END);
6025 return arglist;
6028 static tree
6029 check_duplicates (hash hsh, int methods, int is_class)
6031 tree meth = NULL_TREE;
6033 if (hsh)
6035 meth = hsh->key;
6037 if (hsh->list)
6039 /* We have two or more methods with the same name but
6040 different types. */
6041 attr loop;
6043 /* But just how different are those types? If
6044 -Wno-strict-selector-match is specified, we shall not
6045 complain if the differences are solely among types with
6046 identical size and alignment. */
6047 if (!warn_strict_selector_match)
6049 for (loop = hsh->list; loop; loop = loop->next)
6050 if (!comp_proto_with_proto (meth, loop->value, 0))
6051 goto issue_warning;
6053 return meth;
6056 issue_warning:
6057 if (methods)
6059 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6061 warning_at (input_location, 0,
6062 "multiple methods named %<%c%E%> found",
6063 (is_class ? '+' : '-'),
6064 METHOD_SEL_NAME (meth));
6065 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6066 (type ? '-' : '+'),
6067 identifier_to_locale (gen_method_decl (meth)));
6069 else
6071 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6073 warning_at (input_location, 0,
6074 "multiple selectors named %<%c%E%> found",
6075 (is_class ? '+' : '-'),
6076 METHOD_SEL_NAME (meth));
6077 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6078 (type ? '-' : '+'),
6079 identifier_to_locale (gen_method_decl (meth)));
6082 for (loop = hsh->list; loop; loop = loop->next)
6084 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6086 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6087 (type ? '-' : '+'),
6088 identifier_to_locale (gen_method_decl (loop->value)));
6092 return meth;
6095 /* If RECEIVER is a class reference, return the identifier node for
6096 the referenced class. RECEIVER is created by objc_get_class_reference,
6097 so we check the exact form created depending on which runtimes are
6098 used. */
6100 static tree
6101 receiver_is_class_object (tree receiver, int self, int super)
6103 tree chain, exp, arg;
6105 /* The receiver is 'self' or 'super' in the context of a class method. */
6106 if (objc_method_context
6107 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6108 && (self || super))
6109 return (super
6110 ? CLASS_SUPER_NAME (implementation_template)
6111 : CLASS_NAME (implementation_template));
6113 if (flag_next_runtime)
6115 /* The receiver is a variable created by
6116 build_class_reference_decl. */
6117 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6118 /* Look up the identifier. */
6119 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6120 if (TREE_PURPOSE (chain) == receiver)
6121 return TREE_VALUE (chain);
6124 /* The receiver is a function call that returns an id. Check if
6125 it is a call to objc_getClass, if so, pick up the class name. */
6126 if (TREE_CODE (receiver) == CALL_EXPR
6127 && (exp = CALL_EXPR_FN (receiver))
6128 && TREE_CODE (exp) == ADDR_EXPR
6129 && (exp = TREE_OPERAND (exp, 0))
6130 && TREE_CODE (exp) == FUNCTION_DECL
6131 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6132 prototypes for objc_get_class(). Thankfully, they seem to share the
6133 same function type. */
6134 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6135 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6136 /* We have a call to objc_get_class/objc_getClass! */
6137 && (arg = CALL_EXPR_ARG (receiver, 0)))
6139 STRIP_NOPS (arg);
6140 if (TREE_CODE (arg) == ADDR_EXPR
6141 && (arg = TREE_OPERAND (arg, 0))
6142 && TREE_CODE (arg) == STRING_CST)
6143 /* Finally, we have the class name. */
6144 return get_identifier (TREE_STRING_POINTER (arg));
6146 return 0;
6149 /* If we are currently building a message expr, this holds
6150 the identifier of the selector of the message. This is
6151 used when printing warnings about argument mismatches. */
6153 static tree current_objc_message_selector = 0;
6155 tree
6156 objc_message_selector (void)
6158 return current_objc_message_selector;
6161 /* Construct an expression for sending a message.
6162 MESS has the object to send to in TREE_PURPOSE
6163 and the argument list (including selector) in TREE_VALUE.
6165 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6166 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6168 tree
6169 objc_build_message_expr (tree mess)
6171 tree receiver = TREE_PURPOSE (mess);
6172 tree sel_name;
6173 #ifdef OBJCPLUS
6174 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6175 #else
6176 tree args = TREE_VALUE (mess);
6177 #endif
6178 tree method_params = NULL_TREE;
6180 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6181 return error_mark_node;
6183 /* Obtain the full selector name. */
6184 if (TREE_CODE (args) == IDENTIFIER_NODE)
6185 /* A unary selector. */
6186 sel_name = args;
6187 else if (TREE_CODE (args) == TREE_LIST)
6188 sel_name = build_keyword_selector (args);
6189 else
6190 abort ();
6192 /* Build the parameter list to give to the method. */
6193 if (TREE_CODE (args) == TREE_LIST)
6194 #ifdef OBJCPLUS
6195 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6196 #else
6198 tree chain = args, prev = NULL_TREE;
6200 /* We have a keyword selector--check for comma expressions. */
6201 while (chain)
6203 tree element = TREE_VALUE (chain);
6205 /* We have a comma expression, must collapse... */
6206 if (TREE_CODE (element) == TREE_LIST)
6208 if (prev)
6209 TREE_CHAIN (prev) = element;
6210 else
6211 args = element;
6213 prev = chain;
6214 chain = TREE_CHAIN (chain);
6216 method_params = args;
6218 #endif
6220 #ifdef OBJCPLUS
6221 if (processing_template_decl)
6222 /* Must wait until template instantiation time. */
6223 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6224 method_params);
6225 #endif
6227 return objc_finish_message_expr (receiver, sel_name, method_params);
6230 /* Look up method SEL_NAME that would be suitable for receiver
6231 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6232 nonzero), and report on any duplicates. */
6234 static tree
6235 lookup_method_in_hash_lists (tree sel_name, int is_class)
6237 hash method_prototype = NULL;
6239 if (!is_class)
6240 method_prototype = hash_lookup (nst_method_hash_list,
6241 sel_name);
6243 if (!method_prototype)
6245 method_prototype = hash_lookup (cls_method_hash_list,
6246 sel_name);
6247 is_class = 1;
6250 return check_duplicates (method_prototype, 1, is_class);
6253 /* The 'objc_finish_message_expr' routine is called from within
6254 'objc_build_message_expr' for non-template functions. In the case of
6255 C++ template functions, it is called from 'build_expr_from_tree'
6256 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6258 tree
6259 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6261 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6262 tree selector, retval, class_tree;
6263 int self, super, have_cast;
6265 /* Extract the receiver of the message, as well as its type
6266 (where the latter may take the form of a cast or be inferred
6267 from the implementation context). */
6268 rtype = receiver;
6269 while (TREE_CODE (rtype) == COMPOUND_EXPR
6270 || TREE_CODE (rtype) == MODIFY_EXPR
6271 || CONVERT_EXPR_P (rtype)
6272 || TREE_CODE (rtype) == COMPONENT_REF)
6273 rtype = TREE_OPERAND (rtype, 0);
6274 self = (rtype == self_decl);
6275 super = (rtype == UOBJC_SUPER_decl);
6276 rtype = TREE_TYPE (receiver);
6277 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6278 || (TREE_CODE (receiver) == COMPOUND_EXPR
6279 && !IS_SUPER (rtype)));
6281 /* If we are calling [super dealloc], reset our warning flag. */
6282 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6283 should_call_super_dealloc = 0;
6285 /* If the receiver is a class object, retrieve the corresponding
6286 @interface, if one exists. */
6287 class_tree = receiver_is_class_object (receiver, self, super);
6289 /* Now determine the receiver type (if an explicit cast has not been
6290 provided). */
6291 if (!have_cast)
6293 if (class_tree)
6294 rtype = lookup_interface (class_tree);
6295 /* Handle `self' and `super'. */
6296 else if (super)
6298 if (!CLASS_SUPER_NAME (implementation_template))
6300 error ("no super class declared in @interface for %qE",
6301 CLASS_NAME (implementation_template));
6302 return error_mark_node;
6304 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6306 else if (self)
6307 rtype = lookup_interface (CLASS_NAME (implementation_template));
6310 /* If receiver is of type `id' or `Class' (or if the @interface for a
6311 class is not visible), we shall be satisfied with the existence of
6312 any instance or class method. */
6313 if (objc_is_id (rtype))
6315 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6316 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6317 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6318 : NULL_TREE);
6319 rtype = NULL_TREE;
6321 if (rprotos)
6323 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6324 in protocols themselves for the method prototype. */
6325 method_prototype
6326 = lookup_method_in_protocol_list (rprotos, sel_name,
6327 class_tree != NULL_TREE);
6329 /* If messaging 'Class <Proto>' but did not find a class method
6330 prototype, search for an instance method instead, and warn
6331 about having done so. */
6332 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6334 method_prototype
6335 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6337 if (method_prototype)
6338 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
6339 sel_name, sel_name);
6343 else if (rtype)
6345 tree orig_rtype = rtype;
6347 if (TREE_CODE (rtype) == POINTER_TYPE)
6348 rtype = TREE_TYPE (rtype);
6349 /* Traverse typedef aliases */
6350 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6351 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6352 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6353 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6354 if (TYPED_OBJECT (rtype))
6356 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6357 rtype = TYPE_OBJC_INTERFACE (rtype);
6359 /* If we could not find an @interface declaration, we must have
6360 only seen a @class declaration; so, we cannot say anything
6361 more intelligent about which methods the receiver will
6362 understand. */
6363 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6364 rtype = NULL_TREE;
6365 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6366 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6368 /* We have a valid ObjC class name. Look up the method name
6369 in the published @interface for the class (and its
6370 superclasses). */
6371 method_prototype
6372 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6374 /* If the method was not found in the @interface, it may still
6375 exist locally as part of the @implementation. */
6376 if (!method_prototype && objc_implementation_context
6377 && CLASS_NAME (objc_implementation_context)
6378 == OBJC_TYPE_NAME (rtype))
6379 method_prototype
6380 = lookup_method
6381 ((class_tree
6382 ? CLASS_CLS_METHODS (objc_implementation_context)
6383 : CLASS_NST_METHODS (objc_implementation_context)),
6384 sel_name);
6386 /* If we haven't found a candidate method by now, try looking for
6387 it in the protocol list. */
6388 if (!method_prototype && rprotos)
6389 method_prototype
6390 = lookup_method_in_protocol_list (rprotos, sel_name,
6391 class_tree != NULL_TREE);
6393 else
6395 warning (0, "invalid receiver type %qs",
6396 identifier_to_locale (gen_type_name (orig_rtype)));
6397 /* After issuing the "invalid receiver" warning, perform method
6398 lookup as if we were messaging 'id'. */
6399 rtype = rprotos = NULL_TREE;
6404 /* For 'id' or 'Class' receivers, search in the global hash table
6405 as a last resort. For all receivers, warn if protocol searches
6406 have failed. */
6407 if (!method_prototype)
6409 if (rprotos)
6410 warning (0, "%<%c%E%> not found in protocol(s)",
6411 (class_tree ? '+' : '-'),
6412 sel_name);
6414 if (!rtype)
6415 method_prototype
6416 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6419 if (!method_prototype)
6421 static bool warn_missing_methods = false;
6423 if (rtype)
6424 warning (0, "%qE may not respond to %<%c%E%>",
6425 OBJC_TYPE_NAME (rtype),
6426 (class_tree ? '+' : '-'),
6427 sel_name);
6428 /* If we are messaging an 'id' or 'Class' object and made it here,
6429 then we have failed to find _any_ instance or class method,
6430 respectively. */
6431 else
6432 warning (0, "no %<%c%E%> method found",
6433 (class_tree ? '+' : '-'),
6434 sel_name);
6436 if (!warn_missing_methods)
6438 warning_at (input_location,
6439 0, "(Messages without a matching method signature");
6440 warning_at (input_location,
6441 0, "will be assumed to return %<id%> and accept");
6442 warning_at (input_location,
6443 0, "%<...%> as arguments.)");
6444 warn_missing_methods = true;
6448 /* Save the selector name for printing error messages. */
6449 current_objc_message_selector = sel_name;
6451 /* Build the parameters list for looking up the method.
6452 These are the object itself and the selector. */
6454 if (flag_typed_selectors)
6455 selector = build_typed_selector_reference (input_location,
6456 sel_name, method_prototype);
6457 else
6458 selector = build_selector_reference (input_location, sel_name);
6460 retval = build_objc_method_call (input_location, super, method_prototype,
6461 receiver,
6462 selector, method_params);
6464 current_objc_message_selector = 0;
6466 return retval;
6469 /* Build a tree expression to send OBJECT the operation SELECTOR,
6470 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6471 assuming the method has prototype METHOD_PROTOTYPE.
6472 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6473 LOC is the location of the expression to build.
6474 Use METHOD_PARAMS as list of args to pass to the method.
6475 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6477 static tree
6478 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
6479 tree lookup_object, tree selector,
6480 tree method_params)
6482 tree sender = (super_flag ? umsg_super_decl :
6483 (!flag_next_runtime || flag_nil_receivers
6484 ? (flag_objc_direct_dispatch
6485 ? umsg_fast_decl
6486 : umsg_decl)
6487 : umsg_nonnil_decl));
6488 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6490 /* If a prototype for the method to be called exists, then cast
6491 the sender's return type and arguments to match that of the method.
6492 Otherwise, leave sender as is. */
6493 tree ret_type
6494 = (method_prototype
6495 ? TREE_VALUE (TREE_TYPE (method_prototype))
6496 : objc_object_type);
6497 tree sender_cast
6498 = build_pointer_type
6499 (build_function_type
6500 (ret_type,
6501 get_arg_type_list
6502 (method_prototype, METHOD_REF, super_flag)));
6503 tree method, t;
6505 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
6507 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6508 lookup_object = save_expr (lookup_object);
6510 if (flag_next_runtime)
6512 /* If we are returning a struct in memory, and the address
6513 of that memory location is passed as a hidden first
6514 argument, then change which messenger entry point this
6515 expr will call. NB: Note that sender_cast remains
6516 unchanged (it already has a struct return type). */
6517 if (!targetm.calls.struct_value_rtx (0, 0)
6518 && (TREE_CODE (ret_type) == RECORD_TYPE
6519 || TREE_CODE (ret_type) == UNION_TYPE)
6520 && targetm.calls.return_in_memory (ret_type, 0))
6521 sender = (super_flag ? umsg_super_stret_decl :
6522 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6524 method_params = tree_cons (NULL_TREE, lookup_object,
6525 tree_cons (NULL_TREE, selector,
6526 method_params));
6527 method = build_fold_addr_expr_loc (input_location, sender);
6529 else
6531 /* This is the portable (GNU) way. */
6532 tree object;
6534 /* First, call the lookup function to get a pointer to the method,
6535 then cast the pointer, then call it with the method arguments. */
6537 object = (super_flag ? self_decl : lookup_object);
6539 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6540 t = tree_cons (NULL_TREE, lookup_object, t);
6541 method = build_function_call (loc, sender, t);
6543 /* Pass the object to the method. */
6544 method_params = tree_cons (NULL_TREE, object,
6545 tree_cons (NULL_TREE, selector,
6546 method_params));
6549 /* ??? Selector is not at this point something we can use inside
6550 the compiler itself. Set it to garbage for the nonce. */
6551 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6552 return build_function_call (loc,
6553 t, method_params);
6556 static void
6557 build_protocol_reference (tree p)
6559 tree decl;
6560 const char *proto_name;
6562 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6564 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6565 decl = start_var_decl (objc_protocol_template, proto_name);
6567 PROTOCOL_FORWARD_DECL (p) = decl;
6570 /* This function is called by the parser when (and only when) a
6571 @protocol() expression is found, in order to compile it. */
6572 tree
6573 objc_build_protocol_expr (tree protoname)
6575 tree expr;
6576 tree p = lookup_protocol (protoname);
6578 if (!p)
6580 error ("cannot find protocol declaration for %qE",
6581 protoname);
6582 return error_mark_node;
6585 if (!PROTOCOL_FORWARD_DECL (p))
6586 build_protocol_reference (p);
6588 expr = build_unary_op (input_location,
6589 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6591 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6592 if we have it, rather than converting it here. */
6593 expr = convert (objc_protocol_type, expr);
6595 /* The @protocol() expression is being compiled into a pointer to a
6596 statically allocated instance of the Protocol class. To become
6597 usable at runtime, the 'isa' pointer of the instance need to be
6598 fixed up at runtime by the runtime library, to point to the
6599 actual 'Protocol' class. */
6601 /* For the GNU runtime, put the static Protocol instance in the list
6602 of statically allocated instances, so that we make sure that its
6603 'isa' pointer is fixed up at runtime by the GNU runtime library
6604 to point to the Protocol class (at runtime, when loading the
6605 module, the GNU runtime library loops on the statically allocated
6606 instances (as found in the defs field in objc_symtab) and fixups
6607 all the 'isa' pointers of those objects). */
6608 if (! flag_next_runtime)
6610 /* This type is a struct containing the fields of a Protocol
6611 object. (Cfr. objc_protocol_type instead is the type of a pointer
6612 to such a struct). */
6613 tree protocol_struct_type = xref_tag
6614 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6615 tree *chain;
6617 /* Look for the list of Protocol statically allocated instances
6618 to fixup at runtime. Create a new list to hold Protocol
6619 statically allocated instances, if the list is not found. At
6620 present there is only another list, holding NSConstantString
6621 static instances to be fixed up at runtime. */
6622 for (chain = &objc_static_instances;
6623 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6624 chain = &TREE_CHAIN (*chain));
6625 if (!*chain)
6627 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6628 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6629 class_names);
6632 /* Add this statically allocated instance to the Protocol list. */
6633 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6634 PROTOCOL_FORWARD_DECL (p),
6635 TREE_PURPOSE (*chain));
6639 return expr;
6642 /* This function is called by the parser when a @selector() expression
6643 is found, in order to compile it. It is only called by the parser
6644 and only to compile a @selector(). LOC is the location of the
6645 @selector. */
6646 tree
6647 objc_build_selector_expr (location_t loc, tree selnamelist)
6649 tree selname;
6651 /* Obtain the full selector name. */
6652 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6653 /* A unary selector. */
6654 selname = selnamelist;
6655 else if (TREE_CODE (selnamelist) == TREE_LIST)
6656 selname = build_keyword_selector (selnamelist);
6657 else
6658 abort ();
6660 /* If we are required to check @selector() expressions as they
6661 are found, check that the selector has been declared. */
6662 if (warn_undeclared_selector)
6664 /* Look the selector up in the list of all known class and
6665 instance methods (up to this line) to check that the selector
6666 exists. */
6667 hash hsh;
6669 /* First try with instance methods. */
6670 hsh = hash_lookup (nst_method_hash_list, selname);
6672 /* If not found, try with class methods. */
6673 if (!hsh)
6675 hsh = hash_lookup (cls_method_hash_list, selname);
6678 /* If still not found, print out a warning. */
6679 if (!hsh)
6681 warning (0, "undeclared selector %qE", selname);
6686 if (flag_typed_selectors)
6687 return build_typed_selector_reference (loc, selname, 0);
6688 else
6689 return build_selector_reference (loc, selname);
6692 tree
6693 objc_build_encode_expr (tree type)
6695 tree result;
6696 const char *string;
6698 encode_type (type, obstack_object_size (&util_obstack),
6699 OBJC_ENCODE_INLINE_DEFS);
6700 obstack_1grow (&util_obstack, 0); /* null terminate string */
6701 string = XOBFINISH (&util_obstack, const char *);
6703 /* Synthesize a string that represents the encoded struct/union. */
6704 result = my_build_string (strlen (string) + 1, string);
6705 obstack_free (&util_obstack, util_firstobj);
6706 return result;
6709 static tree
6710 build_ivar_reference (tree id)
6712 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6714 /* Historically, a class method that produced objects (factory
6715 method) would assign `self' to the instance that it
6716 allocated. This would effectively turn the class method into
6717 an instance method. Following this assignment, the instance
6718 variables could be accessed. That practice, while safe,
6719 violates the simple rule that a class method should not refer
6720 to an instance variable. It's better to catch the cases
6721 where this is done unknowingly than to support the above
6722 paradigm. */
6723 warning (0, "instance variable %qE accessed in class method",
6724 id);
6725 self_decl = convert (objc_instance_type, self_decl); /* cast */
6728 return objc_build_component_ref (build_indirect_ref (input_location,
6729 self_decl, RO_ARROW),
6730 id);
6733 /* Compute a hash value for a given method SEL_NAME. */
6735 static size_t
6736 hash_func (tree sel_name)
6738 const unsigned char *s
6739 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6740 size_t h = 0;
6742 while (*s)
6743 h = h * 67 + *s++ - 113;
6744 return h;
6747 static void
6748 hash_init (void)
6750 nst_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
6751 cls_method_hash_list = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
6753 /* Initialize the hash table used to hold the constant string objects. */
6754 string_htab = htab_create_ggc (31, string_hash,
6755 string_eq, NULL);
6757 /* Initialize the hash table used to hold EH-volatilized types. */
6758 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6759 volatilized_eq, NULL);
6762 /* WARNING!!!! hash_enter is called with a method, and will peek
6763 inside to find its selector! But hash_lookup is given a selector
6764 directly, and looks for the selector that's inside the found
6765 entry's key (method) for comparison. */
6767 static void
6768 hash_enter (hash *hashlist, tree method)
6770 hash obj;
6771 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6773 obj = ggc_alloc_hashed_entry ();
6774 obj->list = 0;
6775 obj->next = hashlist[slot];
6776 obj->key = method;
6778 hashlist[slot] = obj; /* append to front */
6781 static hash
6782 hash_lookup (hash *hashlist, tree sel_name)
6784 hash target;
6786 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6788 while (target)
6790 if (sel_name == METHOD_SEL_NAME (target->key))
6791 return target;
6793 target = target->next;
6795 return 0;
6798 static void
6799 hash_add_attr (hash entry, tree value)
6801 attr obj;
6803 obj = ggc_alloc_hashed_attribute ();
6804 obj->next = entry->list;
6805 obj->value = value;
6807 entry->list = obj; /* append to front */
6810 static tree
6811 lookup_method (tree mchain, tree method)
6813 tree key;
6815 if (TREE_CODE (method) == IDENTIFIER_NODE)
6816 key = method;
6817 else
6818 key = METHOD_SEL_NAME (method);
6820 while (mchain)
6822 if (METHOD_SEL_NAME (mchain) == key)
6823 return mchain;
6825 mchain = DECL_CHAIN (mchain);
6827 return NULL_TREE;
6830 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6831 in INTERFACE, along with any categories and protocols attached thereto.
6832 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6833 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6834 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6835 be found in INTERFACE or any of its superclasses, look for an _instance_
6836 method of the same name in the root class as a last resort.
6838 If a suitable method cannot be found, return NULL_TREE. */
6840 static tree
6841 lookup_method_static (tree interface, tree ident, int flags)
6843 tree meth = NULL_TREE, root_inter = NULL_TREE;
6844 tree inter = interface;
6845 int is_class = (flags & OBJC_LOOKUP_CLASS);
6846 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6848 while (inter)
6850 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6851 tree category = inter;
6853 /* First, look up the method in the class itself. */
6854 if ((meth = lookup_method (chain, ident)))
6855 return meth;
6857 /* Failing that, look for the method in each category of the class. */
6858 while ((category = CLASS_CATEGORY_LIST (category)))
6860 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6862 /* Check directly in each category. */
6863 if ((meth = lookup_method (chain, ident)))
6864 return meth;
6866 /* Failing that, check in each category's protocols. */
6867 if (CLASS_PROTOCOL_LIST (category))
6869 if ((meth = (lookup_method_in_protocol_list
6870 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6871 return meth;
6875 /* If not found in categories, check in protocols of the main class. */
6876 if (CLASS_PROTOCOL_LIST (inter))
6878 if ((meth = (lookup_method_in_protocol_list
6879 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6880 return meth;
6883 /* If we were instructed not to look in superclasses, don't. */
6884 if (no_superclasses)
6885 return NULL_TREE;
6887 /* Failing that, climb up the inheritance hierarchy. */
6888 root_inter = inter;
6889 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6891 while (inter);
6893 /* If no class (factory) method was found, check if an _instance_
6894 method of the same name exists in the root class. This is what
6895 the Objective-C runtime will do. If an instance method was not
6896 found, return 0. */
6897 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6900 /* Add the method to the hash list if it doesn't contain an identical
6901 method already. */
6903 static void
6904 add_method_to_hash_list (hash *hash_list, tree method)
6906 hash hsh;
6908 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6910 /* Install on a global chain. */
6911 hash_enter (hash_list, method);
6913 else
6915 /* Check types against those; if different, add to a list. */
6916 attr loop;
6917 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6918 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6919 already_there |= comp_proto_with_proto (method, loop->value, 1);
6920 if (!already_there)
6921 hash_add_attr (hsh, method);
6925 static tree
6926 objc_add_method (tree klass, tree method, int is_class)
6928 tree mth;
6930 if (!(mth = lookup_method (is_class
6931 ? CLASS_CLS_METHODS (klass)
6932 : CLASS_NST_METHODS (klass), method)))
6934 /* put method on list in reverse order */
6935 if (is_class)
6937 DECL_CHAIN (method) = CLASS_CLS_METHODS (klass);
6938 CLASS_CLS_METHODS (klass) = method;
6940 else
6942 DECL_CHAIN (method) = CLASS_NST_METHODS (klass);
6943 CLASS_NST_METHODS (klass) = method;
6946 else
6948 /* When processing an @interface for a class or category, give hard
6949 errors on methods with identical selectors but differing argument
6950 and/or return types. We do not do this for @implementations, because
6951 C/C++ will do it for us (i.e., there will be duplicate function
6952 definition errors). */
6953 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
6954 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
6955 && !comp_proto_with_proto (method, mth, 1))
6956 error ("duplicate declaration of method %<%c%E%>",
6957 is_class ? '+' : '-',
6958 METHOD_SEL_NAME (mth));
6961 if (is_class)
6962 add_method_to_hash_list (cls_method_hash_list, method);
6963 else
6965 add_method_to_hash_list (nst_method_hash_list, method);
6967 /* Instance methods in root classes (and categories thereof)
6968 may act as class methods as a last resort. We also add
6969 instance methods listed in @protocol declarations to
6970 the class hash table, on the assumption that @protocols
6971 may be adopted by root classes or categories. */
6972 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
6973 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
6974 klass = lookup_interface (CLASS_NAME (klass));
6976 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
6977 || !CLASS_SUPER_NAME (klass))
6978 add_method_to_hash_list (cls_method_hash_list, method);
6981 return method;
6984 static tree
6985 add_class (tree class_name, tree name)
6987 struct interface_tuple **slot;
6989 /* Put interfaces on list in reverse order. */
6990 TREE_CHAIN (class_name) = interface_chain;
6991 interface_chain = class_name;
6993 if (interface_htab == NULL)
6994 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6995 slot = (struct interface_tuple **)
6996 htab_find_slot_with_hash (interface_htab, name,
6997 IDENTIFIER_HASH_VALUE (name),
6998 INSERT);
6999 if (!*slot)
7001 *slot = ggc_alloc_cleared_interface_tuple ();
7002 (*slot)->id = name;
7004 (*slot)->class_name = class_name;
7006 return interface_chain;
7009 static void
7010 add_category (tree klass, tree category)
7012 /* Put categories on list in reverse order. */
7013 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7015 if (cat)
7017 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7018 CLASS_NAME (klass),
7019 CLASS_SUPER_NAME (category));
7021 else
7023 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7024 CLASS_CATEGORY_LIST (klass) = category;
7028 /* Called after parsing each instance variable declaration. Necessary to
7029 preserve typedefs and implement public/private...
7031 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7033 static tree
7034 add_instance_variable (tree klass, int visibility, tree field_decl)
7036 tree field_type = TREE_TYPE (field_decl);
7037 const char *ivar_name = DECL_NAME (field_decl)
7038 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7039 : _("<unnamed>");
7041 #ifdef OBJCPLUS
7042 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7044 error ("illegal reference type specified for instance variable %qs",
7045 ivar_name);
7046 /* Return class as is without adding this ivar. */
7047 return klass;
7049 #endif
7051 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7052 || TYPE_SIZE (field_type) == error_mark_node)
7053 /* 'type[0]' is allowed, but 'type[]' is not! */
7055 error ("instance variable %qs has unknown size", ivar_name);
7056 /* Return class as is without adding this ivar. */
7057 return klass;
7060 #ifdef OBJCPLUS
7061 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7062 need to either (1) warn the user about it or (2) generate suitable
7063 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7064 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7065 if (MAYBE_CLASS_TYPE_P (field_type)
7066 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7067 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7068 || TYPE_POLYMORPHIC_P (field_type)))
7070 tree type_name = OBJC_TYPE_NAME (field_type);
7072 if (flag_objc_call_cxx_cdtors)
7074 /* Since the ObjC runtime will be calling the constructors and
7075 destructors for us, the only thing we can't handle is the lack
7076 of a default constructor. */
7077 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7078 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7080 warning (0, "type %qE has no default constructor to call",
7081 type_name);
7083 /* If we cannot call a constructor, we should also avoid
7084 calling the destructor, for symmetry. */
7085 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7086 warning (0, "destructor for %qE shall not be run either",
7087 type_name);
7090 else
7092 static bool warn_cxx_ivars = false;
7094 if (TYPE_POLYMORPHIC_P (field_type))
7096 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7097 initialize them. */
7098 error ("type %qE has virtual member functions", type_name);
7099 error ("illegal aggregate type %qE specified "
7100 "for instance variable %qs",
7101 type_name, ivar_name);
7102 /* Return class as is without adding this ivar. */
7103 return klass;
7106 /* User-defined constructors and destructors are not known to Obj-C
7107 and hence will not be called. This may or may not be a problem. */
7108 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7109 warning (0, "type %qE has a user-defined constructor", type_name);
7110 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7111 warning (0, "type %qE has a user-defined destructor", type_name);
7113 if (!warn_cxx_ivars)
7115 warning (0, "C++ constructors and destructors will not "
7116 "be invoked for Objective-C fields");
7117 warn_cxx_ivars = true;
7121 #endif
7123 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7124 switch (visibility)
7126 case 0:
7127 TREE_PUBLIC (field_decl) = 0;
7128 TREE_PRIVATE (field_decl) = 0;
7129 TREE_PROTECTED (field_decl) = 1;
7130 break;
7132 case 1:
7133 TREE_PUBLIC (field_decl) = 1;
7134 TREE_PRIVATE (field_decl) = 0;
7135 TREE_PROTECTED (field_decl) = 0;
7136 break;
7138 case 2:
7139 TREE_PUBLIC (field_decl) = 0;
7140 TREE_PRIVATE (field_decl) = 1;
7141 TREE_PROTECTED (field_decl) = 0;
7142 break;
7146 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7148 return klass;
7151 static tree
7152 is_ivar (tree decl_chain, tree ident)
7154 for ( ; decl_chain; decl_chain = DECL_CHAIN (decl_chain))
7155 if (DECL_NAME (decl_chain) == ident)
7156 return decl_chain;
7157 return NULL_TREE;
7160 /* True if the ivar is private and we are not in its implementation. */
7162 static int
7163 is_private (tree decl)
7165 return (TREE_PRIVATE (decl)
7166 && ! is_ivar (CLASS_IVARS (implementation_template),
7167 DECL_NAME (decl)));
7170 /* We have an instance variable reference;, check to see if it is public. */
7173 objc_is_public (tree expr, tree identifier)
7175 tree basetype, decl;
7177 #ifdef OBJCPLUS
7178 if (processing_template_decl)
7179 return 1;
7180 #endif
7182 if (TREE_TYPE (expr) == error_mark_node)
7183 return 1;
7185 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7187 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7189 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7191 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7193 if (!klass)
7195 error ("cannot find interface declaration for %qE",
7196 OBJC_TYPE_NAME (basetype));
7197 return 0;
7200 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7202 if (TREE_PUBLIC (decl))
7203 return 1;
7205 /* Important difference between the Stepstone translator:
7206 all instance variables should be public within the context
7207 of the implementation. */
7208 if (objc_implementation_context
7209 && ((TREE_CODE (objc_implementation_context)
7210 == CLASS_IMPLEMENTATION_TYPE)
7211 || (TREE_CODE (objc_implementation_context)
7212 == CATEGORY_IMPLEMENTATION_TYPE)))
7214 tree curtype = TYPE_MAIN_VARIANT
7215 (CLASS_STATIC_TEMPLATE
7216 (implementation_template));
7218 if (basetype == curtype
7219 || DERIVED_FROM_P (basetype, curtype))
7221 int priv = is_private (decl);
7223 if (priv)
7224 error ("instance variable %qE is declared private",
7225 DECL_NAME (decl));
7227 return !priv;
7231 /* The 2.95.2 compiler sometimes allowed C functions to access
7232 non-@public ivars. We will let this slide for now... */
7233 if (!objc_method_context)
7235 warning (0, "instance variable %qE is %s; "
7236 "this will be a hard error in the future",
7237 identifier,
7238 TREE_PRIVATE (decl) ? "@private" : "@protected");
7239 return 1;
7242 error ("instance variable %qE is declared %s",
7243 identifier,
7244 TREE_PRIVATE (decl) ? "private" : "protected");
7245 return 0;
7250 return 1;
7253 /* Make sure all entries in CHAIN are also in LIST. */
7255 static int
7256 check_methods (tree chain, tree list, int mtype)
7258 int first = 1;
7260 while (chain)
7262 if (!lookup_method (list, chain))
7264 if (first)
7266 if (TREE_CODE (objc_implementation_context)
7267 == CLASS_IMPLEMENTATION_TYPE)
7268 warning (0, "incomplete implementation of class %qE",
7269 CLASS_NAME (objc_implementation_context));
7270 else if (TREE_CODE (objc_implementation_context)
7271 == CATEGORY_IMPLEMENTATION_TYPE)
7272 warning (0, "incomplete implementation of category %qE",
7273 CLASS_SUPER_NAME (objc_implementation_context));
7274 first = 0;
7277 warning (0, "method definition for %<%c%E%> not found",
7278 mtype, METHOD_SEL_NAME (chain));
7281 chain = DECL_CHAIN (chain);
7284 return first;
7287 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7289 static int
7290 conforms_to_protocol (tree klass, tree protocol)
7292 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7294 tree p = CLASS_PROTOCOL_LIST (klass);
7295 while (p && TREE_VALUE (p) != protocol)
7296 p = TREE_CHAIN (p);
7298 if (!p)
7300 tree super = (CLASS_SUPER_NAME (klass)
7301 ? lookup_interface (CLASS_SUPER_NAME (klass))
7302 : NULL_TREE);
7303 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7304 if (!tmp)
7305 return 0;
7309 return 1;
7312 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7313 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7315 static int
7316 check_methods_accessible (tree chain, tree context, int mtype)
7318 int first = 1;
7319 tree list;
7320 tree base_context = context;
7322 while (chain)
7324 context = base_context;
7325 while (context)
7327 if (mtype == '+')
7328 list = CLASS_CLS_METHODS (context);
7329 else
7330 list = CLASS_NST_METHODS (context);
7332 if (lookup_method (list, chain))
7333 break;
7335 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7336 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7337 context = (CLASS_SUPER_NAME (context)
7338 ? lookup_interface (CLASS_SUPER_NAME (context))
7339 : NULL_TREE);
7341 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7342 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7343 context = (CLASS_NAME (context)
7344 ? lookup_interface (CLASS_NAME (context))
7345 : NULL_TREE);
7346 else
7347 abort ();
7350 if (context == NULL_TREE)
7352 if (first)
7354 if (TREE_CODE (objc_implementation_context)
7355 == CLASS_IMPLEMENTATION_TYPE)
7356 warning (0, "incomplete implementation of class %qE",
7357 CLASS_NAME (objc_implementation_context));
7358 else if (TREE_CODE (objc_implementation_context)
7359 == CATEGORY_IMPLEMENTATION_TYPE)
7360 warning (0, "incomplete implementation of category %qE",
7361 CLASS_SUPER_NAME (objc_implementation_context));
7362 first = 0;
7364 warning (0, "method definition for %<%c%E%> not found",
7365 mtype, METHOD_SEL_NAME (chain));
7368 chain = TREE_CHAIN (chain); /* next method... */
7370 return first;
7373 /* Check whether the current interface (accessible via
7374 'objc_implementation_context') actually implements protocol P, along
7375 with any protocols that P inherits. */
7377 static void
7378 check_protocol (tree p, const char *type, tree name)
7380 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7382 int f1, f2;
7384 /* Ensure that all protocols have bodies! */
7385 if (warn_protocol)
7387 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7388 CLASS_CLS_METHODS (objc_implementation_context),
7389 '+');
7390 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7391 CLASS_NST_METHODS (objc_implementation_context),
7392 '-');
7394 else
7396 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7397 objc_implementation_context,
7398 '+');
7399 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7400 objc_implementation_context,
7401 '-');
7404 if (!f1 || !f2)
7405 warning (0, "%s %qE does not fully implement the %qE protocol",
7406 type, name, PROTOCOL_NAME (p));
7409 /* Check protocols recursively. */
7410 if (PROTOCOL_LIST (p))
7412 tree subs = PROTOCOL_LIST (p);
7413 tree super_class =
7414 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7416 while (subs)
7418 tree sub = TREE_VALUE (subs);
7420 /* If the superclass does not conform to the protocols
7421 inherited by P, then we must! */
7422 if (!super_class || !conforms_to_protocol (super_class, sub))
7423 check_protocol (sub, type, name);
7424 subs = TREE_CHAIN (subs);
7429 /* Check whether the current interface (accessible via
7430 'objc_implementation_context') actually implements the protocols listed
7431 in PROTO_LIST. */
7433 static void
7434 check_protocols (tree proto_list, const char *type, tree name)
7436 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7438 tree p = TREE_VALUE (proto_list);
7440 check_protocol (p, type, name);
7444 /* Make sure that the class CLASS_NAME is defined
7445 CODE says which kind of thing CLASS_NAME ought to be.
7446 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7447 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7449 static tree
7450 start_class (enum tree_code code, tree class_name, tree super_name,
7451 tree protocol_list)
7453 tree klass, decl;
7455 #ifdef OBJCPLUS
7456 if (current_namespace != global_namespace) {
7457 error ("Objective-C declarations may only appear in global scope");
7459 #endif /* OBJCPLUS */
7461 if (objc_implementation_context)
7463 warning (0, "%<@end%> missing in implementation context");
7464 finish_class (objc_implementation_context);
7465 objc_ivar_chain = NULL_TREE;
7466 objc_implementation_context = NULL_TREE;
7469 klass = make_node (code);
7470 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7472 /* Check for existence of the super class, if one was specified. Note
7473 that we must have seen an @interface, not just a @class. If we
7474 are looking at a @compatibility_alias, traverse it first. */
7475 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7476 && super_name)
7478 tree super = objc_is_class_name (super_name);
7480 if (!super || !lookup_interface (super))
7482 error ("cannot find interface declaration for %qE, superclass of %qE",
7483 super ? super : super_name,
7484 class_name);
7485 super_name = NULL_TREE;
7487 else
7488 super_name = super;
7491 CLASS_NAME (klass) = class_name;
7492 CLASS_SUPER_NAME (klass) = super_name;
7493 CLASS_CLS_METHODS (klass) = NULL_TREE;
7495 if (! objc_is_class_name (class_name)
7496 && (decl = lookup_name (class_name)))
7498 error ("%qE redeclared as different kind of symbol",
7499 class_name);
7500 error ("previous declaration of %q+D",
7501 decl);
7504 if (code == CLASS_IMPLEMENTATION_TYPE)
7507 tree chain;
7509 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7510 if (TREE_VALUE (chain) == class_name)
7512 error ("reimplementation of class %qE",
7513 class_name);
7514 return error_mark_node;
7516 implemented_classes = tree_cons (NULL_TREE, class_name,
7517 implemented_classes);
7520 /* Reset for multiple classes per file. */
7521 method_slot = 0;
7523 objc_implementation_context = klass;
7525 /* Lookup the interface for this implementation. */
7527 if (!(implementation_template = lookup_interface (class_name)))
7529 warning (0, "cannot find interface declaration for %qE",
7530 class_name);
7531 add_class (implementation_template = objc_implementation_context,
7532 class_name);
7535 /* If a super class has been specified in the implementation,
7536 insure it conforms to the one specified in the interface. */
7538 if (super_name
7539 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7541 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7542 error ("conflicting super class name %qE",
7543 super_name);
7544 if (previous_name)
7545 error ("previous declaration of %qE", previous_name);
7546 else
7547 error ("previous declaration");
7550 else if (! super_name)
7552 CLASS_SUPER_NAME (objc_implementation_context)
7553 = CLASS_SUPER_NAME (implementation_template);
7557 else if (code == CLASS_INTERFACE_TYPE)
7559 if (lookup_interface (class_name))
7560 #ifdef OBJCPLUS
7561 error ("duplicate interface declaration for class %qE",
7562 #else
7563 warning (0, "duplicate interface declaration for class %qE",
7564 #endif
7565 class_name);
7566 else
7567 add_class (klass, class_name);
7569 if (protocol_list)
7570 CLASS_PROTOCOL_LIST (klass)
7571 = lookup_and_install_protocols (protocol_list);
7574 else if (code == CATEGORY_INTERFACE_TYPE)
7576 tree class_category_is_assoc_with;
7578 /* For a category, class_name is really the name of the class that
7579 the following set of methods will be associated with. We must
7580 find the interface so that can derive the objects template. */
7582 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7584 error ("cannot find interface declaration for %qE",
7585 class_name);
7586 exit (FATAL_EXIT_CODE);
7588 else
7589 add_category (class_category_is_assoc_with, klass);
7591 if (protocol_list)
7592 CLASS_PROTOCOL_LIST (klass)
7593 = lookup_and_install_protocols (protocol_list);
7596 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7598 /* Reset for multiple classes per file. */
7599 method_slot = 0;
7601 objc_implementation_context = klass;
7603 /* For a category, class_name is really the name of the class that
7604 the following set of methods will be associated with. We must
7605 find the interface so that can derive the objects template. */
7607 if (!(implementation_template = lookup_interface (class_name)))
7609 error ("cannot find interface declaration for %qE",
7610 class_name);
7611 exit (FATAL_EXIT_CODE);
7614 return klass;
7617 static tree
7618 continue_class (tree klass)
7620 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7621 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7623 struct imp_entry *imp_entry;
7625 /* Check consistency of the instance variables. */
7627 if (CLASS_RAW_IVARS (klass))
7628 check_ivars (implementation_template, klass);
7630 /* code generation */
7632 #ifdef OBJCPLUS
7633 push_lang_context (lang_name_c);
7634 #endif
7636 build_private_template (implementation_template);
7637 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7638 objc_instance_type = build_pointer_type (uprivate_record);
7640 imp_entry = ggc_alloc_imp_entry ();
7642 imp_entry->next = imp_list;
7643 imp_entry->imp_context = klass;
7644 imp_entry->imp_template = implementation_template;
7646 synth_forward_declarations ();
7647 imp_entry->class_decl = UOBJC_CLASS_decl;
7648 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7649 imp_entry->has_cxx_cdtors = 0;
7651 /* Append to front and increment count. */
7652 imp_list = imp_entry;
7653 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7654 imp_count++;
7655 else
7656 cat_count++;
7658 #ifdef OBJCPLUS
7659 pop_lang_context ();
7660 #endif /* OBJCPLUS */
7662 return get_class_ivars (implementation_template, true);
7665 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7667 #ifdef OBJCPLUS
7668 push_lang_context (lang_name_c);
7669 #endif /* OBJCPLUS */
7671 build_private_template (klass);
7673 #ifdef OBJCPLUS
7674 pop_lang_context ();
7675 #endif /* OBJCPLUS */
7677 return NULL_TREE;
7680 else
7681 return error_mark_node;
7684 /* This is called once we see the "@end" in an interface/implementation. */
7686 static void
7687 finish_class (tree klass)
7689 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7691 /* All code generation is done in finish_objc. */
7693 if (implementation_template != objc_implementation_context)
7695 /* Ensure that all method listed in the interface contain bodies. */
7696 check_methods (CLASS_CLS_METHODS (implementation_template),
7697 CLASS_CLS_METHODS (objc_implementation_context), '+');
7698 check_methods (CLASS_NST_METHODS (implementation_template),
7699 CLASS_NST_METHODS (objc_implementation_context), '-');
7701 if (CLASS_PROTOCOL_LIST (implementation_template))
7702 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7703 "class",
7704 CLASS_NAME (objc_implementation_context));
7708 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7710 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7712 if (category)
7714 /* Ensure all method listed in the interface contain bodies. */
7715 check_methods (CLASS_CLS_METHODS (category),
7716 CLASS_CLS_METHODS (objc_implementation_context), '+');
7717 check_methods (CLASS_NST_METHODS (category),
7718 CLASS_NST_METHODS (objc_implementation_context), '-');
7720 if (CLASS_PROTOCOL_LIST (category))
7721 check_protocols (CLASS_PROTOCOL_LIST (category),
7722 "category",
7723 CLASS_SUPER_NAME (objc_implementation_context));
7728 static tree
7729 add_protocol (tree protocol)
7731 /* Put protocol on list in reverse order. */
7732 TREE_CHAIN (protocol) = protocol_chain;
7733 protocol_chain = protocol;
7734 return protocol_chain;
7737 static tree
7738 lookup_protocol (tree ident)
7740 tree chain;
7742 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7743 if (ident == PROTOCOL_NAME (chain))
7744 return chain;
7746 return NULL_TREE;
7749 /* This function forward declares the protocols named by NAMES. If
7750 they are already declared or defined, the function has no effect. */
7752 void
7753 objc_declare_protocols (tree names)
7755 tree list;
7757 #ifdef OBJCPLUS
7758 if (current_namespace != global_namespace) {
7759 error ("Objective-C declarations may only appear in global scope");
7761 #endif /* OBJCPLUS */
7763 for (list = names; list; list = TREE_CHAIN (list))
7765 tree name = TREE_VALUE (list);
7767 if (lookup_protocol (name) == NULL_TREE)
7769 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7771 TYPE_LANG_SLOT_1 (protocol)
7772 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7773 PROTOCOL_NAME (protocol) = name;
7774 PROTOCOL_LIST (protocol) = NULL_TREE;
7775 add_protocol (protocol);
7776 PROTOCOL_DEFINED (protocol) = 0;
7777 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7782 static tree
7783 start_protocol (enum tree_code code, tree name, tree list)
7785 tree protocol;
7787 #ifdef OBJCPLUS
7788 if (current_namespace != global_namespace) {
7789 error ("Objective-C declarations may only appear in global scope");
7791 #endif /* OBJCPLUS */
7793 protocol = lookup_protocol (name);
7795 if (!protocol)
7797 protocol = make_node (code);
7798 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7800 PROTOCOL_NAME (protocol) = name;
7801 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7802 add_protocol (protocol);
7803 PROTOCOL_DEFINED (protocol) = 1;
7804 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7806 check_protocol_recursively (protocol, list);
7808 else if (! PROTOCOL_DEFINED (protocol))
7810 PROTOCOL_DEFINED (protocol) = 1;
7811 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7813 check_protocol_recursively (protocol, list);
7815 else
7817 warning (0, "duplicate declaration for protocol %qE",
7818 name);
7820 return protocol;
7824 /* "Encode" a data type into a string, which grows in util_obstack.
7825 ??? What is the FORMAT? Someone please document this! */
7827 static void
7828 encode_type_qualifiers (tree declspecs)
7830 tree spec;
7832 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7834 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7835 obstack_1grow (&util_obstack, 'n');
7836 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7837 obstack_1grow (&util_obstack, 'N');
7838 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7839 obstack_1grow (&util_obstack, 'o');
7840 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7841 obstack_1grow (&util_obstack, 'O');
7842 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7843 obstack_1grow (&util_obstack, 'R');
7844 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7845 obstack_1grow (&util_obstack, 'V');
7849 /* Encode a pointer type. */
7851 static void
7852 encode_pointer (tree type, int curtype, int format)
7854 tree pointer_to = TREE_TYPE (type);
7856 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7858 if (OBJC_TYPE_NAME (pointer_to)
7859 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7861 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7863 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7865 obstack_1grow (&util_obstack, '@');
7866 return;
7868 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7869 && TYPE_OBJC_INTERFACE (pointer_to))
7871 if (generating_instance_variables)
7873 obstack_1grow (&util_obstack, '@');
7874 obstack_1grow (&util_obstack, '"');
7875 obstack_grow (&util_obstack, name, strlen (name));
7876 obstack_1grow (&util_obstack, '"');
7877 return;
7879 else
7881 obstack_1grow (&util_obstack, '@');
7882 return;
7885 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7887 obstack_1grow (&util_obstack, '#');
7888 return;
7890 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7892 obstack_1grow (&util_obstack, ':');
7893 return;
7897 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7898 && TYPE_MODE (pointer_to) == QImode)
7900 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7901 ? OBJC_TYPE_NAME (pointer_to)
7902 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7904 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7906 /* It appears that "r*" means "const char *" rather than
7907 "char *const". */
7908 if (TYPE_READONLY (pointer_to))
7909 obstack_1grow (&util_obstack, 'r');
7911 obstack_1grow (&util_obstack, '*');
7912 return;
7916 /* We have a type that does not get special treatment. */
7918 /* NeXT extension */
7919 obstack_1grow (&util_obstack, '^');
7920 encode_type (pointer_to, curtype, format);
7923 static void
7924 encode_array (tree type, int curtype, int format)
7926 tree an_int_cst = TYPE_SIZE (type);
7927 tree array_of = TREE_TYPE (type);
7928 char buffer[40];
7930 /* An incomplete array is treated like a pointer. */
7931 if (an_int_cst == NULL)
7933 encode_pointer (type, curtype, format);
7934 return;
7937 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7938 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7939 else
7940 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7941 TREE_INT_CST_LOW (an_int_cst)
7942 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7944 obstack_grow (&util_obstack, buffer, strlen (buffer));
7945 encode_type (array_of, curtype, format);
7946 obstack_1grow (&util_obstack, ']');
7947 return;
7950 static void
7951 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7953 tree field = TYPE_FIELDS (type);
7955 for (; field; field = DECL_CHAIN (field))
7957 #ifdef OBJCPLUS
7958 /* C++ static members, and things that are not field at all,
7959 should not appear in the encoding. */
7960 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7961 continue;
7962 #endif
7964 /* Recursively encode fields of embedded base classes. */
7965 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7966 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7968 encode_aggregate_fields (TREE_TYPE (field),
7969 pointed_to, curtype, format);
7970 continue;
7973 if (generating_instance_variables && !pointed_to)
7975 tree fname = DECL_NAME (field);
7977 obstack_1grow (&util_obstack, '"');
7979 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7980 obstack_grow (&util_obstack,
7981 IDENTIFIER_POINTER (fname),
7982 strlen (IDENTIFIER_POINTER (fname)));
7984 obstack_1grow (&util_obstack, '"');
7987 encode_field_decl (field, curtype, format);
7991 static void
7992 encode_aggregate_within (tree type, int curtype, int format, int left,
7993 int right)
7995 tree name;
7996 /* NB: aggregates that are pointed to have slightly different encoding
7997 rules in that you never encode the names of instance variables. */
7998 int ob_size = obstack_object_size (&util_obstack);
7999 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8000 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8001 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8002 int inline_contents
8003 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8004 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8006 /* Traverse struct aliases; it is important to get the
8007 original struct and its tag name (if any). */
8008 type = TYPE_MAIN_VARIANT (type);
8009 name = OBJC_TYPE_NAME (type);
8010 /* Open parenth/bracket. */
8011 obstack_1grow (&util_obstack, left);
8013 /* Encode the struct/union tag name, or '?' if a tag was
8014 not provided. Typedef aliases do not qualify. */
8015 #ifdef OBJCPLUS
8016 /* For compatibility with the NeXT runtime, ObjC++ encodes template
8017 args as a composite struct tag name. */
8018 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8019 /* Did this struct have a tag? */
8020 && !TYPE_WAS_ANONYMOUS (type))
8021 obstack_grow (&util_obstack,
8022 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
8023 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
8024 #else
8025 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
8026 obstack_grow (&util_obstack,
8027 IDENTIFIER_POINTER (name),
8028 strlen (IDENTIFIER_POINTER (name)));
8029 #endif
8030 else
8031 obstack_1grow (&util_obstack, '?');
8033 /* Encode the types (and possibly names) of the inner fields,
8034 if required. */
8035 if (inline_contents)
8037 obstack_1grow (&util_obstack, '=');
8038 encode_aggregate_fields (type, pointed_to, curtype, format);
8040 /* Close parenth/bracket. */
8041 obstack_1grow (&util_obstack, right);
8044 static void
8045 encode_aggregate (tree type, int curtype, int format)
8047 enum tree_code code = TREE_CODE (type);
8049 switch (code)
8051 case RECORD_TYPE:
8053 encode_aggregate_within (type, curtype, format, '{', '}');
8054 break;
8056 case UNION_TYPE:
8058 encode_aggregate_within (type, curtype, format, '(', ')');
8059 break;
8062 case ENUMERAL_TYPE:
8063 obstack_1grow (&util_obstack, 'i');
8064 break;
8066 default:
8067 break;
8071 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8072 field type. */
8074 static void
8075 encode_next_bitfield (int width)
8077 char buffer[40];
8078 sprintf (buffer, "b%d", width);
8079 obstack_grow (&util_obstack, buffer, strlen (buffer));
8082 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8083 static void
8084 encode_type (tree type, int curtype, int format)
8086 enum tree_code code = TREE_CODE (type);
8087 char c;
8089 if (type == error_mark_node)
8090 return;
8092 if (TYPE_READONLY (type))
8093 obstack_1grow (&util_obstack, 'r');
8095 if (code == INTEGER_TYPE)
8097 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8099 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8100 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8101 case 32:
8102 if (type == long_unsigned_type_node
8103 || type == long_integer_type_node)
8104 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8105 else
8106 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8107 break;
8108 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8109 default: abort ();
8111 obstack_1grow (&util_obstack, c);
8114 else if (code == REAL_TYPE)
8116 /* Floating point types. */
8117 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8119 case 32: c = 'f'; break;
8120 case 64:
8121 case 96:
8122 case 128: c = 'd'; break;
8123 default: abort ();
8125 obstack_1grow (&util_obstack, c);
8128 else if (code == VOID_TYPE)
8129 obstack_1grow (&util_obstack, 'v');
8131 else if (code == BOOLEAN_TYPE)
8132 obstack_1grow (&util_obstack, 'B');
8134 else if (code == ARRAY_TYPE)
8135 encode_array (type, curtype, format);
8137 else if (code == POINTER_TYPE)
8138 encode_pointer (type, curtype, format);
8140 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8141 encode_aggregate (type, curtype, format);
8143 else if (code == FUNCTION_TYPE) /* '?' */
8144 obstack_1grow (&util_obstack, '?');
8146 else if (code == COMPLEX_TYPE)
8148 obstack_1grow (&util_obstack, 'j');
8149 encode_type (TREE_TYPE (type), curtype, format);
8153 static void
8154 encode_gnu_bitfield (int position, tree type, int size)
8156 enum tree_code code = TREE_CODE (type);
8157 char buffer[40];
8158 char charType = '?';
8160 if (code == INTEGER_TYPE)
8162 if (integer_zerop (TYPE_MIN_VALUE (type)))
8164 /* Unsigned integer types. */
8166 if (TYPE_MODE (type) == QImode)
8167 charType = 'C';
8168 else if (TYPE_MODE (type) == HImode)
8169 charType = 'S';
8170 else if (TYPE_MODE (type) == SImode)
8172 if (type == long_unsigned_type_node)
8173 charType = 'L';
8174 else
8175 charType = 'I';
8177 else if (TYPE_MODE (type) == DImode)
8178 charType = 'Q';
8181 else
8182 /* Signed integer types. */
8184 if (TYPE_MODE (type) == QImode)
8185 charType = 'c';
8186 else if (TYPE_MODE (type) == HImode)
8187 charType = 's';
8188 else if (TYPE_MODE (type) == SImode)
8190 if (type == long_integer_type_node)
8191 charType = 'l';
8192 else
8193 charType = 'i';
8196 else if (TYPE_MODE (type) == DImode)
8197 charType = 'q';
8200 else if (code == ENUMERAL_TYPE)
8201 charType = 'i';
8202 else
8203 abort ();
8205 sprintf (buffer, "b%d%c%d", position, charType, size);
8206 obstack_grow (&util_obstack, buffer, strlen (buffer));
8209 static void
8210 encode_field_decl (tree field_decl, int curtype, int format)
8212 #ifdef OBJCPLUS
8213 /* C++ static members, and things that are not fields at all,
8214 should not appear in the encoding. */
8215 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8216 return;
8217 #endif
8219 /* Generate the bitfield typing information, if needed. Note the difference
8220 between GNU and NeXT runtimes. */
8221 if (DECL_BIT_FIELD_TYPE (field_decl))
8223 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8225 if (flag_next_runtime)
8226 encode_next_bitfield (size);
8227 else
8228 encode_gnu_bitfield (int_bit_position (field_decl),
8229 DECL_BIT_FIELD_TYPE (field_decl), size);
8231 else
8232 encode_type (TREE_TYPE (field_decl), curtype, format);
8235 static GTY(()) tree objc_parmlist = NULL_TREE;
8237 /* Append PARM to a list of formal parameters of a method, making a necessary
8238 array-to-pointer adjustment along the way. */
8240 static void
8241 objc_push_parm (tree parm)
8243 bool relayout_needed = false;
8245 if (TREE_TYPE (parm) == error_mark_node)
8247 objc_parmlist = chainon (objc_parmlist, parm);
8248 return;
8251 /* Decay arrays and functions into pointers. */
8252 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8254 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8255 relayout_needed = true;
8257 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8259 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8260 relayout_needed = true;
8263 if (relayout_needed)
8264 relayout_decl (parm);
8267 DECL_ARG_TYPE (parm)
8268 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8270 /* Record constancy and volatility. */
8271 c_apply_type_quals_to_decl
8272 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8273 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8274 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8276 objc_parmlist = chainon (objc_parmlist, parm);
8279 /* Retrieve the formal parameter list constructed via preceding calls to
8280 objc_push_parm(). */
8282 #ifdef OBJCPLUS
8283 static tree
8284 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8285 #else
8286 static struct c_arg_info *
8287 objc_get_parm_info (int have_ellipsis)
8288 #endif
8290 #ifdef OBJCPLUS
8291 tree parm_info = objc_parmlist;
8292 objc_parmlist = NULL_TREE;
8294 return parm_info;
8295 #else
8296 tree parm_info = objc_parmlist;
8297 struct c_arg_info *arg_info;
8298 /* The C front-end requires an elaborate song and dance at
8299 this point. */
8300 push_scope ();
8301 declare_parm_level ();
8302 while (parm_info)
8304 tree next = DECL_CHAIN (parm_info);
8306 DECL_CHAIN (parm_info) = NULL_TREE;
8307 parm_info = pushdecl (parm_info);
8308 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
8309 parm_info = next;
8311 arg_info = get_parm_info (have_ellipsis);
8312 pop_scope ();
8313 objc_parmlist = NULL_TREE;
8314 return arg_info;
8315 #endif
8318 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8319 method definitions. In the case of instance methods, we can be more
8320 specific as to the type of 'self'. */
8322 static void
8323 synth_self_and_ucmd_args (void)
8325 tree self_type;
8327 if (objc_method_context
8328 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8329 self_type = objc_instance_type;
8330 else
8331 /* Really a `struct objc_class *'. However, we allow people to
8332 assign to self, which changes its type midstream. */
8333 self_type = objc_object_type;
8335 /* id self; */
8336 objc_push_parm (build_decl (input_location,
8337 PARM_DECL, self_id, self_type));
8339 /* SEL _cmd; */
8340 objc_push_parm (build_decl (input_location,
8341 PARM_DECL, ucmd_id, objc_selector_type));
8344 /* Transform an Objective-C method definition into a static C function
8345 definition, synthesizing the first two arguments, "self" and "_cmd",
8346 in the process. */
8348 static void
8349 start_method_def (tree method)
8351 tree parmlist;
8352 #ifdef OBJCPLUS
8353 tree parm_info;
8354 #else
8355 struct c_arg_info *parm_info;
8356 #endif
8357 int have_ellipsis = 0;
8359 /* If we are defining a "dealloc" method in a non-root class, we
8360 will need to check if a [super dealloc] is missing, and warn if
8361 it is. */
8362 if(CLASS_SUPER_NAME (objc_implementation_context)
8363 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8364 should_call_super_dealloc = 1;
8365 else
8366 should_call_super_dealloc = 0;
8368 /* Required to implement _msgSuper. */
8369 objc_method_context = method;
8370 UOBJC_SUPER_decl = NULL_TREE;
8372 /* Generate prototype declarations for arguments..."new-style". */
8373 synth_self_and_ucmd_args ();
8375 /* Generate argument declarations if a keyword_decl. */
8376 parmlist = METHOD_SEL_ARGS (method);
8377 while (parmlist)
8379 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8381 parm = build_decl (input_location,
8382 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8383 objc_push_parm (parm);
8384 parmlist = DECL_CHAIN (parmlist);
8387 if (METHOD_ADD_ARGS (method))
8389 tree akey;
8391 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8392 akey; akey = TREE_CHAIN (akey))
8394 objc_push_parm (TREE_VALUE (akey));
8397 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8398 have_ellipsis = 1;
8401 parm_info = objc_get_parm_info (have_ellipsis);
8403 really_start_method (objc_method_context, parm_info);
8406 /* Return 1 if TYPE1 is equivalent to TYPE2
8407 for purposes of method overloading. */
8409 static int
8410 objc_types_are_equivalent (tree type1, tree type2)
8412 if (type1 == type2)
8413 return 1;
8415 /* Strip away indirections. */
8416 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8417 && (TREE_CODE (type1) == TREE_CODE (type2)))
8418 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8419 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8420 return 0;
8422 type1 = (TYPE_HAS_OBJC_INFO (type1)
8423 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8424 : NULL_TREE);
8425 type2 = (TYPE_HAS_OBJC_INFO (type2)
8426 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8427 : NULL_TREE);
8429 if (list_length (type1) == list_length (type2))
8431 for (; type2; type2 = TREE_CHAIN (type2))
8432 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8433 return 0;
8434 return 1;
8436 return 0;
8439 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8441 static int
8442 objc_types_share_size_and_alignment (tree type1, tree type2)
8444 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8445 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8448 /* Return 1 if PROTO1 is equivalent to PROTO2
8449 for purposes of method overloading. Ordinarily, the type signatures
8450 should match up exactly, unless STRICT is zero, in which case we
8451 shall allow differences in which the size and alignment of a type
8452 is the same. */
8454 static int
8455 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8457 tree type1, type2;
8459 /* The following test is needed in case there are hashing
8460 collisions. */
8461 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8462 return 0;
8464 /* Compare return types. */
8465 type1 = TREE_VALUE (TREE_TYPE (proto1));
8466 type2 = TREE_VALUE (TREE_TYPE (proto2));
8468 if (!objc_types_are_equivalent (type1, type2)
8469 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8470 return 0;
8472 /* Compare argument types. */
8473 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8474 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8475 type1 && type2;
8476 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8478 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8479 && (strict
8480 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8481 TREE_VALUE (type2))))
8482 return 0;
8485 return (!type1 && !type2);
8488 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8489 this occurs. ObjC method dispatches are _not_ like C++ virtual
8490 member function dispatches, and we account for the difference here. */
8491 tree
8492 #ifdef OBJCPLUS
8493 objc_fold_obj_type_ref (tree ref, tree known_type)
8494 #else
8495 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8496 tree known_type ATTRIBUTE_UNUSED)
8497 #endif
8499 #ifdef OBJCPLUS
8500 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8502 /* If the receiver does not have virtual member functions, there
8503 is nothing we can (or need to) do here. */
8504 if (!v)
8505 return NULL_TREE;
8507 /* Let C++ handle C++ virtual functions. */
8508 return cp_fold_obj_type_ref (ref, known_type);
8509 #else
8510 /* For plain ObjC, we currently do not need to do anything. */
8511 return NULL_TREE;
8512 #endif
8515 static void
8516 objc_start_function (tree name, tree type, tree attrs,
8517 #ifdef OBJCPLUS
8518 tree params
8519 #else
8520 struct c_arg_info *params
8521 #endif
8524 tree fndecl = build_decl (input_location,
8525 FUNCTION_DECL, name, type);
8527 #ifdef OBJCPLUS
8528 DECL_ARGUMENTS (fndecl) = params;
8529 DECL_INITIAL (fndecl) = error_mark_node;
8530 DECL_EXTERNAL (fndecl) = 0;
8531 TREE_STATIC (fndecl) = 1;
8532 retrofit_lang_decl (fndecl);
8533 cplus_decl_attributes (&fndecl, attrs, 0);
8534 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8535 #else
8536 current_function_returns_value = 0; /* Assume, until we see it does. */
8537 current_function_returns_null = 0;
8539 decl_attributes (&fndecl, attrs, 0);
8540 announce_function (fndecl);
8541 DECL_INITIAL (fndecl) = error_mark_node;
8542 DECL_EXTERNAL (fndecl) = 0;
8543 TREE_STATIC (fndecl) = 1;
8544 current_function_decl = pushdecl (fndecl);
8545 push_scope ();
8546 declare_parm_level ();
8547 DECL_RESULT (current_function_decl)
8548 = build_decl (input_location,
8549 RESULT_DECL, NULL_TREE,
8550 TREE_TYPE (TREE_TYPE (current_function_decl)));
8551 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8552 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8553 start_fname_decls ();
8554 store_parm_decls_from (params);
8555 #endif
8557 TREE_USED (current_function_decl) = 1;
8560 /* - Generate an identifier for the function. the format is "_n_cls",
8561 where 1 <= n <= nMethods, and cls is the name the implementation we
8562 are processing.
8563 - Install the return type from the method declaration.
8564 - If we have a prototype, check for type consistency. */
8566 static void
8567 really_start_method (tree method,
8568 #ifdef OBJCPLUS
8569 tree parmlist
8570 #else
8571 struct c_arg_info *parmlist
8572 #endif
8575 tree ret_type, meth_type;
8576 tree method_id;
8577 const char *sel_name, *class_name, *cat_name;
8578 char *buf;
8580 /* Synth the storage class & assemble the return type. */
8581 ret_type = TREE_VALUE (TREE_TYPE (method));
8583 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8584 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8585 cat_name = ((TREE_CODE (objc_implementation_context)
8586 == CLASS_IMPLEMENTATION_TYPE)
8587 ? NULL
8588 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8589 method_slot++;
8591 /* Make sure this is big enough for any plausible method label. */
8592 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8593 + (cat_name ? strlen (cat_name) : 0));
8595 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8596 class_name, cat_name, sel_name, method_slot);
8598 method_id = get_identifier (buf);
8600 #ifdef OBJCPLUS
8601 /* Objective-C methods cannot be overloaded, so we don't need
8602 the type encoding appended. It looks bad anyway... */
8603 push_lang_context (lang_name_c);
8604 #endif
8606 meth_type
8607 = build_function_type (ret_type,
8608 get_arg_type_list (method, METHOD_DEF, 0));
8609 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8611 /* Set self_decl from the first argument. */
8612 self_decl = DECL_ARGUMENTS (current_function_decl);
8614 /* Suppress unused warnings. */
8615 TREE_USED (self_decl) = 1;
8616 DECL_READ_P (self_decl) = 1;
8617 TREE_USED (DECL_CHAIN (self_decl)) = 1;
8618 DECL_READ_P (DECL_CHAIN (self_decl)) = 1;
8619 #ifdef OBJCPLUS
8620 pop_lang_context ();
8621 #endif
8623 METHOD_DEFINITION (method) = current_function_decl;
8625 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8627 if (implementation_template != objc_implementation_context)
8629 tree proto
8630 = lookup_method_static (implementation_template,
8631 METHOD_SEL_NAME (method),
8632 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8633 | OBJC_LOOKUP_NO_SUPER));
8635 if (proto)
8637 if (!comp_proto_with_proto (method, proto, 1))
8639 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8641 warning_at (DECL_SOURCE_LOCATION (method), 0,
8642 "conflicting types for %<%c%s%>",
8643 (type ? '-' : '+'),
8644 identifier_to_locale (gen_method_decl (method)));
8645 inform (DECL_SOURCE_LOCATION (proto),
8646 "previous declaration of %<%c%s%>",
8647 (type ? '-' : '+'),
8648 identifier_to_locale (gen_method_decl (proto)));
8651 else
8653 /* We have a method @implementation even though we did not
8654 see a corresponding @interface declaration (which is allowed
8655 by Objective-C rules). Go ahead and place the method in
8656 the @interface anyway, so that message dispatch lookups
8657 will see it. */
8658 tree interface = implementation_template;
8660 if (TREE_CODE (objc_implementation_context)
8661 == CATEGORY_IMPLEMENTATION_TYPE)
8662 interface = lookup_category
8663 (interface,
8664 CLASS_SUPER_NAME (objc_implementation_context));
8666 if (interface)
8667 objc_add_method (interface, copy_node (method),
8668 TREE_CODE (method) == CLASS_METHOD_DECL);
8673 static void *UOBJC_SUPER_scope = 0;
8675 /* _n_Method (id self, SEL sel, ...)
8677 struct objc_super _S;
8678 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8679 } */
8681 static tree
8682 get_super_receiver (void)
8684 if (objc_method_context)
8686 tree super_expr, super_expr_list;
8688 if (!UOBJC_SUPER_decl)
8690 UOBJC_SUPER_decl = build_decl (input_location,
8691 VAR_DECL, get_identifier (TAG_SUPER),
8692 objc_super_template);
8693 /* This prevents `unused variable' warnings when compiling with -Wall. */
8694 TREE_USED (UOBJC_SUPER_decl) = 1;
8695 DECL_READ_P (UOBJC_SUPER_decl) = 1;
8696 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8697 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
8698 NULL_TREE);
8699 UOBJC_SUPER_scope = objc_get_current_scope ();
8702 /* Set receiver to self. */
8703 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8704 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8705 NOP_EXPR, input_location, self_decl,
8706 NULL_TREE);
8707 super_expr_list = super_expr;
8709 /* Set class to begin searching. */
8710 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8711 get_identifier ("super_class"));
8713 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8715 /* [_cls, __cls]Super are "pre-built" in
8716 synth_forward_declarations. */
8718 super_expr = build_modify_expr (input_location, super_expr,
8719 NULL_TREE, NOP_EXPR,
8720 input_location,
8721 ((TREE_CODE (objc_method_context)
8722 == INSTANCE_METHOD_DECL)
8723 ? ucls_super_ref
8724 : uucls_super_ref),
8725 NULL_TREE);
8728 else
8729 /* We have a category. */
8731 tree super_name = CLASS_SUPER_NAME (implementation_template);
8732 tree super_class;
8734 /* Barf if super used in a category of Object. */
8735 if (!super_name)
8737 error ("no super class declared in interface for %qE",
8738 CLASS_NAME (implementation_template));
8739 return error_mark_node;
8742 if (flag_next_runtime && !flag_zero_link)
8744 super_class = objc_get_class_reference (super_name);
8745 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8746 /* If we are in a class method, we must retrieve the
8747 _metaclass_ for the current class, pointed at by
8748 the class's "isa" pointer. The following assumes that
8749 "isa" is the first ivar in a class (which it must be). */
8750 super_class
8751 = build_indirect_ref
8752 (input_location,
8753 build_c_cast (input_location,
8754 build_pointer_type (objc_class_type),
8755 super_class), RO_UNARY_STAR);
8757 else
8759 add_class_reference (super_name);
8760 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8761 ? objc_get_class_decl : objc_get_meta_class_decl);
8762 assemble_external (super_class);
8763 super_class
8764 = build_function_call
8765 (input_location,
8766 super_class,
8767 build_tree_list
8768 (NULL_TREE,
8769 my_build_string_pointer
8770 (IDENTIFIER_LENGTH (super_name) + 1,
8771 IDENTIFIER_POINTER (super_name))));
8774 super_expr
8775 = build_modify_expr (input_location, super_expr, NULL_TREE,
8776 NOP_EXPR,
8777 input_location,
8778 build_c_cast (input_location,
8779 TREE_TYPE (super_expr),
8780 super_class),
8781 NULL_TREE);
8784 super_expr_list = build_compound_expr (input_location,
8785 super_expr_list, super_expr);
8787 super_expr = build_unary_op (input_location,
8788 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8789 super_expr_list = build_compound_expr (input_location,
8790 super_expr_list, super_expr);
8792 return super_expr_list;
8794 else
8796 error ("[super ...] must appear in a method context");
8797 return error_mark_node;
8801 /* When exiting a scope, sever links to a 'super' declaration (if any)
8802 therein contained. */
8804 void
8805 objc_clear_super_receiver (void)
8807 if (objc_method_context
8808 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8809 UOBJC_SUPER_decl = 0;
8810 UOBJC_SUPER_scope = 0;
8814 void
8815 objc_finish_method_definition (tree fndecl)
8817 /* We cannot validly inline ObjC methods, at least not without a language
8818 extension to declare that a method need not be dynamically
8819 dispatched, so suppress all thoughts of doing so. */
8820 DECL_UNINLINABLE (fndecl) = 1;
8822 #ifndef OBJCPLUS
8823 /* The C++ front-end will have called finish_function() for us. */
8824 finish_function ();
8825 #endif
8827 METHOD_ENCODING (objc_method_context)
8828 = encode_method_prototype (objc_method_context);
8830 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8831 since the optimizer may find "may be used before set" errors. */
8832 objc_method_context = NULL_TREE;
8834 if (should_call_super_dealloc)
8835 warning (0, "method possibly missing a [super dealloc] call");
8838 /* Given a tree DECL node, produce a printable description of it in the given
8839 buffer, overwriting the buffer. */
8841 static char *
8842 gen_declaration (tree decl)
8844 errbuf[0] = '\0';
8846 if (DECL_P (decl))
8848 gen_type_name_0 (TREE_TYPE (decl));
8850 if (DECL_NAME (decl))
8852 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8853 strcat (errbuf, " ");
8855 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8858 if (DECL_INITIAL (decl)
8859 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8860 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8861 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8864 return errbuf;
8867 /* Given a tree TYPE node, produce a printable description of it in the given
8868 buffer, overwriting the buffer. */
8870 static char *
8871 gen_type_name_0 (tree type)
8873 tree orig = type, proto;
8875 if (TYPE_P (type) && TYPE_NAME (type))
8876 type = TYPE_NAME (type);
8877 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8879 tree inner = TREE_TYPE (type);
8881 while (TREE_CODE (inner) == ARRAY_TYPE)
8882 inner = TREE_TYPE (inner);
8884 gen_type_name_0 (inner);
8886 if (!POINTER_TYPE_P (inner))
8887 strcat (errbuf, " ");
8889 if (POINTER_TYPE_P (type))
8890 strcat (errbuf, "*");
8891 else
8892 while (type != inner)
8894 strcat (errbuf, "[");
8896 if (TYPE_DOMAIN (type))
8898 char sz[20];
8900 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8901 (TREE_INT_CST_LOW
8902 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8903 strcat (errbuf, sz);
8906 strcat (errbuf, "]");
8907 type = TREE_TYPE (type);
8910 goto exit_function;
8913 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8914 type = DECL_NAME (type);
8916 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8917 ? IDENTIFIER_POINTER (type)
8918 : "");
8920 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8921 if (objc_is_id (orig))
8922 orig = TREE_TYPE (orig);
8924 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8926 if (proto)
8928 strcat (errbuf, " <");
8930 while (proto) {
8931 strcat (errbuf,
8932 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8933 proto = TREE_CHAIN (proto);
8934 strcat (errbuf, proto ? ", " : ">");
8938 exit_function:
8939 return errbuf;
8942 static char *
8943 gen_type_name (tree type)
8945 errbuf[0] = '\0';
8947 return gen_type_name_0 (type);
8950 /* Given a method tree, put a printable description into the given
8951 buffer (overwriting) and return a pointer to the buffer. */
8953 static char *
8954 gen_method_decl (tree method)
8956 tree chain;
8958 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8959 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8960 strcat (errbuf, ")");
8961 chain = METHOD_SEL_ARGS (method);
8963 if (chain)
8965 /* We have a chain of keyword_decls. */
8968 if (KEYWORD_KEY_NAME (chain))
8969 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8971 strcat (errbuf, ":(");
8972 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8973 strcat (errbuf, ")");
8975 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8976 if ((chain = DECL_CHAIN (chain)))
8977 strcat (errbuf, " ");
8979 while (chain);
8981 if (METHOD_ADD_ARGS (method))
8983 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8985 /* Know we have a chain of parm_decls. */
8986 while (chain)
8988 strcat (errbuf, ", ");
8989 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8990 chain = TREE_CHAIN (chain);
8993 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8994 strcat (errbuf, ", ...");
8998 else
8999 /* We have a unary selector. */
9000 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9002 return errbuf;
9005 /* Debug info. */
9008 /* Dump an @interface declaration of the supplied class CHAIN to the
9009 supplied file FP. Used to implement the -gen-decls option (which
9010 prints out an @interface declaration of all classes compiled in
9011 this run); potentially useful for debugging the compiler too. */
9012 static void
9013 dump_interface (FILE *fp, tree chain)
9015 /* FIXME: A heap overflow here whenever a method (or ivar)
9016 declaration is so long that it doesn't fit in the buffer. The
9017 code and all the related functions should be rewritten to avoid
9018 using fixed size buffers. */
9019 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9020 tree ivar_decls = CLASS_RAW_IVARS (chain);
9021 tree nst_methods = CLASS_NST_METHODS (chain);
9022 tree cls_methods = CLASS_CLS_METHODS (chain);
9024 fprintf (fp, "\n@interface %s", my_name);
9026 /* CLASS_SUPER_NAME is used to store the superclass name for
9027 classes, and the category name for categories. */
9028 if (CLASS_SUPER_NAME (chain))
9030 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9032 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9033 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9035 fprintf (fp, " (%s)\n", name);
9037 else
9039 fprintf (fp, " : %s\n", name);
9042 else
9043 fprintf (fp, "\n");
9045 /* FIXME - the following doesn't seem to work at the moment. */
9046 if (ivar_decls)
9048 fprintf (fp, "{\n");
9051 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9052 ivar_decls = TREE_CHAIN (ivar_decls);
9054 while (ivar_decls);
9055 fprintf (fp, "}\n");
9058 while (nst_methods)
9060 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9061 nst_methods = TREE_CHAIN (nst_methods);
9064 while (cls_methods)
9066 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9067 cls_methods = TREE_CHAIN (cls_methods);
9070 fprintf (fp, "@end\n");
9073 /* Demangle function for Objective-C */
9074 static const char *
9075 objc_demangle (const char *mangled)
9077 char *demangled, *cp;
9079 if (mangled[0] == '_' &&
9080 (mangled[1] == 'i' || mangled[1] == 'c') &&
9081 mangled[2] == '_')
9083 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9084 if (mangled[1] == 'i')
9085 *cp++ = '-'; /* for instance method */
9086 else
9087 *cp++ = '+'; /* for class method */
9088 *cp++ = '['; /* opening left brace */
9089 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9090 while (*cp && *cp == '_')
9091 cp++; /* skip any initial underbars in class name */
9092 cp = strchr(cp, '_'); /* find first non-initial underbar */
9093 if (cp == NULL)
9095 free(demangled); /* not mangled name */
9096 return mangled;
9098 if (cp[1] == '_') /* easy case: no category name */
9100 *cp++ = ' '; /* replace two '_' with one ' ' */
9101 strcpy(cp, mangled + (cp - demangled) + 2);
9103 else
9105 *cp++ = '('; /* less easy case: category name */
9106 cp = strchr(cp, '_');
9107 if (cp == 0)
9109 free(demangled); /* not mangled name */
9110 return mangled;
9112 *cp++ = ')';
9113 *cp++ = ' '; /* overwriting 1st char of method name... */
9114 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9116 while (*cp && *cp == '_')
9117 cp++; /* skip any initial underbars in method name */
9118 for (; *cp; cp++)
9119 if (*cp == '_')
9120 *cp = ':'; /* replace remaining '_' with ':' */
9121 *cp++ = ']'; /* closing right brace */
9122 *cp++ = 0; /* string terminator */
9123 return demangled;
9125 else
9126 return mangled; /* not an objc mangled name */
9129 const char *
9130 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9132 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9135 static void
9136 init_objc (void)
9138 gcc_obstack_init (&util_obstack);
9139 util_firstobj = (char *) obstack_finish (&util_obstack);
9141 errbuf = XNEWVEC (char, 1024 * 10);
9142 hash_init ();
9143 synth_module_prologue ();
9146 static void
9147 finish_objc (void)
9149 struct imp_entry *impent;
9150 tree chain;
9151 /* The internally generated initializers appear to have missing braces.
9152 Don't warn about this. */
9153 int save_warn_missing_braces = warn_missing_braces;
9154 warn_missing_braces = 0;
9156 /* A missing @end may not be detected by the parser. */
9157 if (objc_implementation_context)
9159 warning (0, "%<@end%> missing in implementation context");
9160 finish_class (objc_implementation_context);
9161 objc_ivar_chain = NULL_TREE;
9162 objc_implementation_context = NULL_TREE;
9165 /* Process the static instances here because initialization of objc_symtab
9166 depends on them. */
9167 if (objc_static_instances)
9168 generate_static_references ();
9170 /* forward declare categories */
9171 if (cat_count)
9172 forward_declare_categories ();
9174 for (impent = imp_list; impent; impent = impent->next)
9176 objc_implementation_context = impent->imp_context;
9177 implementation_template = impent->imp_template;
9179 /* FIXME: This needs reworking to be more obvious. */
9181 UOBJC_CLASS_decl = impent->class_decl;
9182 UOBJC_METACLASS_decl = impent->meta_decl;
9184 /* Dump the @interface of each class as we compile it, if the
9185 -gen-decls option is in use. TODO: Dump the classes in the
9186 order they were found, rather than in reverse order as we
9187 are doing now. */
9188 if (flag_gen_declaration)
9190 dump_interface (gen_declaration_file, objc_implementation_context);
9193 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9195 /* all of the following reference the string pool... */
9196 generate_ivar_lists ();
9197 generate_dispatch_tables ();
9198 generate_shared_structures (impent);
9200 else
9202 generate_dispatch_tables ();
9203 generate_category (impent);
9206 impent->class_decl = UOBJC_CLASS_decl;
9207 impent->meta_decl = UOBJC_METACLASS_decl;
9210 /* If we are using an array of selectors, we must always
9211 finish up the array decl even if no selectors were used. */
9212 if (flag_next_runtime)
9213 build_next_selector_translation_table ();
9214 else
9215 build_gnu_selector_translation_table ();
9217 if (protocol_chain)
9218 generate_protocols ();
9220 if (flag_next_runtime)
9221 generate_objc_image_info ();
9223 if (imp_list || class_names_chain
9224 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9225 generate_objc_symtab_decl ();
9227 /* Arrange for ObjC data structures to be initialized at run time. */
9228 if (objc_implementation_context || class_names_chain || objc_static_instances
9229 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9231 build_module_descriptor ();
9233 if (!flag_next_runtime)
9234 build_module_initializer_routine ();
9237 /* Dump the class references. This forces the appropriate classes
9238 to be linked into the executable image, preserving unix archive
9239 semantics. This can be removed when we move to a more dynamically
9240 linked environment. */
9242 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9244 handle_class_ref (chain);
9245 if (TREE_PURPOSE (chain))
9246 generate_classref_translation_entry (chain);
9249 for (impent = imp_list; impent; impent = impent->next)
9250 handle_impent (impent);
9252 if (warn_selector)
9254 int slot;
9255 hash hsh;
9257 /* Run through the selector hash tables and print a warning for any
9258 selector which has multiple methods. */
9260 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9262 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9263 check_duplicates (hsh, 0, 1);
9264 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9265 check_duplicates (hsh, 0, 1);
9269 warn_missing_braces = save_warn_missing_braces;
9272 /* Subroutines of finish_objc. */
9274 static void
9275 generate_classref_translation_entry (tree chain)
9277 tree expr, decl, type;
9279 decl = TREE_PURPOSE (chain);
9280 type = TREE_TYPE (decl);
9282 expr = add_objc_string (TREE_VALUE (chain), class_names);
9283 expr = convert (type, expr); /* cast! */
9285 /* This is a class reference. It is re-written by the runtime,
9286 but will be optimized away unless we force it. */
9287 DECL_PRESERVE_P (decl) = 1;
9288 finish_var_decl (decl, expr);
9289 return;
9292 static void
9293 handle_class_ref (tree chain)
9295 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9296 char *string = (char *) alloca (strlen (name) + 30);
9297 tree decl;
9298 tree exp;
9300 sprintf (string, "%sobjc_class_name_%s",
9301 (flag_next_runtime ? "." : "__"), name);
9303 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9304 if (flag_next_runtime)
9306 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9307 return;
9309 #endif
9311 /* Make a decl for this name, so we can use its address in a tree. */
9312 decl = build_decl (input_location,
9313 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
9314 DECL_EXTERNAL (decl) = 1;
9315 TREE_PUBLIC (decl) = 1;
9316 pushdecl (decl);
9317 finish_var_decl (decl, 0);
9319 /* Make a decl for the address. */
9320 sprintf (string, "%sobjc_class_ref_%s",
9321 (flag_next_runtime ? "." : "__"), name);
9322 exp = build1 (ADDR_EXPR, string_type_node, decl);
9323 decl = build_decl (input_location,
9324 VAR_DECL, get_identifier (string), string_type_node);
9325 TREE_STATIC (decl) = 1;
9326 TREE_USED (decl) = 1;
9327 DECL_READ_P (decl) = 1;
9328 DECL_ARTIFICIAL (decl) = 1;
9329 DECL_INITIAL (decl) = error_mark_node;
9331 /* We must force the reference. */
9332 DECL_PRESERVE_P (decl) = 1;
9334 pushdecl (decl);
9335 finish_var_decl (decl, exp);
9338 static void
9339 handle_impent (struct imp_entry *impent)
9341 char *string;
9343 objc_implementation_context = impent->imp_context;
9344 implementation_template = impent->imp_template;
9346 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9348 const char *const class_name =
9349 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9351 string = (char *) alloca (strlen (class_name) + 30);
9353 sprintf (string, "%sobjc_class_name_%s",
9354 (flag_next_runtime ? "." : "__"), class_name);
9356 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9358 const char *const class_name =
9359 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9360 const char *const class_super_name =
9361 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9363 string = (char *) alloca (strlen (class_name)
9364 + strlen (class_super_name) + 30);
9366 /* Do the same for categories. Even though no references to
9367 these symbols are generated automatically by the compiler, it
9368 gives you a handle to pull them into an archive by hand. */
9369 sprintf (string, "*%sobjc_category_name_%s_%s",
9370 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9372 else
9373 return;
9375 #ifdef ASM_DECLARE_CLASS_REFERENCE
9376 if (flag_next_runtime)
9378 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9379 return;
9381 else
9382 #endif
9384 tree decl, init;
9386 init = integer_zero_node;
9387 decl = build_decl (input_location,
9388 VAR_DECL, get_identifier (string), TREE_TYPE (init));
9389 TREE_PUBLIC (decl) = 1;
9390 TREE_READONLY (decl) = 1;
9391 TREE_USED (decl) = 1;
9392 TREE_CONSTANT (decl) = 1;
9393 DECL_CONTEXT (decl) = NULL_TREE;
9394 DECL_ARTIFICIAL (decl) = 1;
9395 TREE_STATIC (decl) = 1;
9396 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
9397 /* We must force the reference. */
9398 DECL_PRESERVE_P (decl) = 1;
9400 finish_var_decl(decl, init) ;
9404 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9405 later requires that ObjC translation units participating in F&C be
9406 specially marked. The following routine accomplishes this. */
9408 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9410 static void
9411 generate_objc_image_info (void)
9413 tree decl;
9414 int flags
9415 = ((flag_replace_objc_classes && imp_count ? 1 : 0)
9416 | (flag_objc_gc ? 2 : 0));
9417 VEC(constructor_elt,gc) *v = NULL;
9418 tree array_type;
9420 if (!flags)
9421 return; /* No need for an image_info entry. */
9423 array_type = build_sized_array_type (integer_type_node, 2);
9425 decl = start_var_decl (array_type, "_OBJC_IMAGE_INFO");
9427 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
9428 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
9429 /* If we need this (determined above) it is because the runtime wants to
9430 refer to it in a manner hidden from the compiler. So we must force the
9431 output. */
9432 DECL_PRESERVE_P (decl) = 1;
9433 finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
9436 /* Look up ID as an instance variable. OTHER contains the result of
9437 the C or C++ lookup, which we may want to use instead. */
9439 tree
9440 objc_lookup_ivar (tree other, tree id)
9442 tree ivar;
9444 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9445 if (!objc_method_context)
9446 return other;
9448 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9449 /* We have a message to super. */
9450 return get_super_receiver ();
9452 /* In a class method, look up an instance variable only as a last
9453 resort. */
9454 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9455 && other && other != error_mark_node)
9456 return other;
9458 /* Look up the ivar, but do not use it if it is not accessible. */
9459 ivar = is_ivar (objc_ivar_chain, id);
9461 if (!ivar || is_private (ivar))
9462 return other;
9464 /* In an instance method, a local variable (or parameter) may hide the
9465 instance variable. */
9466 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9467 && other && other != error_mark_node
9468 #ifdef OBJCPLUS
9469 && CP_DECL_CONTEXT (other) != global_namespace)
9470 #else
9471 && !DECL_FILE_SCOPE_P (other))
9472 #endif
9474 warning (0, "local declaration of %qE hides instance variable",
9475 id);
9477 return other;
9480 /* At this point, we are either in an instance method with no obscuring
9481 local definitions, or in a class method with no alternate definitions
9482 at all. */
9483 return build_ivar_reference (id);
9486 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9487 needs to be done if we are calling a function through a cast. */
9489 tree
9490 objc_rewrite_function_call (tree function, tree first_param)
9492 if (TREE_CODE (function) == NOP_EXPR
9493 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9494 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9495 == FUNCTION_DECL)
9497 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9498 TREE_OPERAND (function, 0),
9499 first_param, size_zero_node);
9502 return function;
9505 /* Look for the special case of OBJC_TYPE_REF with the address of
9506 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9507 of its cousins). */
9510 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9512 enum gimplify_status r0, r1;
9513 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9514 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9515 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9516 == FUNCTION_DECL)
9518 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9519 value of the OBJ_TYPE_REF, so force them to be emitted
9520 during subexpression evaluation rather than after the
9521 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9522 C to use direct rather than indirect calls when the
9523 object expression has a postincrement. */
9524 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9525 is_gimple_val, fb_rvalue);
9526 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9527 is_gimple_val, fb_rvalue);
9529 return MIN (r0, r1);
9532 #ifdef OBJCPLUS
9533 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9534 #else
9535 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9536 #endif
9539 #include "gt-objc-objc-act.h"