2005-06-28 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / objc / objc-act.c
blobd4c20a87ec9f2688196932a26cecef4f2bf833c0
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
57 #include "c-common.h"
58 #include "c-pragma.h"
59 #include "flags.h"
60 #include "langhooks.h"
61 #include "objc-act.h"
62 #include "input.h"
63 #include "except.h"
64 #include "function.h"
65 #include "output.h"
66 #include "toplev.h"
67 #include "ggc.h"
68 #include "varray.h"
69 #include "debug.h"
70 #include "target.h"
71 #include "diagnostic.h"
72 #include "cgraph.h"
73 #include "tree-iterator.h"
74 #include "libfuncs.h"
75 #include "hashtab.h"
76 #include "langhooks-def.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 are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
84 #ifdef OBJCPLUS
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
87 #endif /* OBJCPLUS */
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
95 do { \
96 char *temp; \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
99 (CLASS_NAME), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
101 (SEL_NAME)); \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
104 } while (0)
105 #endif
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
110 #endif
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
114 #endif
116 /* Set up for use of obstacks. */
118 #include "obstack.h"
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
125 char *util_firstobj;
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
157 #ifdef OBJCPLUS
158 static void objc_start_function (tree, tree, tree, tree);
159 #else
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
161 #endif
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
174 #ifndef OBJCPLUS
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
177 #endif
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
189 #ifdef OBJCPLUS
190 static void objc_generate_cxx_cdtors (void);
191 #endif
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
204 enum string_section
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
220 /* Type encoding. */
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
226 #ifdef OBJCPLUS
227 static void really_start_method (tree, tree);
228 #else
229 static void really_start_method (tree, struct c_arg_info *);
230 #endif
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
233 #ifdef OBJCPLUS
234 static tree objc_get_parm_info (int);
235 #else
236 static struct c_arg_info *objc_get_parm_info (int);
237 #endif
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
256 ATTRIBUTE_NORETURN;
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
288 NeXT runtime. */
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
371 #define BUFSIZE 1024
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
391 tree literal;
393 /* The resulting constant string. */
394 tree constructor;
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
402 tree type;
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
420 static void
421 generate_struct_by_value_array (void)
423 tree type;
424 tree field_decl, field_decl_chain;
425 int i, j;
426 int aggregate_in_mem[32];
427 int found = 0;
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
432 char buffer[5];
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
439 buffer);
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
446 buffer);
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
453 found = 1;
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
458 if (found)
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
462 break;
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
471 printf ("\n};\n");
474 exit (0);
477 bool
478 objc_init (void)
480 #ifdef OBJCPLUS
481 if (cxx_init () == false)
482 #else
483 if (c_objc_common_init () == false)
484 #endif
485 return false;
487 #ifndef USE_MAPPED_LOCATION
488 /* Force the line number back to 0; check_newline will have
489 raised it to 1, which will make the builtin functions appear
490 not to be built in. */
491 input_line = 0;
492 #endif
494 /* If gen_declaration desired, open the output file. */
495 if (flag_gen_declaration)
497 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
498 gen_declaration_file = fopen (dumpname, "w");
499 if (gen_declaration_file == 0)
500 fatal_error ("can't open %s: %m", dumpname);
501 free (dumpname);
504 if (flag_next_runtime)
506 TAG_GETCLASS = "objc_getClass";
507 TAG_GETMETACLASS = "objc_getMetaClass";
508 TAG_MSGSEND = "objc_msgSend";
509 TAG_MSGSENDSUPER = "objc_msgSendSuper";
510 TAG_MSGSEND_STRET = "objc_msgSend_stret";
511 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
512 default_constant_string_class_name = "NSConstantString";
514 else
516 TAG_GETCLASS = "objc_get_class";
517 TAG_GETMETACLASS = "objc_get_meta_class";
518 TAG_MSGSEND = "objc_msg_lookup";
519 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
520 /* GNU runtime does not provide special functions to support
521 structure-returning methods. */
522 default_constant_string_class_name = "NXConstantString";
523 flag_typed_selectors = 1;
526 init_objc ();
528 if (print_struct_values)
529 generate_struct_by_value_array ();
531 return true;
534 void
535 objc_finish_file (void)
537 mark_referenced_methods ();
539 #ifdef OBJCPLUS
540 /* We need to instantiate templates _before_ we emit ObjC metadata;
541 if we do not, some metadata (such as selectors) may go missing. */
542 at_eof = 1;
543 instantiate_pending_templates (0);
544 #endif
546 /* Finalize Objective-C runtime data. No need to generate tables
547 and code if only checking syntax, or if generating a PCH file. */
548 if (!flag_syntax_only && !pch_file)
549 finish_objc ();
551 if (gen_declaration_file)
552 fclose (gen_declaration_file);
554 #ifdef OBJCPLUS
555 cp_finish_file ();
556 #endif
559 /* Return the first occurrence of a method declaration corresponding
560 to sel_name in rproto_list. Search rproto_list recursively.
561 If is_class is 0, search for instance methods, otherwise for class
562 methods. */
563 static tree
564 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
565 int is_class)
567 tree rproto, p;
568 tree fnd = 0;
570 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
572 p = TREE_VALUE (rproto);
574 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
576 if ((fnd = lookup_method (is_class
577 ? PROTOCOL_CLS_METHODS (p)
578 : PROTOCOL_NST_METHODS (p), sel_name)))
580 else if (PROTOCOL_LIST (p))
581 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
582 sel_name, is_class);
584 else
586 ; /* An identifier...if we could not find a protocol. */
589 if (fnd)
590 return fnd;
593 return 0;
596 static tree
597 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
599 tree rproto, p;
601 /* Make sure the protocol is supported by the object on the rhs. */
602 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
604 tree fnd = 0;
605 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
607 p = TREE_VALUE (rproto);
609 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
611 if (lproto == p)
612 fnd = lproto;
614 else if (PROTOCOL_LIST (p))
615 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
618 if (fnd)
619 return fnd;
622 else
624 ; /* An identifier...if we could not find a protocol. */
627 return 0;
630 void
631 objc_start_class_interface (tree class, tree super_class, tree protos)
633 objc_interface_context
634 = objc_ivar_context
635 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
636 objc_public_flag = 0;
639 void
640 objc_start_category_interface (tree class, tree categ, tree protos)
642 objc_interface_context
643 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
644 objc_ivar_chain
645 = continue_class (objc_interface_context);
648 void
649 objc_start_protocol (tree name, tree protos)
651 objc_interface_context
652 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
655 void
656 objc_continue_interface (void)
658 objc_ivar_chain
659 = continue_class (objc_interface_context);
662 void
663 objc_finish_interface (void)
665 finish_class (objc_interface_context);
666 objc_interface_context = NULL_TREE;
669 void
670 objc_start_class_implementation (tree class, tree super_class)
672 objc_implementation_context
673 = objc_ivar_context
674 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
675 objc_public_flag = 0;
678 void
679 objc_start_category_implementation (tree class, tree categ)
681 objc_implementation_context
682 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
683 objc_ivar_chain
684 = continue_class (objc_implementation_context);
687 void
688 objc_continue_implementation (void)
690 objc_ivar_chain
691 = continue_class (objc_implementation_context);
694 void
695 objc_finish_implementation (void)
697 #ifdef OBJCPLUS
698 if (flag_objc_call_cxx_cdtors)
699 objc_generate_cxx_cdtors ();
700 #endif
702 if (objc_implementation_context)
704 finish_class (objc_implementation_context);
705 objc_ivar_chain = NULL_TREE;
706 objc_implementation_context = NULL_TREE;
708 else
709 warning (0, "%<@end%> must appear in an @implementation context");
712 void
713 objc_set_visibility (int visibility)
715 objc_public_flag = visibility;
718 void
719 objc_set_method_type (enum tree_code type)
721 objc_inherit_code = (type == PLUS_EXPR
722 ? CLASS_METHOD_DECL
723 : INSTANCE_METHOD_DECL);
726 tree
727 objc_build_method_signature (tree rettype, tree selector,
728 tree optparms, bool ellipsis)
730 return build_method_decl (objc_inherit_code, rettype, selector,
731 optparms, ellipsis);
734 void
735 objc_add_method_declaration (tree decl)
737 if (!objc_interface_context)
738 fatal_error ("method declaration not in @interface context");
740 objc_add_method (objc_interface_context,
741 decl,
742 objc_inherit_code == CLASS_METHOD_DECL);
745 void
746 objc_start_method_definition (tree decl)
748 if (!objc_implementation_context)
749 fatal_error ("method definition not in @implementation context");
751 objc_add_method (objc_implementation_context,
752 decl,
753 objc_inherit_code == CLASS_METHOD_DECL);
754 start_method_def (decl);
757 void
758 objc_add_instance_variable (tree decl)
760 (void) add_instance_variable (objc_ivar_context,
761 objc_public_flag,
762 decl);
765 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
766 an '@'. */
769 objc_is_reserved_word (tree ident)
771 unsigned char code = C_RID_CODE (ident);
773 return (OBJC_IS_AT_KEYWORD (code)
774 #ifdef OBJCPLUS
775 || code == RID_CLASS || code == RID_PUBLIC
776 || code == RID_PROTECTED || code == RID_PRIVATE
777 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
778 #endif
782 /* Return true if TYPE is 'id'. */
784 static bool
785 objc_is_object_id (tree type)
787 return OBJC_TYPE_NAME (type) == objc_object_id;
790 static bool
791 objc_is_class_id (tree type)
793 return OBJC_TYPE_NAME (type) == objc_class_id;
796 /* Construct a C struct with tag NAME, a base struct with tag
797 SUPER_NAME (if any), and FIELDS indicated. */
799 static tree
800 objc_build_struct (tree name, tree fields, tree super_name)
802 tree s = start_struct (RECORD_TYPE, name);
803 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
804 tree t, objc_info = NULL_TREE;
806 if (super)
808 /* Prepend a packed variant of the base class into the layout. This
809 is necessary to preserve ObjC ABI compatibility. */
810 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
811 tree field = TYPE_FIELDS (super);
813 while (field && TREE_CHAIN (field)
814 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
815 field = TREE_CHAIN (field);
817 /* For ObjC ABI purposes, the "packed" size of a base class is
818 the the sum of the offset and the size (in bits) of the last
819 field in the class. */
820 DECL_SIZE (base)
821 = (field && TREE_CODE (field) == FIELD_DECL
822 ? size_binop (PLUS_EXPR,
823 size_binop (PLUS_EXPR,
824 size_binop
825 (MULT_EXPR,
826 convert (bitsizetype,
827 DECL_FIELD_OFFSET (field)),
828 bitsize_int (BITS_PER_UNIT)),
829 DECL_FIELD_BIT_OFFSET (field)),
830 DECL_SIZE (field))
831 : bitsize_zero_node);
832 DECL_SIZE_UNIT (base)
833 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
834 size_int (BITS_PER_UNIT));
835 DECL_ARTIFICIAL (base) = 1;
836 DECL_ALIGN (base) = 1;
837 DECL_FIELD_CONTEXT (base) = s;
838 #ifdef OBJCPLUS
839 DECL_FIELD_IS_BASE (base) = 1;
841 if (fields)
842 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
843 #endif /* are following the ObjC ABI here. */
844 TREE_CHAIN (base) = fields;
845 fields = base;
848 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
849 in all variants of this RECORD_TYPE to be clobbered, but it is therein
850 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
851 Hence, we must squirrel away the ObjC-specific information before calling
852 finish_struct(), and then reinstate it afterwards. */
854 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
855 objc_info
856 = chainon (objc_info,
857 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
859 s = finish_struct (s, fields, NULL_TREE);
861 for (t = TYPE_NEXT_VARIANT (s); t;
862 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
863 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
865 /* Use TYPE_BINFO structures to point at the super class, if any. */
866 objc_xref_basetypes (s, super);
868 return s;
871 /* Mark DECL as being 'volatile' for purposes of Darwin
872 _setjmp()/_longjmp() exception handling. Called from
873 objc_mark_locals_volatile(). */
874 void
875 objc_volatilize_decl (tree decl)
877 /* Do not mess with variables that are 'static' or (already)
878 'volatile'. */
879 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
880 && (TREE_CODE (decl) == VAR_DECL
881 || TREE_CODE (decl) == PARM_DECL))
883 tree t = TREE_TYPE (decl);
884 struct volatilized_type key;
885 void **loc;
887 t = build_qualified_type (t, (TYPE_QUALS (t)
888 | TYPE_QUAL_VOLATILE));
889 key.type = t;
890 loc = htab_find_slot (volatilized_htab, &key, INSERT);
892 if (!*loc)
894 *loc = ggc_alloc (sizeof (key));
895 ((struct volatilized_type *) *loc)->type = t;
898 TREE_TYPE (decl) = t;
899 TREE_THIS_VOLATILE (decl) = 1;
900 TREE_SIDE_EFFECTS (decl) = 1;
901 DECL_REGISTER (decl) = 0;
902 #ifndef OBJCPLUS
903 C_DECL_REGISTER (decl) = 0;
904 #endif
908 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
909 (including its categoreis and superclasses) or by object type TYP.
910 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
912 static bool
913 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
915 bool class_type = (cls != NULL_TREE);
917 while (cls)
919 tree c;
921 /* Check protocols adopted by the class and its categories. */
922 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
924 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
925 return true;
928 /* Repeat for superclasses. */
929 cls = lookup_interface (CLASS_SUPER_NAME (cls));
932 /* Check for any protocols attached directly to the object type. */
933 if (TYPE_HAS_OBJC_INFO (typ))
935 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
936 return true;
939 if (warn)
941 strcpy (errbuf, class_type ? "class \'" : "type \'");
942 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
943 strcat (errbuf, "\' does not ");
944 /* NB: Types 'id' and 'Class' cannot reasonably be described as
945 "implementing" a given protocol, since they do not have an
946 implementation. */
947 strcat (errbuf, class_type ? "implement" : "conform to");
948 strcat (errbuf, " the \'");
949 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
950 strcat (errbuf, "\' protocol");
951 warning (0, errbuf);
954 return false;
957 /* Check if class RCLS and instance struct type RTYP conform to at least the
958 same protocols that LCLS and LTYP conform to. */
960 static bool
961 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
963 tree p;
964 bool have_lproto = false;
966 while (lcls)
968 /* NB: We do _not_ look at categories defined for LCLS; these may or
969 may not get loaded in, and therefore it is unreasonable to require
970 that RCLS/RTYP must implement any of their protocols. */
971 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
973 have_lproto = true;
975 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
976 return warn;
979 /* Repeat for superclasses. */
980 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
983 /* Check for any protocols attached directly to the object type. */
984 if (TYPE_HAS_OBJC_INFO (ltyp))
986 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
988 have_lproto = true;
990 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
991 return warn;
995 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
996 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
997 away with simply checking for 'id' or 'Class' (!RCLS), since this
998 routine will not get called in other cases. */
999 return have_lproto || (rcls != NULL_TREE);
1002 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1003 an instance of RTYP to an instance of LTYP or to compare the two
1004 (if ARGNO is equal to -3), per ObjC type system rules. Before
1005 returning 'true', this routine may issue warnings related to, e.g.,
1006 protocol conformance. When returning 'false', the routine must
1007 produce absolutely no warnings; the C or C++ front-end will do so
1008 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1009 the routine must return 'false'.
1011 The ARGNO parameter is encoded as follows:
1012 >= 1 Parameter number (CALLEE contains function being called);
1013 0 Return value;
1014 -1 Assignment;
1015 -2 Initialization;
1016 -3 Comparison (LTYP and RTYP may match in either direction). */
1018 bool
1019 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1021 tree lcls, rcls, lproto, rproto;
1022 bool pointers_compatible;
1024 /* We must be dealing with pointer types */
1025 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1026 return false;
1030 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1031 rtyp = TREE_TYPE (rtyp);
1033 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1035 /* Past this point, we are only interested in ObjC class instances,
1036 or 'id' or 'Class'. */
1037 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1038 return false;
1040 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1041 && !TYPE_HAS_OBJC_INFO (ltyp))
1042 return false;
1044 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1045 && !TYPE_HAS_OBJC_INFO (rtyp))
1046 return false;
1048 /* Past this point, we are committed to returning 'true' to the caller.
1049 However, we can still warn about type and/or protocol mismatches. */
1051 if (TYPE_HAS_OBJC_INFO (ltyp))
1053 lcls = TYPE_OBJC_INTERFACE (ltyp);
1054 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1056 else
1057 lcls = lproto = NULL_TREE;
1059 if (TYPE_HAS_OBJC_INFO (rtyp))
1061 rcls = TYPE_OBJC_INTERFACE (rtyp);
1062 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1064 else
1065 rcls = rproto = NULL_TREE;
1067 /* If either type is an unqualified 'id', we're done. */
1068 if ((!lproto && objc_is_object_id (ltyp))
1069 || (!rproto && objc_is_object_id (rtyp)))
1070 return true;
1072 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1074 /* If the underlying types are the same, and at most one of them has
1075 a protocol list, we do not need to issue any diagnostics. */
1076 if (pointers_compatible && (!lproto || !rproto))
1077 return true;
1079 /* If exactly one of the types is 'Class', issue a diagnostic; any
1080 exceptions of this rule have already been handled. */
1081 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1082 pointers_compatible = false;
1083 /* Otherwise, check for inheritance relations. */
1084 else
1086 if (!pointers_compatible)
1087 pointers_compatible
1088 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1090 if (!pointers_compatible)
1091 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1093 if (!pointers_compatible && argno == -3)
1094 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1097 /* If the pointers match modulo protocols, check for protocol conformance
1098 mismatches. */
1099 if (pointers_compatible)
1101 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1102 argno != -3);
1104 if (!pointers_compatible && argno == -3)
1105 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1106 argno != -3);
1109 if (!pointers_compatible)
1111 /* NB: For the time being, we shall make our warnings look like their
1112 C counterparts. In the future, we may wish to make them more
1113 ObjC-specific. */
1114 switch (argno)
1116 case -3:
1117 warning (0, "comparison of distinct Objective-C types lacks a cast");
1118 break;
1120 case -2:
1121 warning (0, "initialization from distinct Objective-C type");
1122 break;
1124 case -1:
1125 warning (0, "assignment from distinct Objective-C type");
1126 break;
1128 case 0:
1129 warning (0, "distinct Objective-C type in return");
1130 break;
1132 default:
1133 warning (0, "passing argument %d of %qE from distinct "
1134 "Objective-C type", argno, callee);
1135 break;
1139 return true;
1142 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1143 lives in the volatilized hash table, ignore the 'volatile' bit when
1144 making the comparison. */
1146 bool
1147 objc_type_quals_match (tree ltyp, tree rtyp)
1149 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1150 struct volatilized_type key;
1152 key.type = ltyp;
1154 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1155 lquals &= ~TYPE_QUAL_VOLATILE;
1157 key.type = rtyp;
1159 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1160 rquals &= ~TYPE_QUAL_VOLATILE;
1162 return (lquals == rquals);
1165 #ifndef OBJCPLUS
1166 /* Determine if CHILD is derived from PARENT. The routine assumes that
1167 both parameters are RECORD_TYPEs, and is non-reflexive. */
1169 static bool
1170 objc_derived_from_p (tree parent, tree child)
1172 parent = TYPE_MAIN_VARIANT (parent);
1174 for (child = TYPE_MAIN_VARIANT (child);
1175 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1177 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1178 (TYPE_BINFO (child),
1179 0)));
1181 if (child == parent)
1182 return true;
1185 return false;
1187 #endif
1189 static tree
1190 objc_build_component_ref (tree datum, tree component)
1192 /* If COMPONENT is NULL, the caller is referring to the anonymous
1193 base class field. */
1194 if (!component)
1196 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1198 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1201 /* The 'build_component_ref' routine has been removed from the C++
1202 front-end, but 'finish_class_member_access_expr' seems to be
1203 a worthy substitute. */
1204 #ifdef OBJCPLUS
1205 return finish_class_member_access_expr (datum, component);
1206 #else
1207 return build_component_ref (datum, component);
1208 #endif
1211 /* Recursively copy inheritance information rooted at BINFO. To do this,
1212 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1214 static tree
1215 objc_copy_binfo (tree binfo)
1217 tree btype = BINFO_TYPE (binfo);
1218 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1219 tree base_binfo;
1220 int ix;
1222 BINFO_TYPE (binfo2) = btype;
1223 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1224 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1226 /* Recursively copy base binfos of BINFO. */
1227 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1229 tree base_binfo2 = objc_copy_binfo (base_binfo);
1231 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1232 BINFO_BASE_APPEND (binfo2, base_binfo2);
1235 return binfo2;
1238 /* Record superclass information provided in BASETYPE for ObjC class REF.
1239 This is loosely based on cp/decl.c:xref_basetypes(). */
1241 static void
1242 objc_xref_basetypes (tree ref, tree basetype)
1244 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1246 TYPE_BINFO (ref) = binfo;
1247 BINFO_OFFSET (binfo) = size_zero_node;
1248 BINFO_TYPE (binfo) = ref;
1250 if (basetype)
1252 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1254 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1255 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1256 BINFO_BASE_APPEND (binfo, base_binfo);
1257 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1261 static hashval_t
1262 volatilized_hash (const void *ptr)
1264 tree typ = ((struct volatilized_type *)ptr)->type;
1266 return htab_hash_pointer(typ);
1269 static int
1270 volatilized_eq (const void *ptr1, const void *ptr2)
1272 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1273 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1275 return typ1 == typ2;
1278 /* Called from finish_decl. */
1280 void
1281 objc_check_decl (tree decl)
1283 tree type = TREE_TYPE (decl);
1285 if (TREE_CODE (type) != RECORD_TYPE)
1286 return;
1287 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1288 error ("statically allocated instance of Objective-C class %qs",
1289 IDENTIFIER_POINTER (type));
1292 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1293 either name an Objective-C class, or refer to the special 'id' or 'Class'
1294 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1296 tree
1297 objc_get_protocol_qualified_type (tree interface, tree protocols)
1299 /* If INTERFACE is not provided, default to 'id'. */
1300 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1301 bool is_ptr = (type != NULL_TREE);
1303 if (!is_ptr)
1305 type = objc_is_class_name (interface);
1307 if (type)
1308 type = xref_tag (RECORD_TYPE, type);
1309 else
1310 return interface;
1313 if (protocols)
1315 type = build_variant_type_copy (type);
1317 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1318 to the pointee. */
1319 if (is_ptr)
1321 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1322 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1323 type = TREE_TYPE (type);
1326 /* Look up protocols and install in lang specific list. */
1327 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1328 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1330 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1331 return the pointer to the new pointee variant. */
1332 if (is_ptr)
1333 type = TYPE_POINTER_TO (type);
1334 else
1335 TYPE_OBJC_INTERFACE (type)
1336 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1339 return type;
1342 /* Check for circular dependencies in protocols. The arguments are
1343 PROTO, the protocol to check, and LIST, a list of protocol it
1344 conforms to. */
1346 static void
1347 check_protocol_recursively (tree proto, tree list)
1349 tree p;
1351 for (p = list; p; p = TREE_CHAIN (p))
1353 tree pp = TREE_VALUE (p);
1355 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1356 pp = lookup_protocol (pp);
1358 if (pp == proto)
1359 fatal_error ("protocol %qs has circular dependency",
1360 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1361 if (pp)
1362 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1366 /* Look up PROTOCOLS, and return a list of those that are found.
1367 If none are found, return NULL. */
1369 static tree
1370 lookup_and_install_protocols (tree protocols)
1372 tree proto;
1373 tree return_value = NULL_TREE;
1375 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1377 tree ident = TREE_VALUE (proto);
1378 tree p = lookup_protocol (ident);
1380 if (!p)
1381 error ("cannot find protocol declaration for %qs",
1382 IDENTIFIER_POINTER (ident));
1383 else
1384 return_value = chainon (return_value,
1385 build_tree_list (NULL_TREE, p));
1388 return return_value;
1391 /* Create a declaration for field NAME of a given TYPE. */
1393 static tree
1394 create_field_decl (tree type, const char *name)
1396 return build_decl (FIELD_DECL, get_identifier (name), type);
1399 /* Create a global, static declaration for variable NAME of a given TYPE. The
1400 finish_var_decl() routine will need to be called on it afterwards. */
1402 static tree
1403 start_var_decl (tree type, const char *name)
1405 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1407 TREE_STATIC (var) = 1;
1408 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1409 DECL_IGNORED_P (var) = 1;
1410 DECL_ARTIFICIAL (var) = 1;
1411 DECL_CONTEXT (var) = NULL_TREE;
1412 #ifdef OBJCPLUS
1413 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1414 #endif
1416 return var;
1419 /* Finish off the variable declaration created by start_var_decl(). */
1421 static void
1422 finish_var_decl (tree var, tree initializer)
1424 finish_decl (var, initializer, NULL_TREE);
1425 /* Ensure that the variable actually gets output. */
1426 mark_decl_referenced (var);
1427 /* Mark the decl to avoid "defined but not used" warning. */
1428 TREE_USED (var) = 1;
1431 /* Find the decl for the constant string class reference. This is only
1432 used for the NeXT runtime. */
1434 static tree
1435 setup_string_decl (void)
1437 char *name;
1438 size_t length;
1440 /* %s in format will provide room for terminating null */
1441 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1442 + strlen (constant_string_class_name);
1443 name = xmalloc (length);
1444 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1445 constant_string_class_name);
1446 constant_string_global_id = get_identifier (name);
1447 string_class_decl = lookup_name (constant_string_global_id);
1449 return string_class_decl;
1452 /* Purpose: "play" parser, creating/installing representations
1453 of the declarations that are required by Objective-C.
1455 Model:
1457 type_spec--------->sc_spec
1458 (tree_list) (tree_list)
1461 identifier_node identifier_node */
1463 static void
1464 synth_module_prologue (void)
1466 tree type;
1467 enum debug_info_type save_write_symbols = write_symbols;
1468 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1470 /* Suppress outputting debug symbols, because
1471 dbxout_init hasn'r been called yet. */
1472 write_symbols = NO_DEBUG;
1473 debug_hooks = &do_nothing_debug_hooks;
1475 #ifdef OBJCPLUS
1476 push_lang_context (lang_name_c); /* extern "C" */
1477 #endif
1479 /* The following are also defined in <objc/objc.h> and friends. */
1481 objc_object_id = get_identifier (TAG_OBJECT);
1482 objc_class_id = get_identifier (TAG_CLASS);
1484 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1485 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1487 objc_object_type = build_pointer_type (objc_object_reference);
1488 objc_class_type = build_pointer_type (objc_class_reference);
1490 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1491 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1493 /* Declare the 'id' and 'Class' typedefs. */
1495 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1496 objc_object_name,
1497 objc_object_type));
1498 DECL_IN_SYSTEM_HEADER (type) = 1;
1499 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1500 objc_class_name,
1501 objc_class_type));
1502 DECL_IN_SYSTEM_HEADER (type) = 1;
1504 /* Forward-declare '@interface Protocol'. */
1506 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1507 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1508 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1509 type));
1511 /* Declare type of selector-objects that represent an operation name. */
1513 if (flag_next_runtime)
1514 /* `struct objc_selector *' */
1515 objc_selector_type
1516 = build_pointer_type (xref_tag (RECORD_TYPE,
1517 get_identifier (TAG_SELECTOR)));
1518 else
1519 /* `const struct objc_selector *' */
1520 objc_selector_type
1521 = build_pointer_type
1522 (build_qualified_type (xref_tag (RECORD_TYPE,
1523 get_identifier (TAG_SELECTOR)),
1524 TYPE_QUAL_CONST));
1526 /* Declare receiver type used for dispatching messages to 'super'. */
1528 /* `struct objc_super *' */
1529 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1530 get_identifier (TAG_SUPER)));
1532 /* Declare pointers to method and ivar lists. */
1533 objc_method_list_ptr = build_pointer_type
1534 (xref_tag (RECORD_TYPE,
1535 get_identifier (UTAG_METHOD_LIST)));
1536 objc_method_proto_list_ptr
1537 = build_pointer_type (xref_tag (RECORD_TYPE,
1538 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1539 objc_ivar_list_ptr = build_pointer_type
1540 (xref_tag (RECORD_TYPE,
1541 get_identifier (UTAG_IVAR_LIST)));
1543 if (flag_next_runtime)
1545 /* NB: In order to call one of the ..._stret (struct-returning)
1546 functions, the function *MUST* first be cast to a signature that
1547 corresponds to the actual ObjC method being invoked. This is
1548 what is done by the build_objc_method_call() routine below. */
1550 /* id objc_msgSend (id, SEL, ...); */
1551 /* id objc_msgSendNonNil (id, SEL, ...); */
1552 /* id objc_msgSend_stret (id, SEL, ...); */
1553 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1554 type
1555 = build_function_type (objc_object_type,
1556 tree_cons (NULL_TREE, objc_object_type,
1557 tree_cons (NULL_TREE, objc_selector_type,
1558 NULL_TREE)));
1559 umsg_decl = builtin_function (TAG_MSGSEND,
1560 type, 0, NOT_BUILT_IN,
1561 NULL, NULL_TREE);
1562 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1563 type, 0, NOT_BUILT_IN,
1564 NULL, NULL_TREE);
1565 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1566 type, 0, NOT_BUILT_IN,
1567 NULL, NULL_TREE);
1568 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1569 type, 0, NOT_BUILT_IN,
1570 NULL, NULL_TREE);
1572 /* id objc_msgSend_Fast (id, SEL, ...)
1573 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1574 #ifdef OFFS_MSGSEND_FAST
1575 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1576 type, 0, NOT_BUILT_IN,
1577 NULL, NULL_TREE);
1578 DECL_ATTRIBUTES (umsg_fast_decl)
1579 = tree_cons (get_identifier ("hard_coded_address"),
1580 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1581 NULL_TREE);
1582 #else
1583 /* No direct dispatch availible. */
1584 umsg_fast_decl = umsg_decl;
1585 #endif
1587 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1588 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1589 type
1590 = build_function_type (objc_object_type,
1591 tree_cons (NULL_TREE, objc_super_type,
1592 tree_cons (NULL_TREE, objc_selector_type,
1593 NULL_TREE)));
1594 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1595 type, 0, NOT_BUILT_IN,
1596 NULL, NULL_TREE);
1597 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1598 type, 0, NOT_BUILT_IN, 0,
1599 NULL_TREE);
1601 else
1603 /* GNU runtime messenger entry points. */
1605 /* typedef id (*IMP)(id, SEL, ...); */
1606 tree IMP_type
1607 = build_pointer_type
1608 (build_function_type (objc_object_type,
1609 tree_cons (NULL_TREE, objc_object_type,
1610 tree_cons (NULL_TREE, objc_selector_type,
1611 NULL_TREE))));
1613 /* IMP objc_msg_lookup (id, SEL); */
1614 type
1615 = build_function_type (IMP_type,
1616 tree_cons (NULL_TREE, objc_object_type,
1617 tree_cons (NULL_TREE, objc_selector_type,
1618 OBJC_VOID_AT_END)));
1619 umsg_decl = builtin_function (TAG_MSGSEND,
1620 type, 0, NOT_BUILT_IN,
1621 NULL, NULL_TREE);
1623 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1624 type
1625 = build_function_type (IMP_type,
1626 tree_cons (NULL_TREE, objc_super_type,
1627 tree_cons (NULL_TREE, objc_selector_type,
1628 OBJC_VOID_AT_END)));
1629 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1630 type, 0, NOT_BUILT_IN,
1631 NULL, NULL_TREE);
1633 /* The following GNU runtime entry point is called to initialize
1634 each module:
1636 __objc_exec_class (void *); */
1637 type
1638 = build_function_type (void_type_node,
1639 tree_cons (NULL_TREE, ptr_type_node,
1640 OBJC_VOID_AT_END));
1641 execclass_decl = builtin_function (TAG_EXECCLASS,
1642 type, 0, NOT_BUILT_IN,
1643 NULL, NULL_TREE);
1646 /* id objc_getClass (const char *); */
1648 type = build_function_type (objc_object_type,
1649 tree_cons (NULL_TREE,
1650 const_string_type_node,
1651 OBJC_VOID_AT_END));
1653 objc_get_class_decl
1654 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1655 NULL, NULL_TREE);
1657 /* id objc_getMetaClass (const char *); */
1659 objc_get_meta_class_decl
1660 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1662 build_class_template ();
1663 build_super_template ();
1664 build_protocol_template ();
1665 build_category_template ();
1666 build_objc_exception_stuff ();
1668 if (flag_next_runtime)
1669 build_next_objc_exception_stuff ();
1671 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1673 if (! flag_next_runtime)
1674 build_selector_table_decl ();
1676 /* Forward declare constant_string_id and constant_string_type. */
1677 if (!constant_string_class_name)
1678 constant_string_class_name = default_constant_string_class_name;
1680 constant_string_id = get_identifier (constant_string_class_name);
1681 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1683 /* Pre-build the following entities - for speed/convenience. */
1684 self_id = get_identifier ("self");
1685 ucmd_id = get_identifier ("_cmd");
1687 #ifdef OBJCPLUS
1688 pop_lang_context ();
1689 #endif
1691 write_symbols = save_write_symbols;
1692 debug_hooks = save_hooks;
1695 /* Ensure that the ivar list for NSConstantString/NXConstantString
1696 (or whatever was specified via `-fconstant-string-class')
1697 contains fields at least as large as the following three, so that
1698 the runtime can stomp on them with confidence:
1700 struct STRING_OBJECT_CLASS_NAME
1702 Object isa;
1703 char *cString;
1704 unsigned int length;
1705 }; */
1707 static int
1708 check_string_class_template (void)
1710 tree field_decl = TYPE_FIELDS (constant_string_type);
1712 #define AT_LEAST_AS_LARGE_AS(F, T) \
1713 (F && TREE_CODE (F) == FIELD_DECL \
1714 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1715 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1717 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1718 return 0;
1720 field_decl = TREE_CHAIN (field_decl);
1721 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1722 return 0;
1724 field_decl = TREE_CHAIN (field_decl);
1725 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1727 #undef AT_LEAST_AS_LARGE_AS
1730 /* Avoid calling `check_string_class_template ()' more than once. */
1731 static GTY(()) int string_layout_checked;
1733 /* Custom build_string which sets TREE_TYPE! */
1735 static tree
1736 my_build_string (int len, const char *str)
1738 return fix_string_type (build_string (len, str));
1741 /* Build a string with contents STR and length LEN and convert it to a
1742 pointer. */
1744 static tree
1745 my_build_string_pointer (int len, const char *str)
1747 tree string = my_build_string (len, str);
1748 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1749 return build1 (ADDR_EXPR, ptrtype, string);
1752 static hashval_t
1753 string_hash (const void *ptr)
1755 tree str = ((struct string_descriptor *)ptr)->literal;
1756 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1757 int i, len = TREE_STRING_LENGTH (str);
1758 hashval_t h = len;
1760 for (i = 0; i < len; i++)
1761 h = ((h * 613) + p[i]);
1763 return h;
1766 static int
1767 string_eq (const void *ptr1, const void *ptr2)
1769 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1770 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1771 int len1 = TREE_STRING_LENGTH (str1);
1773 return (len1 == TREE_STRING_LENGTH (str2)
1774 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1775 len1));
1778 /* Given a chain of STRING_CST's, build a static instance of
1779 NXConstantString which points at the concatenation of those
1780 strings. We place the string object in the __string_objects
1781 section of the __OBJC segment. The Objective-C runtime will
1782 initialize the isa pointers of the string objects to point at the
1783 NXConstantString class object. */
1785 tree
1786 objc_build_string_object (tree string)
1788 tree initlist, constructor, constant_string_class;
1789 int length;
1790 tree fields, addr;
1791 struct string_descriptor *desc, key;
1792 void **loc;
1794 /* Prep the string argument. */
1795 string = fix_string_type (string);
1796 TREE_SET_CODE (string, STRING_CST);
1797 length = TREE_STRING_LENGTH (string) - 1;
1799 /* Check whether the string class being used actually exists and has the
1800 correct ivar layout. */
1801 if (!string_layout_checked)
1803 string_layout_checked = -1;
1804 constant_string_class = lookup_interface (constant_string_id);
1806 if (!constant_string_class
1807 || !(constant_string_type
1808 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1809 error ("cannot find interface declaration for %qs",
1810 IDENTIFIER_POINTER (constant_string_id));
1811 /* The NSConstantString/NXConstantString ivar layout is now known. */
1812 else if (!check_string_class_template ())
1813 error ("interface %qs does not have valid constant string layout",
1814 IDENTIFIER_POINTER (constant_string_id));
1815 /* For the NeXT runtime, we can generate a literal reference
1816 to the string class, don't need to run a constructor. */
1817 else if (flag_next_runtime && !setup_string_decl ())
1818 error ("cannot find reference tag for class %qs",
1819 IDENTIFIER_POINTER (constant_string_id));
1820 else
1822 string_layout_checked = 1; /* Success! */
1823 add_class_reference (constant_string_id);
1827 if (string_layout_checked == -1)
1828 return error_mark_node;
1830 /* Perhaps we already constructed a constant string just like this one? */
1831 key.literal = string;
1832 loc = htab_find_slot (string_htab, &key, INSERT);
1833 desc = *loc;
1835 if (!desc)
1837 tree var;
1838 *loc = desc = ggc_alloc (sizeof (*desc));
1839 desc->literal = string;
1841 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1842 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1843 fields = TYPE_FIELDS (constant_string_type);
1844 initlist
1845 = build_tree_list (fields,
1846 flag_next_runtime
1847 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1848 : build_int_cst (NULL_TREE, 0));
1849 fields = TREE_CHAIN (fields);
1850 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1851 initlist);
1852 fields = TREE_CHAIN (fields);
1853 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1854 initlist);
1855 constructor = objc_build_constructor (constant_string_type,
1856 nreverse (initlist));
1857 TREE_INVARIANT (constructor) = true;
1859 if (!flag_next_runtime)
1860 constructor
1861 = objc_add_static_instance (constructor, constant_string_type);
1862 else
1864 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1865 DECL_INITIAL (var) = constructor;
1866 TREE_STATIC (var) = 1;
1867 pushdecl_top_level (var);
1868 constructor = var;
1870 desc->constructor = constructor;
1873 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1875 return addr;
1878 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1880 static GTY(()) int num_static_inst;
1882 static tree
1883 objc_add_static_instance (tree constructor, tree class_decl)
1885 tree *chain, decl;
1886 char buf[256];
1888 /* Find the list of static instances for the CLASS_DECL. Create one if
1889 not found. */
1890 for (chain = &objc_static_instances;
1891 *chain && TREE_VALUE (*chain) != class_decl;
1892 chain = &TREE_CHAIN (*chain));
1893 if (!*chain)
1895 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1896 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1899 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1900 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1901 DECL_COMMON (decl) = 1;
1902 TREE_STATIC (decl) = 1;
1903 DECL_ARTIFICIAL (decl) = 1;
1904 DECL_INITIAL (decl) = constructor;
1906 /* We may be writing something else just now.
1907 Postpone till end of input. */
1908 DECL_DEFER_OUTPUT (decl) = 1;
1909 pushdecl_top_level (decl);
1910 rest_of_decl_compilation (decl, 1, 0);
1912 /* Add the DECL to the head of this CLASS' list. */
1913 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1915 return decl;
1918 /* Build a static constant CONSTRUCTOR
1919 with type TYPE and elements ELTS. */
1921 static tree
1922 objc_build_constructor (tree type, tree elts)
1924 tree constructor = build_constructor (type, elts);
1926 TREE_CONSTANT (constructor) = 1;
1927 TREE_STATIC (constructor) = 1;
1928 TREE_READONLY (constructor) = 1;
1930 #ifdef OBJCPLUS
1931 /* Adjust for impedance mismatch. We should figure out how to build
1932 CONSTRUCTORs that consistently please both the C and C++ gods. */
1933 if (!TREE_PURPOSE (elts))
1934 TREE_TYPE (constructor) = NULL_TREE;
1935 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1936 #endif
1938 return constructor;
1941 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1943 /* Predefine the following data type:
1945 struct _objc_symtab
1947 long sel_ref_cnt;
1948 SEL *refs;
1949 short cls_def_cnt;
1950 short cat_def_cnt;
1951 void *defs[cls_def_cnt + cat_def_cnt];
1952 }; */
1954 static void
1955 build_objc_symtab_template (void)
1957 tree field_decl, field_decl_chain;
1959 objc_symtab_template
1960 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1962 /* long sel_ref_cnt; */
1963 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1964 field_decl_chain = field_decl;
1966 /* SEL *refs; */
1967 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1968 "refs");
1969 chainon (field_decl_chain, field_decl);
1971 /* short cls_def_cnt; */
1972 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1973 chainon (field_decl_chain, field_decl);
1975 /* short cat_def_cnt; */
1976 field_decl = create_field_decl (short_integer_type_node,
1977 "cat_def_cnt");
1978 chainon (field_decl_chain, field_decl);
1980 if (imp_count || cat_count || !flag_next_runtime)
1982 /* void *defs[imp_count + cat_count (+ 1)]; */
1983 /* NB: The index is one less than the size of the array. */
1984 int index = imp_count + cat_count
1985 + (flag_next_runtime? -1: 0);
1986 field_decl = create_field_decl
1987 (build_array_type
1988 (ptr_type_node,
1989 build_index_type (build_int_cst (NULL_TREE, index))),
1990 "defs");
1991 chainon (field_decl_chain, field_decl);
1994 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1997 /* Create the initial value for the `defs' field of _objc_symtab.
1998 This is a CONSTRUCTOR. */
2000 static tree
2001 init_def_list (tree type)
2003 tree expr, initlist = NULL_TREE;
2004 struct imp_entry *impent;
2006 if (imp_count)
2007 for (impent = imp_list; impent; impent = impent->next)
2009 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2011 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2012 initlist = tree_cons (NULL_TREE, expr, initlist);
2016 if (cat_count)
2017 for (impent = imp_list; impent; impent = impent->next)
2019 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2021 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2022 initlist = tree_cons (NULL_TREE, expr, initlist);
2026 if (!flag_next_runtime)
2028 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2029 tree expr;
2031 if (static_instances_decl)
2032 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2033 else
2034 expr = build_int_cst (NULL_TREE, 0);
2036 initlist = tree_cons (NULL_TREE, expr, initlist);
2039 return objc_build_constructor (type, nreverse (initlist));
2042 /* Construct the initial value for all of _objc_symtab. */
2044 static tree
2045 init_objc_symtab (tree type)
2047 tree initlist;
2049 /* sel_ref_cnt = { ..., 5, ... } */
2051 initlist = build_tree_list (NULL_TREE,
2052 build_int_cst (long_integer_type_node, 0));
2054 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2056 if (flag_next_runtime || ! sel_ref_chain)
2057 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2058 else
2059 initlist
2060 = tree_cons (NULL_TREE,
2061 convert (build_pointer_type (objc_selector_type),
2062 build_unary_op (ADDR_EXPR,
2063 UOBJC_SELECTOR_TABLE_decl, 1)),
2064 initlist);
2066 /* cls_def_cnt = { ..., 5, ... } */
2068 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2070 /* cat_def_cnt = { ..., 5, ... } */
2072 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2074 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2076 if (imp_count || cat_count || !flag_next_runtime)
2079 tree field = TYPE_FIELDS (type);
2080 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2082 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2083 initlist);
2086 return objc_build_constructor (type, nreverse (initlist));
2089 /* Generate forward declarations for metadata such as
2090 'OBJC_CLASS_...'. */
2092 static tree
2093 build_metadata_decl (const char *name, tree type)
2095 tree decl;
2097 /* struct TYPE NAME_<name>; */
2098 decl = start_var_decl (type, synth_id_with_class_suffix
2099 (name,
2100 objc_implementation_context));
2102 return decl;
2105 /* Push forward-declarations of all the categories so that
2106 init_def_list can use them in a CONSTRUCTOR. */
2108 static void
2109 forward_declare_categories (void)
2111 struct imp_entry *impent;
2112 tree sav = objc_implementation_context;
2114 for (impent = imp_list; impent; impent = impent->next)
2116 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2118 /* Set an invisible arg to synth_id_with_class_suffix. */
2119 objc_implementation_context = impent->imp_context;
2120 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2121 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2122 objc_category_template);
2125 objc_implementation_context = sav;
2128 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2129 and initialized appropriately. */
2131 static void
2132 generate_objc_symtab_decl (void)
2134 /* forward declare categories */
2135 if (cat_count)
2136 forward_declare_categories ();
2138 build_objc_symtab_template ();
2139 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2140 finish_var_decl (UOBJC_SYMBOLS_decl,
2141 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2144 static tree
2145 init_module_descriptor (tree type)
2147 tree initlist, expr;
2149 /* version = { 1, ... } */
2151 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2152 initlist = build_tree_list (NULL_TREE, expr);
2154 /* size = { ..., sizeof (struct _objc_module), ... } */
2156 expr = convert (long_integer_type_node,
2157 size_in_bytes (objc_module_template));
2158 initlist = tree_cons (NULL_TREE, expr, initlist);
2160 /* name = { ..., "foo.m", ... } */
2162 expr = add_objc_string (get_identifier (input_filename), class_names);
2163 initlist = tree_cons (NULL_TREE, expr, initlist);
2165 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2167 if (UOBJC_SYMBOLS_decl)
2168 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2169 else
2170 expr = build_int_cst (NULL_TREE, 0);
2171 initlist = tree_cons (NULL_TREE, expr, initlist);
2173 return objc_build_constructor (type, nreverse (initlist));
2176 /* Write out the data structures to describe Objective C classes defined.
2178 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2180 static void
2181 build_module_descriptor (void)
2183 tree field_decl, field_decl_chain;
2185 #ifdef OBJCPLUS
2186 push_lang_context (lang_name_c); /* extern "C" */
2187 #endif
2189 objc_module_template
2190 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2192 /* long version; */
2193 field_decl = create_field_decl (long_integer_type_node, "version");
2194 field_decl_chain = field_decl;
2196 /* long size; */
2197 field_decl = create_field_decl (long_integer_type_node, "size");
2198 chainon (field_decl_chain, field_decl);
2200 /* char *name; */
2201 field_decl = create_field_decl (string_type_node, "name");
2202 chainon (field_decl_chain, field_decl);
2204 /* struct _objc_symtab *symtab; */
2205 field_decl
2206 = create_field_decl (build_pointer_type
2207 (xref_tag (RECORD_TYPE,
2208 get_identifier (UTAG_SYMTAB))),
2209 "symtab");
2210 chainon (field_decl_chain, field_decl);
2212 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2214 /* Create an instance of "_objc_module". */
2215 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2216 finish_var_decl (UOBJC_MODULES_decl,
2217 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2219 #ifdef OBJCPLUS
2220 pop_lang_context ();
2221 #endif
2224 /* The GNU runtime requires us to provide a static initializer function
2225 for each module:
2227 static void __objc_gnu_init (void) {
2228 __objc_exec_class (&L_OBJC_MODULES);
2229 } */
2231 static void
2232 build_module_initializer_routine (void)
2234 tree body;
2236 #ifdef OBJCPLUS
2237 push_lang_context (lang_name_c); /* extern "C" */
2238 #endif
2240 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2241 objc_start_function (get_identifier (TAG_GNUINIT),
2242 build_function_type (void_type_node,
2243 OBJC_VOID_AT_END),
2244 NULL_TREE, objc_get_parm_info (0));
2246 body = c_begin_compound_stmt (true);
2247 add_stmt (build_function_call
2248 (execclass_decl,
2249 build_tree_list
2250 (NULL_TREE,
2251 build_unary_op (ADDR_EXPR,
2252 UOBJC_MODULES_decl, 0))));
2253 add_stmt (c_end_compound_stmt (body, true));
2255 TREE_PUBLIC (current_function_decl) = 0;
2257 #ifndef OBJCPLUS
2258 /* For Objective-C++, we will need to call __objc_gnu_init
2259 from objc_generate_static_init_call() below. */
2260 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2261 #endif
2263 GNU_INIT_decl = current_function_decl;
2264 finish_function ();
2266 #ifdef OBJCPLUS
2267 pop_lang_context ();
2268 #endif
2271 #ifdef OBJCPLUS
2272 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2273 to be called by the module initializer routine. */
2276 objc_static_init_needed_p (void)
2278 return (GNU_INIT_decl != NULL_TREE);
2281 /* Generate a call to the __objc_gnu_init initializer function. */
2283 tree
2284 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2286 add_stmt (build_stmt (EXPR_STMT,
2287 build_function_call (GNU_INIT_decl, NULL_TREE)));
2289 return ctors;
2291 #endif /* OBJCPLUS */
2293 /* Return the DECL of the string IDENT in the SECTION. */
2295 static tree
2296 get_objc_string_decl (tree ident, enum string_section section)
2298 tree chain;
2300 if (section == class_names)
2301 chain = class_names_chain;
2302 else if (section == meth_var_names)
2303 chain = meth_var_names_chain;
2304 else if (section == meth_var_types)
2305 chain = meth_var_types_chain;
2306 else
2307 abort ();
2309 for (; chain != 0; chain = TREE_CHAIN (chain))
2310 if (TREE_VALUE (chain) == ident)
2311 return (TREE_PURPOSE (chain));
2313 abort ();
2314 return NULL_TREE;
2317 /* Output references to all statically allocated objects. Return the DECL
2318 for the array built. */
2320 static void
2321 generate_static_references (void)
2323 tree decls = NULL_TREE, expr = NULL_TREE;
2324 tree class_name, class, decl, initlist;
2325 tree cl_chain, in_chain, type
2326 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2327 int num_inst, num_class;
2328 char buf[256];
2330 if (flag_next_runtime)
2331 abort ();
2333 for (cl_chain = objc_static_instances, num_class = 0;
2334 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2336 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2337 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2339 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2340 decl = start_var_decl (type, buf);
2342 /* Output {class_name, ...}. */
2343 class = TREE_VALUE (cl_chain);
2344 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2345 initlist = build_tree_list (NULL_TREE,
2346 build_unary_op (ADDR_EXPR, class_name, 1));
2348 /* Output {..., instance, ...}. */
2349 for (in_chain = TREE_PURPOSE (cl_chain);
2350 in_chain; in_chain = TREE_CHAIN (in_chain))
2352 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2353 initlist = tree_cons (NULL_TREE, expr, initlist);
2356 /* Output {..., NULL}. */
2357 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2359 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2360 finish_var_decl (decl, expr);
2361 decls
2362 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2365 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2366 expr = objc_build_constructor (type, nreverse (decls));
2367 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2368 finish_var_decl (static_instances_decl, expr);
2371 /* Output all strings. */
2373 static void
2374 generate_strings (void)
2376 tree chain, string_expr;
2377 tree string, decl, type;
2379 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2381 string = TREE_VALUE (chain);
2382 decl = TREE_PURPOSE (chain);
2383 type = build_array_type
2384 (char_type_node,
2385 build_index_type
2386 (build_int_cst (NULL_TREE,
2387 IDENTIFIER_LENGTH (string))));
2388 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2389 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2390 IDENTIFIER_POINTER (string));
2391 finish_var_decl (decl, string_expr);
2394 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2396 string = TREE_VALUE (chain);
2397 decl = TREE_PURPOSE (chain);
2398 type = build_array_type
2399 (char_type_node,
2400 build_index_type
2401 (build_int_cst (NULL_TREE,
2402 IDENTIFIER_LENGTH (string))));
2403 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2404 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2405 IDENTIFIER_POINTER (string));
2406 finish_var_decl (decl, string_expr);
2409 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2411 string = TREE_VALUE (chain);
2412 decl = TREE_PURPOSE (chain);
2413 type = build_array_type
2414 (char_type_node,
2415 build_index_type
2416 (build_int_cst (NULL_TREE,
2417 IDENTIFIER_LENGTH (string))));
2418 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2419 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2420 IDENTIFIER_POINTER (string));
2421 finish_var_decl (decl, string_expr);
2425 static GTY(()) int selector_reference_idx;
2427 static tree
2428 build_selector_reference_decl (void)
2430 tree decl;
2431 char buf[256];
2433 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2434 decl = start_var_decl (objc_selector_type, buf);
2436 return decl;
2439 static void
2440 build_selector_table_decl (void)
2442 tree temp;
2444 if (flag_typed_selectors)
2446 build_selector_template ();
2447 temp = build_array_type (objc_selector_template, NULL_TREE);
2449 else
2450 temp = build_array_type (objc_selector_type, NULL_TREE);
2452 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2455 /* Just a handy wrapper for add_objc_string. */
2457 static tree
2458 build_selector (tree ident)
2460 return convert (objc_selector_type,
2461 add_objc_string (ident, meth_var_names));
2464 static void
2465 build_selector_translation_table (void)
2467 tree chain, initlist = NULL_TREE;
2468 int offset = 0;
2469 tree decl = NULL_TREE;
2471 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2473 tree expr;
2475 if (warn_selector && objc_implementation_context)
2477 tree method_chain;
2478 bool found = false;
2479 for (method_chain = meth_var_names_chain;
2480 method_chain;
2481 method_chain = TREE_CHAIN (method_chain))
2483 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2485 found = true;
2486 break;
2489 if (!found)
2491 location_t *loc;
2492 if (flag_next_runtime && TREE_PURPOSE (chain))
2493 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2494 else
2495 loc = &input_location;
2496 warning (0, "%Hcreating selector for nonexistent method %qE",
2497 loc, TREE_VALUE (chain));
2501 expr = build_selector (TREE_VALUE (chain));
2502 /* add one for the '\0' character */
2503 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2505 if (flag_next_runtime)
2507 decl = TREE_PURPOSE (chain);
2508 finish_var_decl (decl, expr);
2510 else
2512 if (flag_typed_selectors)
2514 tree eltlist = NULL_TREE;
2515 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2516 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2517 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2518 expr = objc_build_constructor (objc_selector_template,
2519 nreverse (eltlist));
2522 initlist = tree_cons (NULL_TREE, expr, initlist);
2526 if (! flag_next_runtime)
2528 /* Cause the selector table (previously forward-declared)
2529 to be actually output. */
2530 initlist = tree_cons (NULL_TREE,
2531 flag_typed_selectors
2532 ? objc_build_constructor
2533 (objc_selector_template,
2534 tree_cons (NULL_TREE,
2535 build_int_cst (NULL_TREE, 0),
2536 tree_cons (NULL_TREE,
2537 build_int_cst (NULL_TREE, 0),
2538 NULL_TREE)))
2539 : build_int_cst (NULL_TREE, 0), initlist);
2540 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2541 nreverse (initlist));
2542 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2546 static tree
2547 get_proto_encoding (tree proto)
2549 tree encoding;
2550 if (proto)
2552 if (! METHOD_ENCODING (proto))
2554 encoding = encode_method_prototype (proto);
2555 METHOD_ENCODING (proto) = encoding;
2557 else
2558 encoding = METHOD_ENCODING (proto);
2560 return add_objc_string (encoding, meth_var_types);
2562 else
2563 return build_int_cst (NULL_TREE, 0);
2566 /* sel_ref_chain is a list whose "value" fields will be instances of
2567 identifier_node that represent the selector. */
2569 static tree
2570 build_typed_selector_reference (tree ident, tree prototype)
2572 tree *chain = &sel_ref_chain;
2573 tree expr;
2574 int index = 0;
2576 while (*chain)
2578 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2579 goto return_at_index;
2581 index++;
2582 chain = &TREE_CHAIN (*chain);
2585 *chain = tree_cons (prototype, ident, NULL_TREE);
2587 return_at_index:
2588 expr = build_unary_op (ADDR_EXPR,
2589 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2590 build_int_cst (NULL_TREE, index)),
2592 return convert (objc_selector_type, expr);
2595 static tree
2596 build_selector_reference (tree ident)
2598 tree *chain = &sel_ref_chain;
2599 tree expr;
2600 int index = 0;
2602 while (*chain)
2604 if (TREE_VALUE (*chain) == ident)
2605 return (flag_next_runtime
2606 ? TREE_PURPOSE (*chain)
2607 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2608 build_int_cst (NULL_TREE, index)));
2610 index++;
2611 chain = &TREE_CHAIN (*chain);
2614 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2616 *chain = tree_cons (expr, ident, NULL_TREE);
2618 return (flag_next_runtime
2619 ? expr
2620 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2621 build_int_cst (NULL_TREE, index)));
2624 static GTY(()) int class_reference_idx;
2626 static tree
2627 build_class_reference_decl (void)
2629 tree decl;
2630 char buf[256];
2632 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2633 decl = start_var_decl (objc_class_type, buf);
2635 return decl;
2638 /* Create a class reference, but don't create a variable to reference
2639 it. */
2641 static void
2642 add_class_reference (tree ident)
2644 tree chain;
2646 if ((chain = cls_ref_chain))
2648 tree tail;
2651 if (ident == TREE_VALUE (chain))
2652 return;
2654 tail = chain;
2655 chain = TREE_CHAIN (chain);
2657 while (chain);
2659 /* Append to the end of the list */
2660 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2662 else
2663 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2666 /* Get a class reference, creating it if necessary. Also create the
2667 reference variable. */
2669 tree
2670 objc_get_class_reference (tree ident)
2672 tree orig_ident = (DECL_P (ident)
2673 ? DECL_NAME (ident)
2674 : TYPE_P (ident)
2675 ? OBJC_TYPE_NAME (ident)
2676 : ident);
2677 bool local_scope = false;
2679 #ifdef OBJCPLUS
2680 if (processing_template_decl)
2681 /* Must wait until template instantiation time. */
2682 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2683 #endif
2685 if (TREE_CODE (ident) == TYPE_DECL)
2686 ident = (DECL_ORIGINAL_TYPE (ident)
2687 ? DECL_ORIGINAL_TYPE (ident)
2688 : TREE_TYPE (ident));
2690 #ifdef OBJCPLUS
2691 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2692 && TYPE_CONTEXT (ident) != global_namespace)
2693 local_scope = true;
2694 #endif
2696 if (local_scope || !(ident = objc_is_class_name (ident)))
2698 error ("%qs is not an Objective-C class name or alias",
2699 IDENTIFIER_POINTER (orig_ident));
2700 return error_mark_node;
2703 if (flag_next_runtime && !flag_zero_link)
2705 tree *chain;
2706 tree decl;
2708 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2709 if (TREE_VALUE (*chain) == ident)
2711 if (! TREE_PURPOSE (*chain))
2712 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2714 return TREE_PURPOSE (*chain);
2717 decl = build_class_reference_decl ();
2718 *chain = tree_cons (decl, ident, NULL_TREE);
2719 return decl;
2721 else
2723 tree params;
2725 add_class_reference (ident);
2727 params = build_tree_list (NULL_TREE,
2728 my_build_string_pointer
2729 (IDENTIFIER_LENGTH (ident) + 1,
2730 IDENTIFIER_POINTER (ident)));
2732 assemble_external (objc_get_class_decl);
2733 return build_function_call (objc_get_class_decl, params);
2737 /* For each string section we have a chain which maps identifier nodes
2738 to decls for the strings. */
2740 static tree
2741 add_objc_string (tree ident, enum string_section section)
2743 tree *chain, decl;
2745 if (section == class_names)
2746 chain = &class_names_chain;
2747 else if (section == meth_var_names)
2748 chain = &meth_var_names_chain;
2749 else if (section == meth_var_types)
2750 chain = &meth_var_types_chain;
2751 else
2752 abort ();
2754 while (*chain)
2756 if (TREE_VALUE (*chain) == ident)
2757 return convert (string_type_node,
2758 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2760 chain = &TREE_CHAIN (*chain);
2763 decl = build_objc_string_decl (section);
2765 *chain = tree_cons (decl, ident, NULL_TREE);
2767 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2770 static GTY(()) int class_names_idx;
2771 static GTY(()) int meth_var_names_idx;
2772 static GTY(()) int meth_var_types_idx;
2774 static tree
2775 build_objc_string_decl (enum string_section section)
2777 tree decl, ident;
2778 char buf[256];
2780 if (section == class_names)
2781 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2782 else if (section == meth_var_names)
2783 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2784 else if (section == meth_var_types)
2785 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2787 ident = get_identifier (buf);
2789 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2790 DECL_EXTERNAL (decl) = 1;
2791 TREE_PUBLIC (decl) = 0;
2792 TREE_USED (decl) = 1;
2793 TREE_CONSTANT (decl) = 1;
2794 DECL_CONTEXT (decl) = 0;
2795 DECL_ARTIFICIAL (decl) = 1;
2796 #ifdef OBJCPLUS
2797 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2798 #endif
2800 make_decl_rtl (decl);
2801 pushdecl_top_level (decl);
2803 return decl;
2807 void
2808 objc_declare_alias (tree alias_ident, tree class_ident)
2810 tree underlying_class;
2812 #ifdef OBJCPLUS
2813 if (current_namespace != global_namespace) {
2814 error ("Objective-C declarations may only appear in global scope");
2816 #endif /* OBJCPLUS */
2818 if (!(underlying_class = objc_is_class_name (class_ident)))
2819 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2820 else if (objc_is_class_name (alias_ident))
2821 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2822 else
2824 /* Implement @compatibility_alias as a typedef. */
2825 #ifdef OBJCPLUS
2826 push_lang_context (lang_name_c); /* extern "C" */
2827 #endif
2828 lang_hooks.decls.pushdecl (build_decl
2829 (TYPE_DECL,
2830 alias_ident,
2831 xref_tag (RECORD_TYPE, underlying_class)));
2832 #ifdef OBJCPLUS
2833 pop_lang_context ();
2834 #endif
2835 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2839 void
2840 objc_declare_class (tree ident_list)
2842 tree list;
2843 #ifdef OBJCPLUS
2844 if (current_namespace != global_namespace) {
2845 error ("Objective-C declarations may only appear in global scope");
2847 #endif /* OBJCPLUS */
2849 for (list = ident_list; list; list = TREE_CHAIN (list))
2851 tree ident = TREE_VALUE (list);
2853 if (! objc_is_class_name (ident))
2855 tree record = lookup_name (ident), type = record;
2857 if (record)
2859 if (TREE_CODE (record) == TYPE_DECL)
2860 type = DECL_ORIGINAL_TYPE (record);
2862 if (!TYPE_HAS_OBJC_INFO (type)
2863 || !TYPE_OBJC_INTERFACE (type))
2865 error ("%qs redeclared as different kind of symbol",
2866 IDENTIFIER_POINTER (ident));
2867 error ("%Jprevious declaration of '%D'",
2868 record, record);
2872 record = xref_tag (RECORD_TYPE, ident);
2873 INIT_TYPE_OBJC_INFO (record);
2874 TYPE_OBJC_INTERFACE (record) = ident;
2875 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2880 tree
2881 objc_is_class_name (tree ident)
2883 tree chain;
2885 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2886 && identifier_global_value (ident))
2887 ident = identifier_global_value (ident);
2888 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2889 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2891 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2892 ident = OBJC_TYPE_NAME (ident);
2893 #ifdef OBJCPLUS
2894 if (ident && TREE_CODE (ident) == TYPE_DECL)
2895 ident = DECL_NAME (ident);
2896 #endif
2897 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2898 return NULL_TREE;
2900 if (lookup_interface (ident))
2901 return ident;
2903 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2905 if (ident == TREE_VALUE (chain))
2906 return ident;
2909 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2911 if (ident == TREE_VALUE (chain))
2912 return TREE_PURPOSE (chain);
2915 return 0;
2918 /* Check whether TYPE is either 'id' or 'Class'. */
2920 tree
2921 objc_is_id (tree type)
2923 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2924 && identifier_global_value (type))
2925 type = identifier_global_value (type);
2927 if (type && TREE_CODE (type) == TYPE_DECL)
2928 type = TREE_TYPE (type);
2930 /* NB: This function may be called before the ObjC front-end has
2931 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2932 return (objc_object_type && type
2933 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2934 ? type
2935 : NULL_TREE);
2938 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2939 class instance. This is needed by other parts of the compiler to
2940 handle ObjC types gracefully. */
2942 tree
2943 objc_is_object_ptr (tree type)
2945 tree ret;
2947 type = TYPE_MAIN_VARIANT (type);
2948 if (!POINTER_TYPE_P (type))
2949 return 0;
2951 ret = objc_is_id (type);
2952 if (!ret)
2953 ret = objc_is_class_name (TREE_TYPE (type));
2955 return ret;
2958 static int
2959 objc_is_gcable_type (tree type, int or_strong_p)
2961 tree name;
2963 if (!TYPE_P (type))
2964 return 0;
2965 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
2966 return 1;
2967 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
2968 return 1;
2969 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
2970 return 0;
2971 type = TREE_TYPE (type);
2972 if (TREE_CODE (type) != RECORD_TYPE)
2973 return 0;
2974 name = TYPE_NAME (type);
2975 return (objc_is_class_name (name) != NULL_TREE);
2978 static tree
2979 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
2981 if (expr == oldexpr)
2982 return newexpr;
2984 switch (TREE_CODE (expr))
2986 case COMPONENT_REF:
2987 return objc_build_component_ref
2988 (objc_substitute_decl (TREE_OPERAND (expr, 0),
2989 oldexpr,
2990 newexpr),
2991 DECL_NAME (TREE_OPERAND (expr, 1)));
2992 case ARRAY_REF:
2993 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2994 oldexpr,
2995 newexpr),
2996 TREE_OPERAND (expr, 1));
2997 case INDIRECT_REF:
2998 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2999 oldexpr,
3000 newexpr), "->");
3001 default:
3002 return expr;
3006 static tree
3007 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3009 tree func_params;
3010 /* The LHS parameter contains the expression 'outervar->memberspec';
3011 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3012 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3014 tree offs
3015 = objc_substitute_decl
3016 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3017 tree func
3018 = (flag_objc_direct_dispatch
3019 ? objc_assign_ivar_fast_decl
3020 : objc_assign_ivar_decl);
3022 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3023 offs = fold (offs);
3024 func_params = tree_cons (NULL_TREE,
3025 convert (objc_object_type, rhs),
3026 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3027 tree_cons (NULL_TREE, offs,
3028 NULL_TREE)));
3030 assemble_external (func);
3031 return build_function_call (func, func_params);
3034 static tree
3035 objc_build_global_assignment (tree lhs, tree rhs)
3037 tree func_params = tree_cons (NULL_TREE,
3038 convert (objc_object_type, rhs),
3039 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3040 build_unary_op (ADDR_EXPR, lhs, 0)),
3041 NULL_TREE));
3043 assemble_external (objc_assign_global_decl);
3044 return build_function_call (objc_assign_global_decl, func_params);
3047 static tree
3048 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3050 tree func_params = tree_cons (NULL_TREE,
3051 convert (objc_object_type, rhs),
3052 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3053 build_unary_op (ADDR_EXPR, lhs, 0)),
3054 NULL_TREE));
3056 assemble_external (objc_assign_strong_cast_decl);
3057 return build_function_call (objc_assign_strong_cast_decl, func_params);
3060 static int
3061 objc_is_gcable_p (tree expr)
3063 return (TREE_CODE (expr) == COMPONENT_REF
3064 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3065 : TREE_CODE (expr) == ARRAY_REF
3066 ? (objc_is_gcable_p (TREE_TYPE (expr))
3067 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3068 : TREE_CODE (expr) == ARRAY_TYPE
3069 ? objc_is_gcable_p (TREE_TYPE (expr))
3070 : TYPE_P (expr)
3071 ? objc_is_gcable_type (expr, 1)
3072 : (objc_is_gcable_p (TREE_TYPE (expr))
3073 || (DECL_P (expr)
3074 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3077 static int
3078 objc_is_ivar_reference_p (tree expr)
3080 return (TREE_CODE (expr) == ARRAY_REF
3081 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3082 : TREE_CODE (expr) == COMPONENT_REF
3083 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3084 : 0);
3087 static int
3088 objc_is_global_reference_p (tree expr)
3090 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3091 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3092 : DECL_P (expr)
3093 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3094 : 0);
3097 tree
3098 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3100 tree result = NULL_TREE, outer;
3101 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3103 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3104 will have been transformed to the form '*(type *)&expr'. */
3105 if (TREE_CODE (lhs) == INDIRECT_REF)
3107 outer = TREE_OPERAND (lhs, 0);
3109 while (!strong_cast_p
3110 && (TREE_CODE (outer) == CONVERT_EXPR
3111 || TREE_CODE (outer) == NOP_EXPR
3112 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3114 tree lhstype = TREE_TYPE (outer);
3116 /* Descend down the cast chain, and record the first objc_gc
3117 attribute found. */
3118 if (POINTER_TYPE_P (lhstype))
3120 tree attr
3121 = lookup_attribute ("objc_gc",
3122 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3124 if (attr)
3125 strong_cast_p = 1;
3128 outer = TREE_OPERAND (outer, 0);
3132 /* If we have a __strong cast, it trumps all else. */
3133 if (strong_cast_p)
3135 if (modifycode != NOP_EXPR)
3136 goto invalid_pointer_arithmetic;
3138 if (warn_assign_intercept)
3139 warning (0, "strong-cast assignment has been intercepted");
3141 result = objc_build_strong_cast_assignment (lhs, rhs);
3143 goto exit_point;
3146 /* the lhs must be of a suitable type, regardless of its underlying
3147 structure. */
3148 if (!objc_is_gcable_p (lhs))
3149 goto exit_point;
3151 outer = lhs;
3153 while (outer
3154 && (TREE_CODE (outer) == COMPONENT_REF
3155 || TREE_CODE (outer) == ARRAY_REF))
3156 outer = TREE_OPERAND (outer, 0);
3158 if (TREE_CODE (outer) == INDIRECT_REF)
3160 outer = TREE_OPERAND (outer, 0);
3161 indirect_p = 1;
3164 outer_gc_p = objc_is_gcable_p (outer);
3166 /* Handle ivar assignments. */
3167 if (objc_is_ivar_reference_p (lhs))
3169 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3170 doesn't cut it here), the best we can do here is suggest a cast. */
3171 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3173 /* We may still be able to use the global write barrier... */
3174 if (!indirect_p && objc_is_global_reference_p (outer))
3175 goto global_reference;
3177 suggest_cast:
3178 if (modifycode == NOP_EXPR)
3180 if (warn_assign_intercept)
3181 warning (0, "strong-cast may possibly be needed");
3184 goto exit_point;
3187 if (modifycode != NOP_EXPR)
3188 goto invalid_pointer_arithmetic;
3190 if (warn_assign_intercept)
3191 warning (0, "instance variable assignment has been intercepted");
3193 result = objc_build_ivar_assignment (outer, lhs, rhs);
3195 goto exit_point;
3198 /* Likewise, intercept assignment to global/static variables if their type is
3199 GC-marked. */
3200 if (objc_is_global_reference_p (outer))
3202 if (indirect_p)
3203 goto suggest_cast;
3205 global_reference:
3206 if (modifycode != NOP_EXPR)
3208 invalid_pointer_arithmetic:
3209 if (outer_gc_p)
3210 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3212 goto exit_point;
3215 if (warn_assign_intercept)
3216 warning (0, "global/static variable assignment has been intercepted");
3218 result = objc_build_global_assignment (lhs, rhs);
3221 /* In all other cases, fall back to the normal mechanism. */
3222 exit_point:
3223 return result;
3226 struct interface_tuple GTY(())
3228 tree id;
3229 tree class_name;
3232 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3234 static hashval_t
3235 hash_interface (const void *p)
3237 const struct interface_tuple *d = p;
3238 return htab_hash_pointer (d->id);
3241 static int
3242 eq_interface (const void *p1, const void *p2)
3244 const struct interface_tuple *d = p1;
3245 return d->id == p2;
3248 static tree
3249 lookup_interface (tree ident)
3251 #ifdef OBJCPLUS
3252 if (ident && TREE_CODE (ident) == TYPE_DECL)
3253 ident = DECL_NAME (ident);
3254 #endif
3256 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3257 return NULL_TREE;
3260 struct interface_tuple **slot;
3261 tree i = NULL_TREE;
3263 if (interface_htab)
3265 slot = (struct interface_tuple **)
3266 htab_find_slot_with_hash (interface_htab, ident,
3267 htab_hash_pointer (ident),
3268 NO_INSERT);
3269 if (slot && *slot)
3270 i = (*slot)->class_name;
3272 return i;
3276 /* Implement @defs (<classname>) within struct bodies. */
3278 tree
3279 objc_get_class_ivars (tree class_name)
3281 tree interface = lookup_interface (class_name);
3283 if (interface)
3284 return get_class_ivars (interface, true);
3286 error ("cannot find interface declaration for %qs",
3287 IDENTIFIER_POINTER (class_name));
3289 return error_mark_node;
3292 /* Used by: build_private_template, continue_class,
3293 and for @defs constructs. */
3295 static tree
3296 get_class_ivars (tree interface, bool inherited)
3298 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3300 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3301 by the current class (i.e., they do not include super-class ivars).
3302 However, the CLASS_IVARS list will be side-effected by a call to
3303 finish_struct(), which will fill in field offsets. */
3304 if (!CLASS_IVARS (interface))
3305 CLASS_IVARS (interface) = ivar_chain;
3307 if (!inherited)
3308 return ivar_chain;
3310 while (CLASS_SUPER_NAME (interface))
3312 /* Prepend super-class ivars. */
3313 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3314 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3315 ivar_chain);
3318 return ivar_chain;
3321 static tree
3322 objc_create_temporary_var (tree type)
3324 tree decl;
3326 decl = build_decl (VAR_DECL, NULL_TREE, type);
3327 TREE_USED (decl) = 1;
3328 DECL_ARTIFICIAL (decl) = 1;
3329 DECL_IGNORED_P (decl) = 1;
3330 DECL_CONTEXT (decl) = current_function_decl;
3332 return decl;
3335 /* Exception handling constructs. We begin by having the parser do most
3336 of the work and passing us blocks. What we do next depends on whether
3337 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3338 We abstract all of this in a handful of appropriately named routines. */
3340 /* Stack of open try blocks. */
3342 struct objc_try_context
3344 struct objc_try_context *outer;
3346 /* Statements (or statement lists) as processed by the parser. */
3347 tree try_body;
3348 tree finally_body;
3350 /* Some file position locations. */
3351 location_t try_locus;
3352 location_t end_try_locus;
3353 location_t end_catch_locus;
3354 location_t finally_locus;
3355 location_t end_finally_locus;
3357 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3358 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3359 tree catch_list;
3361 /* The CATCH_EXPR of an open @catch clause. */
3362 tree current_catch;
3364 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3365 tree caught_decl;
3366 tree stack_decl;
3367 tree rethrow_decl;
3370 static struct objc_try_context *cur_try_context;
3372 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3373 that represents TYPE. For Objective-C, this is just the class name. */
3374 /* ??? Isn't there a class object or some such? Is it easy to get? */
3376 #ifndef OBJCPLUS
3377 static tree
3378 objc_eh_runtime_type (tree type)
3380 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3382 #endif
3384 /* Initialize exception handling. */
3386 static void
3387 objc_init_exceptions (void)
3389 static bool done = false;
3390 if (done)
3391 return;
3392 done = true;
3394 if (flag_objc_sjlj_exceptions)
3396 /* On Darwin, ObjC exceptions require a sufficiently recent
3397 version of the runtime, so the user must ask for them explicitly. */
3398 if (!flag_objc_exceptions)
3399 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3400 "exception syntax");
3402 #ifndef OBJCPLUS
3403 else
3405 c_eh_initialized_p = true;
3406 eh_personality_libfunc
3407 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3408 ? "__gnu_objc_personality_sj0"
3409 : "__gnu_objc_personality_v0");
3410 default_init_unwind_resume_libfunc ();
3411 using_eh_for_cleanups ();
3412 lang_eh_runtime_type = objc_eh_runtime_type;
3414 #endif
3417 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3418 we'll arrange for it to be initialized (and associated with a binding)
3419 later. */
3421 static tree
3422 objc_build_exc_ptr (void)
3424 if (flag_objc_sjlj_exceptions)
3426 tree var = cur_try_context->caught_decl;
3427 if (!var)
3429 var = objc_create_temporary_var (objc_object_type);
3430 cur_try_context->caught_decl = var;
3432 return var;
3434 else
3435 return build (EXC_PTR_EXPR, objc_object_type);
3438 /* Build "objc_exception_try_exit(&_stack)". */
3440 static tree
3441 next_sjlj_build_try_exit (void)
3443 tree t;
3444 t = build_fold_addr_expr (cur_try_context->stack_decl);
3445 t = tree_cons (NULL, t, NULL);
3446 t = build_function_call (objc_exception_try_exit_decl, t);
3447 return t;
3450 /* Build
3451 objc_exception_try_enter (&_stack);
3452 if (_setjmp(&_stack.buf))
3454 else
3456 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3457 empty, ready for the caller to fill them in. */
3459 static tree
3460 next_sjlj_build_enter_and_setjmp (void)
3462 tree t, enter, sj, cond;
3464 t = build_fold_addr_expr (cur_try_context->stack_decl);
3465 t = tree_cons (NULL, t, NULL);
3466 enter = build_function_call (objc_exception_try_enter_decl, t);
3468 t = objc_build_component_ref (cur_try_context->stack_decl,
3469 get_identifier ("buf"));
3470 t = build_fold_addr_expr (t);
3471 #ifdef OBJCPLUS
3472 /* Convert _setjmp argument to type that is expected. */
3473 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3474 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3475 else
3476 t = convert (ptr_type_node, t);
3477 #else
3478 t = convert (ptr_type_node, t);
3479 #endif
3480 t = tree_cons (NULL, t, NULL);
3481 sj = build_function_call (objc_setjmp_decl, t);
3483 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3484 cond = c_common_truthvalue_conversion (cond);
3486 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3489 /* Build
3490 DECL = objc_exception_extract(&_stack);
3493 static tree
3494 next_sjlj_build_exc_extract (tree decl)
3496 tree t;
3498 t = build_fold_addr_expr (cur_try_context->stack_decl);
3499 t = tree_cons (NULL, t, NULL);
3500 t = build_function_call (objc_exception_extract_decl, t);
3501 t = convert (TREE_TYPE (decl), t);
3502 t = build (MODIFY_EXPR, void_type_node, decl, t);
3504 return t;
3507 /* Build
3508 if (objc_exception_match(obj_get_class(TYPE), _caught)
3509 BODY
3510 else if (...)
3512 else
3514 _rethrow = _caught;
3515 objc_exception_try_exit(&_stack);
3517 from the sequence of CATCH_EXPRs in the current try context. */
3519 static tree
3520 next_sjlj_build_catch_list (void)
3522 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3523 tree catch_seq, t;
3524 tree *last = &catch_seq;
3525 bool saw_id = false;
3527 for (; !tsi_end_p (i); tsi_next (&i))
3529 tree stmt = tsi_stmt (i);
3530 tree type = CATCH_TYPES (stmt);
3531 tree body = CATCH_BODY (stmt);
3533 if (type == NULL)
3535 *last = body;
3536 saw_id = true;
3537 break;
3539 else
3541 tree args, cond;
3543 if (type == error_mark_node)
3544 cond = error_mark_node;
3545 else
3547 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3548 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3549 args = tree_cons (NULL, t, args);
3550 t = build_function_call (objc_exception_match_decl, args);
3551 cond = c_common_truthvalue_conversion (t);
3553 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3554 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3556 *last = t;
3557 last = &COND_EXPR_ELSE (t);
3561 if (!saw_id)
3563 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3564 cur_try_context->caught_decl);
3565 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3566 append_to_statement_list (t, last);
3568 t = next_sjlj_build_try_exit ();
3569 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3570 append_to_statement_list (t, last);
3573 return catch_seq;
3576 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3577 exception handling. We aim to build:
3580 struct _objc_exception_data _stack;
3581 id volatile _rethrow = 0;
3584 objc_exception_try_enter (&_stack);
3585 if (_setjmp(&_stack.buf))
3587 id _caught = objc_exception_extract(&_stack);
3588 objc_exception_try_enter (&_stack);
3589 if (_setjmp(&_stack.buf))
3590 _rethrow = objc_exception_extract(&_stack);
3591 else
3592 CATCH-LIST
3594 else
3595 TRY-BLOCK
3597 finally
3599 if (!_rethrow)
3600 objc_exception_try_exit(&_stack);
3601 FINALLY-BLOCK
3602 if (_rethrow)
3603 objc_exception_throw(_rethrow);
3607 If CATCH-LIST is empty, we can omit all of the block containing
3608 "_caught" except for the setting of _rethrow. Note the use of
3609 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3610 but handles goto and other exits from the block. */
3612 static tree
3613 next_sjlj_build_try_catch_finally (void)
3615 tree rethrow_decl, stack_decl, t;
3616 tree catch_seq, try_fin, bind;
3618 /* Create the declarations involved. */
3619 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3620 stack_decl = objc_create_temporary_var (t);
3621 cur_try_context->stack_decl = stack_decl;
3623 rethrow_decl = objc_create_temporary_var (objc_object_type);
3624 cur_try_context->rethrow_decl = rethrow_decl;
3625 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3626 TREE_CHAIN (rethrow_decl) = stack_decl;
3628 /* Build the outermost variable binding level. */
3629 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3630 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3631 TREE_SIDE_EFFECTS (bind) = 1;
3633 /* Initialize rethrow_decl. */
3634 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3635 convert (objc_object_type, null_pointer_node));
3636 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3637 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3639 /* Build the outermost TRY_FINALLY_EXPR. */
3640 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3641 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3642 TREE_SIDE_EFFECTS (try_fin) = 1;
3643 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3645 /* Create the complete catch sequence. */
3646 if (cur_try_context->catch_list)
3648 tree caught_decl = objc_build_exc_ptr ();
3649 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3651 t = next_sjlj_build_exc_extract (caught_decl);
3652 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3654 t = next_sjlj_build_enter_and_setjmp ();
3655 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3656 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3657 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3659 else
3660 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3661 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3663 /* Build the main register-and-try if statement. */
3664 t = next_sjlj_build_enter_and_setjmp ();
3665 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3666 COND_EXPR_THEN (t) = catch_seq;
3667 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3668 TREE_OPERAND (try_fin, 0) = t;
3670 /* Build the complete FINALLY statement list. */
3671 t = next_sjlj_build_try_exit ();
3672 t = build_stmt (COND_EXPR,
3673 c_common_truthvalue_conversion (rethrow_decl),
3674 NULL, t);
3675 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3676 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3678 append_to_statement_list (cur_try_context->finally_body,
3679 &TREE_OPERAND (try_fin, 1));
3681 t = tree_cons (NULL, rethrow_decl, NULL);
3682 t = build_function_call (objc_exception_throw_decl, t);
3683 t = build_stmt (COND_EXPR,
3684 c_common_truthvalue_conversion (rethrow_decl),
3685 t, NULL);
3686 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3687 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3689 return bind;
3692 /* Called just after parsing the @try and its associated BODY. We now
3693 must prepare for the tricky bits -- handling the catches and finally. */
3695 void
3696 objc_begin_try_stmt (location_t try_locus, tree body)
3698 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3699 c->outer = cur_try_context;
3700 c->try_body = body;
3701 c->try_locus = try_locus;
3702 c->end_try_locus = input_location;
3703 cur_try_context = c;
3705 objc_init_exceptions ();
3707 if (flag_objc_sjlj_exceptions)
3708 objc_mark_locals_volatile (NULL);
3711 /* Called just after parsing "@catch (parm)". Open a binding level,
3712 enter DECL into the binding level, and initialize it. Leave the
3713 binding level open while the body of the compound statement is parsed. */
3715 void
3716 objc_begin_catch_clause (tree decl)
3718 tree compound, type, t;
3720 /* Begin a new scope that the entire catch clause will live in. */
3721 compound = c_begin_compound_stmt (true);
3723 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3724 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3725 lang_hooks.decls.pushdecl (decl);
3727 /* Since a decl is required here by syntax, don't warn if its unused. */
3728 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3729 be what the previous objc implementation did. */
3730 TREE_USED (decl) = 1;
3732 /* Verify that the type of the catch is valid. It must be a pointer
3733 to an Objective-C class, or "id" (which is catch-all). */
3734 type = TREE_TYPE (decl);
3736 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3737 type = NULL;
3738 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3740 error ("@catch parameter is not a known Objective-C class type");
3741 type = error_mark_node;
3743 else if (cur_try_context->catch_list)
3745 /* Examine previous @catch clauses and see if we've already
3746 caught the type in question. */
3747 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3748 for (; !tsi_end_p (i); tsi_next (&i))
3750 tree stmt = tsi_stmt (i);
3751 t = CATCH_TYPES (stmt);
3752 if (t == error_mark_node)
3753 continue;
3754 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3756 warning (0, "exception of type %<%T%> will be caught",
3757 TREE_TYPE (type));
3758 warning (0, "%H by earlier handler for %<%T%>",
3759 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3760 break;
3765 /* Record the data for the catch in the try context so that we can
3766 finalize it later. */
3767 t = build_stmt (CATCH_EXPR, type, compound);
3768 cur_try_context->current_catch = t;
3770 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3771 t = objc_build_exc_ptr ();
3772 t = convert (TREE_TYPE (decl), t);
3773 t = build (MODIFY_EXPR, void_type_node, decl, t);
3774 add_stmt (t);
3777 /* Called just after parsing the closing brace of a @catch clause. Close
3778 the open binding level, and record a CATCH_EXPR for it. */
3780 void
3781 objc_finish_catch_clause (void)
3783 tree c = cur_try_context->current_catch;
3784 cur_try_context->current_catch = NULL;
3785 cur_try_context->end_catch_locus = input_location;
3787 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3788 append_to_statement_list (c, &cur_try_context->catch_list);
3791 /* Called after parsing a @finally clause and its associated BODY.
3792 Record the body for later placement. */
3794 void
3795 objc_build_finally_clause (location_t finally_locus, tree body)
3797 cur_try_context->finally_body = body;
3798 cur_try_context->finally_locus = finally_locus;
3799 cur_try_context->end_finally_locus = input_location;
3802 /* Called to finalize a @try construct. */
3804 tree
3805 objc_finish_try_stmt (void)
3807 struct objc_try_context *c = cur_try_context;
3808 tree stmt;
3810 if (c->catch_list == NULL && c->finally_body == NULL)
3811 error ("%<@try%> without %<@catch%> or %<@finally%>");
3813 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3814 if (flag_objc_sjlj_exceptions)
3816 if (!cur_try_context->finally_body)
3818 cur_try_context->finally_locus = input_location;
3819 cur_try_context->end_finally_locus = input_location;
3821 stmt = next_sjlj_build_try_catch_finally ();
3823 else
3825 /* Otherwise, nest the CATCH inside a FINALLY. */
3826 stmt = c->try_body;
3827 if (c->catch_list)
3829 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3830 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3832 if (c->finally_body)
3834 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3835 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3838 add_stmt (stmt);
3840 cur_try_context = c->outer;
3841 free (c);
3842 return stmt;
3845 tree
3846 objc_build_throw_stmt (tree throw_expr)
3848 tree args;
3850 objc_init_exceptions ();
3852 if (throw_expr == NULL)
3854 /* If we're not inside a @catch block, there is no "current
3855 exception" to be rethrown. */
3856 if (cur_try_context == NULL
3857 || cur_try_context->current_catch == NULL)
3859 error ("%<@throw%> (rethrow) used outside of a @catch block");
3860 return NULL_TREE;
3863 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3864 value that we get from the runtime. */
3865 throw_expr = objc_build_exc_ptr ();
3868 /* A throw is just a call to the runtime throw function with the
3869 object as a parameter. */
3870 args = tree_cons (NULL, throw_expr, NULL);
3871 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3874 tree
3875 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3877 tree args, call;
3879 /* First lock the mutex. */
3880 mutex = save_expr (mutex);
3881 args = tree_cons (NULL, mutex, NULL);
3882 call = build_function_call (objc_sync_enter_decl, args);
3883 SET_EXPR_LOCATION (call, start_locus);
3884 add_stmt (call);
3886 /* Build the mutex unlock. */
3887 args = tree_cons (NULL, mutex, NULL);
3888 call = build_function_call (objc_sync_exit_decl, args);
3889 SET_EXPR_LOCATION (call, input_location);
3891 /* Put the that and the body in a TRY_FINALLY. */
3892 objc_begin_try_stmt (start_locus, body);
3893 objc_build_finally_clause (input_location, call);
3894 return objc_finish_try_stmt ();
3898 /* Predefine the following data type:
3900 struct _objc_exception_data
3902 int buf[_JBLEN];
3903 void *pointers[4];
3904 }; */
3906 /* The following yuckiness should prevent users from having to #include
3907 <setjmp.h> in their code... */
3909 #ifdef TARGET_POWERPC
3910 /* snarfed from /usr/include/ppc/setjmp.h */
3911 #define _JBLEN (26 + 36 + 129 + 1)
3912 #else
3913 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3914 #define _JBLEN 18
3915 #endif
3917 static void
3918 build_next_objc_exception_stuff (void)
3920 tree field_decl, field_decl_chain, index, temp_type;
3922 objc_exception_data_template
3923 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3925 /* int buf[_JBLEN]; */
3927 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3928 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3929 "buf");
3930 field_decl_chain = field_decl;
3932 /* void *pointers[4]; */
3934 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3935 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3936 "pointers");
3937 chainon (field_decl_chain, field_decl);
3939 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3941 /* int _setjmp(...); */
3942 /* If the user includes <setjmp.h>, this shall be superseded by
3943 'int _setjmp(jmp_buf);' */
3944 temp_type = build_function_type (integer_type_node, NULL_TREE);
3945 objc_setjmp_decl
3946 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3948 /* id objc_exception_extract(struct _objc_exception_data *); */
3949 temp_type
3950 = build_function_type (objc_object_type,
3951 tree_cons (NULL_TREE,
3952 build_pointer_type (objc_exception_data_template),
3953 OBJC_VOID_AT_END));
3954 objc_exception_extract_decl
3955 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3956 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3957 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3958 temp_type
3959 = build_function_type (void_type_node,
3960 tree_cons (NULL_TREE,
3961 build_pointer_type (objc_exception_data_template),
3962 OBJC_VOID_AT_END));
3963 objc_exception_try_enter_decl
3964 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3965 objc_exception_try_exit_decl
3966 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3968 /* int objc_exception_match(id, id); */
3969 temp_type
3970 = build_function_type (integer_type_node,
3971 tree_cons (NULL_TREE, objc_object_type,
3972 tree_cons (NULL_TREE, objc_object_type,
3973 OBJC_VOID_AT_END)));
3974 objc_exception_match_decl
3975 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3977 /* id objc_assign_ivar (id, id, unsigned int); */
3978 /* id objc_assign_ivar_Fast (id, id, unsigned int)
3979 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
3980 temp_type
3981 = build_function_type (objc_object_type,
3982 tree_cons
3983 (NULL_TREE, objc_object_type,
3984 tree_cons (NULL_TREE, objc_object_type,
3985 tree_cons (NULL_TREE,
3986 unsigned_type_node,
3987 OBJC_VOID_AT_END))));
3988 objc_assign_ivar_decl
3989 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
3990 NULL, NULL_TREE);
3991 #ifdef OFFS_ASSIGNIVAR_FAST
3992 objc_assign_ivar_fast_decl
3993 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
3994 NOT_BUILT_IN, NULL, NULL_TREE);
3995 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
3996 = tree_cons (get_identifier ("hard_coded_address"),
3997 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
3998 NULL_TREE);
3999 #else
4000 /* Default to slower ivar method. */
4001 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4002 #endif
4004 /* id objc_assign_global (id, id *); */
4005 /* id objc_assign_strongCast (id, id *); */
4006 temp_type = build_function_type (objc_object_type,
4007 tree_cons (NULL_TREE, objc_object_type,
4008 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4009 OBJC_VOID_AT_END)));
4010 objc_assign_global_decl
4011 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4012 objc_assign_strong_cast_decl
4013 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4016 static void
4017 build_objc_exception_stuff (void)
4019 tree noreturn_list, nothrow_list, temp_type;
4021 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4022 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4024 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4025 /* void objc_sync_enter(id); */
4026 /* void objc_sync_exit(id); */
4027 temp_type = build_function_type (void_type_node,
4028 tree_cons (NULL_TREE, objc_object_type,
4029 OBJC_VOID_AT_END));
4030 objc_exception_throw_decl
4031 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4032 noreturn_list);
4033 objc_sync_enter_decl
4034 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4035 NULL, nothrow_list);
4036 objc_sync_exit_decl
4037 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4038 NULL, nothrow_list);
4041 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4042 name as the class:
4044 struct <classname> {
4045 struct _objc_class *isa;
4047 }; */
4049 static void
4050 build_private_template (tree class)
4052 if (!CLASS_STATIC_TEMPLATE (class))
4054 tree record = objc_build_struct (CLASS_NAME (class),
4055 get_class_ivars (class, false),
4056 CLASS_SUPER_NAME (class));
4058 /* mark this record as class template - for class type checking */
4059 INIT_TYPE_OBJC_INFO (record);
4060 TYPE_OBJC_INTERFACE (record) = class;
4061 CLASS_STATIC_TEMPLATE (class) = record;
4063 /* Set the TREE_USED bit for this struct, so that stab generator
4064 can emit stabs for this struct type. */
4065 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4066 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4070 /* Begin code generation for protocols... */
4072 /* struct _objc_protocol {
4073 struct _objc_class *isa;
4074 char *protocol_name;
4075 struct _objc_protocol **protocol_list;
4076 struct _objc__method_prototype_list *instance_methods;
4077 struct _objc__method_prototype_list *class_methods;
4078 }; */
4080 static void
4081 build_protocol_template (void)
4083 tree field_decl, field_decl_chain;
4085 objc_protocol_template = start_struct (RECORD_TYPE,
4086 get_identifier (UTAG_PROTOCOL));
4088 /* struct _objc_class *isa; */
4089 field_decl = create_field_decl (build_pointer_type
4090 (xref_tag (RECORD_TYPE,
4091 get_identifier (UTAG_CLASS))),
4092 "isa");
4093 field_decl_chain = field_decl;
4095 /* char *protocol_name; */
4096 field_decl = create_field_decl (string_type_node, "protocol_name");
4097 chainon (field_decl_chain, field_decl);
4099 /* struct _objc_protocol **protocol_list; */
4100 field_decl = create_field_decl (build_pointer_type
4101 (build_pointer_type
4102 (objc_protocol_template)),
4103 "protocol_list");
4104 chainon (field_decl_chain, field_decl);
4106 /* struct _objc__method_prototype_list *instance_methods; */
4107 field_decl = create_field_decl (objc_method_proto_list_ptr,
4108 "instance_methods");
4109 chainon (field_decl_chain, field_decl);
4111 /* struct _objc__method_prototype_list *class_methods; */
4112 field_decl = create_field_decl (objc_method_proto_list_ptr,
4113 "class_methods");
4114 chainon (field_decl_chain, field_decl);
4116 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4119 static tree
4120 build_descriptor_table_initializer (tree type, tree entries)
4122 tree initlist = NULL_TREE;
4126 tree eltlist = NULL_TREE;
4128 eltlist
4129 = tree_cons (NULL_TREE,
4130 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4131 eltlist
4132 = tree_cons (NULL_TREE,
4133 add_objc_string (METHOD_ENCODING (entries),
4134 meth_var_types),
4135 eltlist);
4137 initlist
4138 = tree_cons (NULL_TREE,
4139 objc_build_constructor (type, nreverse (eltlist)),
4140 initlist);
4142 entries = TREE_CHAIN (entries);
4144 while (entries);
4146 return objc_build_constructor (build_array_type (type, 0),
4147 nreverse (initlist));
4150 /* struct objc_method_prototype_list {
4151 int count;
4152 struct objc_method_prototype {
4153 SEL name;
4154 char *types;
4155 } list[1];
4156 }; */
4158 static tree
4159 build_method_prototype_list_template (tree list_type, int size)
4161 tree objc_ivar_list_record;
4162 tree field_decl, field_decl_chain;
4164 /* Generate an unnamed struct definition. */
4166 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4168 /* int method_count; */
4169 field_decl = create_field_decl (integer_type_node, "method_count");
4170 field_decl_chain = field_decl;
4172 /* struct objc_method method_list[]; */
4173 field_decl = create_field_decl (build_array_type
4174 (list_type,
4175 build_index_type
4176 (build_int_cst (NULL_TREE, size - 1))),
4177 "method_list");
4178 chainon (field_decl_chain, field_decl);
4180 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4182 return objc_ivar_list_record;
4185 static tree
4186 build_method_prototype_template (void)
4188 tree proto_record;
4189 tree field_decl, field_decl_chain;
4191 proto_record
4192 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4194 /* SEL _cmd; */
4195 field_decl = create_field_decl (objc_selector_type, "_cmd");
4196 field_decl_chain = field_decl;
4198 /* char *method_types; */
4199 field_decl = create_field_decl (string_type_node, "method_types");
4200 chainon (field_decl_chain, field_decl);
4202 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4204 return proto_record;
4207 static tree
4208 objc_method_parm_type (tree type)
4210 type = TREE_VALUE (TREE_TYPE (type));
4211 if (TREE_CODE (type) == TYPE_DECL)
4212 type = TREE_TYPE (type);
4213 return type;
4216 static int
4217 objc_encoded_type_size (tree type)
4219 int sz = int_size_in_bytes (type);
4221 /* Make all integer and enum types at least as large
4222 as an int. */
4223 if (sz > 0 && INTEGRAL_TYPE_P (type))
4224 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4225 /* Treat arrays as pointers, since that's how they're
4226 passed in. */
4227 else if (TREE_CODE (type) == ARRAY_TYPE)
4228 sz = int_size_in_bytes (ptr_type_node);
4229 return sz;
4232 static tree
4233 encode_method_prototype (tree method_decl)
4235 tree parms;
4236 int parm_offset, i;
4237 char buf[40];
4238 tree result;
4240 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4241 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4243 /* Encode return type. */
4244 encode_type (objc_method_parm_type (method_decl),
4245 obstack_object_size (&util_obstack),
4246 OBJC_ENCODE_INLINE_DEFS);
4248 /* Stack size. */
4249 /* The first two arguments (self and _cmd) are pointers; account for
4250 their size. */
4251 i = int_size_in_bytes (ptr_type_node);
4252 parm_offset = 2 * i;
4253 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4254 parms = TREE_CHAIN (parms))
4256 tree type = objc_method_parm_type (parms);
4257 int sz = objc_encoded_type_size (type);
4259 /* If a type size is not known, bail out. */
4260 if (sz < 0)
4262 error ("%Jtype '%D' does not have a known size",
4263 type, type);
4264 /* Pretend that the encoding succeeded; the compilation will
4265 fail nevertheless. */
4266 goto finish_encoding;
4268 parm_offset += sz;
4271 sprintf (buf, "%d@0:%d", parm_offset, i);
4272 obstack_grow (&util_obstack, buf, strlen (buf));
4274 /* Argument types. */
4275 parm_offset = 2 * i;
4276 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4277 parms = TREE_CHAIN (parms))
4279 tree type = objc_method_parm_type (parms);
4281 /* Process argument qualifiers for user supplied arguments. */
4282 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4284 /* Type. */
4285 encode_type (type, obstack_object_size (&util_obstack),
4286 OBJC_ENCODE_INLINE_DEFS);
4288 /* Compute offset. */
4289 sprintf (buf, "%d", parm_offset);
4290 parm_offset += objc_encoded_type_size (type);
4292 obstack_grow (&util_obstack, buf, strlen (buf));
4295 finish_encoding:
4296 obstack_1grow (&util_obstack, '\0');
4297 result = get_identifier (obstack_finish (&util_obstack));
4298 obstack_free (&util_obstack, util_firstobj);
4299 return result;
4302 static tree
4303 generate_descriptor_table (tree type, const char *name, int size, tree list,
4304 tree proto)
4306 tree decl, initlist;
4308 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4310 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4311 initlist = tree_cons (NULL_TREE, list, initlist);
4313 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4315 return decl;
4318 static void
4319 generate_method_descriptors (tree protocol)
4321 tree initlist, chain, method_list_template;
4322 int size;
4324 if (!objc_method_prototype_template)
4325 objc_method_prototype_template = build_method_prototype_template ();
4327 chain = PROTOCOL_CLS_METHODS (protocol);
4328 if (chain)
4330 size = list_length (chain);
4332 method_list_template
4333 = build_method_prototype_list_template (objc_method_prototype_template,
4334 size);
4336 initlist
4337 = build_descriptor_table_initializer (objc_method_prototype_template,
4338 chain);
4340 UOBJC_CLASS_METHODS_decl
4341 = generate_descriptor_table (method_list_template,
4342 "_OBJC_PROTOCOL_CLASS_METHODS",
4343 size, initlist, protocol);
4345 else
4346 UOBJC_CLASS_METHODS_decl = 0;
4348 chain = PROTOCOL_NST_METHODS (protocol);
4349 if (chain)
4351 size = list_length (chain);
4353 method_list_template
4354 = build_method_prototype_list_template (objc_method_prototype_template,
4355 size);
4356 initlist
4357 = build_descriptor_table_initializer (objc_method_prototype_template,
4358 chain);
4360 UOBJC_INSTANCE_METHODS_decl
4361 = generate_descriptor_table (method_list_template,
4362 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4363 size, initlist, protocol);
4365 else
4366 UOBJC_INSTANCE_METHODS_decl = 0;
4369 static void
4370 generate_protocol_references (tree plist)
4372 tree lproto;
4374 /* Forward declare protocols referenced. */
4375 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4377 tree proto = TREE_VALUE (lproto);
4379 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4380 && PROTOCOL_NAME (proto))
4382 if (! PROTOCOL_FORWARD_DECL (proto))
4383 build_protocol_reference (proto);
4385 if (PROTOCOL_LIST (proto))
4386 generate_protocol_references (PROTOCOL_LIST (proto));
4391 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4392 current class. */
4393 #ifdef OBJCPLUS
4394 static void
4395 objc_generate_cxx_ctor_or_dtor (bool dtor)
4397 tree fn, body, compound_stmt, ivar;
4399 /* - (id) .cxx_construct { ... return self; } */
4400 /* - (void) .cxx_construct { ... } */
4402 objc_set_method_type (MINUS_EXPR);
4403 objc_start_method_definition
4404 (objc_build_method_signature (build_tree_list (NULL_TREE,
4405 dtor
4406 ? void_type_node
4407 : objc_object_type),
4408 get_identifier (dtor
4409 ? TAG_CXX_DESTRUCT
4410 : TAG_CXX_CONSTRUCT),
4411 make_node (TREE_LIST),
4412 false));
4413 body = begin_function_body ();
4414 compound_stmt = begin_compound_stmt (0);
4416 ivar = CLASS_IVARS (implementation_template);
4417 /* Destroy ivars in reverse order. */
4418 if (dtor)
4419 ivar = nreverse (copy_list (ivar));
4421 for (; ivar; ivar = TREE_CHAIN (ivar))
4423 if (TREE_CODE (ivar) == FIELD_DECL)
4425 tree type = TREE_TYPE (ivar);
4427 /* Call the ivar's default constructor or destructor. Do not
4428 call the destructor unless a corresponding constructor call
4429 has also been made (or is not needed). */
4430 if (IS_AGGR_TYPE (type)
4431 && (dtor
4432 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4433 && (!TYPE_NEEDS_CONSTRUCTING (type)
4434 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4435 : (TYPE_NEEDS_CONSTRUCTING (type)
4436 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4437 finish_expr_stmt
4438 (build_special_member_call
4439 (build_ivar_reference (DECL_NAME (ivar)),
4440 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4441 NULL_TREE, type, LOOKUP_NORMAL));
4445 /* The constructor returns 'self'. */
4446 if (!dtor)
4447 finish_return_stmt (self_decl);
4449 finish_compound_stmt (compound_stmt);
4450 finish_function_body (body);
4451 fn = current_function_decl;
4452 finish_function ();
4453 objc_finish_method_definition (fn);
4456 /* The following routine will examine the current @interface for any
4457 non-POD C++ ivars requiring non-trivial construction and/or
4458 destruction, and then synthesize special '- .cxx_construct' and/or
4459 '- .cxx_destruct' methods which will run the appropriate
4460 construction or destruction code. Note that ivars inherited from
4461 super-classes are _not_ considered. */
4462 static void
4463 objc_generate_cxx_cdtors (void)
4465 bool need_ctor = false, need_dtor = false;
4466 tree ivar;
4468 /* We do not want to do this for categories, since they do not have
4469 their own ivars. */
4471 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4472 return;
4474 /* First, determine if we even need a constructor and/or destructor. */
4476 for (ivar = CLASS_IVARS (implementation_template); ivar;
4477 ivar = TREE_CHAIN (ivar))
4479 if (TREE_CODE (ivar) == FIELD_DECL)
4481 tree type = TREE_TYPE (ivar);
4483 if (IS_AGGR_TYPE (type))
4485 if (TYPE_NEEDS_CONSTRUCTING (type)
4486 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4487 /* NB: If a default constructor is not available, we will not
4488 be able to initialize this ivar; the add_instance_variable()
4489 routine will already have warned about this. */
4490 need_ctor = true;
4492 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4493 && (!TYPE_NEEDS_CONSTRUCTING (type)
4494 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4495 /* NB: If a default constructor is not available, we will not
4496 call the destructor either, for symmetry. */
4497 need_dtor = true;
4502 /* Generate '- .cxx_construct' if needed. */
4504 if (need_ctor)
4505 objc_generate_cxx_ctor_or_dtor (false);
4507 /* Generate '- .cxx_destruct' if needed. */
4509 if (need_dtor)
4510 objc_generate_cxx_ctor_or_dtor (true);
4512 /* The 'imp_list' variable points at an imp_entry record for the current
4513 @implementation. Record the existence of '- .cxx_construct' and/or
4514 '- .cxx_destruct' methods therein; it will be included in the
4515 metadata for the class. */
4516 if (flag_next_runtime)
4517 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4519 #endif
4521 /* For each protocol which was referenced either from a @protocol()
4522 expression, or because a class/category implements it (then a
4523 pointer to the protocol is stored in the struct describing the
4524 class/category), we create a statically allocated instance of the
4525 Protocol class. The code is written in such a way as to generate
4526 as few Protocol objects as possible; we generate a unique Protocol
4527 instance for each protocol, and we don't generate a Protocol
4528 instance if the protocol is never referenced (either from a
4529 @protocol() or from a class/category implementation). These
4530 statically allocated objects can be referred to via the static
4531 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4533 The statically allocated Protocol objects that we generate here
4534 need to be fixed up at runtime in order to be used: the 'isa'
4535 pointer of the objects need to be set up to point to the 'Protocol'
4536 class, as known at runtime.
4538 The NeXT runtime fixes up all protocols at program startup time,
4539 before main() is entered. It uses a low-level trick to look up all
4540 those symbols, then loops on them and fixes them up.
4542 The GNU runtime as well fixes up all protocols before user code
4543 from the module is executed; it requires pointers to those symbols
4544 to be put in the objc_symtab (which is then passed as argument to
4545 the function __objc_exec_class() which the compiler sets up to be
4546 executed automatically when the module is loaded); setup of those
4547 Protocol objects happen in two ways in the GNU runtime: all
4548 Protocol objects referred to by a class or category implementation
4549 are fixed up when the class/category is loaded; all Protocol
4550 objects referred to by a @protocol() expression are added by the
4551 compiler to the list of statically allocated instances to fixup
4552 (the same list holding the statically allocated constant string
4553 objects). Because, as explained above, the compiler generates as
4554 few Protocol objects as possible, some Protocol object might end up
4555 being referenced multiple times when compiled with the GNU runtime,
4556 and end up being fixed up multiple times at runtime initialization.
4557 But that doesn't hurt, it's just a little inefficient. */
4559 static void
4560 generate_protocols (void)
4562 tree p, encoding;
4563 tree decl;
4564 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4566 /* If a protocol was directly referenced, pull in indirect references. */
4567 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4568 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4569 generate_protocol_references (PROTOCOL_LIST (p));
4571 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4573 tree nst_methods = PROTOCOL_NST_METHODS (p);
4574 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4576 /* If protocol wasn't referenced, don't generate any code. */
4577 decl = PROTOCOL_FORWARD_DECL (p);
4579 if (!decl)
4580 continue;
4582 /* Make sure we link in the Protocol class. */
4583 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4585 while (nst_methods)
4587 if (! METHOD_ENCODING (nst_methods))
4589 encoding = encode_method_prototype (nst_methods);
4590 METHOD_ENCODING (nst_methods) = encoding;
4592 nst_methods = TREE_CHAIN (nst_methods);
4595 while (cls_methods)
4597 if (! METHOD_ENCODING (cls_methods))
4599 encoding = encode_method_prototype (cls_methods);
4600 METHOD_ENCODING (cls_methods) = encoding;
4603 cls_methods = TREE_CHAIN (cls_methods);
4605 generate_method_descriptors (p);
4607 if (PROTOCOL_LIST (p))
4608 refs_decl = generate_protocol_list (p);
4609 else
4610 refs_decl = 0;
4612 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4613 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4615 if (refs_decl)
4616 refs_expr = convert (build_pointer_type (build_pointer_type
4617 (objc_protocol_template)),
4618 build_unary_op (ADDR_EXPR, refs_decl, 0));
4619 else
4620 refs_expr = build_int_cst (NULL_TREE, 0);
4622 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4623 by generate_method_descriptors, which is called above. */
4624 initlist = build_protocol_initializer (TREE_TYPE (decl),
4625 protocol_name_expr, refs_expr,
4626 UOBJC_INSTANCE_METHODS_decl,
4627 UOBJC_CLASS_METHODS_decl);
4628 finish_var_decl (decl, initlist);
4632 static tree
4633 build_protocol_initializer (tree type, tree protocol_name,
4634 tree protocol_list, tree instance_methods,
4635 tree class_methods)
4637 tree initlist = NULL_TREE, expr;
4638 tree cast_type = build_pointer_type
4639 (xref_tag (RECORD_TYPE,
4640 get_identifier (UTAG_CLASS)));
4642 /* Filling the "isa" in with one allows the runtime system to
4643 detect that the version change...should remove before final release. */
4645 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4646 initlist = tree_cons (NULL_TREE, expr, initlist);
4647 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4648 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4650 if (!instance_methods)
4651 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4652 else
4654 expr = convert (objc_method_proto_list_ptr,
4655 build_unary_op (ADDR_EXPR, instance_methods, 0));
4656 initlist = tree_cons (NULL_TREE, expr, initlist);
4659 if (!class_methods)
4660 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4661 else
4663 expr = convert (objc_method_proto_list_ptr,
4664 build_unary_op (ADDR_EXPR, class_methods, 0));
4665 initlist = tree_cons (NULL_TREE, expr, initlist);
4668 return objc_build_constructor (type, nreverse (initlist));
4671 /* struct _objc_category {
4672 char *category_name;
4673 char *class_name;
4674 struct _objc_method_list *instance_methods;
4675 struct _objc_method_list *class_methods;
4676 struct _objc_protocol_list *protocols;
4677 }; */
4679 static void
4680 build_category_template (void)
4682 tree field_decl, field_decl_chain;
4684 objc_category_template = start_struct (RECORD_TYPE,
4685 get_identifier (UTAG_CATEGORY));
4687 /* char *category_name; */
4688 field_decl = create_field_decl (string_type_node, "category_name");
4689 field_decl_chain = field_decl;
4691 /* char *class_name; */
4692 field_decl = create_field_decl (string_type_node, "class_name");
4693 chainon (field_decl_chain, field_decl);
4695 /* struct _objc_method_list *instance_methods; */
4696 field_decl = create_field_decl (objc_method_list_ptr,
4697 "instance_methods");
4698 chainon (field_decl_chain, field_decl);
4700 /* struct _objc_method_list *class_methods; */
4701 field_decl = create_field_decl (objc_method_list_ptr,
4702 "class_methods");
4703 chainon (field_decl_chain, field_decl);
4705 /* struct _objc_protocol **protocol_list; */
4706 field_decl = create_field_decl (build_pointer_type
4707 (build_pointer_type
4708 (objc_protocol_template)),
4709 "protocol_list");
4710 chainon (field_decl_chain, field_decl);
4712 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4715 /* struct _objc_selector {
4716 SEL sel_id;
4717 char *sel_type;
4718 }; */
4720 static void
4721 build_selector_template (void)
4724 tree field_decl, field_decl_chain;
4726 objc_selector_template
4727 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4729 /* SEL sel_id; */
4730 field_decl = create_field_decl (objc_selector_type, "sel_id");
4731 field_decl_chain = field_decl;
4733 /* char *sel_type; */
4734 field_decl = create_field_decl (string_type_node, "sel_type");
4735 chainon (field_decl_chain, field_decl);
4737 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4740 /* struct _objc_class {
4741 struct _objc_class *isa;
4742 struct _objc_class *super_class;
4743 char *name;
4744 long version;
4745 long info;
4746 long instance_size;
4747 struct _objc_ivar_list *ivars;
4748 struct _objc_method_list *methods;
4749 #ifdef __NEXT_RUNTIME__
4750 struct objc_cache *cache;
4751 #else
4752 struct sarray *dtable;
4753 struct _objc_class *subclass_list;
4754 struct _objc_class *sibling_class;
4755 #endif
4756 struct _objc_protocol_list *protocols;
4757 #ifdef __NEXT_RUNTIME__
4758 void *sel_id;
4759 #endif
4760 void *gc_object_type;
4761 }; */
4763 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4764 the NeXT/Apple runtime; still, the compiler must generate them to
4765 maintain backward binary compatibility (and to allow for future
4766 expansion). */
4768 static void
4769 build_class_template (void)
4771 tree field_decl, field_decl_chain;
4773 objc_class_template
4774 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4776 /* struct _objc_class *isa; */
4777 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4778 "isa");
4779 field_decl_chain = field_decl;
4781 /* struct _objc_class *super_class; */
4782 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4783 "super_class");
4784 chainon (field_decl_chain, field_decl);
4786 /* char *name; */
4787 field_decl = create_field_decl (string_type_node, "name");
4788 chainon (field_decl_chain, field_decl);
4790 /* long version; */
4791 field_decl = create_field_decl (long_integer_type_node, "version");
4792 chainon (field_decl_chain, field_decl);
4794 /* long info; */
4795 field_decl = create_field_decl (long_integer_type_node, "info");
4796 chainon (field_decl_chain, field_decl);
4798 /* long instance_size; */
4799 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4800 chainon (field_decl_chain, field_decl);
4802 /* struct _objc_ivar_list *ivars; */
4803 field_decl = create_field_decl (objc_ivar_list_ptr,
4804 "ivars");
4805 chainon (field_decl_chain, field_decl);
4807 /* struct _objc_method_list *methods; */
4808 field_decl = create_field_decl (objc_method_list_ptr,
4809 "methods");
4810 chainon (field_decl_chain, field_decl);
4812 if (flag_next_runtime)
4814 /* struct objc_cache *cache; */
4815 field_decl = create_field_decl (build_pointer_type
4816 (xref_tag (RECORD_TYPE,
4817 get_identifier
4818 ("objc_cache"))),
4819 "cache");
4820 chainon (field_decl_chain, field_decl);
4822 else
4824 /* struct sarray *dtable; */
4825 field_decl = create_field_decl (build_pointer_type
4826 (xref_tag (RECORD_TYPE,
4827 get_identifier
4828 ("sarray"))),
4829 "dtable");
4830 chainon (field_decl_chain, field_decl);
4832 /* struct objc_class *subclass_list; */
4833 field_decl = create_field_decl (build_pointer_type
4834 (objc_class_template),
4835 "subclass_list");
4836 chainon (field_decl_chain, field_decl);
4838 /* struct objc_class *sibling_class; */
4839 field_decl = create_field_decl (build_pointer_type
4840 (objc_class_template),
4841 "sibling_class");
4842 chainon (field_decl_chain, field_decl);
4845 /* struct _objc_protocol **protocol_list; */
4846 field_decl = create_field_decl (build_pointer_type
4847 (build_pointer_type
4848 (xref_tag (RECORD_TYPE,
4849 get_identifier
4850 (UTAG_PROTOCOL)))),
4851 "protocol_list");
4852 chainon (field_decl_chain, field_decl);
4854 if (flag_next_runtime)
4856 /* void *sel_id; */
4857 field_decl = create_field_decl (build_pointer_type (void_type_node),
4858 "sel_id");
4859 chainon (field_decl_chain, field_decl);
4862 /* void *gc_object_type; */
4863 field_decl = create_field_decl (build_pointer_type (void_type_node),
4864 "gc_object_type");
4865 chainon (field_decl_chain, field_decl);
4867 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4870 /* Generate appropriate forward declarations for an implementation. */
4872 static void
4873 synth_forward_declarations (void)
4875 tree an_id;
4877 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4878 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4879 objc_class_template);
4881 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4882 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4883 objc_class_template);
4885 /* Pre-build the following entities - for speed/convenience. */
4887 an_id = get_identifier ("super_class");
4888 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4889 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4892 static void
4893 error_with_ivar (const char *message, tree decl)
4895 error ("%J%s %qs", decl,
4896 message, gen_declaration (decl));
4900 static void
4901 check_ivars (tree inter, tree imp)
4903 tree intdecls = CLASS_RAW_IVARS (inter);
4904 tree impdecls = CLASS_RAW_IVARS (imp);
4906 while (1)
4908 tree t1, t2;
4910 #ifdef OBJCPLUS
4911 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4912 intdecls = TREE_CHAIN (intdecls);
4913 #endif
4914 if (intdecls == 0 && impdecls == 0)
4915 break;
4916 if (intdecls == 0 || impdecls == 0)
4918 error ("inconsistent instance variable specification");
4919 break;
4922 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4924 if (!comptypes (t1, t2)
4925 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4926 DECL_INITIAL (impdecls)))
4928 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4930 error_with_ivar ("conflicting instance variable type",
4931 impdecls);
4932 error_with_ivar ("previous declaration of",
4933 intdecls);
4935 else /* both the type and the name don't match */
4937 error ("inconsistent instance variable specification");
4938 break;
4942 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4944 error_with_ivar ("conflicting instance variable name",
4945 impdecls);
4946 error_with_ivar ("previous declaration of",
4947 intdecls);
4950 intdecls = TREE_CHAIN (intdecls);
4951 impdecls = TREE_CHAIN (impdecls);
4955 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4956 This needs to be done just once per compilation. */
4958 /* struct _objc_super {
4959 struct _objc_object *self;
4960 struct _objc_class *super_class;
4961 }; */
4963 static void
4964 build_super_template (void)
4966 tree field_decl, field_decl_chain;
4968 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4970 /* struct _objc_object *self; */
4971 field_decl = create_field_decl (objc_object_type, "self");
4972 field_decl_chain = field_decl;
4974 /* struct _objc_class *super_class; */
4975 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4976 "super_class");
4977 chainon (field_decl_chain, field_decl);
4979 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4982 /* struct _objc_ivar {
4983 char *ivar_name;
4984 char *ivar_type;
4985 int ivar_offset;
4986 }; */
4988 static tree
4989 build_ivar_template (void)
4991 tree objc_ivar_id, objc_ivar_record;
4992 tree field_decl, field_decl_chain;
4994 objc_ivar_id = get_identifier (UTAG_IVAR);
4995 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4997 /* char *ivar_name; */
4998 field_decl = create_field_decl (string_type_node, "ivar_name");
4999 field_decl_chain = field_decl;
5001 /* char *ivar_type; */
5002 field_decl = create_field_decl (string_type_node, "ivar_type");
5003 chainon (field_decl_chain, field_decl);
5005 /* int ivar_offset; */
5006 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5007 chainon (field_decl_chain, field_decl);
5009 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5011 return objc_ivar_record;
5014 /* struct {
5015 int ivar_count;
5016 struct objc_ivar ivar_list[ivar_count];
5017 }; */
5019 static tree
5020 build_ivar_list_template (tree list_type, int size)
5022 tree objc_ivar_list_record;
5023 tree field_decl, field_decl_chain;
5025 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5027 /* int ivar_count; */
5028 field_decl = create_field_decl (integer_type_node, "ivar_count");
5029 field_decl_chain = field_decl;
5031 /* struct objc_ivar ivar_list[]; */
5032 field_decl = create_field_decl (build_array_type
5033 (list_type,
5034 build_index_type
5035 (build_int_cst (NULL_TREE, size - 1))),
5036 "ivar_list");
5037 chainon (field_decl_chain, field_decl);
5039 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5041 return objc_ivar_list_record;
5044 /* struct {
5045 struct _objc__method_prototype_list *method_next;
5046 int method_count;
5047 struct objc_method method_list[method_count];
5048 }; */
5050 static tree
5051 build_method_list_template (tree list_type, int size)
5053 tree objc_ivar_list_record;
5054 tree field_decl, field_decl_chain;
5056 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5058 /* struct _objc__method_prototype_list *method_next; */
5059 field_decl = create_field_decl (objc_method_proto_list_ptr,
5060 "method_next");
5061 field_decl_chain = field_decl;
5063 /* int method_count; */
5064 field_decl = create_field_decl (integer_type_node, "method_count");
5065 chainon (field_decl_chain, field_decl);
5067 /* struct objc_method method_list[]; */
5068 field_decl = create_field_decl (build_array_type
5069 (list_type,
5070 build_index_type
5071 (build_int_cst (NULL_TREE, size - 1))),
5072 "method_list");
5073 chainon (field_decl_chain, field_decl);
5075 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5077 return objc_ivar_list_record;
5080 static tree
5081 build_ivar_list_initializer (tree type, tree field_decl)
5083 tree initlist = NULL_TREE;
5087 tree ivar = NULL_TREE;
5089 /* Set name. */
5090 if (DECL_NAME (field_decl))
5091 ivar = tree_cons (NULL_TREE,
5092 add_objc_string (DECL_NAME (field_decl),
5093 meth_var_names),
5094 ivar);
5095 else
5096 /* Unnamed bit-field ivar (yuck). */
5097 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5099 /* Set type. */
5100 encode_field_decl (field_decl,
5101 obstack_object_size (&util_obstack),
5102 OBJC_ENCODE_DONT_INLINE_DEFS);
5104 /* Null terminate string. */
5105 obstack_1grow (&util_obstack, 0);
5106 ivar
5107 = tree_cons
5108 (NULL_TREE,
5109 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5110 meth_var_types),
5111 ivar);
5112 obstack_free (&util_obstack, util_firstobj);
5114 /* Set offset. */
5115 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5116 initlist = tree_cons (NULL_TREE,
5117 objc_build_constructor (type, nreverse (ivar)),
5118 initlist);
5120 field_decl = TREE_CHAIN (field_decl);
5121 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5123 while (field_decl);
5125 return objc_build_constructor (build_array_type (type, 0),
5126 nreverse (initlist));
5129 static tree
5130 generate_ivars_list (tree type, const char *name, int size, tree list)
5132 tree decl, initlist;
5134 decl = start_var_decl (type, synth_id_with_class_suffix
5135 (name, objc_implementation_context));
5137 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5138 initlist = tree_cons (NULL_TREE, list, initlist);
5140 finish_var_decl (decl,
5141 objc_build_constructor (TREE_TYPE (decl),
5142 nreverse (initlist)));
5144 return decl;
5147 /* Count only the fields occurring in T. */
5148 static int
5149 ivar_list_length (tree t)
5151 int count = 0;
5153 for (; t; t = TREE_CHAIN (t))
5154 if (TREE_CODE (t) == FIELD_DECL)
5155 ++count;
5157 return count;
5160 static void
5161 generate_ivar_lists (void)
5163 tree initlist, ivar_list_template, chain;
5164 int size;
5166 generating_instance_variables = 1;
5168 if (!objc_ivar_template)
5169 objc_ivar_template = build_ivar_template ();
5171 /* Only generate class variables for the root of the inheritance
5172 hierarchy since these will be the same for every class. */
5174 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5175 && (chain = TYPE_FIELDS (objc_class_template)))
5177 size = ivar_list_length (chain);
5179 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5180 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5182 UOBJC_CLASS_VARIABLES_decl
5183 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5184 size, initlist);
5186 else
5187 UOBJC_CLASS_VARIABLES_decl = 0;
5189 chain = CLASS_IVARS (implementation_template);
5190 if (chain)
5192 size = ivar_list_length (chain);
5193 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5194 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5196 UOBJC_INSTANCE_VARIABLES_decl
5197 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5198 size, initlist);
5200 else
5201 UOBJC_INSTANCE_VARIABLES_decl = 0;
5203 generating_instance_variables = 0;
5206 static tree
5207 build_dispatch_table_initializer (tree type, tree entries)
5209 tree initlist = NULL_TREE;
5213 tree elemlist = NULL_TREE;
5215 elemlist = tree_cons (NULL_TREE,
5216 build_selector (METHOD_SEL_NAME (entries)),
5217 NULL_TREE);
5219 /* Generate the method encoding if we don't have one already. */
5220 if (! METHOD_ENCODING (entries))
5221 METHOD_ENCODING (entries) =
5222 encode_method_prototype (entries);
5224 elemlist = tree_cons (NULL_TREE,
5225 add_objc_string (METHOD_ENCODING (entries),
5226 meth_var_types),
5227 elemlist);
5229 elemlist
5230 = tree_cons (NULL_TREE,
5231 convert (ptr_type_node,
5232 build_unary_op (ADDR_EXPR,
5233 METHOD_DEFINITION (entries), 1)),
5234 elemlist);
5236 initlist = tree_cons (NULL_TREE,
5237 objc_build_constructor (type, nreverse (elemlist)),
5238 initlist);
5240 entries = TREE_CHAIN (entries);
5242 while (entries);
5244 return objc_build_constructor (build_array_type (type, 0),
5245 nreverse (initlist));
5248 /* To accomplish method prototyping without generating all kinds of
5249 inane warnings, the definition of the dispatch table entries were
5250 changed from:
5252 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5254 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5256 static tree
5257 build_method_template (void)
5259 tree _SLT_record;
5260 tree field_decl, field_decl_chain;
5262 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5264 /* SEL _cmd; */
5265 field_decl = create_field_decl (objc_selector_type, "_cmd");
5266 field_decl_chain = field_decl;
5268 /* char *method_types; */
5269 field_decl = create_field_decl (string_type_node, "method_types");
5270 chainon (field_decl_chain, field_decl);
5272 /* void *_imp; */
5273 field_decl = create_field_decl (build_pointer_type (void_type_node),
5274 "_imp");
5275 chainon (field_decl_chain, field_decl);
5277 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5279 return _SLT_record;
5283 static tree
5284 generate_dispatch_table (tree type, const char *name, int size, tree list)
5286 tree decl, initlist;
5288 decl = start_var_decl (type, synth_id_with_class_suffix
5289 (name, objc_implementation_context));
5291 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5292 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5293 initlist = tree_cons (NULL_TREE, list, initlist);
5295 finish_var_decl (decl,
5296 objc_build_constructor (TREE_TYPE (decl),
5297 nreverse (initlist)));
5299 return decl;
5302 static void
5303 mark_referenced_methods (void)
5305 struct imp_entry *impent;
5306 tree chain;
5308 for (impent = imp_list; impent; impent = impent->next)
5310 chain = CLASS_CLS_METHODS (impent->imp_context);
5311 while (chain)
5313 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5314 chain = TREE_CHAIN (chain);
5317 chain = CLASS_NST_METHODS (impent->imp_context);
5318 while (chain)
5320 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5321 chain = TREE_CHAIN (chain);
5326 static void
5327 generate_dispatch_tables (void)
5329 tree initlist, chain, method_list_template;
5330 int size;
5332 if (!objc_method_template)
5333 objc_method_template = build_method_template ();
5335 chain = CLASS_CLS_METHODS (objc_implementation_context);
5336 if (chain)
5338 size = list_length (chain);
5340 method_list_template
5341 = build_method_list_template (objc_method_template, size);
5342 initlist
5343 = build_dispatch_table_initializer (objc_method_template, chain);
5345 UOBJC_CLASS_METHODS_decl
5346 = generate_dispatch_table (method_list_template,
5347 ((TREE_CODE (objc_implementation_context)
5348 == CLASS_IMPLEMENTATION_TYPE)
5349 ? "_OBJC_CLASS_METHODS"
5350 : "_OBJC_CATEGORY_CLASS_METHODS"),
5351 size, initlist);
5353 else
5354 UOBJC_CLASS_METHODS_decl = 0;
5356 chain = CLASS_NST_METHODS (objc_implementation_context);
5357 if (chain)
5359 size = list_length (chain);
5361 method_list_template
5362 = build_method_list_template (objc_method_template, size);
5363 initlist
5364 = build_dispatch_table_initializer (objc_method_template, chain);
5366 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5367 UOBJC_INSTANCE_METHODS_decl
5368 = generate_dispatch_table (method_list_template,
5369 "_OBJC_INSTANCE_METHODS",
5370 size, initlist);
5371 else
5372 /* We have a category. */
5373 UOBJC_INSTANCE_METHODS_decl
5374 = generate_dispatch_table (method_list_template,
5375 "_OBJC_CATEGORY_INSTANCE_METHODS",
5376 size, initlist);
5378 else
5379 UOBJC_INSTANCE_METHODS_decl = 0;
5382 static tree
5383 generate_protocol_list (tree i_or_p)
5385 tree initlist;
5386 tree refs_decl, lproto, e, plist;
5387 int size = 0;
5388 const char *ref_name;
5390 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5391 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5392 plist = CLASS_PROTOCOL_LIST (i_or_p);
5393 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5394 plist = PROTOCOL_LIST (i_or_p);
5395 else
5396 abort ();
5398 /* Compute size. */
5399 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5400 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5401 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5402 size++;
5404 /* Build initializer. */
5405 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5406 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5407 initlist = tree_cons (NULL_TREE, e, initlist);
5409 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5411 tree pval = TREE_VALUE (lproto);
5413 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5414 && PROTOCOL_FORWARD_DECL (pval))
5416 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5417 initlist = tree_cons (NULL_TREE, e, initlist);
5421 /* static struct objc_protocol *refs[n]; */
5423 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5424 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5425 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5426 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5427 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5428 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5429 else
5430 abort ();
5432 refs_decl = start_var_decl
5433 (build_array_type
5434 (build_pointer_type (objc_protocol_template),
5435 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5436 ref_name);
5438 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5439 nreverse (initlist)));
5441 return refs_decl;
5444 static tree
5445 build_category_initializer (tree type, tree cat_name, tree class_name,
5446 tree instance_methods, tree class_methods,
5447 tree protocol_list)
5449 tree initlist = NULL_TREE, expr;
5451 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5452 initlist = tree_cons (NULL_TREE, class_name, initlist);
5454 if (!instance_methods)
5455 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5456 else
5458 expr = convert (objc_method_list_ptr,
5459 build_unary_op (ADDR_EXPR, instance_methods, 0));
5460 initlist = tree_cons (NULL_TREE, expr, initlist);
5462 if (!class_methods)
5463 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5464 else
5466 expr = convert (objc_method_list_ptr,
5467 build_unary_op (ADDR_EXPR, class_methods, 0));
5468 initlist = tree_cons (NULL_TREE, expr, initlist);
5471 /* protocol_list = */
5472 if (!protocol_list)
5473 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5474 else
5476 expr = convert (build_pointer_type
5477 (build_pointer_type
5478 (objc_protocol_template)),
5479 build_unary_op (ADDR_EXPR, protocol_list, 0));
5480 initlist = tree_cons (NULL_TREE, expr, initlist);
5483 return objc_build_constructor (type, nreverse (initlist));
5486 /* struct _objc_class {
5487 struct objc_class *isa;
5488 struct objc_class *super_class;
5489 char *name;
5490 long version;
5491 long info;
5492 long instance_size;
5493 struct objc_ivar_list *ivars;
5494 struct objc_method_list *methods;
5495 if (flag_next_runtime)
5496 struct objc_cache *cache;
5497 else {
5498 struct sarray *dtable;
5499 struct objc_class *subclass_list;
5500 struct objc_class *sibling_class;
5502 struct objc_protocol_list *protocols;
5503 if (flag_next_runtime)
5504 void *sel_id;
5505 void *gc_object_type;
5506 }; */
5508 static tree
5509 build_shared_structure_initializer (tree type, tree isa, tree super,
5510 tree name, tree size, int status,
5511 tree dispatch_table, tree ivar_list,
5512 tree protocol_list)
5514 tree initlist = NULL_TREE, expr;
5516 /* isa = */
5517 initlist = tree_cons (NULL_TREE, isa, initlist);
5519 /* super_class = */
5520 initlist = tree_cons (NULL_TREE, super, initlist);
5522 /* name = */
5523 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5525 /* version = */
5526 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5527 initlist);
5529 /* info = */
5530 initlist = tree_cons (NULL_TREE,
5531 build_int_cst (long_integer_type_node, status),
5532 initlist);
5534 /* instance_size = */
5535 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5536 initlist);
5538 /* objc_ivar_list = */
5539 if (!ivar_list)
5540 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5541 else
5543 expr = convert (objc_ivar_list_ptr,
5544 build_unary_op (ADDR_EXPR, ivar_list, 0));
5545 initlist = tree_cons (NULL_TREE, expr, initlist);
5548 /* objc_method_list = */
5549 if (!dispatch_table)
5550 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5551 else
5553 expr = convert (objc_method_list_ptr,
5554 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5555 initlist = tree_cons (NULL_TREE, expr, initlist);
5558 if (flag_next_runtime)
5559 /* method_cache = */
5560 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5561 else
5563 /* dtable = */
5564 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5566 /* subclass_list = */
5567 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5569 /* sibling_class = */
5570 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5573 /* protocol_list = */
5574 if (! protocol_list)
5575 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5576 else
5578 expr = convert (build_pointer_type
5579 (build_pointer_type
5580 (objc_protocol_template)),
5581 build_unary_op (ADDR_EXPR, protocol_list, 0));
5582 initlist = tree_cons (NULL_TREE, expr, initlist);
5585 if (flag_next_runtime)
5586 /* sel_id = NULL */
5587 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5589 /* gc_object_type = NULL */
5590 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5592 return objc_build_constructor (type, nreverse (initlist));
5595 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5597 static inline tree
5598 lookup_category (tree class, tree cat_name)
5600 tree category = CLASS_CATEGORY_LIST (class);
5602 while (category && CLASS_SUPER_NAME (category) != cat_name)
5603 category = CLASS_CATEGORY_LIST (category);
5604 return category;
5607 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5609 static void
5610 generate_category (tree cat)
5612 tree decl;
5613 tree initlist, cat_name_expr, class_name_expr;
5614 tree protocol_decl, category;
5616 add_class_reference (CLASS_NAME (cat));
5617 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5619 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5621 category = lookup_category (implementation_template,
5622 CLASS_SUPER_NAME (cat));
5624 if (category && CLASS_PROTOCOL_LIST (category))
5626 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5627 protocol_decl = generate_protocol_list (category);
5629 else
5630 protocol_decl = 0;
5632 decl = start_var_decl (objc_category_template,
5633 synth_id_with_class_suffix
5634 ("_OBJC_CATEGORY", objc_implementation_context));
5636 initlist = build_category_initializer (TREE_TYPE (decl),
5637 cat_name_expr, class_name_expr,
5638 UOBJC_INSTANCE_METHODS_decl,
5639 UOBJC_CLASS_METHODS_decl,
5640 protocol_decl);
5642 finish_var_decl (decl, initlist);
5645 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5646 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5648 static void
5649 generate_shared_structures (int cls_flags)
5651 tree sc_spec, decl_specs, decl;
5652 tree name_expr, super_expr, root_expr;
5653 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5654 tree cast_type, initlist, protocol_decl;
5656 my_super_id = CLASS_SUPER_NAME (implementation_template);
5657 if (my_super_id)
5659 add_class_reference (my_super_id);
5661 /* Compute "my_root_id" - this is required for code generation.
5662 the "isa" for all meta class structures points to the root of
5663 the inheritance hierarchy (e.g. "__Object")... */
5664 my_root_id = my_super_id;
5667 tree my_root_int = lookup_interface (my_root_id);
5669 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5670 my_root_id = CLASS_SUPER_NAME (my_root_int);
5671 else
5672 break;
5674 while (1);
5676 else
5677 /* No super class. */
5678 my_root_id = CLASS_NAME (implementation_template);
5680 cast_type = build_pointer_type (objc_class_template);
5681 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5682 class_names);
5684 /* Install class `isa' and `super' pointers at runtime. */
5685 if (my_super_id)
5687 super_expr = add_objc_string (my_super_id, class_names);
5688 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5690 else
5691 super_expr = build_int_cst (NULL_TREE, 0);
5693 root_expr = add_objc_string (my_root_id, class_names);
5694 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5696 if (CLASS_PROTOCOL_LIST (implementation_template))
5698 generate_protocol_references
5699 (CLASS_PROTOCOL_LIST (implementation_template));
5700 protocol_decl = generate_protocol_list (implementation_template);
5702 else
5703 protocol_decl = 0;
5705 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5707 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5708 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5710 decl = start_var_decl (objc_class_template,
5711 IDENTIFIER_POINTER
5712 (DECL_NAME (UOBJC_METACLASS_decl)));
5714 initlist
5715 = build_shared_structure_initializer
5716 (TREE_TYPE (decl),
5717 root_expr, super_expr, name_expr,
5718 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5719 2 /*CLS_META*/,
5720 UOBJC_CLASS_METHODS_decl,
5721 UOBJC_CLASS_VARIABLES_decl,
5722 protocol_decl);
5724 finish_var_decl (decl, initlist);
5726 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5728 decl = start_var_decl (objc_class_template,
5729 IDENTIFIER_POINTER
5730 (DECL_NAME (UOBJC_CLASS_decl)));
5732 initlist
5733 = build_shared_structure_initializer
5734 (TREE_TYPE (decl),
5735 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5736 super_expr, name_expr,
5737 convert (integer_type_node,
5738 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5739 (implementation_template))),
5740 1 /*CLS_FACTORY*/ | cls_flags,
5741 UOBJC_INSTANCE_METHODS_decl,
5742 UOBJC_INSTANCE_VARIABLES_decl,
5743 protocol_decl);
5745 finish_var_decl (decl, initlist);
5749 static const char *
5750 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5752 static char string[BUFSIZE];
5754 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5755 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5757 sprintf (string, "%s_%s", preamble,
5758 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5760 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5761 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5763 /* We have a category. */
5764 const char *const class_name
5765 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5766 const char *const class_super_name
5767 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5768 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5770 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5772 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5773 sprintf (string, "%s_%s", preamble, protocol_name);
5775 else
5776 abort ();
5778 return string;
5781 /* If type is empty or only type qualifiers are present, add default
5782 type of id (otherwise grokdeclarator will default to int). */
5784 static tree
5785 adjust_type_for_id_default (tree type)
5787 if (!type)
5788 type = make_node (TREE_LIST);
5790 if (!TREE_VALUE (type))
5791 TREE_VALUE (type) = objc_object_type;
5792 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5793 && TYPED_OBJECT (TREE_VALUE (type)))
5794 error ("can not use an object as parameter to a method");
5796 return type;
5799 /* Usage:
5800 keyworddecl:
5801 selector ':' '(' typename ')' identifier
5803 Purpose:
5804 Transform an Objective-C keyword argument into
5805 the C equivalent parameter declarator.
5807 In: key_name, an "identifier_node" (optional).
5808 arg_type, a "tree_list" (optional).
5809 arg_name, an "identifier_node".
5811 Note: It would be really nice to strongly type the preceding
5812 arguments in the function prototype; however, then I
5813 could not use the "accessor" macros defined in "tree.h".
5815 Out: an instance of "keyword_decl". */
5817 tree
5818 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5820 tree keyword_decl;
5822 /* If no type is specified, default to "id". */
5823 arg_type = adjust_type_for_id_default (arg_type);
5825 keyword_decl = make_node (KEYWORD_DECL);
5827 TREE_TYPE (keyword_decl) = arg_type;
5828 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5829 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5831 return keyword_decl;
5834 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5836 static tree
5837 build_keyword_selector (tree selector)
5839 int len = 0;
5840 tree key_chain, key_name;
5841 char *buf;
5843 /* Scan the selector to see how much space we'll need. */
5844 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5846 if (TREE_CODE (selector) == KEYWORD_DECL)
5847 key_name = KEYWORD_KEY_NAME (key_chain);
5848 else if (TREE_CODE (selector) == TREE_LIST)
5849 key_name = TREE_PURPOSE (key_chain);
5850 else
5851 abort ();
5853 if (key_name)
5854 len += IDENTIFIER_LENGTH (key_name) + 1;
5855 else
5856 /* Just a ':' arg. */
5857 len++;
5860 buf = (char *) alloca (len + 1);
5861 /* Start the buffer out as an empty string. */
5862 buf[0] = '\0';
5864 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5866 if (TREE_CODE (selector) == KEYWORD_DECL)
5867 key_name = KEYWORD_KEY_NAME (key_chain);
5868 else if (TREE_CODE (selector) == TREE_LIST)
5870 key_name = TREE_PURPOSE (key_chain);
5871 /* The keyword decl chain will later be used as a function argument
5872 chain. Unhook the selector itself so as to not confuse other
5873 parts of the compiler. */
5874 TREE_PURPOSE (key_chain) = NULL_TREE;
5876 else
5877 abort ();
5879 if (key_name)
5880 strcat (buf, IDENTIFIER_POINTER (key_name));
5881 strcat (buf, ":");
5884 return get_identifier (buf);
5887 /* Used for declarations and definitions. */
5889 static tree
5890 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5891 tree add_args, bool ellipsis)
5893 tree method_decl;
5895 /* If no type is specified, default to "id". */
5896 ret_type = adjust_type_for_id_default (ret_type);
5898 method_decl = make_node (code);
5899 TREE_TYPE (method_decl) = ret_type;
5901 /* If we have a keyword selector, create an identifier_node that
5902 represents the full selector name (`:' included)... */
5903 if (TREE_CODE (selector) == KEYWORD_DECL)
5905 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5906 METHOD_SEL_ARGS (method_decl) = selector;
5907 METHOD_ADD_ARGS (method_decl) = add_args;
5908 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5910 else
5912 METHOD_SEL_NAME (method_decl) = selector;
5913 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5914 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5917 return method_decl;
5920 #define METHOD_DEF 0
5921 #define METHOD_REF 1
5923 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5924 an argument list for method METH. CONTEXT is either METHOD_DEF or
5925 METHOD_REF, saying whether we are trying to define a method or call
5926 one. SUPERFLAG says this is for a send to super; this makes a
5927 difference for the NeXT calling sequence in which the lookup and
5928 the method call are done together. If METH is null, user-defined
5929 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5931 static tree
5932 get_arg_type_list (tree meth, int context, int superflag)
5934 tree arglist, akey;
5936 /* Receiver type. */
5937 if (flag_next_runtime && superflag)
5938 arglist = build_tree_list (NULL_TREE, objc_super_type);
5939 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5940 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5941 else
5942 arglist = build_tree_list (NULL_TREE, objc_object_type);
5944 /* Selector type - will eventually change to `int'. */
5945 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5947 /* No actual method prototype given -- assume that remaining arguments
5948 are `...'. */
5949 if (!meth)
5950 return arglist;
5952 /* Build a list of argument types. */
5953 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5955 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5957 /* Decay arrays and functions into pointers. */
5958 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5959 arg_type = build_pointer_type (TREE_TYPE (arg_type));
5960 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
5961 arg_type = build_pointer_type (arg_type);
5963 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5966 if (METHOD_ADD_ARGS (meth))
5968 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5969 akey; akey = TREE_CHAIN (akey))
5971 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5973 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5976 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
5977 goto lack_of_ellipsis;
5979 else
5981 lack_of_ellipsis:
5982 chainon (arglist, OBJC_VOID_AT_END);
5985 return arglist;
5988 static tree
5989 check_duplicates (hash hsh, int methods, int is_class)
5991 tree meth = NULL_TREE;
5993 if (hsh)
5995 meth = hsh->key;
5997 if (hsh->list)
5999 /* We have two or more methods with the same name but
6000 different types. */
6001 attr loop;
6003 /* But just how different are those types? If
6004 -Wno-strict-selector-match is specified, we shall not
6005 complain if the differences are solely among types with
6006 identical size and alignment. */
6007 if (!warn_strict_selector_match)
6009 for (loop = hsh->list; loop; loop = loop->next)
6010 if (!comp_proto_with_proto (meth, loop->value, 0))
6011 goto issue_warning;
6013 return meth;
6016 issue_warning:
6017 warning (0, "multiple %s named %<%c%s%> found",
6018 methods ? "methods" : "selectors",
6019 (is_class ? '+' : '-'),
6020 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6022 warn_with_method (methods ? "using" : "found",
6023 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6024 ? '-'
6025 : '+'),
6026 meth);
6027 for (loop = hsh->list; loop; loop = loop->next)
6028 warn_with_method ("also found",
6029 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6030 ? '-'
6031 : '+'),
6032 loop->value);
6035 return meth;
6038 /* If RECEIVER is a class reference, return the identifier node for
6039 the referenced class. RECEIVER is created by objc_get_class_reference,
6040 so we check the exact form created depending on which runtimes are
6041 used. */
6043 static tree
6044 receiver_is_class_object (tree receiver, int self, int super)
6046 tree chain, exp, arg;
6048 /* The receiver is 'self' or 'super' in the context of a class method. */
6049 if (objc_method_context
6050 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6051 && (self || super))
6052 return (super
6053 ? CLASS_SUPER_NAME (implementation_template)
6054 : CLASS_NAME (implementation_template));
6056 if (flag_next_runtime)
6058 /* The receiver is a variable created by
6059 build_class_reference_decl. */
6060 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6061 /* Look up the identifier. */
6062 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6063 if (TREE_PURPOSE (chain) == receiver)
6064 return TREE_VALUE (chain);
6067 /* The receiver is a function call that returns an id. Check if
6068 it is a call to objc_getClass, if so, pick up the class name. */
6069 if (TREE_CODE (receiver) == CALL_EXPR
6070 && (exp = TREE_OPERAND (receiver, 0))
6071 && TREE_CODE (exp) == ADDR_EXPR
6072 && (exp = TREE_OPERAND (exp, 0))
6073 && TREE_CODE (exp) == FUNCTION_DECL
6074 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6075 prototypes for objc_get_class(). Thankfully, they seem to share the
6076 same function type. */
6077 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6078 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6079 /* We have a call to objc_get_class/objc_getClass! */
6080 && (arg = TREE_OPERAND (receiver, 1))
6081 && TREE_CODE (arg) == TREE_LIST
6082 && (arg = TREE_VALUE (arg)))
6084 STRIP_NOPS (arg);
6085 if (TREE_CODE (arg) == ADDR_EXPR
6086 && (arg = TREE_OPERAND (arg, 0))
6087 && TREE_CODE (arg) == STRING_CST)
6088 /* Finally, we have the class name. */
6089 return get_identifier (TREE_STRING_POINTER (arg));
6091 return 0;
6094 /* If we are currently building a message expr, this holds
6095 the identifier of the selector of the message. This is
6096 used when printing warnings about argument mismatches. */
6098 static tree current_objc_message_selector = 0;
6100 tree
6101 objc_message_selector (void)
6103 return current_objc_message_selector;
6106 /* Construct an expression for sending a message.
6107 MESS has the object to send to in TREE_PURPOSE
6108 and the argument list (including selector) in TREE_VALUE.
6110 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6111 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6113 tree
6114 objc_build_message_expr (tree mess)
6116 tree receiver = TREE_PURPOSE (mess);
6117 tree sel_name;
6118 #ifdef OBJCPLUS
6119 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6120 #else
6121 tree args = TREE_VALUE (mess);
6122 #endif
6123 tree method_params = NULL_TREE;
6125 if (TREE_CODE (receiver) == ERROR_MARK)
6126 return error_mark_node;
6128 /* Obtain the full selector name. */
6129 if (TREE_CODE (args) == IDENTIFIER_NODE)
6130 /* A unary selector. */
6131 sel_name = args;
6132 else if (TREE_CODE (args) == TREE_LIST)
6133 sel_name = build_keyword_selector (args);
6134 else
6135 abort ();
6137 /* Build the parameter list to give to the method. */
6138 if (TREE_CODE (args) == TREE_LIST)
6139 #ifdef OBJCPLUS
6140 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6141 #else
6143 tree chain = args, prev = NULL_TREE;
6145 /* We have a keyword selector--check for comma expressions. */
6146 while (chain)
6148 tree element = TREE_VALUE (chain);
6150 /* We have a comma expression, must collapse... */
6151 if (TREE_CODE (element) == TREE_LIST)
6153 if (prev)
6154 TREE_CHAIN (prev) = element;
6155 else
6156 args = element;
6158 prev = chain;
6159 chain = TREE_CHAIN (chain);
6161 method_params = args;
6163 #endif
6165 #ifdef OBJCPLUS
6166 if (processing_template_decl)
6167 /* Must wait until template instantiation time. */
6168 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6169 method_params);
6170 #endif
6172 return objc_finish_message_expr (receiver, sel_name, method_params);
6175 /* Look up method SEL_NAME that would be suitable for receiver
6176 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6177 nonzero), and report on any duplicates. */
6179 static tree
6180 lookup_method_in_hash_lists (tree sel_name, int is_class)
6182 hash method_prototype = NULL;
6184 if (!is_class)
6185 method_prototype = hash_lookup (nst_method_hash_list,
6186 sel_name);
6188 if (!method_prototype)
6190 method_prototype = hash_lookup (cls_method_hash_list,
6191 sel_name);
6192 is_class = 1;
6195 return check_duplicates (method_prototype, 1, is_class);
6198 /* The 'objc_finish_message_expr' routine is called from within
6199 'objc_build_message_expr' for non-template functions. In the case of
6200 C++ template functions, it is called from 'build_expr_from_tree'
6201 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6203 tree
6204 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6206 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6207 tree selector, retval, class_tree;
6208 int self, super, have_cast;
6210 /* Extract the receiver of the message, as well as its type
6211 (where the latter may take the form of a cast or be inferred
6212 from the implementation context). */
6213 rtype = receiver;
6214 while (TREE_CODE (rtype) == COMPOUND_EXPR
6215 || TREE_CODE (rtype) == MODIFY_EXPR
6216 || TREE_CODE (rtype) == NOP_EXPR
6217 || TREE_CODE (rtype) == CONVERT_EXPR
6218 || TREE_CODE (rtype) == COMPONENT_REF)
6219 rtype = TREE_OPERAND (rtype, 0);
6220 self = (rtype == self_decl);
6221 super = (rtype == UOBJC_SUPER_decl);
6222 rtype = TREE_TYPE (receiver);
6223 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6224 || (TREE_CODE (receiver) == COMPOUND_EXPR
6225 && !IS_SUPER (rtype)));
6227 /* If we are calling [super dealloc], reset our warning flag. */
6228 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6229 should_call_super_dealloc = 0;
6231 /* If the receiver is a class object, retrieve the corresponding
6232 @interface, if one exists. */
6233 class_tree = receiver_is_class_object (receiver, self, super);
6235 /* Now determine the receiver type (if an explicit cast has not been
6236 provided). */
6237 if (!have_cast)
6239 if (class_tree)
6240 rtype = lookup_interface (class_tree);
6241 /* Handle `self' and `super'. */
6242 else if (super)
6244 if (!CLASS_SUPER_NAME (implementation_template))
6246 error ("no super class declared in @interface for %qs",
6247 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6248 return error_mark_node;
6250 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6252 else if (self)
6253 rtype = lookup_interface (CLASS_NAME (implementation_template));
6256 /* If receiver is of type `id' or `Class' (or if the @interface for a
6257 class is not visible), we shall be satisfied with the existence of
6258 any instance or class method. */
6259 if (objc_is_id (rtype))
6261 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6262 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6263 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6264 : NULL_TREE);
6265 rtype = NULL_TREE;
6267 if (rprotos)
6269 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6270 in protocols themselves for the method prototype. */
6271 method_prototype
6272 = lookup_method_in_protocol_list (rprotos, sel_name,
6273 class_tree != NULL_TREE);
6275 /* If messaging 'Class <Proto>' but did not find a class method
6276 prototype, search for an instance method instead, and warn
6277 about having done so. */
6278 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6280 method_prototype
6281 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6283 if (method_prototype)
6284 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6285 IDENTIFIER_POINTER (sel_name),
6286 IDENTIFIER_POINTER (sel_name));
6290 else if (rtype)
6292 tree orig_rtype = rtype, saved_rtype;
6294 if (TREE_CODE (rtype) == POINTER_TYPE)
6295 rtype = TREE_TYPE (rtype);
6296 /* Traverse typedef aliases */
6297 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6298 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6299 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6300 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6301 saved_rtype = rtype;
6302 if (TYPED_OBJECT (rtype))
6304 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6305 rtype = TYPE_OBJC_INTERFACE (rtype);
6307 /* If we could not find an @interface declaration, we must have
6308 only seen a @class declaration; so, we cannot say anything
6309 more intelligent about which methods the receiver will
6310 understand. */
6311 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6312 rtype = NULL_TREE;
6313 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6314 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6316 /* We have a valid ObjC class name. Look up the method name
6317 in the published @interface for the class (and its
6318 superclasses). */
6319 method_prototype
6320 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6322 /* If the method was not found in the @interface, it may still
6323 exist locally as part of the @implementation. */
6324 if (!method_prototype && objc_implementation_context
6325 && CLASS_NAME (objc_implementation_context)
6326 == OBJC_TYPE_NAME (rtype))
6327 method_prototype
6328 = lookup_method
6329 ((class_tree
6330 ? CLASS_CLS_METHODS (objc_implementation_context)
6331 : CLASS_NST_METHODS (objc_implementation_context)),
6332 sel_name);
6334 /* If we haven't found a candidate method by now, try looking for
6335 it in the protocol list. */
6336 if (!method_prototype && rprotos)
6337 method_prototype
6338 = lookup_method_in_protocol_list (rprotos, sel_name,
6339 class_tree != NULL_TREE);
6341 else
6343 warning (0, "invalid receiver type %qs",
6344 gen_type_name (orig_rtype));
6345 /* After issuing the "invalid receiver" warning, perform method
6346 lookup as if we were messaging 'id'. */
6347 rtype = rprotos = NULL_TREE;
6352 /* For 'id' or 'Class' receivers, search in the global hash table
6353 as a last resort. For all receivers, warn if protocol searches
6354 have failed. */
6355 if (!method_prototype)
6357 if (rprotos)
6358 warning (0, "%<%c%s%> not found in protocol(s)",
6359 (class_tree ? '+' : '-'),
6360 IDENTIFIER_POINTER (sel_name));
6362 if (!rtype)
6363 method_prototype
6364 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6367 if (!method_prototype)
6369 static bool warn_missing_methods = false;
6371 if (rtype)
6372 warning (0, "%qs may not respond to %<%c%s%>",
6373 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6374 (class_tree ? '+' : '-'),
6375 IDENTIFIER_POINTER (sel_name));
6376 /* If we are messaging an 'id' or 'Class' object and made it here,
6377 then we have failed to find _any_ instance or class method,
6378 respectively. */
6379 else
6380 warning (0, "no %<%c%s%> method found",
6381 (class_tree ? '+' : '-'),
6382 IDENTIFIER_POINTER (sel_name));
6384 if (!warn_missing_methods)
6386 warning (0, "(Messages without a matching method signature");
6387 warning (0, "will be assumed to return %<id%> and accept");
6388 warning (0, "%<...%> as arguments.)");
6389 warn_missing_methods = true;
6393 /* Save the selector name for printing error messages. */
6394 current_objc_message_selector = sel_name;
6396 /* Build the parameters list for looking up the method.
6397 These are the object itself and the selector. */
6399 if (flag_typed_selectors)
6400 selector = build_typed_selector_reference (sel_name, method_prototype);
6401 else
6402 selector = build_selector_reference (sel_name);
6404 retval = build_objc_method_call (super, method_prototype,
6405 receiver,
6406 selector, method_params);
6408 current_objc_message_selector = 0;
6410 return retval;
6413 /* Build a tree expression to send OBJECT the operation SELECTOR,
6414 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6415 assuming the method has prototype METHOD_PROTOTYPE.
6416 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6417 Use METHOD_PARAMS as list of args to pass to the method.
6418 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6420 static tree
6421 build_objc_method_call (int super_flag, tree method_prototype,
6422 tree lookup_object, tree selector,
6423 tree method_params)
6425 tree sender = (super_flag ? umsg_super_decl :
6426 (!flag_next_runtime || flag_nil_receivers
6427 ? (flag_objc_direct_dispatch
6428 ? umsg_fast_decl
6429 : umsg_decl)
6430 : umsg_nonnil_decl));
6431 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6433 /* If a prototype for the method to be called exists, then cast
6434 the sender's return type and arguments to match that of the method.
6435 Otherwise, leave sender as is. */
6436 tree ret_type
6437 = (method_prototype
6438 ? TREE_VALUE (TREE_TYPE (method_prototype))
6439 : objc_object_type);
6440 tree sender_cast
6441 = build_pointer_type
6442 (build_function_type
6443 (ret_type,
6444 get_arg_type_list
6445 (method_prototype, METHOD_REF, super_flag)));
6446 tree method, t;
6448 lookup_object = build_c_cast (rcv_p, lookup_object);
6450 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6451 lookup_object = save_expr (lookup_object);
6453 if (flag_next_runtime)
6455 /* If we are returning a struct in memory, and the address
6456 of that memory location is passed as a hidden first
6457 argument, then change which messenger entry point this
6458 expr will call. NB: Note that sender_cast remains
6459 unchanged (it already has a struct return type). */
6460 if (!targetm.calls.struct_value_rtx (0, 0)
6461 && (TREE_CODE (ret_type) == RECORD_TYPE
6462 || TREE_CODE (ret_type) == UNION_TYPE)
6463 && targetm.calls.return_in_memory (ret_type, 0))
6464 sender = (super_flag ? umsg_super_stret_decl :
6465 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6467 method_params = tree_cons (NULL_TREE, lookup_object,
6468 tree_cons (NULL_TREE, selector,
6469 method_params));
6470 method = build_fold_addr_expr (sender);
6472 else
6474 /* This is the portable (GNU) way. */
6475 tree object;
6477 /* First, call the lookup function to get a pointer to the method,
6478 then cast the pointer, then call it with the method arguments. */
6480 object = (super_flag ? self_decl : lookup_object);
6482 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6483 t = tree_cons (NULL_TREE, lookup_object, t);
6484 method = build_function_call (sender, t);
6486 /* Pass the object to the method. */
6487 method_params = tree_cons (NULL_TREE, object,
6488 tree_cons (NULL_TREE, selector,
6489 method_params));
6492 /* ??? Selector is not at this point something we can use inside
6493 the compiler itself. Set it to garbage for the nonce. */
6494 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6495 return build_function_call (t, method_params);
6498 static void
6499 build_protocol_reference (tree p)
6501 tree decl;
6502 const char *proto_name;
6504 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6506 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6507 decl = start_var_decl (objc_protocol_template, proto_name);
6509 PROTOCOL_FORWARD_DECL (p) = decl;
6512 /* This function is called by the parser when (and only when) a
6513 @protocol() expression is found, in order to compile it. */
6514 tree
6515 objc_build_protocol_expr (tree protoname)
6517 tree expr;
6518 tree p = lookup_protocol (protoname);
6520 if (!p)
6522 error ("cannot find protocol declaration for %qs",
6523 IDENTIFIER_POINTER (protoname));
6524 return error_mark_node;
6527 if (!PROTOCOL_FORWARD_DECL (p))
6528 build_protocol_reference (p);
6530 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6532 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6533 if we have it, rather than converting it here. */
6534 expr = convert (objc_protocol_type, expr);
6536 /* The @protocol() expression is being compiled into a pointer to a
6537 statically allocated instance of the Protocol class. To become
6538 usable at runtime, the 'isa' pointer of the instance need to be
6539 fixed up at runtime by the runtime library, to point to the
6540 actual 'Protocol' class. */
6542 /* For the GNU runtime, put the static Protocol instance in the list
6543 of statically allocated instances, so that we make sure that its
6544 'isa' pointer is fixed up at runtime by the GNU runtime library
6545 to point to the Protocol class (at runtime, when loading the
6546 module, the GNU runtime library loops on the statically allocated
6547 instances (as found in the defs field in objc_symtab) and fixups
6548 all the 'isa' pointers of those objects). */
6549 if (! flag_next_runtime)
6551 /* This type is a struct containing the fields of a Protocol
6552 object. (Cfr. objc_protocol_type instead is the type of a pointer
6553 to such a struct). */
6554 tree protocol_struct_type = xref_tag
6555 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6556 tree *chain;
6558 /* Look for the list of Protocol statically allocated instances
6559 to fixup at runtime. Create a new list to hold Protocol
6560 statically allocated instances, if the list is not found. At
6561 present there is only another list, holding NSConstantString
6562 static instances to be fixed up at runtime. */
6563 for (chain = &objc_static_instances;
6564 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6565 chain = &TREE_CHAIN (*chain));
6566 if (!*chain)
6568 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6569 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6570 class_names);
6573 /* Add this statically allocated instance to the Protocol list. */
6574 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6575 PROTOCOL_FORWARD_DECL (p),
6576 TREE_PURPOSE (*chain));
6580 return expr;
6583 /* This function is called by the parser when a @selector() expression
6584 is found, in order to compile it. It is only called by the parser
6585 and only to compile a @selector(). */
6586 tree
6587 objc_build_selector_expr (tree selnamelist)
6589 tree selname;
6591 /* Obtain the full selector name. */
6592 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6593 /* A unary selector. */
6594 selname = selnamelist;
6595 else if (TREE_CODE (selnamelist) == TREE_LIST)
6596 selname = build_keyword_selector (selnamelist);
6597 else
6598 abort ();
6600 /* If we are required to check @selector() expressions as they
6601 are found, check that the selector has been declared. */
6602 if (warn_undeclared_selector)
6604 /* Look the selector up in the list of all known class and
6605 instance methods (up to this line) to check that the selector
6606 exists. */
6607 hash hsh;
6609 /* First try with instance methods. */
6610 hsh = hash_lookup (nst_method_hash_list, selname);
6612 /* If not found, try with class methods. */
6613 if (!hsh)
6615 hsh = hash_lookup (cls_method_hash_list, selname);
6618 /* If still not found, print out a warning. */
6619 if (!hsh)
6621 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6626 if (flag_typed_selectors)
6627 return build_typed_selector_reference (selname, 0);
6628 else
6629 return build_selector_reference (selname);
6632 tree
6633 objc_build_encode_expr (tree type)
6635 tree result;
6636 const char *string;
6638 encode_type (type, obstack_object_size (&util_obstack),
6639 OBJC_ENCODE_INLINE_DEFS);
6640 obstack_1grow (&util_obstack, 0); /* null terminate string */
6641 string = obstack_finish (&util_obstack);
6643 /* Synthesize a string that represents the encoded struct/union. */
6644 result = my_build_string (strlen (string) + 1, string);
6645 obstack_free (&util_obstack, util_firstobj);
6646 return result;
6649 static tree
6650 build_ivar_reference (tree id)
6652 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6654 /* Historically, a class method that produced objects (factory
6655 method) would assign `self' to the instance that it
6656 allocated. This would effectively turn the class method into
6657 an instance method. Following this assignment, the instance
6658 variables could be accessed. That practice, while safe,
6659 violates the simple rule that a class method should not refer
6660 to an instance variable. It's better to catch the cases
6661 where this is done unknowingly than to support the above
6662 paradigm. */
6663 warning (0, "instance variable %qs accessed in class method",
6664 IDENTIFIER_POINTER (id));
6665 self_decl = convert (objc_instance_type, self_decl); /* cast */
6668 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6671 /* Compute a hash value for a given method SEL_NAME. */
6673 static size_t
6674 hash_func (tree sel_name)
6676 const unsigned char *s
6677 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6678 size_t h = 0;
6680 while (*s)
6681 h = h * 67 + *s++ - 113;
6682 return h;
6685 static void
6686 hash_init (void)
6688 nst_method_hash_list
6689 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6690 cls_method_hash_list
6691 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6693 /* Initialize the hash table used to hold the constant string objects. */
6694 string_htab = htab_create_ggc (31, string_hash,
6695 string_eq, NULL);
6697 /* Initialize the hash table used to hold EH-volatilized types. */
6698 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6699 volatilized_eq, NULL);
6702 /* WARNING!!!! hash_enter is called with a method, and will peek
6703 inside to find its selector! But hash_lookup is given a selector
6704 directly, and looks for the selector that's inside the found
6705 entry's key (method) for comparison. */
6707 static void
6708 hash_enter (hash *hashlist, tree method)
6710 hash obj;
6711 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6713 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6714 obj->list = 0;
6715 obj->next = hashlist[slot];
6716 obj->key = method;
6718 hashlist[slot] = obj; /* append to front */
6721 static hash
6722 hash_lookup (hash *hashlist, tree sel_name)
6724 hash target;
6726 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6728 while (target)
6730 if (sel_name == METHOD_SEL_NAME (target->key))
6731 return target;
6733 target = target->next;
6735 return 0;
6738 static void
6739 hash_add_attr (hash entry, tree value)
6741 attr obj;
6743 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6744 obj->next = entry->list;
6745 obj->value = value;
6747 entry->list = obj; /* append to front */
6750 static tree
6751 lookup_method (tree mchain, tree method)
6753 tree key;
6755 if (TREE_CODE (method) == IDENTIFIER_NODE)
6756 key = method;
6757 else
6758 key = METHOD_SEL_NAME (method);
6760 while (mchain)
6762 if (METHOD_SEL_NAME (mchain) == key)
6763 return mchain;
6765 mchain = TREE_CHAIN (mchain);
6767 return NULL_TREE;
6770 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6771 in INTERFACE, along with any categories and protocols attached thereto.
6772 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6773 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6774 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6775 be found in INTERFACE or any of its superclasses, look for an _instance_
6776 method of the same name in the root class as a last resort.
6778 If a suitable method cannot be found, return NULL_TREE. */
6780 static tree
6781 lookup_method_static (tree interface, tree ident, int flags)
6783 tree meth = NULL_TREE, root_inter = NULL_TREE;
6784 tree inter = interface;
6785 int is_class = (flags & OBJC_LOOKUP_CLASS);
6786 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6788 while (inter)
6790 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6791 tree category = inter;
6793 /* First, look up the method in the class itself. */
6794 if ((meth = lookup_method (chain, ident)))
6795 return meth;
6797 /* Failing that, look for the method in each category of the class. */
6798 while ((category = CLASS_CATEGORY_LIST (category)))
6800 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6802 /* Check directly in each category. */
6803 if ((meth = lookup_method (chain, ident)))
6804 return meth;
6806 /* Failing that, check in each category's protocols. */
6807 if (CLASS_PROTOCOL_LIST (category))
6809 if ((meth = (lookup_method_in_protocol_list
6810 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6811 return meth;
6815 /* If not found in categories, check in protocols of the main class. */
6816 if (CLASS_PROTOCOL_LIST (inter))
6818 if ((meth = (lookup_method_in_protocol_list
6819 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6820 return meth;
6823 /* If we were instructed not to look in superclasses, don't. */
6824 if (no_superclasses)
6825 return NULL_TREE;
6827 /* Failing that, climb up the inheritance hierarchy. */
6828 root_inter = inter;
6829 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6831 while (inter);
6833 /* If no class (factory) method was found, check if an _instance_
6834 method of the same name exists in the root class. This is what
6835 the Objective-C runtime will do. If an instance method was not
6836 found, return 0. */
6837 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6840 /* Add the method to the hash list if it doesn't contain an identical
6841 method already. */
6842 static void
6843 add_method_to_hash_list (hash *hash_list, tree method)
6845 hash hsh;
6847 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6849 /* Install on a global chain. */
6850 hash_enter (hash_list, method);
6852 else
6854 /* Check types against those; if different, add to a list. */
6855 attr loop;
6856 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6857 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6858 already_there |= comp_proto_with_proto (method, loop->value, 1);
6859 if (!already_there)
6860 hash_add_attr (hsh, method);
6864 static tree
6865 objc_add_method (tree class, tree method, int is_class)
6867 tree mth;
6869 if (!(mth = lookup_method (is_class
6870 ? CLASS_CLS_METHODS (class)
6871 : CLASS_NST_METHODS (class), method)))
6873 /* put method on list in reverse order */
6874 if (is_class)
6876 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6877 CLASS_CLS_METHODS (class) = method;
6879 else
6881 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6882 CLASS_NST_METHODS (class) = method;
6885 else
6887 /* When processing an @interface for a class or category, give hard
6888 errors on methods with identical selectors but differing argument
6889 and/or return types. We do not do this for @implementations, because
6890 C/C++ will do it for us (i.e., there will be duplicate function
6891 definition errors). */
6892 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6893 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6894 && !comp_proto_with_proto (method, mth, 1))
6895 error ("duplicate declaration of method %<%c%s%>",
6896 is_class ? '+' : '-',
6897 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6900 if (is_class)
6901 add_method_to_hash_list (cls_method_hash_list, method);
6902 else
6904 add_method_to_hash_list (nst_method_hash_list, method);
6906 /* Instance methods in root classes (and categories thereof)
6907 may act as class methods as a last resort. We also add
6908 instance methods listed in @protocol declarations to
6909 the class hash table, on the assumption that @protocols
6910 may be adopted by root classes or categories. */
6911 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6912 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6913 class = lookup_interface (CLASS_NAME (class));
6915 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6916 || !CLASS_SUPER_NAME (class))
6917 add_method_to_hash_list (cls_method_hash_list, method);
6920 return method;
6923 static tree
6924 add_class (tree class_name, tree name)
6926 struct interface_tuple **slot;
6928 /* Put interfaces on list in reverse order. */
6929 TREE_CHAIN (class_name) = interface_chain;
6930 interface_chain = class_name;
6932 if (interface_htab == NULL)
6933 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6934 slot = (struct interface_tuple **)
6935 htab_find_slot_with_hash (interface_htab, name,
6936 htab_hash_pointer (name),
6937 INSERT);
6938 if (!*slot)
6940 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6941 (*slot)->id = name;
6943 (*slot)->class_name = class_name;
6945 return interface_chain;
6948 static void
6949 add_category (tree class, tree category)
6951 /* Put categories on list in reverse order. */
6952 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6954 if (cat)
6956 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
6957 IDENTIFIER_POINTER (CLASS_NAME (class)),
6958 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6960 else
6962 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6963 CLASS_CATEGORY_LIST (class) = category;
6967 /* Called after parsing each instance variable declaration. Necessary to
6968 preserve typedefs and implement public/private...
6970 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6972 static tree
6973 add_instance_variable (tree class, int public, tree field_decl)
6975 tree field_type = TREE_TYPE (field_decl);
6976 const char *ivar_name = DECL_NAME (field_decl)
6977 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6978 : "<unnamed>";
6980 #ifdef OBJCPLUS
6981 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6983 error ("illegal reference type specified for instance variable %qs",
6984 ivar_name);
6985 /* Return class as is without adding this ivar. */
6986 return class;
6988 #endif
6990 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6991 || TYPE_SIZE (field_type) == error_mark_node)
6992 /* 'type[0]' is allowed, but 'type[]' is not! */
6994 error ("instance variable %qs has unknown size", ivar_name);
6995 /* Return class as is without adding this ivar. */
6996 return class;
6999 #ifdef OBJCPLUS
7000 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7001 need to either (1) warn the user about it or (2) generate suitable
7002 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7003 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7004 if (IS_AGGR_TYPE (field_type)
7005 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7006 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7007 || TYPE_POLYMORPHIC_P (field_type)))
7009 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7011 if (flag_objc_call_cxx_cdtors)
7013 /* Since the ObjC runtime will be calling the constructors and
7014 destructors for us, the only thing we can't handle is the lack
7015 of a default constructor. */
7016 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7017 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7019 warning (0, "type `%s' has no default constructor to call",
7020 type_name);
7022 /* If we cannot call a constructor, we should also avoid
7023 calling the destructor, for symmetry. */
7024 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7025 warning (0, "destructor for `%s' shall not be run either",
7026 type_name);
7029 else
7031 static bool warn_cxx_ivars = false;
7033 if (TYPE_POLYMORPHIC_P (field_type))
7035 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7036 initialize them. */
7037 error ("type `%s' has virtual member functions", type_name);
7038 error ("illegal aggregate type `%s' specified "
7039 "for instance variable `%s'",
7040 type_name, ivar_name);
7041 /* Return class as is without adding this ivar. */
7042 return class;
7045 /* User-defined constructors and destructors are not known to Obj-C
7046 and hence will not be called. This may or may not be a problem. */
7047 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7048 warning (0, "type `%s' has a user-defined constructor", type_name);
7049 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7050 warning (0, "type `%s' has a user-defined destructor", type_name);
7052 if (!warn_cxx_ivars)
7054 warning (0, "C++ constructors and destructors will not "
7055 "be invoked for Objective-C fields");
7056 warn_cxx_ivars = true;
7060 #endif
7062 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7063 switch (public)
7065 case 0:
7066 TREE_PUBLIC (field_decl) = 0;
7067 TREE_PRIVATE (field_decl) = 0;
7068 TREE_PROTECTED (field_decl) = 1;
7069 break;
7071 case 1:
7072 TREE_PUBLIC (field_decl) = 1;
7073 TREE_PRIVATE (field_decl) = 0;
7074 TREE_PROTECTED (field_decl) = 0;
7075 break;
7077 case 2:
7078 TREE_PUBLIC (field_decl) = 0;
7079 TREE_PRIVATE (field_decl) = 1;
7080 TREE_PROTECTED (field_decl) = 0;
7081 break;
7085 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7087 return class;
7090 static tree
7091 is_ivar (tree decl_chain, tree ident)
7093 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7094 if (DECL_NAME (decl_chain) == ident)
7095 return decl_chain;
7096 return NULL_TREE;
7099 /* True if the ivar is private and we are not in its implementation. */
7101 static int
7102 is_private (tree decl)
7104 return (TREE_PRIVATE (decl)
7105 && ! is_ivar (CLASS_IVARS (implementation_template),
7106 DECL_NAME (decl)));
7109 /* We have an instance variable reference;, check to see if it is public. */
7112 objc_is_public (tree expr, tree identifier)
7114 tree basetype, decl;
7116 #ifdef OBJCPLUS
7117 if (processing_template_decl)
7118 return 1;
7119 #endif
7121 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7123 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7125 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7127 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7129 if (!class)
7131 error ("cannot find interface declaration for %qs",
7132 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7133 return 0;
7136 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7138 if (TREE_PUBLIC (decl))
7139 return 1;
7141 /* Important difference between the Stepstone translator:
7142 all instance variables should be public within the context
7143 of the implementation. */
7144 if (objc_implementation_context
7145 && ((TREE_CODE (objc_implementation_context)
7146 == CLASS_IMPLEMENTATION_TYPE)
7147 || (TREE_CODE (objc_implementation_context)
7148 == CATEGORY_IMPLEMENTATION_TYPE)))
7150 tree curtype = TYPE_MAIN_VARIANT
7151 (CLASS_STATIC_TEMPLATE
7152 (implementation_template));
7154 if (basetype == curtype
7155 || DERIVED_FROM_P (basetype, curtype))
7157 int private = is_private (decl);
7159 if (private)
7160 error ("instance variable %qs is declared private",
7161 IDENTIFIER_POINTER (DECL_NAME (decl)));
7163 return !private;
7167 /* The 2.95.2 compiler sometimes allowed C functions to access
7168 non-@public ivars. We will let this slide for now... */
7169 if (!objc_method_context)
7171 warning (0, "instance variable %qs is %s; "
7172 "this will be a hard error in the future",
7173 IDENTIFIER_POINTER (identifier),
7174 TREE_PRIVATE (decl) ? "@private" : "@protected");
7175 return 1;
7178 error ("instance variable %qs is declared %s",
7179 IDENTIFIER_POINTER (identifier),
7180 TREE_PRIVATE (decl) ? "private" : "protected");
7181 return 0;
7186 return 1;
7189 /* Make sure all entries in CHAIN are also in LIST. */
7191 static int
7192 check_methods (tree chain, tree list, int mtype)
7194 int first = 1;
7196 while (chain)
7198 if (!lookup_method (list, chain))
7200 if (first)
7202 if (TREE_CODE (objc_implementation_context)
7203 == CLASS_IMPLEMENTATION_TYPE)
7204 warning (0, "incomplete implementation of class %qs",
7205 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7206 else if (TREE_CODE (objc_implementation_context)
7207 == CATEGORY_IMPLEMENTATION_TYPE)
7208 warning (0, "incomplete implementation of category %qs",
7209 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7210 first = 0;
7213 warning (0, "method definition for %<%c%s%> not found",
7214 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7217 chain = TREE_CHAIN (chain);
7220 return first;
7223 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7225 static int
7226 conforms_to_protocol (tree class, tree protocol)
7228 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7230 tree p = CLASS_PROTOCOL_LIST (class);
7231 while (p && TREE_VALUE (p) != protocol)
7232 p = TREE_CHAIN (p);
7234 if (!p)
7236 tree super = (CLASS_SUPER_NAME (class)
7237 ? lookup_interface (CLASS_SUPER_NAME (class))
7238 : NULL_TREE);
7239 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7240 if (!tmp)
7241 return 0;
7245 return 1;
7248 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7249 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7251 static int
7252 check_methods_accessible (tree chain, tree context, int mtype)
7254 int first = 1;
7255 tree list;
7256 tree base_context = context;
7258 while (chain)
7260 context = base_context;
7261 while (context)
7263 if (mtype == '+')
7264 list = CLASS_CLS_METHODS (context);
7265 else
7266 list = CLASS_NST_METHODS (context);
7268 if (lookup_method (list, chain))
7269 break;
7271 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7272 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7273 context = (CLASS_SUPER_NAME (context)
7274 ? lookup_interface (CLASS_SUPER_NAME (context))
7275 : NULL_TREE);
7277 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7278 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7279 context = (CLASS_NAME (context)
7280 ? lookup_interface (CLASS_NAME (context))
7281 : NULL_TREE);
7282 else
7283 abort ();
7286 if (context == NULL_TREE)
7288 if (first)
7290 if (TREE_CODE (objc_implementation_context)
7291 == CLASS_IMPLEMENTATION_TYPE)
7292 warning (0, "incomplete implementation of class %qs",
7293 IDENTIFIER_POINTER
7294 (CLASS_NAME (objc_implementation_context)));
7295 else if (TREE_CODE (objc_implementation_context)
7296 == CATEGORY_IMPLEMENTATION_TYPE)
7297 warning (0, "incomplete implementation of category %qs",
7298 IDENTIFIER_POINTER
7299 (CLASS_SUPER_NAME (objc_implementation_context)));
7300 first = 0;
7302 warning (0, "method definition for %<%c%s%> not found",
7303 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7306 chain = TREE_CHAIN (chain); /* next method... */
7308 return first;
7311 /* Check whether the current interface (accessible via
7312 'objc_implementation_context') actually implements protocol P, along
7313 with any protocols that P inherits. */
7315 static void
7316 check_protocol (tree p, const char *type, const char *name)
7318 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7320 int f1, f2;
7322 /* Ensure that all protocols have bodies! */
7323 if (warn_protocol)
7325 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7326 CLASS_CLS_METHODS (objc_implementation_context),
7327 '+');
7328 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7329 CLASS_NST_METHODS (objc_implementation_context),
7330 '-');
7332 else
7334 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7335 objc_implementation_context,
7336 '+');
7337 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7338 objc_implementation_context,
7339 '-');
7342 if (!f1 || !f2)
7343 warning (0, "%s %qs does not fully implement the %qs protocol",
7344 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7347 /* Check protocols recursively. */
7348 if (PROTOCOL_LIST (p))
7350 tree subs = PROTOCOL_LIST (p);
7351 tree super_class =
7352 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7354 while (subs)
7356 tree sub = TREE_VALUE (subs);
7358 /* If the superclass does not conform to the protocols
7359 inherited by P, then we must! */
7360 if (!super_class || !conforms_to_protocol (super_class, sub))
7361 check_protocol (sub, type, name);
7362 subs = TREE_CHAIN (subs);
7367 /* Check whether the current interface (accessible via
7368 'objc_implementation_context') actually implements the protocols listed
7369 in PROTO_LIST. */
7371 static void
7372 check_protocols (tree proto_list, const char *type, const char *name)
7374 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7376 tree p = TREE_VALUE (proto_list);
7378 check_protocol (p, type, name);
7382 /* Make sure that the class CLASS_NAME is defined
7383 CODE says which kind of thing CLASS_NAME ought to be.
7384 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7385 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7387 static tree
7388 start_class (enum tree_code code, tree class_name, tree super_name,
7389 tree protocol_list)
7391 tree class, decl;
7393 #ifdef OBJCPLUS
7394 if (current_namespace != global_namespace) {
7395 error ("Objective-C declarations may only appear in global scope");
7397 #endif /* OBJCPLUS */
7399 if (objc_implementation_context)
7401 warning (0, "%<@end%> missing in implementation context");
7402 finish_class (objc_implementation_context);
7403 objc_ivar_chain = NULL_TREE;
7404 objc_implementation_context = NULL_TREE;
7407 class = make_node (code);
7408 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7410 /* Check for existence of the super class, if one was specified. Note
7411 that we must have seen an @interface, not just a @class. If we
7412 are looking at a @compatibility_alias, traverse it first. */
7413 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7414 && super_name)
7416 tree super = objc_is_class_name (super_name);
7418 if (!super || !lookup_interface (super))
7420 error ("cannot find interface declaration for %qs, superclass of %qs",
7421 IDENTIFIER_POINTER (super ? super : super_name),
7422 IDENTIFIER_POINTER (class_name));
7423 super_name = NULL_TREE;
7425 else
7426 super_name = super;
7429 CLASS_NAME (class) = class_name;
7430 CLASS_SUPER_NAME (class) = super_name;
7431 CLASS_CLS_METHODS (class) = NULL_TREE;
7433 if (! objc_is_class_name (class_name)
7434 && (decl = lookup_name (class_name)))
7436 error ("%qs redeclared as different kind of symbol",
7437 IDENTIFIER_POINTER (class_name));
7438 error ("%Jprevious declaration of '%D'",
7439 decl, decl);
7442 if (code == CLASS_IMPLEMENTATION_TYPE)
7445 tree chain;
7447 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7448 if (TREE_VALUE (chain) == class_name)
7450 error ("reimplementation of class %qs",
7451 IDENTIFIER_POINTER (class_name));
7452 return error_mark_node;
7454 implemented_classes = tree_cons (NULL_TREE, class_name,
7455 implemented_classes);
7458 /* Reset for multiple classes per file. */
7459 method_slot = 0;
7461 objc_implementation_context = class;
7463 /* Lookup the interface for this implementation. */
7465 if (!(implementation_template = lookup_interface (class_name)))
7467 warning (0, "cannot find interface declaration for %qs",
7468 IDENTIFIER_POINTER (class_name));
7469 add_class (implementation_template = objc_implementation_context,
7470 class_name);
7473 /* If a super class has been specified in the implementation,
7474 insure it conforms to the one specified in the interface. */
7476 if (super_name
7477 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7479 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7480 const char *const name =
7481 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7482 error ("conflicting super class name %qs",
7483 IDENTIFIER_POINTER (super_name));
7484 error ("previous declaration of %qs", name);
7487 else if (! super_name)
7489 CLASS_SUPER_NAME (objc_implementation_context)
7490 = CLASS_SUPER_NAME (implementation_template);
7494 else if (code == CLASS_INTERFACE_TYPE)
7496 if (lookup_interface (class_name))
7497 #ifdef OBJCPLUS
7498 error ("duplicate interface declaration for class %qs",
7499 #else
7500 warning (0, "duplicate interface declaration for class %qs",
7501 #endif
7502 IDENTIFIER_POINTER (class_name));
7503 else
7504 add_class (class, class_name);
7506 if (protocol_list)
7507 CLASS_PROTOCOL_LIST (class)
7508 = lookup_and_install_protocols (protocol_list);
7511 else if (code == CATEGORY_INTERFACE_TYPE)
7513 tree class_category_is_assoc_with;
7515 /* For a category, class_name is really the name of the class that
7516 the following set of methods will be associated with. We must
7517 find the interface so that can derive the objects template. */
7519 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7521 error ("cannot find interface declaration for %qs",
7522 IDENTIFIER_POINTER (class_name));
7523 exit (FATAL_EXIT_CODE);
7525 else
7526 add_category (class_category_is_assoc_with, class);
7528 if (protocol_list)
7529 CLASS_PROTOCOL_LIST (class)
7530 = lookup_and_install_protocols (protocol_list);
7533 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7535 /* Reset for multiple classes per file. */
7536 method_slot = 0;
7538 objc_implementation_context = class;
7540 /* For a category, class_name is really the name of the class that
7541 the following set of methods will be associated with. We must
7542 find the interface so that can derive the objects template. */
7544 if (!(implementation_template = lookup_interface (class_name)))
7546 error ("cannot find interface declaration for %qs",
7547 IDENTIFIER_POINTER (class_name));
7548 exit (FATAL_EXIT_CODE);
7551 return class;
7554 static tree
7555 continue_class (tree class)
7557 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7558 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7560 struct imp_entry *imp_entry;
7562 /* Check consistency of the instance variables. */
7564 if (CLASS_RAW_IVARS (class))
7565 check_ivars (implementation_template, class);
7567 /* code generation */
7569 #ifdef OBJCPLUS
7570 push_lang_context (lang_name_c);
7571 #endif
7573 build_private_template (implementation_template);
7574 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7575 objc_instance_type = build_pointer_type (uprivate_record);
7577 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7579 imp_entry->next = imp_list;
7580 imp_entry->imp_context = class;
7581 imp_entry->imp_template = implementation_template;
7583 synth_forward_declarations ();
7584 imp_entry->class_decl = UOBJC_CLASS_decl;
7585 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7586 imp_entry->has_cxx_cdtors = 0;
7588 /* Append to front and increment count. */
7589 imp_list = imp_entry;
7590 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7591 imp_count++;
7592 else
7593 cat_count++;
7595 #ifdef OBJCPLUS
7596 pop_lang_context ();
7597 #endif /* OBJCPLUS */
7599 return get_class_ivars (implementation_template, true);
7602 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7604 #ifdef OBJCPLUS
7605 push_lang_context (lang_name_c);
7606 #endif /* OBJCPLUS */
7608 build_private_template (class);
7610 #ifdef OBJCPLUS
7611 pop_lang_context ();
7612 #endif /* OBJCPLUS */
7614 return NULL_TREE;
7617 else
7618 return error_mark_node;
7621 /* This is called once we see the "@end" in an interface/implementation. */
7623 static void
7624 finish_class (tree class)
7626 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7628 /* All code generation is done in finish_objc. */
7630 if (implementation_template != objc_implementation_context)
7632 /* Ensure that all method listed in the interface contain bodies. */
7633 check_methods (CLASS_CLS_METHODS (implementation_template),
7634 CLASS_CLS_METHODS (objc_implementation_context), '+');
7635 check_methods (CLASS_NST_METHODS (implementation_template),
7636 CLASS_NST_METHODS (objc_implementation_context), '-');
7638 if (CLASS_PROTOCOL_LIST (implementation_template))
7639 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7640 "class",
7641 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7645 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7647 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7649 if (category)
7651 /* Ensure all method listed in the interface contain bodies. */
7652 check_methods (CLASS_CLS_METHODS (category),
7653 CLASS_CLS_METHODS (objc_implementation_context), '+');
7654 check_methods (CLASS_NST_METHODS (category),
7655 CLASS_NST_METHODS (objc_implementation_context), '-');
7657 if (CLASS_PROTOCOL_LIST (category))
7658 check_protocols (CLASS_PROTOCOL_LIST (category),
7659 "category",
7660 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7665 static tree
7666 add_protocol (tree protocol)
7668 /* Put protocol on list in reverse order. */
7669 TREE_CHAIN (protocol) = protocol_chain;
7670 protocol_chain = protocol;
7671 return protocol_chain;
7674 static tree
7675 lookup_protocol (tree ident)
7677 tree chain;
7679 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7680 if (ident == PROTOCOL_NAME (chain))
7681 return chain;
7683 return NULL_TREE;
7686 /* This function forward declares the protocols named by NAMES. If
7687 they are already declared or defined, the function has no effect. */
7689 void
7690 objc_declare_protocols (tree names)
7692 tree list;
7694 #ifdef OBJCPLUS
7695 if (current_namespace != global_namespace) {
7696 error ("Objective-C declarations may only appear in global scope");
7698 #endif /* OBJCPLUS */
7700 for (list = names; list; list = TREE_CHAIN (list))
7702 tree name = TREE_VALUE (list);
7704 if (lookup_protocol (name) == NULL_TREE)
7706 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7708 TYPE_LANG_SLOT_1 (protocol)
7709 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7710 PROTOCOL_NAME (protocol) = name;
7711 PROTOCOL_LIST (protocol) = NULL_TREE;
7712 add_protocol (protocol);
7713 PROTOCOL_DEFINED (protocol) = 0;
7714 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7719 static tree
7720 start_protocol (enum tree_code code, tree name, tree list)
7722 tree protocol;
7724 #ifdef OBJCPLUS
7725 if (current_namespace != global_namespace) {
7726 error ("Objective-C declarations may only appear in global scope");
7728 #endif /* OBJCPLUS */
7730 protocol = lookup_protocol (name);
7732 if (!protocol)
7734 protocol = make_node (code);
7735 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7737 PROTOCOL_NAME (protocol) = name;
7738 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7739 add_protocol (protocol);
7740 PROTOCOL_DEFINED (protocol) = 1;
7741 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7743 check_protocol_recursively (protocol, list);
7745 else if (! PROTOCOL_DEFINED (protocol))
7747 PROTOCOL_DEFINED (protocol) = 1;
7748 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7750 check_protocol_recursively (protocol, list);
7752 else
7754 warning (0, "duplicate declaration for protocol %qs",
7755 IDENTIFIER_POINTER (name));
7757 return protocol;
7761 /* "Encode" a data type into a string, which grows in util_obstack.
7762 ??? What is the FORMAT? Someone please document this! */
7764 static void
7765 encode_type_qualifiers (tree declspecs)
7767 tree spec;
7769 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7771 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7772 obstack_1grow (&util_obstack, 'n');
7773 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7774 obstack_1grow (&util_obstack, 'N');
7775 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7776 obstack_1grow (&util_obstack, 'o');
7777 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7778 obstack_1grow (&util_obstack, 'O');
7779 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7780 obstack_1grow (&util_obstack, 'R');
7781 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7782 obstack_1grow (&util_obstack, 'V');
7786 /* Encode a pointer type. */
7788 static void
7789 encode_pointer (tree type, int curtype, int format)
7791 tree pointer_to = TREE_TYPE (type);
7793 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7795 if (OBJC_TYPE_NAME (pointer_to)
7796 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7798 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7800 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7802 obstack_1grow (&util_obstack, '@');
7803 return;
7805 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7806 && TYPE_OBJC_INTERFACE (pointer_to))
7808 if (generating_instance_variables)
7810 obstack_1grow (&util_obstack, '@');
7811 obstack_1grow (&util_obstack, '"');
7812 obstack_grow (&util_obstack, name, strlen (name));
7813 obstack_1grow (&util_obstack, '"');
7814 return;
7816 else
7818 obstack_1grow (&util_obstack, '@');
7819 return;
7822 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7824 obstack_1grow (&util_obstack, '#');
7825 return;
7827 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7829 obstack_1grow (&util_obstack, ':');
7830 return;
7834 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7835 && TYPE_MODE (pointer_to) == QImode)
7837 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7838 ? OBJC_TYPE_NAME (pointer_to)
7839 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7841 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7843 /* It appears that "r*" means "const char *" rather than
7844 "char *const". */
7845 if (TYPE_READONLY (pointer_to))
7846 obstack_1grow (&util_obstack, 'r');
7848 obstack_1grow (&util_obstack, '*');
7849 return;
7853 /* We have a type that does not get special treatment. */
7855 /* NeXT extension */
7856 obstack_1grow (&util_obstack, '^');
7857 encode_type (pointer_to, curtype, format);
7860 static void
7861 encode_array (tree type, int curtype, int format)
7863 tree an_int_cst = TYPE_SIZE (type);
7864 tree array_of = TREE_TYPE (type);
7865 char buffer[40];
7867 /* An incomplete array is treated like a pointer. */
7868 if (an_int_cst == NULL)
7870 encode_pointer (type, curtype, format);
7871 return;
7874 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7875 (TREE_INT_CST_LOW (an_int_cst)
7876 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7878 obstack_grow (&util_obstack, buffer, strlen (buffer));
7879 encode_type (array_of, curtype, format);
7880 obstack_1grow (&util_obstack, ']');
7881 return;
7884 static void
7885 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7887 tree field = TYPE_FIELDS (type);
7889 for (; field; field = TREE_CHAIN (field))
7891 #ifdef OBJCPLUS
7892 /* C++ static members, and things that are not field at all,
7893 should not appear in the encoding. */
7894 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7895 continue;
7896 #endif
7898 /* Recursively encode fields of embedded base classes. */
7899 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7900 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7902 encode_aggregate_fields (TREE_TYPE (field),
7903 pointed_to, curtype, format);
7904 continue;
7907 if (generating_instance_variables && !pointed_to)
7909 tree fname = DECL_NAME (field);
7911 obstack_1grow (&util_obstack, '"');
7913 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7914 obstack_grow (&util_obstack,
7915 IDENTIFIER_POINTER (fname),
7916 strlen (IDENTIFIER_POINTER (fname)));
7918 obstack_1grow (&util_obstack, '"');
7921 encode_field_decl (field, curtype, format);
7925 static void
7926 encode_aggregate_within (tree type, int curtype, int format, int left,
7927 int right)
7929 tree name;
7930 /* NB: aggregates that are pointed to have slightly different encoding
7931 rules in that you never encode the names of instance variables. */
7932 int ob_size = obstack_object_size (&util_obstack);
7933 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7934 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7935 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7936 int inline_contents
7937 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7938 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7940 /* Traverse struct aliases; it is important to get the
7941 original struct and its tag name (if any). */
7942 type = TYPE_MAIN_VARIANT (type);
7943 name = OBJC_TYPE_NAME (type);
7944 /* Open parenth/bracket. */
7945 obstack_1grow (&util_obstack, left);
7947 /* Encode the struct/union tag name, or '?' if a tag was
7948 not provided. Typedef aliases do not qualify. */
7949 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7950 #ifdef OBJCPLUS
7951 /* Did this struct have a tag? */
7952 && !TYPE_WAS_ANONYMOUS (type)
7953 #endif
7955 obstack_grow (&util_obstack,
7956 IDENTIFIER_POINTER (name),
7957 strlen (IDENTIFIER_POINTER (name)));
7958 else
7959 obstack_1grow (&util_obstack, '?');
7961 /* Encode the types (and possibly names) of the inner fields,
7962 if required. */
7963 if (inline_contents)
7965 obstack_1grow (&util_obstack, '=');
7966 encode_aggregate_fields (type, pointed_to, curtype, format);
7968 /* Close parenth/bracket. */
7969 obstack_1grow (&util_obstack, right);
7972 static void
7973 encode_aggregate (tree type, int curtype, int format)
7975 enum tree_code code = TREE_CODE (type);
7977 switch (code)
7979 case RECORD_TYPE:
7981 encode_aggregate_within (type, curtype, format, '{', '}');
7982 break;
7984 case UNION_TYPE:
7986 encode_aggregate_within (type, curtype, format, '(', ')');
7987 break;
7990 case ENUMERAL_TYPE:
7991 obstack_1grow (&util_obstack, 'i');
7992 break;
7994 default:
7995 break;
7999 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8000 field type. */
8002 static void
8003 encode_next_bitfield (int width)
8005 char buffer[40];
8006 sprintf (buffer, "b%d", width);
8007 obstack_grow (&util_obstack, buffer, strlen (buffer));
8010 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8011 static void
8012 encode_type (tree type, int curtype, int format)
8014 enum tree_code code = TREE_CODE (type);
8015 char c;
8017 if (TYPE_READONLY (type))
8018 obstack_1grow (&util_obstack, 'r');
8020 if (code == INTEGER_TYPE)
8022 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8024 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8025 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8026 case 32:
8027 if (type == long_unsigned_type_node
8028 || type == long_integer_type_node)
8029 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8030 else
8031 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8032 break;
8033 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8034 default: abort ();
8036 obstack_1grow (&util_obstack, c);
8039 else if (code == REAL_TYPE)
8041 /* Floating point types. */
8042 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8044 case 32: c = 'f'; break;
8045 case 64:
8046 case 96:
8047 case 128: c = 'd'; break;
8048 default: abort ();
8050 obstack_1grow (&util_obstack, c);
8053 else if (code == VOID_TYPE)
8054 obstack_1grow (&util_obstack, 'v');
8056 else if (code == BOOLEAN_TYPE)
8057 obstack_1grow (&util_obstack, 'B');
8059 else if (code == ARRAY_TYPE)
8060 encode_array (type, curtype, format);
8062 else if (code == POINTER_TYPE)
8063 encode_pointer (type, curtype, format);
8065 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8066 encode_aggregate (type, curtype, format);
8068 else if (code == FUNCTION_TYPE) /* '?' */
8069 obstack_1grow (&util_obstack, '?');
8072 static void
8073 encode_gnu_bitfield (int position, tree type, int size)
8075 enum tree_code code = TREE_CODE (type);
8076 char buffer[40];
8077 char charType = '?';
8079 if (code == INTEGER_TYPE)
8081 if (integer_zerop (TYPE_MIN_VALUE (type)))
8083 /* Unsigned integer types. */
8085 if (TYPE_MODE (type) == QImode)
8086 charType = 'C';
8087 else if (TYPE_MODE (type) == HImode)
8088 charType = 'S';
8089 else if (TYPE_MODE (type) == SImode)
8091 if (type == long_unsigned_type_node)
8092 charType = 'L';
8093 else
8094 charType = 'I';
8096 else if (TYPE_MODE (type) == DImode)
8097 charType = 'Q';
8100 else
8101 /* Signed integer types. */
8103 if (TYPE_MODE (type) == QImode)
8104 charType = 'c';
8105 else if (TYPE_MODE (type) == HImode)
8106 charType = 's';
8107 else if (TYPE_MODE (type) == SImode)
8109 if (type == long_integer_type_node)
8110 charType = 'l';
8111 else
8112 charType = 'i';
8115 else if (TYPE_MODE (type) == DImode)
8116 charType = 'q';
8119 else if (code == ENUMERAL_TYPE)
8120 charType = 'i';
8121 else
8122 abort ();
8124 sprintf (buffer, "b%d%c%d", position, charType, size);
8125 obstack_grow (&util_obstack, buffer, strlen (buffer));
8128 static void
8129 encode_field_decl (tree field_decl, int curtype, int format)
8131 tree type;
8133 #ifdef OBJCPLUS
8134 /* C++ static members, and things that are not fields at all,
8135 should not appear in the encoding. */
8136 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8137 return;
8138 #endif
8140 type = TREE_TYPE (field_decl);
8142 /* Generate the bitfield typing information, if needed. Note the difference
8143 between GNU and NeXT runtimes. */
8144 if (DECL_BIT_FIELD_TYPE (field_decl))
8146 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8148 if (flag_next_runtime)
8149 encode_next_bitfield (size);
8150 else
8151 encode_gnu_bitfield (int_bit_position (field_decl),
8152 DECL_BIT_FIELD_TYPE (field_decl), size);
8154 else
8155 encode_type (TREE_TYPE (field_decl), curtype, format);
8158 static GTY(()) tree objc_parmlist = NULL_TREE;
8160 /* Append PARM to a list of formal parameters of a method, making a necessary
8161 array-to-pointer adjustment along the way. */
8163 static void
8164 objc_push_parm (tree parm)
8166 /* Decay arrays and functions into pointers. */
8167 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8168 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8169 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8170 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8172 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
8173 DECL_ARG_TYPE (parm)
8174 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8176 /* Record constancy and volatility. */
8177 c_apply_type_quals_to_decl
8178 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8179 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8180 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8182 objc_parmlist = chainon (objc_parmlist, parm);
8185 /* Retrieve the formal parameter list constructed via preceding calls to
8186 objc_push_parm(). */
8188 #ifdef OBJCPLUS
8189 static tree
8190 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8191 #else
8192 static struct c_arg_info *
8193 objc_get_parm_info (int have_ellipsis)
8194 #endif
8196 #ifdef OBJCPLUS
8197 tree parm_info = objc_parmlist;
8198 objc_parmlist = NULL_TREE;
8200 return parm_info;
8201 #else
8202 tree parm_info = objc_parmlist;
8203 struct c_arg_info *arg_info;
8204 /* The C front-end requires an elaborate song and dance at
8205 this point. */
8206 push_scope ();
8207 declare_parm_level ();
8208 while (parm_info)
8210 tree next = TREE_CHAIN (parm_info);
8212 TREE_CHAIN (parm_info) = NULL_TREE;
8213 parm_info = pushdecl (parm_info);
8214 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8215 parm_info = next;
8217 arg_info = get_parm_info (have_ellipsis);
8218 pop_scope ();
8219 objc_parmlist = NULL_TREE;
8220 return arg_info;
8221 #endif
8224 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8225 method definitions. In the case of instance methods, we can be more
8226 specific as to the type of 'self'. */
8228 static void
8229 synth_self_and_ucmd_args (void)
8231 tree self_type;
8233 if (objc_method_context
8234 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8235 self_type = objc_instance_type;
8236 else
8237 /* Really a `struct objc_class *'. However, we allow people to
8238 assign to self, which changes its type midstream. */
8239 self_type = objc_object_type;
8241 /* id self; */
8242 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8244 /* SEL _cmd; */
8245 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8248 /* Transform an Objective-C method definition into a static C function
8249 definition, synthesizing the first two arguments, "self" and "_cmd",
8250 in the process. */
8252 static void
8253 start_method_def (tree method)
8255 tree parmlist;
8256 #ifdef OBJCPLUS
8257 tree parm_info;
8258 #else
8259 struct c_arg_info *parm_info;
8260 #endif
8261 int have_ellipsis = 0;
8263 /* If we are defining a "dealloc" method in a non-root class, we
8264 will need to check if a [super dealloc] is missing, and warn if
8265 it is. */
8266 if(CLASS_SUPER_NAME (objc_implementation_context)
8267 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8268 should_call_super_dealloc = 1;
8269 else
8270 should_call_super_dealloc = 0;
8272 /* Required to implement _msgSuper. */
8273 objc_method_context = method;
8274 UOBJC_SUPER_decl = NULL_TREE;
8276 /* Generate prototype declarations for arguments..."new-style". */
8277 synth_self_and_ucmd_args ();
8279 /* Generate argument declarations if a keyword_decl. */
8280 parmlist = METHOD_SEL_ARGS (method);
8281 while (parmlist)
8283 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8285 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8286 objc_push_parm (parm);
8287 parmlist = TREE_CHAIN (parmlist);
8290 if (METHOD_ADD_ARGS (method))
8292 tree akey;
8294 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8295 akey; akey = TREE_CHAIN (akey))
8297 objc_push_parm (TREE_VALUE (akey));
8300 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8301 have_ellipsis = 1;
8304 parm_info = objc_get_parm_info (have_ellipsis);
8306 really_start_method (objc_method_context, parm_info);
8309 static void
8310 warn_with_method (const char *message, int mtype, tree method)
8312 /* Add a readable method name to the warning. */
8313 warning (0, "%J%s %<%c%s%>", method,
8314 message, mtype, gen_method_decl (method));
8317 /* Return 1 if TYPE1 is equivalent to TYPE2
8318 for purposes of method overloading. */
8320 static int
8321 objc_types_are_equivalent (tree type1, tree type2)
8323 if (type1 == type2)
8324 return 1;
8326 /* Strip away indirections. */
8327 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8328 && (TREE_CODE (type1) == TREE_CODE (type2)))
8329 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8330 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8331 return 0;
8333 type1 = (TYPE_HAS_OBJC_INFO (type1)
8334 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8335 : NULL_TREE);
8336 type2 = (TYPE_HAS_OBJC_INFO (type2)
8337 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8338 : NULL_TREE);
8340 if (list_length (type1) == list_length (type2))
8342 for (; type2; type2 = TREE_CHAIN (type2))
8343 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8344 return 0;
8345 return 1;
8347 return 0;
8350 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8352 static int
8353 objc_types_share_size_and_alignment (tree type1, tree type2)
8355 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8356 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8359 /* Return 1 if PROTO1 is equivalent to PROTO2
8360 for purposes of method overloading. Ordinarily, the type signatures
8361 should match up exactly, unless STRICT is zero, in which case we
8362 shall allow differences in which the size and alignment of a type
8363 is the same. */
8365 static int
8366 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8368 tree type1, type2;
8370 /* The following test is needed in case there are hashing
8371 collisions. */
8372 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8373 return 0;
8375 /* Compare return types. */
8376 type1 = TREE_VALUE (TREE_TYPE (proto1));
8377 type2 = TREE_VALUE (TREE_TYPE (proto2));
8379 if (!objc_types_are_equivalent (type1, type2)
8380 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8381 return 0;
8383 /* Compare argument types. */
8384 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8385 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8386 type1 && type2;
8387 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8389 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8390 && (strict
8391 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8392 TREE_VALUE (type2))))
8393 return 0;
8396 return (!type1 && !type2);
8399 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8400 this occurs. ObjC method dispatches are _not_ like C++ virtual
8401 member function dispatches, and we account for the difference here. */
8402 tree
8403 #ifdef OBJCPLUS
8404 objc_fold_obj_type_ref (tree ref, tree known_type)
8405 #else
8406 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8407 tree known_type ATTRIBUTE_UNUSED)
8408 #endif
8410 #ifdef OBJCPLUS
8411 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8413 /* If the receiver does not have virtual member functions, there
8414 is nothing we can (or need to) do here. */
8415 if (!v)
8416 return NULL_TREE;
8418 /* Let C++ handle C++ virtual functions. */
8419 return cp_fold_obj_type_ref (ref, known_type);
8420 #else
8421 /* For plain ObjC, we currently do not need to do anything. */
8422 return NULL_TREE;
8423 #endif
8426 static void
8427 objc_start_function (tree name, tree type, tree attrs,
8428 #ifdef OBJCPLUS
8429 tree params
8430 #else
8431 struct c_arg_info *params
8432 #endif
8435 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8437 #ifdef OBJCPLUS
8438 DECL_ARGUMENTS (fndecl) = params;
8439 DECL_INITIAL (fndecl) = error_mark_node;
8440 DECL_EXTERNAL (fndecl) = 0;
8441 TREE_STATIC (fndecl) = 1;
8442 retrofit_lang_decl (fndecl);
8443 cplus_decl_attributes (&fndecl, attrs, 0);
8444 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8445 #else
8446 struct c_label_context_se *nstack_se;
8447 struct c_label_context_vm *nstack_vm;
8448 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8449 nstack_se->labels_def = NULL;
8450 nstack_se->labels_used = NULL;
8451 nstack_se->next = label_context_stack_se;
8452 label_context_stack_se = nstack_se;
8453 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8454 nstack_vm->labels_def = NULL;
8455 nstack_vm->labels_used = NULL;
8456 nstack_vm->scope = 0;
8457 nstack_vm->next = label_context_stack_vm;
8458 label_context_stack_vm = nstack_vm;
8459 current_function_returns_value = 0; /* Assume, until we see it does. */
8460 current_function_returns_null = 0;
8462 decl_attributes (&fndecl, attrs, 0);
8463 announce_function (fndecl);
8464 DECL_INITIAL (fndecl) = error_mark_node;
8465 DECL_EXTERNAL (fndecl) = 0;
8466 TREE_STATIC (fndecl) = 1;
8467 current_function_decl = pushdecl (fndecl);
8468 push_scope ();
8469 declare_parm_level ();
8470 DECL_RESULT (current_function_decl)
8471 = build_decl (RESULT_DECL, NULL_TREE,
8472 TREE_TYPE (TREE_TYPE (current_function_decl)));
8473 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8474 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8475 start_fname_decls ();
8476 store_parm_decls_from (params);
8477 #endif
8479 TREE_USED (current_function_decl) = 1;
8482 /* - Generate an identifier for the function. the format is "_n_cls",
8483 where 1 <= n <= nMethods, and cls is the name the implementation we
8484 are processing.
8485 - Install the return type from the method declaration.
8486 - If we have a prototype, check for type consistency. */
8488 static void
8489 really_start_method (tree method,
8490 #ifdef OBJCPLUS
8491 tree parmlist
8492 #else
8493 struct c_arg_info *parmlist
8494 #endif
8497 tree ret_type, meth_type;
8498 tree method_id;
8499 const char *sel_name, *class_name, *cat_name;
8500 char *buf;
8502 /* Synth the storage class & assemble the return type. */
8503 ret_type = TREE_VALUE (TREE_TYPE (method));
8505 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8506 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8507 cat_name = ((TREE_CODE (objc_implementation_context)
8508 == CLASS_IMPLEMENTATION_TYPE)
8509 ? NULL
8510 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8511 method_slot++;
8513 /* Make sure this is big enough for any plausible method label. */
8514 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8515 + (cat_name ? strlen (cat_name) : 0));
8517 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8518 class_name, cat_name, sel_name, method_slot);
8520 method_id = get_identifier (buf);
8522 #ifdef OBJCPLUS
8523 /* Objective-C methods cannot be overloaded, so we don't need
8524 the type encoding appended. It looks bad anyway... */
8525 push_lang_context (lang_name_c);
8526 #endif
8528 meth_type
8529 = build_function_type (ret_type,
8530 get_arg_type_list (method, METHOD_DEF, 0));
8531 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8533 /* Set self_decl from the first argument. */
8534 self_decl = DECL_ARGUMENTS (current_function_decl);
8536 /* Suppress unused warnings. */
8537 TREE_USED (self_decl) = 1;
8538 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8539 #ifdef OBJCPLUS
8540 pop_lang_context ();
8541 #endif
8543 METHOD_DEFINITION (method) = current_function_decl;
8545 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8547 if (implementation_template != objc_implementation_context)
8549 tree proto
8550 = lookup_method_static (implementation_template,
8551 METHOD_SEL_NAME (method),
8552 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8553 | OBJC_LOOKUP_NO_SUPER));
8555 if (proto)
8557 if (!comp_proto_with_proto (method, proto, 1))
8559 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8561 warn_with_method ("conflicting types for", type, method);
8562 warn_with_method ("previous declaration of", type, proto);
8565 else
8567 /* We have a method @implementation even though we did not
8568 see a corresponding @interface declaration (which is allowed
8569 by Objective-C rules). Go ahead and place the method in
8570 the @interface anyway, so that message dispatch lookups
8571 will see it. */
8572 tree interface = implementation_template;
8574 if (TREE_CODE (objc_implementation_context)
8575 == CATEGORY_IMPLEMENTATION_TYPE)
8576 interface = lookup_category
8577 (interface,
8578 CLASS_SUPER_NAME (objc_implementation_context));
8580 if (interface)
8581 objc_add_method (interface, copy_node (method),
8582 TREE_CODE (method) == CLASS_METHOD_DECL);
8587 static void *UOBJC_SUPER_scope = 0;
8589 /* _n_Method (id self, SEL sel, ...)
8591 struct objc_super _S;
8592 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8593 } */
8595 static tree
8596 get_super_receiver (void)
8598 if (objc_method_context)
8600 tree super_expr, super_expr_list;
8602 if (!UOBJC_SUPER_decl)
8604 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8605 objc_super_template);
8606 /* This prevents `unused variable' warnings when compiling with -Wall. */
8607 TREE_USED (UOBJC_SUPER_decl) = 1;
8608 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8609 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8610 UOBJC_SUPER_scope = objc_get_current_scope ();
8613 /* Set receiver to self. */
8614 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8615 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8616 super_expr_list = super_expr;
8618 /* Set class to begin searching. */
8619 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8620 get_identifier ("super_class"));
8622 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8624 /* [_cls, __cls]Super are "pre-built" in
8625 synth_forward_declarations. */
8627 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8628 ((TREE_CODE (objc_method_context)
8629 == INSTANCE_METHOD_DECL)
8630 ? ucls_super_ref
8631 : uucls_super_ref));
8634 else
8635 /* We have a category. */
8637 tree super_name = CLASS_SUPER_NAME (implementation_template);
8638 tree super_class;
8640 /* Barf if super used in a category of Object. */
8641 if (!super_name)
8643 error ("no super class declared in interface for %qs",
8644 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8645 return error_mark_node;
8648 if (flag_next_runtime && !flag_zero_link)
8650 super_class = objc_get_class_reference (super_name);
8651 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8652 /* If we are in a class method, we must retrieve the
8653 _metaclass_ for the current class, pointed at by
8654 the class's "isa" pointer. The following assumes that
8655 "isa" is the first ivar in a class (which it must be). */
8656 super_class
8657 = build_indirect_ref
8658 (build_c_cast (build_pointer_type (objc_class_type),
8659 super_class), "unary *");
8661 else
8663 add_class_reference (super_name);
8664 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8665 ? objc_get_class_decl : objc_get_meta_class_decl);
8666 assemble_external (super_class);
8667 super_class
8668 = build_function_call
8669 (super_class,
8670 build_tree_list
8671 (NULL_TREE,
8672 my_build_string_pointer
8673 (IDENTIFIER_LENGTH (super_name) + 1,
8674 IDENTIFIER_POINTER (super_name))));
8677 super_expr
8678 = build_modify_expr (super_expr, NOP_EXPR,
8679 build_c_cast (TREE_TYPE (super_expr),
8680 super_class));
8683 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8685 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8686 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8688 return super_expr_list;
8690 else
8692 error ("[super ...] must appear in a method context");
8693 return error_mark_node;
8697 /* When exiting a scope, sever links to a 'super' declaration (if any)
8698 therein contained. */
8700 void
8701 objc_clear_super_receiver (void)
8703 if (objc_method_context
8704 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8705 UOBJC_SUPER_decl = 0;
8706 UOBJC_SUPER_scope = 0;
8710 void
8711 objc_finish_method_definition (tree fndecl)
8713 /* We cannot validly inline ObjC methods, at least not without a language
8714 extension to declare that a method need not be dynamically
8715 dispatched, so suppress all thoughts of doing so. */
8716 DECL_INLINE (fndecl) = 0;
8717 DECL_UNINLINABLE (fndecl) = 1;
8719 #ifndef OBJCPLUS
8720 /* The C++ front-end will have called finish_function() for us. */
8721 finish_function ();
8722 #endif
8724 METHOD_ENCODING (objc_method_context)
8725 = encode_method_prototype (objc_method_context);
8727 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8728 since the optimizer may find "may be used before set" errors. */
8729 objc_method_context = NULL_TREE;
8731 if (should_call_super_dealloc)
8732 warning (0, "method possibly missing a [super dealloc] call");
8735 #if 0
8737 lang_report_error_function (tree decl)
8739 if (objc_method_context)
8741 fprintf (stderr, "In method %qs\n",
8742 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8743 return 1;
8746 else
8747 return 0;
8749 #endif
8751 /* Given a tree DECL node, produce a printable description of it in the given
8752 buffer, overwriting the buffer. */
8754 static char *
8755 gen_declaration (tree decl)
8757 errbuf[0] = '\0';
8759 if (DECL_P (decl))
8761 gen_type_name_0 (TREE_TYPE (decl));
8763 if (DECL_NAME (decl))
8765 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8766 strcat (errbuf, " ");
8768 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8771 if (DECL_INITIAL (decl)
8772 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8773 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8774 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8777 return errbuf;
8780 /* Given a tree TYPE node, produce a printable description of it in the given
8781 buffer, overwriting the buffer. */
8783 static char *
8784 gen_type_name_0 (tree type)
8786 tree orig = type, proto;
8788 if (TYPE_P (type) && TYPE_NAME (type))
8789 type = TYPE_NAME (type);
8790 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8792 tree inner = TREE_TYPE (type);
8794 while (TREE_CODE (inner) == ARRAY_TYPE)
8795 inner = TREE_TYPE (inner);
8797 gen_type_name_0 (inner);
8799 if (!POINTER_TYPE_P (inner))
8800 strcat (errbuf, " ");
8802 if (POINTER_TYPE_P (type))
8803 strcat (errbuf, "*");
8804 else
8805 while (type != inner)
8807 strcat (errbuf, "[");
8809 if (TYPE_DOMAIN (type))
8811 char sz[20];
8813 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8814 (TREE_INT_CST_LOW
8815 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8816 strcat (errbuf, sz);
8819 strcat (errbuf, "]");
8820 type = TREE_TYPE (type);
8823 goto exit_function;
8826 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8827 type = DECL_NAME (type);
8829 strcat (errbuf, IDENTIFIER_POINTER (type));
8831 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8832 if (objc_is_id (orig))
8833 orig = TREE_TYPE (orig);
8835 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8837 if (proto)
8839 strcat (errbuf, " <");
8841 while (proto) {
8842 strcat (errbuf,
8843 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8844 proto = TREE_CHAIN (proto);
8845 strcat (errbuf, proto ? ", " : ">");
8849 exit_function:
8850 return errbuf;
8853 static char *
8854 gen_type_name (tree type)
8856 errbuf[0] = '\0';
8858 return gen_type_name_0 (type);
8861 /* Given a method tree, put a printable description into the given
8862 buffer (overwriting) and return a pointer to the buffer. */
8864 static char *
8865 gen_method_decl (tree method)
8867 tree chain;
8869 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8870 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8871 strcat (errbuf, ")");
8872 chain = METHOD_SEL_ARGS (method);
8874 if (chain)
8876 /* We have a chain of keyword_decls. */
8879 if (KEYWORD_KEY_NAME (chain))
8880 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8882 strcat (errbuf, ":(");
8883 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8884 strcat (errbuf, ")");
8886 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8887 if ((chain = TREE_CHAIN (chain)))
8888 strcat (errbuf, " ");
8890 while (chain);
8892 if (METHOD_ADD_ARGS (method))
8894 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8896 /* Know we have a chain of parm_decls. */
8897 while (chain)
8899 strcat (errbuf, ", ");
8900 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8901 chain = TREE_CHAIN (chain);
8904 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8905 strcat (errbuf, ", ...");
8909 else
8910 /* We have a unary selector. */
8911 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8913 return errbuf;
8916 /* Debug info. */
8919 /* Dump an @interface declaration of the supplied class CHAIN to the
8920 supplied file FP. Used to implement the -gen-decls option (which
8921 prints out an @interface declaration of all classes compiled in
8922 this run); potentially useful for debugging the compiler too. */
8923 static void
8924 dump_interface (FILE *fp, tree chain)
8926 /* FIXME: A heap overflow here whenever a method (or ivar)
8927 declaration is so long that it doesn't fit in the buffer. The
8928 code and all the related functions should be rewritten to avoid
8929 using fixed size buffers. */
8930 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8931 tree ivar_decls = CLASS_RAW_IVARS (chain);
8932 tree nst_methods = CLASS_NST_METHODS (chain);
8933 tree cls_methods = CLASS_CLS_METHODS (chain);
8935 fprintf (fp, "\n@interface %s", my_name);
8937 /* CLASS_SUPER_NAME is used to store the superclass name for
8938 classes, and the category name for categories. */
8939 if (CLASS_SUPER_NAME (chain))
8941 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8943 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8944 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8946 fprintf (fp, " (%s)\n", name);
8948 else
8950 fprintf (fp, " : %s\n", name);
8953 else
8954 fprintf (fp, "\n");
8956 /* FIXME - the following doesn't seem to work at the moment. */
8957 if (ivar_decls)
8959 fprintf (fp, "{\n");
8962 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8963 ivar_decls = TREE_CHAIN (ivar_decls);
8965 while (ivar_decls);
8966 fprintf (fp, "}\n");
8969 while (nst_methods)
8971 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8972 nst_methods = TREE_CHAIN (nst_methods);
8975 while (cls_methods)
8977 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8978 cls_methods = TREE_CHAIN (cls_methods);
8981 fprintf (fp, "@end\n");
8984 /* Demangle function for Objective-C */
8985 static const char *
8986 objc_demangle (const char *mangled)
8988 char *demangled, *cp;
8990 if (mangled[0] == '_' &&
8991 (mangled[1] == 'i' || mangled[1] == 'c') &&
8992 mangled[2] == '_')
8994 cp = demangled = xmalloc(strlen(mangled) + 2);
8995 if (mangled[1] == 'i')
8996 *cp++ = '-'; /* for instance method */
8997 else
8998 *cp++ = '+'; /* for class method */
8999 *cp++ = '['; /* opening left brace */
9000 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9001 while (*cp && *cp == '_')
9002 cp++; /* skip any initial underbars in class name */
9003 cp = strchr(cp, '_'); /* find first non-initial underbar */
9004 if (cp == NULL)
9006 free(demangled); /* not mangled name */
9007 return mangled;
9009 if (cp[1] == '_') /* easy case: no category name */
9011 *cp++ = ' '; /* replace two '_' with one ' ' */
9012 strcpy(cp, mangled + (cp - demangled) + 2);
9014 else
9016 *cp++ = '('; /* less easy case: category name */
9017 cp = strchr(cp, '_');
9018 if (cp == 0)
9020 free(demangled); /* not mangled name */
9021 return mangled;
9023 *cp++ = ')';
9024 *cp++ = ' '; /* overwriting 1st char of method name... */
9025 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9027 while (*cp && *cp == '_')
9028 cp++; /* skip any initial underbars in method name */
9029 for (; *cp; cp++)
9030 if (*cp == '_')
9031 *cp = ':'; /* replace remaining '_' with ':' */
9032 *cp++ = ']'; /* closing right brace */
9033 *cp++ = 0; /* string terminator */
9034 return demangled;
9036 else
9037 return mangled; /* not an objc mangled name */
9040 const char *
9041 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9043 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9046 static void
9047 init_objc (void)
9049 gcc_obstack_init (&util_obstack);
9050 util_firstobj = (char *) obstack_finish (&util_obstack);
9052 errbuf = (char *) xmalloc (1024 * 10);
9053 hash_init ();
9054 synth_module_prologue ();
9057 static void
9058 finish_objc (void)
9060 struct imp_entry *impent;
9061 tree chain;
9062 /* The internally generated initializers appear to have missing braces.
9063 Don't warn about this. */
9064 int save_warn_missing_braces = warn_missing_braces;
9065 warn_missing_braces = 0;
9067 /* A missing @end may not be detected by the parser. */
9068 if (objc_implementation_context)
9070 warning (0, "%<@end%> missing in implementation context");
9071 finish_class (objc_implementation_context);
9072 objc_ivar_chain = NULL_TREE;
9073 objc_implementation_context = NULL_TREE;
9076 /* Process the static instances here because initialization of objc_symtab
9077 depends on them. */
9078 if (objc_static_instances)
9079 generate_static_references ();
9081 if (imp_list || class_names_chain
9082 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9083 generate_objc_symtab_decl ();
9085 for (impent = imp_list; impent; impent = impent->next)
9087 objc_implementation_context = impent->imp_context;
9088 implementation_template = impent->imp_template;
9090 UOBJC_CLASS_decl = impent->class_decl;
9091 UOBJC_METACLASS_decl = impent->meta_decl;
9093 /* Dump the @interface of each class as we compile it, if the
9094 -gen-decls option is in use. TODO: Dump the classes in the
9095 order they were found, rather than in reverse order as we
9096 are doing now. */
9097 if (flag_gen_declaration)
9099 dump_interface (gen_declaration_file, objc_implementation_context);
9102 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9104 /* all of the following reference the string pool... */
9105 generate_ivar_lists ();
9106 generate_dispatch_tables ();
9107 generate_shared_structures (impent->has_cxx_cdtors
9108 ? CLS_HAS_CXX_STRUCTORS
9109 : 0);
9111 else
9113 generate_dispatch_tables ();
9114 generate_category (objc_implementation_context);
9118 /* If we are using an array of selectors, we must always
9119 finish up the array decl even if no selectors were used. */
9120 if (! flag_next_runtime || sel_ref_chain)
9121 build_selector_translation_table ();
9123 if (protocol_chain)
9124 generate_protocols ();
9126 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9127 generate_objc_image_info ();
9129 /* Arrange for ObjC data structures to be initialized at run time. */
9130 if (objc_implementation_context || class_names_chain || objc_static_instances
9131 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9133 build_module_descriptor ();
9135 if (!flag_next_runtime)
9136 build_module_initializer_routine ();
9139 /* Dump the class references. This forces the appropriate classes
9140 to be linked into the executable image, preserving unix archive
9141 semantics. This can be removed when we move to a more dynamically
9142 linked environment. */
9144 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9146 handle_class_ref (chain);
9147 if (TREE_PURPOSE (chain))
9148 generate_classref_translation_entry (chain);
9151 for (impent = imp_list; impent; impent = impent->next)
9152 handle_impent (impent);
9154 /* Dump the string table last. */
9156 generate_strings ();
9158 if (warn_selector)
9160 int slot;
9161 hash hsh;
9163 /* Run through the selector hash tables and print a warning for any
9164 selector which has multiple methods. */
9166 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9168 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9169 check_duplicates (hsh, 0, 1);
9170 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9171 check_duplicates (hsh, 0, 1);
9175 warn_missing_braces = save_warn_missing_braces;
9178 /* Subroutines of finish_objc. */
9180 static void
9181 generate_classref_translation_entry (tree chain)
9183 tree expr, decl, type;
9185 decl = TREE_PURPOSE (chain);
9186 type = TREE_TYPE (decl);
9188 expr = add_objc_string (TREE_VALUE (chain), class_names);
9189 expr = convert (type, expr); /* cast! */
9191 /* The decl that is the one that we
9192 forward declared in build_class_reference. */
9193 finish_var_decl (decl, expr);
9194 return;
9197 static void
9198 handle_class_ref (tree chain)
9200 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9201 char *string = (char *) alloca (strlen (name) + 30);
9202 tree decl;
9203 tree exp;
9205 sprintf (string, "%sobjc_class_name_%s",
9206 (flag_next_runtime ? "." : "__"), name);
9208 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9209 if (flag_next_runtime)
9211 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9212 return;
9214 #endif
9216 /* Make a decl for this name, so we can use its address in a tree. */
9217 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9218 DECL_EXTERNAL (decl) = 1;
9219 TREE_PUBLIC (decl) = 1;
9221 pushdecl (decl);
9222 rest_of_decl_compilation (decl, 0, 0);
9224 /* Make a decl for the address. */
9225 sprintf (string, "%sobjc_class_ref_%s",
9226 (flag_next_runtime ? "." : "__"), name);
9227 exp = build1 (ADDR_EXPR, string_type_node, decl);
9228 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9229 DECL_INITIAL (decl) = exp;
9230 TREE_STATIC (decl) = 1;
9231 TREE_USED (decl) = 1;
9233 pushdecl (decl);
9234 rest_of_decl_compilation (decl, 0, 0);
9237 static void
9238 handle_impent (struct imp_entry *impent)
9240 char *string;
9242 objc_implementation_context = impent->imp_context;
9243 implementation_template = impent->imp_template;
9245 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9247 const char *const class_name =
9248 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9250 string = (char *) alloca (strlen (class_name) + 30);
9252 sprintf (string, "%sobjc_class_name_%s",
9253 (flag_next_runtime ? "." : "__"), class_name);
9255 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9257 const char *const class_name =
9258 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9259 const char *const class_super_name =
9260 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9262 string = (char *) alloca (strlen (class_name)
9263 + strlen (class_super_name) + 30);
9265 /* Do the same for categories. Even though no references to
9266 these symbols are generated automatically by the compiler, it
9267 gives you a handle to pull them into an archive by hand. */
9268 sprintf (string, "*%sobjc_category_name_%s_%s",
9269 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9271 else
9272 return;
9274 #ifdef ASM_DECLARE_CLASS_REFERENCE
9275 if (flag_next_runtime)
9277 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9278 return;
9280 else
9281 #endif
9283 tree decl, init;
9285 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9286 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9287 TREE_PUBLIC (decl) = 1;
9288 TREE_READONLY (decl) = 1;
9289 TREE_USED (decl) = 1;
9290 TREE_CONSTANT (decl) = 1;
9291 DECL_CONTEXT (decl) = 0;
9292 DECL_ARTIFICIAL (decl) = 1;
9293 DECL_INITIAL (decl) = init;
9294 assemble_variable (decl, 1, 0, 0);
9298 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9299 later requires that ObjC translation units participating in F&C be
9300 specially marked. The following routine accomplishes this. */
9302 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9304 static void
9305 generate_objc_image_info (void)
9307 tree decl, initlist;
9308 int flags
9309 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9310 | (flag_objc_gc ? 2 : 0));
9312 decl = start_var_decl (build_array_type
9313 (integer_type_node,
9314 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9315 "_OBJC_IMAGE_INFO");
9317 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9318 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9319 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9321 finish_var_decl (decl, initlist);
9324 /* Look up ID as an instance variable. OTHER contains the result of
9325 the C or C++ lookup, which we may want to use instead. */
9327 tree
9328 objc_lookup_ivar (tree other, tree id)
9330 tree ivar;
9332 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9333 if (!objc_method_context)
9334 return other;
9336 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9337 /* We have a message to super. */
9338 return get_super_receiver ();
9340 /* In a class method, look up an instance variable only as a last
9341 resort. */
9342 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9343 && other && other != error_mark_node)
9344 return other;
9346 /* Look up the ivar, but do not use it if it is not accessible. */
9347 ivar = is_ivar (objc_ivar_chain, id);
9349 if (!ivar || is_private (ivar))
9350 return other;
9352 /* In an instance method, a local variable (or parameter) may hide the
9353 instance variable. */
9354 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9355 && other && other != error_mark_node
9356 #ifdef OBJCPLUS
9357 && CP_DECL_CONTEXT (other) != global_namespace)
9358 #else
9359 && !DECL_FILE_SCOPE_P (other))
9360 #endif
9362 warning (0, "local declaration of %qs hides instance variable",
9363 IDENTIFIER_POINTER (id));
9365 return other;
9368 /* At this point, we are either in an instance method with no obscuring
9369 local definitions, or in a class method with no alternate definitions
9370 at all. */
9371 return build_ivar_reference (id);
9374 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9375 needs to be done if we are calling a function through a cast. */
9377 tree
9378 objc_rewrite_function_call (tree function, tree params)
9380 if (TREE_CODE (function) == NOP_EXPR
9381 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9382 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9383 == FUNCTION_DECL)
9385 function = build (OBJ_TYPE_REF, TREE_TYPE (function),
9386 TREE_OPERAND (function, 0),
9387 TREE_VALUE (params), size_zero_node);
9390 return function;
9393 /* Look for the special case of OBJC_TYPE_REF with the address of
9394 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9395 of its cousins). */
9397 enum gimplify_status
9398 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9400 enum gimplify_status r0, r1;
9401 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9402 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9403 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9404 == FUNCTION_DECL)
9406 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9407 value of the OBJ_TYPE_REF, so force them to be emitted
9408 during subexpression evaluation rather than after the
9409 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9410 C to use direct rather than indirect calls when the
9411 object expression has a postincrement. */
9412 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9413 is_gimple_val, fb_rvalue);
9414 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9415 is_gimple_val, fb_rvalue);
9417 return MIN (r0, r1);
9420 #ifdef OBJCPLUS
9421 return cp_gimplify_expr (expr_p, pre_p, post_p);
9422 #else
9423 return c_gimplify_expr (expr_p, pre_p, post_p);
9424 #endif
9427 /* Given a CALL expression, find the function being called. The ObjC
9428 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9430 tree
9431 objc_get_callee_fndecl (tree call_expr)
9433 tree addr = TREE_OPERAND (call_expr, 0);
9434 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9435 return 0;
9437 addr = OBJ_TYPE_REF_EXPR (addr);
9439 /* If the address is just `&f' for some function `f', then we know
9440 that `f' is being called. */
9441 if (TREE_CODE (addr) == ADDR_EXPR
9442 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9443 return TREE_OPERAND (addr, 0);
9445 return 0;
9448 #include "gt-objc-objc-act.h"