* var-tracking.c (insn_stack_adjust_offset_pre_post): If insn has a
[official-gcc.git] / gcc / objc / objc-act.c
blobc23fb9ecba247722987a888d54a099e5c12d89c4
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, 2007, 2008 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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
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 /* If gen_declaration desired, open the output file. */
488 if (flag_gen_declaration)
490 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
491 gen_declaration_file = fopen (dumpname, "w");
492 if (gen_declaration_file == 0)
493 fatal_error ("can't open %s: %m", dumpname);
494 free (dumpname);
497 if (flag_next_runtime)
499 TAG_GETCLASS = "objc_getClass";
500 TAG_GETMETACLASS = "objc_getMetaClass";
501 TAG_MSGSEND = "objc_msgSend";
502 TAG_MSGSENDSUPER = "objc_msgSendSuper";
503 TAG_MSGSEND_STRET = "objc_msgSend_stret";
504 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
505 default_constant_string_class_name = "NSConstantString";
507 else
509 TAG_GETCLASS = "objc_get_class";
510 TAG_GETMETACLASS = "objc_get_meta_class";
511 TAG_MSGSEND = "objc_msg_lookup";
512 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
513 /* GNU runtime does not provide special functions to support
514 structure-returning methods. */
515 default_constant_string_class_name = "NXConstantString";
516 flag_typed_selectors = 1;
519 init_objc ();
521 if (print_struct_values)
522 generate_struct_by_value_array ();
524 return true;
527 void
528 objc_finish_file (void)
530 mark_referenced_methods ();
532 #ifdef OBJCPLUS
533 /* We need to instantiate templates _before_ we emit ObjC metadata;
534 if we do not, some metadata (such as selectors) may go missing. */
535 at_eof = 1;
536 instantiate_pending_templates (0);
537 #endif
539 /* Finalize Objective-C runtime data. No need to generate tables
540 and code if only checking syntax, or if generating a PCH file. */
541 if (!flag_syntax_only && !pch_file)
542 finish_objc ();
544 if (gen_declaration_file)
545 fclose (gen_declaration_file);
548 /* Return the first occurrence of a method declaration corresponding
549 to sel_name in rproto_list. Search rproto_list recursively.
550 If is_class is 0, search for instance methods, otherwise for class
551 methods. */
552 static tree
553 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
554 int is_class)
556 tree rproto, p;
557 tree fnd = 0;
559 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
561 p = TREE_VALUE (rproto);
563 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
565 if ((fnd = lookup_method (is_class
566 ? PROTOCOL_CLS_METHODS (p)
567 : PROTOCOL_NST_METHODS (p), sel_name)))
569 else if (PROTOCOL_LIST (p))
570 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
571 sel_name, is_class);
573 else
575 ; /* An identifier...if we could not find a protocol. */
578 if (fnd)
579 return fnd;
582 return 0;
585 static tree
586 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
588 tree rproto, p;
590 /* Make sure the protocol is supported by the object on the rhs. */
591 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
593 tree fnd = 0;
594 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
596 p = TREE_VALUE (rproto);
598 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
600 if (lproto == p)
601 fnd = lproto;
603 else if (PROTOCOL_LIST (p))
604 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
607 if (fnd)
608 return fnd;
611 else
613 ; /* An identifier...if we could not find a protocol. */
616 return 0;
619 void
620 objc_start_class_interface (tree klass, tree super_class, tree protos)
622 objc_interface_context
623 = objc_ivar_context
624 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
625 objc_public_flag = 0;
628 void
629 objc_start_category_interface (tree klass, tree categ, tree protos)
631 objc_interface_context
632 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
633 objc_ivar_chain
634 = continue_class (objc_interface_context);
637 void
638 objc_start_protocol (tree name, tree protos)
640 objc_interface_context
641 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
644 void
645 objc_continue_interface (void)
647 objc_ivar_chain
648 = continue_class (objc_interface_context);
651 void
652 objc_finish_interface (void)
654 finish_class (objc_interface_context);
655 objc_interface_context = NULL_TREE;
658 void
659 objc_start_class_implementation (tree klass, tree super_class)
661 objc_implementation_context
662 = objc_ivar_context
663 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
664 objc_public_flag = 0;
667 void
668 objc_start_category_implementation (tree klass, tree categ)
670 objc_implementation_context
671 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
672 objc_ivar_chain
673 = continue_class (objc_implementation_context);
676 void
677 objc_continue_implementation (void)
679 objc_ivar_chain
680 = continue_class (objc_implementation_context);
683 void
684 objc_finish_implementation (void)
686 #ifdef OBJCPLUS
687 if (flag_objc_call_cxx_cdtors)
688 objc_generate_cxx_cdtors ();
689 #endif
691 if (objc_implementation_context)
693 finish_class (objc_implementation_context);
694 objc_ivar_chain = NULL_TREE;
695 objc_implementation_context = NULL_TREE;
697 else
698 warning (0, "%<@end%> must appear in an @implementation context");
701 void
702 objc_set_visibility (int visibility)
704 objc_public_flag = visibility;
707 void
708 objc_set_method_type (enum tree_code type)
710 objc_inherit_code = (type == PLUS_EXPR
711 ? CLASS_METHOD_DECL
712 : INSTANCE_METHOD_DECL);
715 tree
716 objc_build_method_signature (tree rettype, tree selector,
717 tree optparms, bool ellipsis)
719 return build_method_decl (objc_inherit_code, rettype, selector,
720 optparms, ellipsis);
723 void
724 objc_add_method_declaration (tree decl)
726 if (!objc_interface_context)
727 fatal_error ("method declaration not in @interface context");
729 objc_add_method (objc_interface_context,
730 decl,
731 objc_inherit_code == CLASS_METHOD_DECL);
734 void
735 objc_start_method_definition (tree decl)
737 if (!objc_implementation_context)
738 fatal_error ("method definition not in @implementation context");
740 objc_add_method (objc_implementation_context,
741 decl,
742 objc_inherit_code == CLASS_METHOD_DECL);
743 start_method_def (decl);
746 void
747 objc_add_instance_variable (tree decl)
749 (void) add_instance_variable (objc_ivar_context,
750 objc_public_flag,
751 decl);
754 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
755 an '@'. */
758 objc_is_reserved_word (tree ident)
760 unsigned char code = C_RID_CODE (ident);
762 return (OBJC_IS_AT_KEYWORD (code)
763 || code == RID_CLASS || code == RID_PUBLIC
764 || code == RID_PROTECTED || code == RID_PRIVATE
765 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
768 /* Return true if TYPE is 'id'. */
770 static bool
771 objc_is_object_id (tree type)
773 return OBJC_TYPE_NAME (type) == objc_object_id;
776 static bool
777 objc_is_class_id (tree type)
779 return OBJC_TYPE_NAME (type) == objc_class_id;
782 /* Construct a C struct with same name as KLASS, a base struct with tag
783 SUPER_NAME (if any), and FIELDS indicated. */
785 static tree
786 objc_build_struct (tree klass, tree fields, tree super_name)
788 tree name = CLASS_NAME (klass);
789 tree s = start_struct (RECORD_TYPE, name);
790 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
791 tree t, objc_info = NULL_TREE;
793 if (super)
795 /* Prepend a packed variant of the base class into the layout. This
796 is necessary to preserve ObjC ABI compatibility. */
797 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
798 tree field = TYPE_FIELDS (super);
800 while (field && TREE_CHAIN (field)
801 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
802 field = TREE_CHAIN (field);
804 /* For ObjC ABI purposes, the "packed" size of a base class is
805 the sum of the offset and the size (in bits) of the last field
806 in the class. */
807 DECL_SIZE (base)
808 = (field && TREE_CODE (field) == FIELD_DECL
809 ? size_binop (PLUS_EXPR,
810 size_binop (PLUS_EXPR,
811 size_binop
812 (MULT_EXPR,
813 convert (bitsizetype,
814 DECL_FIELD_OFFSET (field)),
815 bitsize_int (BITS_PER_UNIT)),
816 DECL_FIELD_BIT_OFFSET (field)),
817 DECL_SIZE (field))
818 : bitsize_zero_node);
819 DECL_SIZE_UNIT (base)
820 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
821 size_int (BITS_PER_UNIT));
822 DECL_ARTIFICIAL (base) = 1;
823 DECL_ALIGN (base) = 1;
824 DECL_FIELD_CONTEXT (base) = s;
825 #ifdef OBJCPLUS
826 DECL_FIELD_IS_BASE (base) = 1;
828 if (fields)
829 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
830 #endif /* are following the ObjC ABI here. */
831 TREE_CHAIN (base) = fields;
832 fields = base;
835 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
836 in all variants of this RECORD_TYPE to be clobbered, but it is therein
837 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
838 Hence, we must squirrel away the ObjC-specific information before calling
839 finish_struct(), and then reinstate it afterwards. */
841 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
842 objc_info
843 = chainon (objc_info,
844 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
846 /* Point the struct at its related Objective-C class. */
847 INIT_TYPE_OBJC_INFO (s);
848 TYPE_OBJC_INTERFACE (s) = klass;
850 s = finish_struct (s, fields, NULL_TREE);
852 for (t = TYPE_NEXT_VARIANT (s); t;
853 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
855 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
856 /* Replace the IDENTIFIER_NODE with an actual @interface. */
857 TYPE_OBJC_INTERFACE (t) = klass;
860 /* Use TYPE_BINFO structures to point at the super class, if any. */
861 objc_xref_basetypes (s, super);
863 /* Mark this struct as a class template. */
864 CLASS_STATIC_TEMPLATE (klass) = s;
866 return s;
869 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
870 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
871 process. */
872 static tree
873 objc_build_volatilized_type (tree type)
875 tree t;
877 /* Check if we have not constructed the desired variant already. */
878 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
880 /* The type qualifiers must (obviously) match up. */
881 if (!TYPE_VOLATILE (t)
882 || (TYPE_READONLY (t) != TYPE_READONLY (type))
883 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
884 continue;
886 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
887 info, if any) must match up. */
888 if (POINTER_TYPE_P (t)
889 && (TREE_TYPE (t) != TREE_TYPE (type)))
890 continue;
892 /* Everything matches up! */
893 return t;
896 /* Ok, we could not re-use any of the pre-existing variants. Create
897 a new one. */
898 t = build_variant_type_copy (type);
899 TYPE_VOLATILE (t) = 1;
901 /* Set up the canonical type information. */
902 if (TYPE_STRUCTURAL_EQUALITY_P (type))
903 SET_TYPE_STRUCTURAL_EQUALITY (t);
904 else if (TYPE_CANONICAL (type) != type)
905 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
906 else
907 TYPE_CANONICAL (t) = t;
909 return t;
912 /* Mark DECL as being 'volatile' for purposes of Darwin
913 _setjmp()/_longjmp() exception handling. Called from
914 objc_mark_locals_volatile(). */
915 void
916 objc_volatilize_decl (tree decl)
918 /* Do not mess with variables that are 'static' or (already)
919 'volatile'. */
920 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
921 && (TREE_CODE (decl) == VAR_DECL
922 || TREE_CODE (decl) == PARM_DECL))
924 tree t = TREE_TYPE (decl);
925 struct volatilized_type key;
926 void **loc;
928 t = objc_build_volatilized_type (t);
929 key.type = t;
930 loc = htab_find_slot (volatilized_htab, &key, INSERT);
932 if (!*loc)
934 *loc = ggc_alloc (sizeof (key));
935 ((struct volatilized_type *) *loc)->type = t;
938 TREE_TYPE (decl) = t;
939 TREE_THIS_VOLATILE (decl) = 1;
940 TREE_SIDE_EFFECTS (decl) = 1;
941 DECL_REGISTER (decl) = 0;
942 #ifndef OBJCPLUS
943 C_DECL_REGISTER (decl) = 0;
944 #endif
948 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
949 (including its categories and superclasses) or by object type TYP.
950 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
952 static bool
953 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
955 bool class_type = (cls != NULL_TREE);
957 while (cls)
959 tree c;
961 /* Check protocols adopted by the class and its categories. */
962 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
964 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
965 return true;
968 /* Repeat for superclasses. */
969 cls = lookup_interface (CLASS_SUPER_NAME (cls));
972 /* Check for any protocols attached directly to the object type. */
973 if (TYPE_HAS_OBJC_INFO (typ))
975 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
976 return true;
979 if (warn)
981 strcpy (errbuf, class_type ? "class \'" : "type \'");
982 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
983 strcat (errbuf, "\' does not ");
984 /* NB: Types 'id' and 'Class' cannot reasonably be described as
985 "implementing" a given protocol, since they do not have an
986 implementation. */
987 strcat (errbuf, class_type ? "implement" : "conform to");
988 strcat (errbuf, " the \'");
989 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
990 strcat (errbuf, "\' protocol");
991 warning (0, errbuf);
994 return false;
997 /* Check if class RCLS and instance struct type RTYP conform to at least the
998 same protocols that LCLS and LTYP conform to. */
1000 static bool
1001 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1003 tree p;
1004 bool have_lproto = false;
1006 while (lcls)
1008 /* NB: We do _not_ look at categories defined for LCLS; these may or
1009 may not get loaded in, and therefore it is unreasonable to require
1010 that RCLS/RTYP must implement any of their protocols. */
1011 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1013 have_lproto = true;
1015 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1016 return warn;
1019 /* Repeat for superclasses. */
1020 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1023 /* Check for any protocols attached directly to the object type. */
1024 if (TYPE_HAS_OBJC_INFO (ltyp))
1026 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1028 have_lproto = true;
1030 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1031 return warn;
1035 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1036 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1037 away with simply checking for 'id' or 'Class' (!RCLS), since this
1038 routine will not get called in other cases. */
1039 return have_lproto || (rcls != NULL_TREE);
1042 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1043 an instance of RTYP to an instance of LTYP or to compare the two
1044 (if ARGNO is equal to -3), per ObjC type system rules. Before
1045 returning 'true', this routine may issue warnings related to, e.g.,
1046 protocol conformance. When returning 'false', the routine must
1047 produce absolutely no warnings; the C or C++ front-end will do so
1048 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1049 the routine must return 'false'.
1051 The ARGNO parameter is encoded as follows:
1052 >= 1 Parameter number (CALLEE contains function being called);
1053 0 Return value;
1054 -1 Assignment;
1055 -2 Initialization;
1056 -3 Comparison (LTYP and RTYP may match in either direction). */
1058 bool
1059 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1061 tree lcls, rcls, lproto, rproto;
1062 bool pointers_compatible;
1064 /* We must be dealing with pointer types */
1065 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1066 return false;
1070 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1071 rtyp = TREE_TYPE (rtyp);
1073 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1075 /* Past this point, we are only interested in ObjC class instances,
1076 or 'id' or 'Class'. */
1077 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1078 return false;
1080 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1081 && !TYPE_HAS_OBJC_INFO (ltyp))
1082 return false;
1084 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1085 && !TYPE_HAS_OBJC_INFO (rtyp))
1086 return false;
1088 /* Past this point, we are committed to returning 'true' to the caller.
1089 However, we can still warn about type and/or protocol mismatches. */
1091 if (TYPE_HAS_OBJC_INFO (ltyp))
1093 lcls = TYPE_OBJC_INTERFACE (ltyp);
1094 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1096 else
1097 lcls = lproto = NULL_TREE;
1099 if (TYPE_HAS_OBJC_INFO (rtyp))
1101 rcls = TYPE_OBJC_INTERFACE (rtyp);
1102 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1104 else
1105 rcls = rproto = NULL_TREE;
1107 /* If we could not find an @interface declaration, we must have
1108 only seen a @class declaration; for purposes of type comparison,
1109 treat it as a stand-alone (root) class. */
1111 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1112 lcls = NULL_TREE;
1114 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1115 rcls = NULL_TREE;
1117 /* If either type is an unqualified 'id', we're done. */
1118 if ((!lproto && objc_is_object_id (ltyp))
1119 || (!rproto && objc_is_object_id (rtyp)))
1120 return true;
1122 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1124 /* If the underlying types are the same, and at most one of them has
1125 a protocol list, we do not need to issue any diagnostics. */
1126 if (pointers_compatible && (!lproto || !rproto))
1127 return true;
1129 /* If exactly one of the types is 'Class', issue a diagnostic; any
1130 exceptions of this rule have already been handled. */
1131 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1132 pointers_compatible = false;
1133 /* Otherwise, check for inheritance relations. */
1134 else
1136 if (!pointers_compatible)
1137 pointers_compatible
1138 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1140 if (!pointers_compatible)
1141 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1143 if (!pointers_compatible && argno == -3)
1144 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1147 /* If the pointers match modulo protocols, check for protocol conformance
1148 mismatches. */
1149 if (pointers_compatible)
1151 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1152 argno != -3);
1154 if (!pointers_compatible && argno == -3)
1155 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1156 argno != -3);
1159 if (!pointers_compatible)
1161 /* NB: For the time being, we shall make our warnings look like their
1162 C counterparts. In the future, we may wish to make them more
1163 ObjC-specific. */
1164 switch (argno)
1166 case -3:
1167 warning (0, "comparison of distinct Objective-C types lacks a cast");
1168 break;
1170 case -2:
1171 warning (0, "initialization from distinct Objective-C type");
1172 break;
1174 case -1:
1175 warning (0, "assignment from distinct Objective-C type");
1176 break;
1178 case 0:
1179 warning (0, "distinct Objective-C type in return");
1180 break;
1182 default:
1183 warning (0, "passing argument %d of %qE from distinct "
1184 "Objective-C type", argno, callee);
1185 break;
1189 return true;
1192 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1193 lives in the volatilized hash table, ignore the 'volatile' bit when
1194 making the comparison. */
1196 bool
1197 objc_type_quals_match (tree ltyp, tree rtyp)
1199 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1200 struct volatilized_type key;
1202 key.type = ltyp;
1204 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1205 lquals &= ~TYPE_QUAL_VOLATILE;
1207 key.type = rtyp;
1209 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1210 rquals &= ~TYPE_QUAL_VOLATILE;
1212 return (lquals == rquals);
1215 #ifndef OBJCPLUS
1216 /* Determine if CHILD is derived from PARENT. The routine assumes that
1217 both parameters are RECORD_TYPEs, and is non-reflexive. */
1219 static bool
1220 objc_derived_from_p (tree parent, tree child)
1222 parent = TYPE_MAIN_VARIANT (parent);
1224 for (child = TYPE_MAIN_VARIANT (child);
1225 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1227 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1228 (TYPE_BINFO (child),
1229 0)));
1231 if (child == parent)
1232 return true;
1235 return false;
1237 #endif
1239 static tree
1240 objc_build_component_ref (tree datum, tree component)
1242 /* If COMPONENT is NULL, the caller is referring to the anonymous
1243 base class field. */
1244 if (!component)
1246 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1248 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1251 /* The 'build_component_ref' routine has been removed from the C++
1252 front-end, but 'finish_class_member_access_expr' seems to be
1253 a worthy substitute. */
1254 #ifdef OBJCPLUS
1255 return finish_class_member_access_expr (datum, component, false,
1256 tf_warning_or_error);
1257 #else
1258 return build_component_ref (datum, component);
1259 #endif
1262 /* Recursively copy inheritance information rooted at BINFO. To do this,
1263 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1265 static tree
1266 objc_copy_binfo (tree binfo)
1268 tree btype = BINFO_TYPE (binfo);
1269 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1270 tree base_binfo;
1271 int ix;
1273 BINFO_TYPE (binfo2) = btype;
1274 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1275 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1277 /* Recursively copy base binfos of BINFO. */
1278 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1280 tree base_binfo2 = objc_copy_binfo (base_binfo);
1282 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1283 BINFO_BASE_APPEND (binfo2, base_binfo2);
1286 return binfo2;
1289 /* Record superclass information provided in BASETYPE for ObjC class REF.
1290 This is loosely based on cp/decl.c:xref_basetypes(). */
1292 static void
1293 objc_xref_basetypes (tree ref, tree basetype)
1295 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1297 TYPE_BINFO (ref) = binfo;
1298 BINFO_OFFSET (binfo) = size_zero_node;
1299 BINFO_TYPE (binfo) = ref;
1301 if (basetype)
1303 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1305 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1306 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1307 BINFO_BASE_APPEND (binfo, base_binfo);
1308 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1312 static hashval_t
1313 volatilized_hash (const void *ptr)
1315 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1317 return htab_hash_pointer(typ);
1320 static int
1321 volatilized_eq (const void *ptr1, const void *ptr2)
1323 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1324 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1326 return typ1 == typ2;
1329 /* Called from finish_decl. */
1331 void
1332 objc_check_decl (tree decl)
1334 tree type = TREE_TYPE (decl);
1336 if (TREE_CODE (type) != RECORD_TYPE)
1337 return;
1338 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1339 error ("statically allocated instance of Objective-C class %qs",
1340 IDENTIFIER_POINTER (type));
1343 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1344 either name an Objective-C class, or refer to the special 'id' or 'Class'
1345 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1347 tree
1348 objc_get_protocol_qualified_type (tree interface, tree protocols)
1350 /* If INTERFACE is not provided, default to 'id'. */
1351 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1352 bool is_ptr = (type != NULL_TREE);
1354 if (!is_ptr)
1356 type = objc_is_class_name (interface);
1358 if (type)
1359 type = xref_tag (RECORD_TYPE, type);
1360 else
1361 return interface;
1364 if (protocols)
1366 type = build_variant_type_copy (type);
1368 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1369 to the pointee. */
1370 if (is_ptr)
1372 tree orig_pointee_type = TREE_TYPE (type);
1373 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1375 /* Set up the canonical type information. */
1376 TYPE_CANONICAL (type)
1377 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1379 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1380 type = TREE_TYPE (type);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1385 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1389 if (is_ptr)
1390 type = TYPE_POINTER_TO (type);
1391 else
1392 TYPE_OBJC_INTERFACE (type)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1396 return type;
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1401 conforms to. */
1403 static void
1404 check_protocol_recursively (tree proto, tree list)
1406 tree p;
1408 for (p = list; p; p = TREE_CHAIN (p))
1410 tree pp = TREE_VALUE (p);
1412 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1413 pp = lookup_protocol (pp);
1415 if (pp == proto)
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1418 if (pp)
1419 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1426 static tree
1427 lookup_and_install_protocols (tree protocols)
1429 tree proto;
1430 tree return_value = NULL_TREE;
1432 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1434 tree ident = TREE_VALUE (proto);
1435 tree p = lookup_protocol (ident);
1437 if (p)
1438 return_value = chainon (return_value,
1439 build_tree_list (NULL_TREE, p));
1440 else if (ident != error_mark_node)
1441 error ("cannot find protocol declaration for %qs",
1442 IDENTIFIER_POINTER (ident));
1445 return return_value;
1448 /* Create a declaration for field NAME of a given TYPE. */
1450 static tree
1451 create_field_decl (tree type, const char *name)
1453 return build_decl (FIELD_DECL, get_identifier (name), type);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1459 static tree
1460 start_var_decl (tree type, const char *name)
1462 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1464 TREE_STATIC (var) = 1;
1465 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var) = 1;
1467 DECL_ARTIFICIAL (var) = 1;
1468 DECL_CONTEXT (var) = NULL_TREE;
1469 #ifdef OBJCPLUS
1470 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1471 #endif
1473 return var;
1476 /* Finish off the variable declaration created by start_var_decl(). */
1478 static void
1479 finish_var_decl (tree var, tree initializer)
1481 finish_decl (var, initializer, NULL_TREE);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1491 static tree
1492 setup_string_decl (void)
1494 char *name;
1495 size_t length;
1497 /* %s in format will provide room for terminating null */
1498 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1499 + strlen (constant_string_class_name);
1500 name = XNEWVEC (char, length);
1501 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1502 constant_string_class_name);
1503 constant_string_global_id = get_identifier (name);
1504 string_class_decl = lookup_name (constant_string_global_id);
1506 return string_class_decl;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1512 Model:
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1520 static void
1521 synth_module_prologue (void)
1523 tree type;
1524 enum debug_info_type save_write_symbols = write_symbols;
1525 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn't been called yet. */
1529 write_symbols = NO_DEBUG;
1530 debug_hooks = &do_nothing_debug_hooks;
1532 #ifdef OBJCPLUS
1533 push_lang_context (lang_name_c); /* extern "C" */
1534 #endif
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id = get_identifier (TAG_OBJECT);
1539 objc_class_id = get_identifier (TAG_CLASS);
1541 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1542 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1544 objc_object_type = build_pointer_type (objc_object_reference);
1545 objc_class_type = build_pointer_type (objc_class_reference);
1547 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1548 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1553 objc_object_name,
1554 objc_object_type));
1555 TREE_NO_WARNING (type) = 1;
1556 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1557 objc_class_name,
1558 objc_class_type));
1559 TREE_NO_WARNING (type) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1564 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1565 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1566 type));
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime)
1571 /* `struct objc_selector *' */
1572 objc_selector_type
1573 = build_pointer_type (xref_tag (RECORD_TYPE,
1574 get_identifier (TAG_SELECTOR)));
1575 else
1576 /* `const struct objc_selector *' */
1577 objc_selector_type
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE,
1580 get_identifier (TAG_SELECTOR)),
1581 TYPE_QUAL_CONST));
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1587 get_identifier (TAG_SUPER)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr = build_pointer_type
1591 (xref_tag (RECORD_TYPE,
1592 get_identifier (UTAG_METHOD_LIST)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1596 objc_ivar_list_ptr = build_pointer_type
1597 (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_IVAR_LIST)));
1600 /* TREE_NOTHROW is cleared for the message-sending functions,
1601 because the function that gets called can throw in Obj-C++, or
1602 could itself call something that can throw even in Obj-C. */
1604 if (flag_next_runtime)
1606 /* NB: In order to call one of the ..._stret (struct-returning)
1607 functions, the function *MUST* first be cast to a signature that
1608 corresponds to the actual ObjC method being invoked. This is
1609 what is done by the build_objc_method_call() routine below. */
1611 /* id objc_msgSend (id, SEL, ...); */
1612 /* id objc_msgSendNonNil (id, SEL, ...); */
1613 /* id objc_msgSend_stret (id, SEL, ...); */
1614 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1615 type
1616 = build_function_type (objc_object_type,
1617 tree_cons (NULL_TREE, objc_object_type,
1618 tree_cons (NULL_TREE, objc_selector_type,
1619 NULL_TREE)));
1620 umsg_decl = add_builtin_function (TAG_MSGSEND,
1621 type, 0, NOT_BUILT_IN,
1622 NULL, NULL_TREE);
1623 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1624 type, 0, NOT_BUILT_IN,
1625 NULL, NULL_TREE);
1626 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1627 type, 0, NOT_BUILT_IN,
1628 NULL, NULL_TREE);
1629 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1630 type, 0, NOT_BUILT_IN,
1631 NULL, NULL_TREE);
1633 /* These can throw, because the function that gets called can throw
1634 in Obj-C++, or could itself call something that can throw even
1635 in Obj-C. */
1636 TREE_NOTHROW (umsg_decl) = 0;
1637 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1638 TREE_NOTHROW (umsg_stret_decl) = 0;
1639 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1641 /* id objc_msgSend_Fast (id, SEL, ...)
1642 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1643 #ifdef OFFS_MSGSEND_FAST
1644 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1645 type, 0, NOT_BUILT_IN,
1646 NULL, NULL_TREE);
1647 TREE_NOTHROW (umsg_fast_decl) = 0;
1648 DECL_ATTRIBUTES (umsg_fast_decl)
1649 = tree_cons (get_identifier ("hard_coded_address"),
1650 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1651 NULL_TREE);
1652 #else
1653 /* No direct dispatch available. */
1654 umsg_fast_decl = umsg_decl;
1655 #endif
1657 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1658 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1659 type
1660 = build_function_type (objc_object_type,
1661 tree_cons (NULL_TREE, objc_super_type,
1662 tree_cons (NULL_TREE, objc_selector_type,
1663 NULL_TREE)));
1664 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1665 type, 0, NOT_BUILT_IN,
1666 NULL, NULL_TREE);
1667 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1668 type, 0, NOT_BUILT_IN, 0,
1669 NULL_TREE);
1670 TREE_NOTHROW (umsg_super_decl) = 0;
1671 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1673 else
1675 /* GNU runtime messenger entry points. */
1677 /* typedef id (*IMP)(id, SEL, ...); */
1678 tree IMP_type
1679 = build_pointer_type
1680 (build_function_type (objc_object_type,
1681 tree_cons (NULL_TREE, objc_object_type,
1682 tree_cons (NULL_TREE, objc_selector_type,
1683 NULL_TREE))));
1685 /* IMP objc_msg_lookup (id, SEL); */
1686 type
1687 = build_function_type (IMP_type,
1688 tree_cons (NULL_TREE, objc_object_type,
1689 tree_cons (NULL_TREE, objc_selector_type,
1690 OBJC_VOID_AT_END)));
1691 umsg_decl = add_builtin_function (TAG_MSGSEND,
1692 type, 0, NOT_BUILT_IN,
1693 NULL, NULL_TREE);
1694 TREE_NOTHROW (umsg_decl) = 0;
1696 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1697 type
1698 = build_function_type (IMP_type,
1699 tree_cons (NULL_TREE, objc_super_type,
1700 tree_cons (NULL_TREE, objc_selector_type,
1701 OBJC_VOID_AT_END)));
1702 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1703 type, 0, NOT_BUILT_IN,
1704 NULL, NULL_TREE);
1705 TREE_NOTHROW (umsg_super_decl) = 0;
1707 /* The following GNU runtime entry point is called to initialize
1708 each module:
1710 __objc_exec_class (void *); */
1711 type
1712 = build_function_type (void_type_node,
1713 tree_cons (NULL_TREE, ptr_type_node,
1714 OBJC_VOID_AT_END));
1715 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1716 type, 0, NOT_BUILT_IN,
1717 NULL, NULL_TREE);
1720 /* id objc_getClass (const char *); */
1722 type = build_function_type (objc_object_type,
1723 tree_cons (NULL_TREE,
1724 const_string_type_node,
1725 OBJC_VOID_AT_END));
1727 objc_get_class_decl
1728 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1729 NULL, NULL_TREE);
1731 /* id objc_getMetaClass (const char *); */
1733 objc_get_meta_class_decl
1734 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1736 build_class_template ();
1737 build_super_template ();
1738 build_protocol_template ();
1739 build_category_template ();
1740 build_objc_exception_stuff ();
1742 if (flag_next_runtime)
1743 build_next_objc_exception_stuff ();
1745 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1747 if (! flag_next_runtime)
1748 build_selector_table_decl ();
1750 /* Forward declare constant_string_id and constant_string_type. */
1751 if (!constant_string_class_name)
1752 constant_string_class_name = default_constant_string_class_name;
1754 constant_string_id = get_identifier (constant_string_class_name);
1755 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1757 /* Pre-build the following entities - for speed/convenience. */
1758 self_id = get_identifier ("self");
1759 ucmd_id = get_identifier ("_cmd");
1761 #ifdef OBJCPLUS
1762 pop_lang_context ();
1763 #endif
1765 write_symbols = save_write_symbols;
1766 debug_hooks = save_hooks;
1769 /* Ensure that the ivar list for NSConstantString/NXConstantString
1770 (or whatever was specified via `-fconstant-string-class')
1771 contains fields at least as large as the following three, so that
1772 the runtime can stomp on them with confidence:
1774 struct STRING_OBJECT_CLASS_NAME
1776 Object isa;
1777 char *cString;
1778 unsigned int length;
1779 }; */
1781 static int
1782 check_string_class_template (void)
1784 tree field_decl = objc_get_class_ivars (constant_string_id);
1786 #define AT_LEAST_AS_LARGE_AS(F, T) \
1787 (F && TREE_CODE (F) == FIELD_DECL \
1788 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1789 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1791 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1792 return 0;
1794 field_decl = TREE_CHAIN (field_decl);
1795 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1796 return 0;
1798 field_decl = TREE_CHAIN (field_decl);
1799 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1801 #undef AT_LEAST_AS_LARGE_AS
1804 /* Avoid calling `check_string_class_template ()' more than once. */
1805 static GTY(()) int string_layout_checked;
1807 /* Construct an internal string layout to be used as a template for
1808 creating NSConstantString/NXConstantString instances. */
1810 static tree
1811 objc_build_internal_const_str_type (void)
1813 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1814 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1815 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1817 TREE_CHAIN (field) = fields; fields = field;
1818 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1819 TREE_CHAIN (field) = fields; fields = field;
1820 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1821 reverse order! */
1822 finish_builtin_struct (type, "__builtin_ObjCString",
1823 fields, NULL_TREE);
1825 return type;
1828 /* Custom build_string which sets TREE_TYPE! */
1830 static tree
1831 my_build_string (int len, const char *str)
1833 return fix_string_type (build_string (len, str));
1836 /* Build a string with contents STR and length LEN and convert it to a
1837 pointer. */
1839 static tree
1840 my_build_string_pointer (int len, const char *str)
1842 tree string = my_build_string (len, str);
1843 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1844 return build1 (ADDR_EXPR, ptrtype, string);
1847 static hashval_t
1848 string_hash (const void *ptr)
1850 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1851 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1852 int i, len = TREE_STRING_LENGTH (str);
1853 hashval_t h = len;
1855 for (i = 0; i < len; i++)
1856 h = ((h * 613) + p[i]);
1858 return h;
1861 static int
1862 string_eq (const void *ptr1, const void *ptr2)
1864 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1865 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1866 int len1 = TREE_STRING_LENGTH (str1);
1868 return (len1 == TREE_STRING_LENGTH (str2)
1869 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1870 len1));
1873 /* Given a chain of STRING_CST's, build a static instance of
1874 NXConstantString which points at the concatenation of those
1875 strings. We place the string object in the __string_objects
1876 section of the __OBJC segment. The Objective-C runtime will
1877 initialize the isa pointers of the string objects to point at the
1878 NXConstantString class object. */
1880 tree
1881 objc_build_string_object (tree string)
1883 tree initlist, constructor, constant_string_class;
1884 int length;
1885 tree fields, addr;
1886 struct string_descriptor *desc, key;
1887 void **loc;
1889 /* Prep the string argument. */
1890 string = fix_string_type (string);
1891 TREE_SET_CODE (string, STRING_CST);
1892 length = TREE_STRING_LENGTH (string) - 1;
1894 /* Check whether the string class being used actually exists and has the
1895 correct ivar layout. */
1896 if (!string_layout_checked)
1898 string_layout_checked = -1;
1899 constant_string_class = lookup_interface (constant_string_id);
1900 internal_const_str_type = objc_build_internal_const_str_type ();
1902 if (!constant_string_class
1903 || !(constant_string_type
1904 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1905 error ("cannot find interface declaration for %qs",
1906 IDENTIFIER_POINTER (constant_string_id));
1907 /* The NSConstantString/NXConstantString ivar layout is now known. */
1908 else if (!check_string_class_template ())
1909 error ("interface %qs does not have valid constant string layout",
1910 IDENTIFIER_POINTER (constant_string_id));
1911 /* For the NeXT runtime, we can generate a literal reference
1912 to the string class, don't need to run a constructor. */
1913 else if (flag_next_runtime && !setup_string_decl ())
1914 error ("cannot find reference tag for class %qs",
1915 IDENTIFIER_POINTER (constant_string_id));
1916 else
1918 string_layout_checked = 1; /* Success! */
1919 add_class_reference (constant_string_id);
1923 if (string_layout_checked == -1)
1924 return error_mark_node;
1926 /* Perhaps we already constructed a constant string just like this one? */
1927 key.literal = string;
1928 loc = htab_find_slot (string_htab, &key, INSERT);
1929 desc = (struct string_descriptor *) *loc;
1931 if (!desc)
1933 tree var;
1934 *loc = desc = GGC_NEW (struct string_descriptor);
1935 desc->literal = string;
1937 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1938 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1939 fields = TYPE_FIELDS (internal_const_str_type);
1940 initlist
1941 = build_tree_list (fields,
1942 flag_next_runtime
1943 ? build_unary_op (input_location,
1944 ADDR_EXPR, string_class_decl, 0)
1945 : build_int_cst (NULL_TREE, 0));
1946 fields = TREE_CHAIN (fields);
1947 initlist = tree_cons (fields, build_unary_op (input_location,
1948 ADDR_EXPR, string, 1),
1949 initlist);
1950 fields = TREE_CHAIN (fields);
1951 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1952 initlist);
1953 constructor = objc_build_constructor (internal_const_str_type,
1954 nreverse (initlist));
1956 if (!flag_next_runtime)
1957 constructor
1958 = objc_add_static_instance (constructor, constant_string_type);
1959 else
1961 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1962 DECL_INITIAL (var) = constructor;
1963 TREE_STATIC (var) = 1;
1964 pushdecl_top_level (var);
1965 constructor = var;
1967 desc->constructor = constructor;
1970 addr = convert (build_pointer_type (constant_string_type),
1971 build_unary_op (input_location,
1972 ADDR_EXPR, desc->constructor, 1));
1974 return addr;
1977 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1979 static GTY(()) int num_static_inst;
1981 static tree
1982 objc_add_static_instance (tree constructor, tree class_decl)
1984 tree *chain, decl;
1985 char buf[256];
1987 /* Find the list of static instances for the CLASS_DECL. Create one if
1988 not found. */
1989 for (chain = &objc_static_instances;
1990 *chain && TREE_VALUE (*chain) != class_decl;
1991 chain = &TREE_CHAIN (*chain));
1992 if (!*chain)
1994 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1995 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1998 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1999 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
2000 DECL_COMMON (decl) = 1;
2001 TREE_STATIC (decl) = 1;
2002 DECL_ARTIFICIAL (decl) = 1;
2003 TREE_USED (decl) = 1;
2004 DECL_INITIAL (decl) = constructor;
2006 /* We may be writing something else just now.
2007 Postpone till end of input. */
2008 DECL_DEFER_OUTPUT (decl) = 1;
2009 pushdecl_top_level (decl);
2010 rest_of_decl_compilation (decl, 1, 0);
2012 /* Add the DECL to the head of this CLASS' list. */
2013 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2015 return decl;
2018 /* Build a static constant CONSTRUCTOR
2019 with type TYPE and elements ELTS. */
2021 static tree
2022 objc_build_constructor (tree type, tree elts)
2024 tree constructor = build_constructor_from_list (type, elts);
2026 TREE_CONSTANT (constructor) = 1;
2027 TREE_STATIC (constructor) = 1;
2028 TREE_READONLY (constructor) = 1;
2030 #ifdef OBJCPLUS
2031 /* Adjust for impedance mismatch. We should figure out how to build
2032 CONSTRUCTORs that consistently please both the C and C++ gods. */
2033 if (!TREE_PURPOSE (elts))
2034 TREE_TYPE (constructor) = init_list_type_node;
2035 #endif
2037 return constructor;
2040 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2042 /* Predefine the following data type:
2044 struct _objc_symtab
2046 long sel_ref_cnt;
2047 SEL *refs;
2048 short cls_def_cnt;
2049 short cat_def_cnt;
2050 void *defs[cls_def_cnt + cat_def_cnt];
2051 }; */
2053 static void
2054 build_objc_symtab_template (void)
2056 tree field_decl, field_decl_chain;
2058 objc_symtab_template
2059 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2061 /* long sel_ref_cnt; */
2062 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2063 field_decl_chain = field_decl;
2065 /* SEL *refs; */
2066 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2067 "refs");
2068 chainon (field_decl_chain, field_decl);
2070 /* short cls_def_cnt; */
2071 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2072 chainon (field_decl_chain, field_decl);
2074 /* short cat_def_cnt; */
2075 field_decl = create_field_decl (short_integer_type_node,
2076 "cat_def_cnt");
2077 chainon (field_decl_chain, field_decl);
2079 if (imp_count || cat_count || !flag_next_runtime)
2081 /* void *defs[imp_count + cat_count (+ 1)]; */
2082 /* NB: The index is one less than the size of the array. */
2083 int index = imp_count + cat_count
2084 + (flag_next_runtime? -1: 0);
2085 field_decl = create_field_decl
2086 (build_array_type
2087 (ptr_type_node,
2088 build_index_type (build_int_cst (NULL_TREE, index))),
2089 "defs");
2090 chainon (field_decl_chain, field_decl);
2093 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2096 /* Create the initial value for the `defs' field of _objc_symtab.
2097 This is a CONSTRUCTOR. */
2099 static tree
2100 init_def_list (tree type)
2102 tree expr, initlist = NULL_TREE;
2103 struct imp_entry *impent;
2105 if (imp_count)
2106 for (impent = imp_list; impent; impent = impent->next)
2108 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2110 expr = build_unary_op (input_location,
2111 ADDR_EXPR, impent->class_decl, 0);
2112 initlist = tree_cons (NULL_TREE, expr, initlist);
2116 if (cat_count)
2117 for (impent = imp_list; impent; impent = impent->next)
2119 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2121 expr = build_unary_op (input_location,
2122 ADDR_EXPR, impent->class_decl, 0);
2123 initlist = tree_cons (NULL_TREE, expr, initlist);
2127 if (!flag_next_runtime)
2129 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2130 tree expr;
2132 if (static_instances_decl)
2133 expr = build_unary_op (input_location,
2134 ADDR_EXPR, static_instances_decl, 0);
2135 else
2136 expr = build_int_cst (NULL_TREE, 0);
2138 initlist = tree_cons (NULL_TREE, expr, initlist);
2141 return objc_build_constructor (type, nreverse (initlist));
2144 /* Construct the initial value for all of _objc_symtab. */
2146 static tree
2147 init_objc_symtab (tree type)
2149 tree initlist;
2151 /* sel_ref_cnt = { ..., 5, ... } */
2153 initlist = build_tree_list (NULL_TREE,
2154 build_int_cst (long_integer_type_node, 0));
2156 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2158 if (flag_next_runtime || ! sel_ref_chain)
2159 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2160 else
2161 initlist
2162 = tree_cons (NULL_TREE,
2163 convert (build_pointer_type (objc_selector_type),
2164 build_unary_op (input_location, ADDR_EXPR,
2165 UOBJC_SELECTOR_TABLE_decl, 1)),
2166 initlist);
2168 /* cls_def_cnt = { ..., 5, ... } */
2170 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2172 /* cat_def_cnt = { ..., 5, ... } */
2174 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2176 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2178 if (imp_count || cat_count || !flag_next_runtime)
2181 tree field = TYPE_FIELDS (type);
2182 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2184 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2185 initlist);
2188 return objc_build_constructor (type, nreverse (initlist));
2191 /* Generate forward declarations for metadata such as
2192 'OBJC_CLASS_...'. */
2194 static tree
2195 build_metadata_decl (const char *name, tree type)
2197 tree decl;
2199 /* struct TYPE NAME_<name>; */
2200 decl = start_var_decl (type, synth_id_with_class_suffix
2201 (name,
2202 objc_implementation_context));
2204 return decl;
2207 /* Push forward-declarations of all the categories so that
2208 init_def_list can use them in a CONSTRUCTOR. */
2210 static void
2211 forward_declare_categories (void)
2213 struct imp_entry *impent;
2214 tree sav = objc_implementation_context;
2216 for (impent = imp_list; impent; impent = impent->next)
2218 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2220 /* Set an invisible arg to synth_id_with_class_suffix. */
2221 objc_implementation_context = impent->imp_context;
2222 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2223 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2224 objc_category_template);
2227 objc_implementation_context = sav;
2230 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2231 and initialized appropriately. */
2233 static void
2234 generate_objc_symtab_decl (void)
2236 /* forward declare categories */
2237 if (cat_count)
2238 forward_declare_categories ();
2240 build_objc_symtab_template ();
2241 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2242 finish_var_decl (UOBJC_SYMBOLS_decl,
2243 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2246 static tree
2247 init_module_descriptor (tree type)
2249 tree initlist, expr;
2251 /* version = { 1, ... } */
2253 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2254 initlist = build_tree_list (NULL_TREE, expr);
2256 /* size = { ..., sizeof (struct _objc_module), ... } */
2258 expr = convert (long_integer_type_node,
2259 size_in_bytes (objc_module_template));
2260 initlist = tree_cons (NULL_TREE, expr, initlist);
2262 /* Don't provide any file name for security reasons. */
2263 /* name = { ..., "", ... } */
2265 expr = add_objc_string (get_identifier (""), class_names);
2266 initlist = tree_cons (NULL_TREE, expr, initlist);
2268 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2270 if (UOBJC_SYMBOLS_decl)
2271 expr = build_unary_op (input_location,
2272 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2273 else
2274 expr = build_int_cst (NULL_TREE, 0);
2275 initlist = tree_cons (NULL_TREE, expr, initlist);
2277 return objc_build_constructor (type, nreverse (initlist));
2280 /* Write out the data structures to describe Objective C classes defined.
2282 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2284 static void
2285 build_module_descriptor (void)
2287 tree field_decl, field_decl_chain;
2289 #ifdef OBJCPLUS
2290 push_lang_context (lang_name_c); /* extern "C" */
2291 #endif
2293 objc_module_template
2294 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2296 /* long version; */
2297 field_decl = create_field_decl (long_integer_type_node, "version");
2298 field_decl_chain = field_decl;
2300 /* long size; */
2301 field_decl = create_field_decl (long_integer_type_node, "size");
2302 chainon (field_decl_chain, field_decl);
2304 /* char *name; */
2305 field_decl = create_field_decl (string_type_node, "name");
2306 chainon (field_decl_chain, field_decl);
2308 /* struct _objc_symtab *symtab; */
2309 field_decl
2310 = create_field_decl (build_pointer_type
2311 (xref_tag (RECORD_TYPE,
2312 get_identifier (UTAG_SYMTAB))),
2313 "symtab");
2314 chainon (field_decl_chain, field_decl);
2316 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2318 /* Create an instance of "_objc_module". */
2319 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2320 finish_var_decl (UOBJC_MODULES_decl,
2321 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2323 #ifdef OBJCPLUS
2324 pop_lang_context ();
2325 #endif
2328 /* The GNU runtime requires us to provide a static initializer function
2329 for each module:
2331 static void __objc_gnu_init (void) {
2332 __objc_exec_class (&L_OBJC_MODULES);
2333 } */
2335 static void
2336 build_module_initializer_routine (void)
2338 tree body;
2340 #ifdef OBJCPLUS
2341 push_lang_context (lang_name_c); /* extern "C" */
2342 #endif
2344 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2345 objc_start_function (get_identifier (TAG_GNUINIT),
2346 build_function_type (void_type_node,
2347 OBJC_VOID_AT_END),
2348 NULL_TREE, objc_get_parm_info (0));
2350 body = c_begin_compound_stmt (true);
2351 add_stmt (build_function_call
2352 (execclass_decl,
2353 build_tree_list
2354 (NULL_TREE,
2355 build_unary_op (input_location, ADDR_EXPR,
2356 UOBJC_MODULES_decl, 0))));
2357 add_stmt (c_end_compound_stmt (body, true));
2359 TREE_PUBLIC (current_function_decl) = 0;
2361 #ifndef OBJCPLUS
2362 /* For Objective-C++, we will need to call __objc_gnu_init
2363 from objc_generate_static_init_call() below. */
2364 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2365 #endif
2367 GNU_INIT_decl = current_function_decl;
2368 finish_function ();
2370 #ifdef OBJCPLUS
2371 pop_lang_context ();
2372 #endif
2375 #ifdef OBJCPLUS
2376 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2377 to be called by the module initializer routine. */
2380 objc_static_init_needed_p (void)
2382 return (GNU_INIT_decl != NULL_TREE);
2385 /* Generate a call to the __objc_gnu_init initializer function. */
2387 tree
2388 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2390 add_stmt (build_stmt (EXPR_STMT,
2391 build_function_call (GNU_INIT_decl, NULL_TREE)));
2393 return ctors;
2395 #endif /* OBJCPLUS */
2397 /* Return the DECL of the string IDENT in the SECTION. */
2399 static tree
2400 get_objc_string_decl (tree ident, enum string_section section)
2402 tree chain;
2404 if (section == class_names)
2405 chain = class_names_chain;
2406 else if (section == meth_var_names)
2407 chain = meth_var_names_chain;
2408 else if (section == meth_var_types)
2409 chain = meth_var_types_chain;
2410 else
2411 abort ();
2413 for (; chain != 0; chain = TREE_CHAIN (chain))
2414 if (TREE_VALUE (chain) == ident)
2415 return (TREE_PURPOSE (chain));
2417 abort ();
2418 return NULL_TREE;
2421 /* Output references to all statically allocated objects. Return the DECL
2422 for the array built. */
2424 static void
2425 generate_static_references (void)
2427 tree decls = NULL_TREE, expr = NULL_TREE;
2428 tree class_name, klass, decl, initlist;
2429 tree cl_chain, in_chain, type
2430 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2431 int num_inst, num_class;
2432 char buf[256];
2434 if (flag_next_runtime)
2435 abort ();
2437 for (cl_chain = objc_static_instances, num_class = 0;
2438 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2440 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2441 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2443 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2444 decl = start_var_decl (type, buf);
2446 /* Output {class_name, ...}. */
2447 klass = TREE_VALUE (cl_chain);
2448 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2449 initlist = build_tree_list (NULL_TREE,
2450 build_unary_op (input_location,
2451 ADDR_EXPR, class_name, 1));
2453 /* Output {..., instance, ...}. */
2454 for (in_chain = TREE_PURPOSE (cl_chain);
2455 in_chain; in_chain = TREE_CHAIN (in_chain))
2457 expr = build_unary_op (input_location,
2458 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2459 initlist = tree_cons (NULL_TREE, expr, initlist);
2462 /* Output {..., NULL}. */
2463 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2465 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2466 finish_var_decl (decl, expr);
2467 decls
2468 = tree_cons (NULL_TREE, build_unary_op (input_location,
2469 ADDR_EXPR, decl, 1), decls);
2472 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2473 expr = objc_build_constructor (type, nreverse (decls));
2474 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2475 finish_var_decl (static_instances_decl, expr);
2478 static GTY(()) int selector_reference_idx;
2480 static tree
2481 build_selector_reference_decl (void)
2483 tree decl;
2484 char buf[256];
2486 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2487 decl = start_var_decl (objc_selector_type, buf);
2489 return decl;
2492 static void
2493 build_selector_table_decl (void)
2495 tree temp;
2497 if (flag_typed_selectors)
2499 build_selector_template ();
2500 temp = build_array_type (objc_selector_template, NULL_TREE);
2502 else
2503 temp = build_array_type (objc_selector_type, NULL_TREE);
2505 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2508 /* Just a handy wrapper for add_objc_string. */
2510 static tree
2511 build_selector (tree ident)
2513 return convert (objc_selector_type,
2514 add_objc_string (ident, meth_var_names));
2517 static void
2518 build_selector_translation_table (void)
2520 tree chain, initlist = NULL_TREE;
2521 int offset = 0;
2522 tree decl = NULL_TREE;
2524 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2526 tree expr;
2528 if (warn_selector && objc_implementation_context)
2530 tree method_chain;
2531 bool found = false;
2532 for (method_chain = meth_var_names_chain;
2533 method_chain;
2534 method_chain = TREE_CHAIN (method_chain))
2536 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2538 found = true;
2539 break;
2542 if (!found)
2544 location_t *loc;
2545 if (flag_next_runtime && TREE_PURPOSE (chain))
2546 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2547 else
2548 loc = &input_location;
2549 warning (0, "%Hcreating selector for nonexistent method %qE",
2550 loc, TREE_VALUE (chain));
2554 expr = build_selector (TREE_VALUE (chain));
2555 /* add one for the '\0' character */
2556 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2558 if (flag_next_runtime)
2560 decl = TREE_PURPOSE (chain);
2561 finish_var_decl (decl, expr);
2563 else
2565 if (flag_typed_selectors)
2567 tree eltlist = NULL_TREE;
2568 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2569 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2570 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2571 expr = objc_build_constructor (objc_selector_template,
2572 nreverse (eltlist));
2575 initlist = tree_cons (NULL_TREE, expr, initlist);
2579 if (! flag_next_runtime)
2581 /* Cause the selector table (previously forward-declared)
2582 to be actually output. */
2583 initlist = tree_cons (NULL_TREE,
2584 flag_typed_selectors
2585 ? objc_build_constructor
2586 (objc_selector_template,
2587 tree_cons (NULL_TREE,
2588 build_int_cst (NULL_TREE, 0),
2589 tree_cons (NULL_TREE,
2590 build_int_cst (NULL_TREE, 0),
2591 NULL_TREE)))
2592 : build_int_cst (NULL_TREE, 0), initlist);
2593 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2594 nreverse (initlist));
2595 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2599 static tree
2600 get_proto_encoding (tree proto)
2602 tree encoding;
2603 if (proto)
2605 if (! METHOD_ENCODING (proto))
2607 encoding = encode_method_prototype (proto);
2608 METHOD_ENCODING (proto) = encoding;
2610 else
2611 encoding = METHOD_ENCODING (proto);
2613 return add_objc_string (encoding, meth_var_types);
2615 else
2616 return build_int_cst (NULL_TREE, 0);
2619 /* sel_ref_chain is a list whose "value" fields will be instances of
2620 identifier_node that represent the selector. */
2622 static tree
2623 build_typed_selector_reference (tree ident, tree prototype)
2625 tree *chain = &sel_ref_chain;
2626 tree expr;
2627 int index = 0;
2629 while (*chain)
2631 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2632 goto return_at_index;
2634 index++;
2635 chain = &TREE_CHAIN (*chain);
2638 *chain = tree_cons (prototype, ident, NULL_TREE);
2640 return_at_index:
2641 expr = build_unary_op (input_location, ADDR_EXPR,
2642 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2643 build_int_cst (NULL_TREE, index),
2644 input_location),
2646 return convert (objc_selector_type, expr);
2649 static tree
2650 build_selector_reference (tree ident)
2652 tree *chain = &sel_ref_chain;
2653 tree expr;
2654 int index = 0;
2656 while (*chain)
2658 if (TREE_VALUE (*chain) == ident)
2659 return (flag_next_runtime
2660 ? TREE_PURPOSE (*chain)
2661 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2662 build_int_cst (NULL_TREE, index),
2663 input_location));
2665 index++;
2666 chain = &TREE_CHAIN (*chain);
2669 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2671 *chain = tree_cons (expr, ident, NULL_TREE);
2673 return (flag_next_runtime
2674 ? expr
2675 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2676 build_int_cst (NULL_TREE, index),
2677 input_location));
2680 static GTY(()) int class_reference_idx;
2682 static tree
2683 build_class_reference_decl (void)
2685 tree decl;
2686 char buf[256];
2688 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2689 decl = start_var_decl (objc_class_type, buf);
2691 return decl;
2694 /* Create a class reference, but don't create a variable to reference
2695 it. */
2697 static void
2698 add_class_reference (tree ident)
2700 tree chain;
2702 if ((chain = cls_ref_chain))
2704 tree tail;
2707 if (ident == TREE_VALUE (chain))
2708 return;
2710 tail = chain;
2711 chain = TREE_CHAIN (chain);
2713 while (chain);
2715 /* Append to the end of the list */
2716 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2718 else
2719 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2722 /* Get a class reference, creating it if necessary. Also create the
2723 reference variable. */
2725 tree
2726 objc_get_class_reference (tree ident)
2728 tree orig_ident = (DECL_P (ident)
2729 ? DECL_NAME (ident)
2730 : TYPE_P (ident)
2731 ? OBJC_TYPE_NAME (ident)
2732 : ident);
2733 bool local_scope = false;
2735 #ifdef OBJCPLUS
2736 if (processing_template_decl)
2737 /* Must wait until template instantiation time. */
2738 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2739 #endif
2741 if (TREE_CODE (ident) == TYPE_DECL)
2742 ident = (DECL_ORIGINAL_TYPE (ident)
2743 ? DECL_ORIGINAL_TYPE (ident)
2744 : TREE_TYPE (ident));
2746 #ifdef OBJCPLUS
2747 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2748 && TYPE_CONTEXT (ident) != global_namespace)
2749 local_scope = true;
2750 #endif
2752 if (local_scope || !(ident = objc_is_class_name (ident)))
2754 error ("%qs is not an Objective-C class name or alias",
2755 IDENTIFIER_POINTER (orig_ident));
2756 return error_mark_node;
2759 if (flag_next_runtime && !flag_zero_link)
2761 tree *chain;
2762 tree decl;
2764 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2765 if (TREE_VALUE (*chain) == ident)
2767 if (! TREE_PURPOSE (*chain))
2768 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2770 return TREE_PURPOSE (*chain);
2773 decl = build_class_reference_decl ();
2774 *chain = tree_cons (decl, ident, NULL_TREE);
2775 return decl;
2777 else
2779 tree params;
2781 add_class_reference (ident);
2783 params = build_tree_list (NULL_TREE,
2784 my_build_string_pointer
2785 (IDENTIFIER_LENGTH (ident) + 1,
2786 IDENTIFIER_POINTER (ident)));
2788 assemble_external (objc_get_class_decl);
2789 return build_function_call (objc_get_class_decl, params);
2793 /* For each string section we have a chain which maps identifier nodes
2794 to decls for the strings. */
2796 static tree
2797 add_objc_string (tree ident, enum string_section section)
2799 tree *chain, decl, type, string_expr;
2801 if (section == class_names)
2802 chain = &class_names_chain;
2803 else if (section == meth_var_names)
2804 chain = &meth_var_names_chain;
2805 else if (section == meth_var_types)
2806 chain = &meth_var_types_chain;
2807 else
2808 abort ();
2810 while (*chain)
2812 if (TREE_VALUE (*chain) == ident)
2813 return convert (string_type_node,
2814 build_unary_op (input_location,
2815 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2817 chain = &TREE_CHAIN (*chain);
2820 decl = build_objc_string_decl (section);
2822 type = build_array_type
2823 (char_type_node,
2824 build_index_type
2825 (build_int_cst (NULL_TREE,
2826 IDENTIFIER_LENGTH (ident))));
2827 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2828 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2829 IDENTIFIER_POINTER (ident));
2830 finish_var_decl (decl, string_expr);
2832 *chain = tree_cons (decl, ident, NULL_TREE);
2834 return convert (string_type_node, build_unary_op (input_location,
2835 ADDR_EXPR, decl, 1));
2838 static GTY(()) int class_names_idx;
2839 static GTY(()) int meth_var_names_idx;
2840 static GTY(()) int meth_var_types_idx;
2842 static tree
2843 build_objc_string_decl (enum string_section section)
2845 tree decl, ident;
2846 char buf[256];
2848 if (section == class_names)
2849 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2850 else if (section == meth_var_names)
2851 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2852 else if (section == meth_var_types)
2853 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2855 ident = get_identifier (buf);
2857 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2858 DECL_EXTERNAL (decl) = 1;
2859 TREE_PUBLIC (decl) = 0;
2860 TREE_USED (decl) = 1;
2861 TREE_CONSTANT (decl) = 1;
2862 DECL_CONTEXT (decl) = 0;
2863 DECL_ARTIFICIAL (decl) = 1;
2864 #ifdef OBJCPLUS
2865 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2866 #endif
2868 make_decl_rtl (decl);
2869 pushdecl_top_level (decl);
2871 return decl;
2875 void
2876 objc_declare_alias (tree alias_ident, tree class_ident)
2878 tree underlying_class;
2880 #ifdef OBJCPLUS
2881 if (current_namespace != global_namespace) {
2882 error ("Objective-C declarations may only appear in global scope");
2884 #endif /* OBJCPLUS */
2886 if (!(underlying_class = objc_is_class_name (class_ident)))
2887 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2888 else if (objc_is_class_name (alias_ident))
2889 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2890 else
2892 /* Implement @compatibility_alias as a typedef. */
2893 #ifdef OBJCPLUS
2894 push_lang_context (lang_name_c); /* extern "C" */
2895 #endif
2896 lang_hooks.decls.pushdecl (build_decl
2897 (TYPE_DECL,
2898 alias_ident,
2899 xref_tag (RECORD_TYPE, underlying_class)));
2900 #ifdef OBJCPLUS
2901 pop_lang_context ();
2902 #endif
2903 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2907 void
2908 objc_declare_class (tree ident_list)
2910 tree list;
2911 #ifdef OBJCPLUS
2912 if (current_namespace != global_namespace) {
2913 error ("Objective-C declarations may only appear in global scope");
2915 #endif /* OBJCPLUS */
2917 for (list = ident_list; list; list = TREE_CHAIN (list))
2919 tree ident = TREE_VALUE (list);
2921 if (! objc_is_class_name (ident))
2923 tree record = lookup_name (ident), type = record;
2925 if (record)
2927 if (TREE_CODE (record) == TYPE_DECL)
2928 type = DECL_ORIGINAL_TYPE (record);
2930 if (!TYPE_HAS_OBJC_INFO (type)
2931 || !TYPE_OBJC_INTERFACE (type))
2933 error ("%qs redeclared as different kind of symbol",
2934 IDENTIFIER_POINTER (ident));
2935 error ("previous declaration of %q+D",
2936 record);
2940 record = xref_tag (RECORD_TYPE, ident);
2941 INIT_TYPE_OBJC_INFO (record);
2942 TYPE_OBJC_INTERFACE (record) = ident;
2943 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2948 tree
2949 objc_is_class_name (tree ident)
2951 tree chain;
2953 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2954 && identifier_global_value (ident))
2955 ident = identifier_global_value (ident);
2956 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2957 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2959 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2960 ident = OBJC_TYPE_NAME (ident);
2961 #ifdef OBJCPLUS
2962 if (ident && TREE_CODE (ident) == TYPE_DECL)
2963 ident = DECL_NAME (ident);
2964 #endif
2965 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2966 return NULL_TREE;
2968 if (lookup_interface (ident))
2969 return ident;
2971 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2973 if (ident == TREE_VALUE (chain))
2974 return ident;
2977 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2979 if (ident == TREE_VALUE (chain))
2980 return TREE_PURPOSE (chain);
2983 return 0;
2986 /* Check whether TYPE is either 'id' or 'Class'. */
2988 tree
2989 objc_is_id (tree type)
2991 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2992 && identifier_global_value (type))
2993 type = identifier_global_value (type);
2995 if (type && TREE_CODE (type) == TYPE_DECL)
2996 type = TREE_TYPE (type);
2998 /* NB: This function may be called before the ObjC front-end has
2999 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3000 return (objc_object_type && type
3001 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3002 ? type
3003 : NULL_TREE);
3006 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3007 class instance. This is needed by other parts of the compiler to
3008 handle ObjC types gracefully. */
3010 tree
3011 objc_is_object_ptr (tree type)
3013 tree ret;
3015 type = TYPE_MAIN_VARIANT (type);
3016 if (!POINTER_TYPE_P (type))
3017 return 0;
3019 ret = objc_is_id (type);
3020 if (!ret)
3021 ret = objc_is_class_name (TREE_TYPE (type));
3023 return ret;
3026 static int
3027 objc_is_gcable_type (tree type, int or_strong_p)
3029 tree name;
3031 if (!TYPE_P (type))
3032 return 0;
3033 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3034 return 1;
3035 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3036 return 1;
3037 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3038 return 0;
3039 type = TREE_TYPE (type);
3040 if (TREE_CODE (type) != RECORD_TYPE)
3041 return 0;
3042 name = TYPE_NAME (type);
3043 return (objc_is_class_name (name) != NULL_TREE);
3046 static tree
3047 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3049 if (expr == oldexpr)
3050 return newexpr;
3052 switch (TREE_CODE (expr))
3054 case COMPONENT_REF:
3055 return objc_build_component_ref
3056 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3057 oldexpr,
3058 newexpr),
3059 DECL_NAME (TREE_OPERAND (expr, 1)));
3060 case ARRAY_REF:
3061 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3062 oldexpr,
3063 newexpr),
3064 TREE_OPERAND (expr, 1),
3065 input_location);
3066 case INDIRECT_REF:
3067 return build_indirect_ref (input_location,
3068 objc_substitute_decl (TREE_OPERAND (expr, 0),
3069 oldexpr,
3070 newexpr), "->");
3071 default:
3072 return expr;
3076 static tree
3077 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3079 tree func_params;
3080 /* The LHS parameter contains the expression 'outervar->memberspec';
3081 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3082 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3084 tree offs
3085 = objc_substitute_decl
3086 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3087 tree func
3088 = (flag_objc_direct_dispatch
3089 ? objc_assign_ivar_fast_decl
3090 : objc_assign_ivar_decl);
3092 offs = convert (integer_type_node, build_unary_op (input_location,
3093 ADDR_EXPR, offs, 0));
3094 offs = fold (offs);
3095 func_params = tree_cons (NULL_TREE,
3096 convert (objc_object_type, rhs),
3097 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3098 tree_cons (NULL_TREE, offs,
3099 NULL_TREE)));
3101 assemble_external (func);
3102 return build_function_call (func, func_params);
3105 static tree
3106 objc_build_global_assignment (tree lhs, tree rhs)
3108 tree func_params = tree_cons (NULL_TREE,
3109 convert (objc_object_type, rhs),
3110 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3111 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3112 NULL_TREE));
3114 assemble_external (objc_assign_global_decl);
3115 return build_function_call (objc_assign_global_decl, func_params);
3118 static tree
3119 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3121 tree func_params = tree_cons (NULL_TREE,
3122 convert (objc_object_type, rhs),
3123 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3124 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3125 NULL_TREE));
3127 assemble_external (objc_assign_strong_cast_decl);
3128 return build_function_call (objc_assign_strong_cast_decl, func_params);
3131 static int
3132 objc_is_gcable_p (tree expr)
3134 return (TREE_CODE (expr) == COMPONENT_REF
3135 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3136 : TREE_CODE (expr) == ARRAY_REF
3137 ? (objc_is_gcable_p (TREE_TYPE (expr))
3138 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3139 : TREE_CODE (expr) == ARRAY_TYPE
3140 ? objc_is_gcable_p (TREE_TYPE (expr))
3141 : TYPE_P (expr)
3142 ? objc_is_gcable_type (expr, 1)
3143 : (objc_is_gcable_p (TREE_TYPE (expr))
3144 || (DECL_P (expr)
3145 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3148 static int
3149 objc_is_ivar_reference_p (tree expr)
3151 return (TREE_CODE (expr) == ARRAY_REF
3152 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3153 : TREE_CODE (expr) == COMPONENT_REF
3154 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3155 : 0);
3158 static int
3159 objc_is_global_reference_p (tree expr)
3161 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3162 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3163 : DECL_P (expr)
3164 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3165 : 0);
3168 tree
3169 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3171 tree result = NULL_TREE, outer;
3172 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3174 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3175 will have been transformed to the form '*(type *)&expr'. */
3176 if (TREE_CODE (lhs) == INDIRECT_REF)
3178 outer = TREE_OPERAND (lhs, 0);
3180 while (!strong_cast_p
3181 && (CONVERT_EXPR_P (outer)
3182 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3184 tree lhstype = TREE_TYPE (outer);
3186 /* Descend down the cast chain, and record the first objc_gc
3187 attribute found. */
3188 if (POINTER_TYPE_P (lhstype))
3190 tree attr
3191 = lookup_attribute ("objc_gc",
3192 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3194 if (attr)
3195 strong_cast_p = 1;
3198 outer = TREE_OPERAND (outer, 0);
3202 /* If we have a __strong cast, it trumps all else. */
3203 if (strong_cast_p)
3205 if (modifycode != NOP_EXPR)
3206 goto invalid_pointer_arithmetic;
3208 if (warn_assign_intercept)
3209 warning (0, "strong-cast assignment has been intercepted");
3211 result = objc_build_strong_cast_assignment (lhs, rhs);
3213 goto exit_point;
3216 /* the lhs must be of a suitable type, regardless of its underlying
3217 structure. */
3218 if (!objc_is_gcable_p (lhs))
3219 goto exit_point;
3221 outer = lhs;
3223 while (outer
3224 && (TREE_CODE (outer) == COMPONENT_REF
3225 || TREE_CODE (outer) == ARRAY_REF))
3226 outer = TREE_OPERAND (outer, 0);
3228 if (TREE_CODE (outer) == INDIRECT_REF)
3230 outer = TREE_OPERAND (outer, 0);
3231 indirect_p = 1;
3234 outer_gc_p = objc_is_gcable_p (outer);
3236 /* Handle ivar assignments. */
3237 if (objc_is_ivar_reference_p (lhs))
3239 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3240 doesn't cut it here), the best we can do here is suggest a cast. */
3241 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3243 /* We may still be able to use the global write barrier... */
3244 if (!indirect_p && objc_is_global_reference_p (outer))
3245 goto global_reference;
3247 suggest_cast:
3248 if (modifycode == NOP_EXPR)
3250 if (warn_assign_intercept)
3251 warning (0, "strong-cast may possibly be needed");
3254 goto exit_point;
3257 if (modifycode != NOP_EXPR)
3258 goto invalid_pointer_arithmetic;
3260 if (warn_assign_intercept)
3261 warning (0, "instance variable assignment has been intercepted");
3263 result = objc_build_ivar_assignment (outer, lhs, rhs);
3265 goto exit_point;
3268 /* Likewise, intercept assignment to global/static variables if their type is
3269 GC-marked. */
3270 if (objc_is_global_reference_p (outer))
3272 if (indirect_p)
3273 goto suggest_cast;
3275 global_reference:
3276 if (modifycode != NOP_EXPR)
3278 invalid_pointer_arithmetic:
3279 if (outer_gc_p)
3280 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3282 goto exit_point;
3285 if (warn_assign_intercept)
3286 warning (0, "global/static variable assignment has been intercepted");
3288 result = objc_build_global_assignment (lhs, rhs);
3291 /* In all other cases, fall back to the normal mechanism. */
3292 exit_point:
3293 return result;
3296 struct interface_tuple GTY(())
3298 tree id;
3299 tree class_name;
3302 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3304 static hashval_t
3305 hash_interface (const void *p)
3307 const struct interface_tuple *d = (const struct interface_tuple *) p;
3308 return IDENTIFIER_HASH_VALUE (d->id);
3311 static int
3312 eq_interface (const void *p1, const void *p2)
3314 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3315 return d->id == p2;
3318 static tree
3319 lookup_interface (tree ident)
3321 #ifdef OBJCPLUS
3322 if (ident && TREE_CODE (ident) == TYPE_DECL)
3323 ident = DECL_NAME (ident);
3324 #endif
3326 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3327 return NULL_TREE;
3330 struct interface_tuple **slot;
3331 tree i = NULL_TREE;
3333 if (interface_htab)
3335 slot = (struct interface_tuple **)
3336 htab_find_slot_with_hash (interface_htab, ident,
3337 IDENTIFIER_HASH_VALUE (ident),
3338 NO_INSERT);
3339 if (slot && *slot)
3340 i = (*slot)->class_name;
3342 return i;
3346 /* Implement @defs (<classname>) within struct bodies. */
3348 tree
3349 objc_get_class_ivars (tree class_name)
3351 tree interface = lookup_interface (class_name);
3353 if (interface)
3354 return get_class_ivars (interface, true);
3356 error ("cannot find interface declaration for %qs",
3357 IDENTIFIER_POINTER (class_name));
3359 return error_mark_node;
3362 /* Used by: build_private_template, continue_class,
3363 and for @defs constructs. */
3365 static tree
3366 get_class_ivars (tree interface, bool inherited)
3368 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3370 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3371 by the current class (i.e., they do not include super-class ivars).
3372 However, the CLASS_IVARS list will be side-effected by a call to
3373 finish_struct(), which will fill in field offsets. */
3374 if (!CLASS_IVARS (interface))
3375 CLASS_IVARS (interface) = ivar_chain;
3377 if (!inherited)
3378 return ivar_chain;
3380 while (CLASS_SUPER_NAME (interface))
3382 /* Prepend super-class ivars. */
3383 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3384 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3385 ivar_chain);
3388 return ivar_chain;
3391 static tree
3392 objc_create_temporary_var (tree type)
3394 tree decl;
3396 decl = build_decl (VAR_DECL, NULL_TREE, type);
3397 TREE_USED (decl) = 1;
3398 DECL_ARTIFICIAL (decl) = 1;
3399 DECL_IGNORED_P (decl) = 1;
3400 DECL_CONTEXT (decl) = current_function_decl;
3402 return decl;
3405 /* Exception handling constructs. We begin by having the parser do most
3406 of the work and passing us blocks. What we do next depends on whether
3407 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3408 We abstract all of this in a handful of appropriately named routines. */
3410 /* Stack of open try blocks. */
3412 struct objc_try_context
3414 struct objc_try_context *outer;
3416 /* Statements (or statement lists) as processed by the parser. */
3417 tree try_body;
3418 tree finally_body;
3420 /* Some file position locations. */
3421 location_t try_locus;
3422 location_t end_try_locus;
3423 location_t end_catch_locus;
3424 location_t finally_locus;
3425 location_t end_finally_locus;
3427 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3428 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3429 tree catch_list;
3431 /* The CATCH_EXPR of an open @catch clause. */
3432 tree current_catch;
3434 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3435 tree caught_decl;
3436 tree stack_decl;
3437 tree rethrow_decl;
3440 static struct objc_try_context *cur_try_context;
3442 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3443 that represents TYPE. For Objective-C, this is just the class name. */
3444 /* ??? Isn't there a class object or some such? Is it easy to get? */
3446 #ifndef OBJCPLUS
3447 static tree
3448 objc_eh_runtime_type (tree type)
3450 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3452 #endif
3454 /* Initialize exception handling. */
3456 static void
3457 objc_init_exceptions (void)
3459 static bool done = false;
3460 if (done)
3461 return;
3462 done = true;
3464 if (flag_objc_sjlj_exceptions)
3466 /* On Darwin, ObjC exceptions require a sufficiently recent
3467 version of the runtime, so the user must ask for them explicitly. */
3468 if (!flag_objc_exceptions)
3469 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3470 "exception syntax");
3472 #ifndef OBJCPLUS
3473 else
3475 c_eh_initialized_p = true;
3476 eh_personality_libfunc
3477 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3478 ? "__gnu_objc_personality_sj0"
3479 : "__gnu_objc_personality_v0");
3480 default_init_unwind_resume_libfunc ();
3481 using_eh_for_cleanups ();
3482 lang_eh_runtime_type = objc_eh_runtime_type;
3484 #endif
3487 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3488 we'll arrange for it to be initialized (and associated with a binding)
3489 later. */
3491 static tree
3492 objc_build_exc_ptr (void)
3494 if (flag_objc_sjlj_exceptions)
3496 tree var = cur_try_context->caught_decl;
3497 if (!var)
3499 var = objc_create_temporary_var (objc_object_type);
3500 cur_try_context->caught_decl = var;
3502 return var;
3504 else
3505 return build0 (EXC_PTR_EXPR, objc_object_type);
3508 /* Build "objc_exception_try_exit(&_stack)". */
3510 static tree
3511 next_sjlj_build_try_exit (void)
3513 tree t;
3514 t = build_fold_addr_expr (cur_try_context->stack_decl);
3515 t = tree_cons (NULL, t, NULL);
3516 t = build_function_call (objc_exception_try_exit_decl, t);
3517 return t;
3520 /* Build
3521 objc_exception_try_enter (&_stack);
3522 if (_setjmp(&_stack.buf))
3524 else
3526 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3527 empty, ready for the caller to fill them in. */
3529 static tree
3530 next_sjlj_build_enter_and_setjmp (void)
3532 tree t, enter, sj, cond;
3534 t = build_fold_addr_expr (cur_try_context->stack_decl);
3535 t = tree_cons (NULL, t, NULL);
3536 enter = build_function_call (objc_exception_try_enter_decl, t);
3538 t = objc_build_component_ref (cur_try_context->stack_decl,
3539 get_identifier ("buf"));
3540 t = build_fold_addr_expr (t);
3541 #ifdef OBJCPLUS
3542 /* Convert _setjmp argument to type that is expected. */
3543 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3544 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3545 else
3546 t = convert (ptr_type_node, t);
3547 #else
3548 t = convert (ptr_type_node, t);
3549 #endif
3550 t = tree_cons (NULL, t, NULL);
3551 sj = build_function_call (objc_setjmp_decl, t);
3553 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3554 cond = c_common_truthvalue_conversion (input_location, cond);
3556 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3559 /* Build:
3561 DECL = objc_exception_extract(&_stack); */
3563 static tree
3564 next_sjlj_build_exc_extract (tree decl)
3566 tree t;
3568 t = build_fold_addr_expr (cur_try_context->stack_decl);
3569 t = tree_cons (NULL, t, NULL);
3570 t = build_function_call (objc_exception_extract_decl, t);
3571 t = convert (TREE_TYPE (decl), t);
3572 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3574 return t;
3577 /* Build
3578 if (objc_exception_match(obj_get_class(TYPE), _caught)
3579 BODY
3580 else if (...)
3582 else
3584 _rethrow = _caught;
3585 objc_exception_try_exit(&_stack);
3587 from the sequence of CATCH_EXPRs in the current try context. */
3589 static tree
3590 next_sjlj_build_catch_list (void)
3592 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3593 tree catch_seq, t;
3594 tree *last = &catch_seq;
3595 bool saw_id = false;
3597 for (; !tsi_end_p (i); tsi_next (&i))
3599 tree stmt = tsi_stmt (i);
3600 tree type = CATCH_TYPES (stmt);
3601 tree body = CATCH_BODY (stmt);
3603 if (type == NULL)
3605 *last = body;
3606 saw_id = true;
3607 break;
3609 else
3611 tree args, cond;
3613 if (type == error_mark_node)
3614 cond = error_mark_node;
3615 else
3617 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3618 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3619 args = tree_cons (NULL, t, args);
3620 t = build_function_call (objc_exception_match_decl, args);
3621 cond = c_common_truthvalue_conversion (input_location, t);
3623 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3624 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3626 *last = t;
3627 last = &COND_EXPR_ELSE (t);
3631 if (!saw_id)
3633 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3634 cur_try_context->caught_decl);
3635 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3636 append_to_statement_list (t, last);
3638 t = next_sjlj_build_try_exit ();
3639 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3640 append_to_statement_list (t, last);
3643 return catch_seq;
3646 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3647 exception handling. We aim to build:
3650 struct _objc_exception_data _stack;
3651 id _rethrow = 0;
3654 objc_exception_try_enter (&_stack);
3655 if (_setjmp(&_stack.buf))
3657 id _caught = objc_exception_extract(&_stack);
3658 objc_exception_try_enter (&_stack);
3659 if (_setjmp(&_stack.buf))
3660 _rethrow = objc_exception_extract(&_stack);
3661 else
3662 CATCH-LIST
3664 else
3665 TRY-BLOCK
3667 finally
3669 if (!_rethrow)
3670 objc_exception_try_exit(&_stack);
3671 FINALLY-BLOCK
3672 if (_rethrow)
3673 objc_exception_throw(_rethrow);
3677 If CATCH-LIST is empty, we can omit all of the block containing
3678 "_caught" except for the setting of _rethrow. Note the use of
3679 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3680 but handles goto and other exits from the block. */
3682 static tree
3683 next_sjlj_build_try_catch_finally (void)
3685 tree rethrow_decl, stack_decl, t;
3686 tree catch_seq, try_fin, bind;
3688 /* Create the declarations involved. */
3689 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3690 stack_decl = objc_create_temporary_var (t);
3691 cur_try_context->stack_decl = stack_decl;
3693 rethrow_decl = objc_create_temporary_var (objc_object_type);
3694 cur_try_context->rethrow_decl = rethrow_decl;
3695 TREE_CHAIN (rethrow_decl) = stack_decl;
3697 /* Build the outermost variable binding level. */
3698 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3699 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3700 TREE_SIDE_EFFECTS (bind) = 1;
3702 /* Initialize rethrow_decl. */
3703 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3704 convert (objc_object_type, null_pointer_node));
3705 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3706 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3708 /* Build the outermost TRY_FINALLY_EXPR. */
3709 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3710 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3711 TREE_SIDE_EFFECTS (try_fin) = 1;
3712 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3714 /* Create the complete catch sequence. */
3715 if (cur_try_context->catch_list)
3717 tree caught_decl = objc_build_exc_ptr ();
3718 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3719 TREE_SIDE_EFFECTS (catch_seq) = 1;
3721 t = next_sjlj_build_exc_extract (caught_decl);
3722 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3724 t = next_sjlj_build_enter_and_setjmp ();
3725 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3726 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3727 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3729 else
3730 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3731 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3733 /* Build the main register-and-try if statement. */
3734 t = next_sjlj_build_enter_and_setjmp ();
3735 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3736 COND_EXPR_THEN (t) = catch_seq;
3737 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3738 TREE_OPERAND (try_fin, 0) = t;
3740 /* Build the complete FINALLY statement list. */
3741 t = next_sjlj_build_try_exit ();
3742 t = build_stmt (COND_EXPR,
3743 c_common_truthvalue_conversion
3744 (input_location, rethrow_decl),
3745 NULL, t);
3746 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3747 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3749 append_to_statement_list (cur_try_context->finally_body,
3750 &TREE_OPERAND (try_fin, 1));
3752 t = tree_cons (NULL, rethrow_decl, NULL);
3753 t = build_function_call (objc_exception_throw_decl, t);
3754 t = build_stmt (COND_EXPR,
3755 c_common_truthvalue_conversion (input_location,
3756 rethrow_decl),
3757 t, NULL);
3758 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3759 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3761 return bind;
3764 /* Called just after parsing the @try and its associated BODY. We now
3765 must prepare for the tricky bits -- handling the catches and finally. */
3767 void
3768 objc_begin_try_stmt (location_t try_locus, tree body)
3770 struct objc_try_context *c = XCNEW (struct objc_try_context);
3771 c->outer = cur_try_context;
3772 c->try_body = body;
3773 c->try_locus = try_locus;
3774 c->end_try_locus = input_location;
3775 cur_try_context = c;
3777 objc_init_exceptions ();
3779 if (flag_objc_sjlj_exceptions)
3780 objc_mark_locals_volatile (NULL);
3783 /* Called just after parsing "@catch (parm)". Open a binding level,
3784 enter DECL into the binding level, and initialize it. Leave the
3785 binding level open while the body of the compound statement is parsed. */
3787 void
3788 objc_begin_catch_clause (tree decl)
3790 tree compound, type, t;
3792 /* Begin a new scope that the entire catch clause will live in. */
3793 compound = c_begin_compound_stmt (true);
3795 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3796 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3797 lang_hooks.decls.pushdecl (decl);
3799 /* Since a decl is required here by syntax, don't warn if its unused. */
3800 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3801 be what the previous objc implementation did. */
3802 TREE_USED (decl) = 1;
3804 /* Verify that the type of the catch is valid. It must be a pointer
3805 to an Objective-C class, or "id" (which is catch-all). */
3806 type = TREE_TYPE (decl);
3808 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3809 type = NULL;
3810 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3812 error ("@catch parameter is not a known Objective-C class type");
3813 type = error_mark_node;
3815 else if (cur_try_context->catch_list)
3817 /* Examine previous @catch clauses and see if we've already
3818 caught the type in question. */
3819 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3820 for (; !tsi_end_p (i); tsi_next (&i))
3822 tree stmt = tsi_stmt (i);
3823 t = CATCH_TYPES (stmt);
3824 if (t == error_mark_node)
3825 continue;
3826 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3828 warning (0, "exception of type %<%T%> will be caught",
3829 TREE_TYPE (type));
3830 warning (0, "%H by earlier handler for %<%T%>",
3831 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3832 break;
3837 /* Record the data for the catch in the try context so that we can
3838 finalize it later. */
3839 t = build_stmt (CATCH_EXPR, type, compound);
3840 cur_try_context->current_catch = t;
3842 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3843 t = objc_build_exc_ptr ();
3844 t = convert (TREE_TYPE (decl), t);
3845 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3846 add_stmt (t);
3849 /* Called just after parsing the closing brace of a @catch clause. Close
3850 the open binding level, and record a CATCH_EXPR for it. */
3852 void
3853 objc_finish_catch_clause (void)
3855 tree c = cur_try_context->current_catch;
3856 cur_try_context->current_catch = NULL;
3857 cur_try_context->end_catch_locus = input_location;
3859 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3860 append_to_statement_list (c, &cur_try_context->catch_list);
3863 /* Called after parsing a @finally clause and its associated BODY.
3864 Record the body for later placement. */
3866 void
3867 objc_build_finally_clause (location_t finally_locus, tree body)
3869 cur_try_context->finally_body = body;
3870 cur_try_context->finally_locus = finally_locus;
3871 cur_try_context->end_finally_locus = input_location;
3874 /* Called to finalize a @try construct. */
3876 tree
3877 objc_finish_try_stmt (void)
3879 struct objc_try_context *c = cur_try_context;
3880 tree stmt;
3882 if (c->catch_list == NULL && c->finally_body == NULL)
3883 error ("%<@try%> without %<@catch%> or %<@finally%>");
3885 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3886 if (flag_objc_sjlj_exceptions)
3888 if (!cur_try_context->finally_body)
3890 cur_try_context->finally_locus = input_location;
3891 cur_try_context->end_finally_locus = input_location;
3893 stmt = next_sjlj_build_try_catch_finally ();
3895 else
3897 /* Otherwise, nest the CATCH inside a FINALLY. */
3898 stmt = c->try_body;
3899 if (c->catch_list)
3901 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3902 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3904 if (c->finally_body)
3906 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3907 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3910 add_stmt (stmt);
3912 cur_try_context = c->outer;
3913 free (c);
3914 return stmt;
3917 tree
3918 objc_build_throw_stmt (tree throw_expr)
3920 tree args;
3922 objc_init_exceptions ();
3924 if (throw_expr == NULL)
3926 /* If we're not inside a @catch block, there is no "current
3927 exception" to be rethrown. */
3928 if (cur_try_context == NULL
3929 || cur_try_context->current_catch == NULL)
3931 error ("%<@throw%> (rethrow) used outside of a @catch block");
3932 return NULL_TREE;
3935 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3936 value that we get from the runtime. */
3937 throw_expr = objc_build_exc_ptr ();
3940 /* A throw is just a call to the runtime throw function with the
3941 object as a parameter. */
3942 args = tree_cons (NULL, throw_expr, NULL);
3943 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3946 tree
3947 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3949 tree args, call;
3951 /* First lock the mutex. */
3952 mutex = save_expr (mutex);
3953 args = tree_cons (NULL, mutex, NULL);
3954 call = build_function_call (objc_sync_enter_decl, args);
3955 SET_EXPR_LOCATION (call, start_locus);
3956 add_stmt (call);
3958 /* Build the mutex unlock. */
3959 args = tree_cons (NULL, mutex, NULL);
3960 call = build_function_call (objc_sync_exit_decl, args);
3961 SET_EXPR_LOCATION (call, input_location);
3963 /* Put the that and the body in a TRY_FINALLY. */
3964 objc_begin_try_stmt (start_locus, body);
3965 objc_build_finally_clause (input_location, call);
3966 return objc_finish_try_stmt ();
3970 /* Predefine the following data type:
3972 struct _objc_exception_data
3974 int buf[OBJC_JBLEN];
3975 void *pointers[4];
3976 }; */
3978 /* The following yuckiness should prevent users from having to #include
3979 <setjmp.h> in their code... */
3981 /* Define to a harmless positive value so the below code doesn't die. */
3982 #ifndef OBJC_JBLEN
3983 #define OBJC_JBLEN 18
3984 #endif
3986 static void
3987 build_next_objc_exception_stuff (void)
3989 tree field_decl, field_decl_chain, index, temp_type;
3991 objc_exception_data_template
3992 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3994 /* int buf[OBJC_JBLEN]; */
3996 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3997 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3998 "buf");
3999 field_decl_chain = field_decl;
4001 /* void *pointers[4]; */
4003 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
4004 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
4005 "pointers");
4006 chainon (field_decl_chain, field_decl);
4008 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
4010 /* int _setjmp(...); */
4011 /* If the user includes <setjmp.h>, this shall be superseded by
4012 'int _setjmp(jmp_buf);' */
4013 temp_type = build_function_type (integer_type_node, NULL_TREE);
4014 objc_setjmp_decl
4015 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4017 /* id objc_exception_extract(struct _objc_exception_data *); */
4018 temp_type
4019 = build_function_type (objc_object_type,
4020 tree_cons (NULL_TREE,
4021 build_pointer_type (objc_exception_data_template),
4022 OBJC_VOID_AT_END));
4023 objc_exception_extract_decl
4024 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4025 NULL_TREE);
4026 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4027 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4028 temp_type
4029 = build_function_type (void_type_node,
4030 tree_cons (NULL_TREE,
4031 build_pointer_type (objc_exception_data_template),
4032 OBJC_VOID_AT_END));
4033 objc_exception_try_enter_decl
4034 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4035 NULL_TREE);
4036 objc_exception_try_exit_decl
4037 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4038 NULL_TREE);
4040 /* int objc_exception_match(id, id); */
4041 temp_type
4042 = build_function_type (integer_type_node,
4043 tree_cons (NULL_TREE, objc_object_type,
4044 tree_cons (NULL_TREE, objc_object_type,
4045 OBJC_VOID_AT_END)));
4046 objc_exception_match_decl
4047 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4048 NULL_TREE);
4050 /* id objc_assign_ivar (id, id, unsigned int); */
4051 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4052 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4053 temp_type
4054 = build_function_type (objc_object_type,
4055 tree_cons
4056 (NULL_TREE, objc_object_type,
4057 tree_cons (NULL_TREE, objc_object_type,
4058 tree_cons (NULL_TREE,
4059 unsigned_type_node,
4060 OBJC_VOID_AT_END))));
4061 objc_assign_ivar_decl
4062 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4063 NULL, NULL_TREE);
4064 #ifdef OFFS_ASSIGNIVAR_FAST
4065 objc_assign_ivar_fast_decl
4066 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4067 NOT_BUILT_IN, NULL, NULL_TREE);
4068 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4069 = tree_cons (get_identifier ("hard_coded_address"),
4070 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4071 NULL_TREE);
4072 #else
4073 /* Default to slower ivar method. */
4074 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4075 #endif
4077 /* id objc_assign_global (id, id *); */
4078 /* id objc_assign_strongCast (id, id *); */
4079 temp_type = build_function_type (objc_object_type,
4080 tree_cons (NULL_TREE, objc_object_type,
4081 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4082 OBJC_VOID_AT_END)));
4083 objc_assign_global_decl
4084 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4085 NULL_TREE);
4086 objc_assign_strong_cast_decl
4087 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4088 NULL_TREE);
4091 static void
4092 build_objc_exception_stuff (void)
4094 tree noreturn_list, nothrow_list, temp_type;
4096 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4097 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4099 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4100 /* void objc_sync_enter(id); */
4101 /* void objc_sync_exit(id); */
4102 temp_type = build_function_type (void_type_node,
4103 tree_cons (NULL_TREE, objc_object_type,
4104 OBJC_VOID_AT_END));
4105 objc_exception_throw_decl
4106 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4107 noreturn_list);
4108 objc_sync_enter_decl
4109 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4110 NULL, nothrow_list);
4111 objc_sync_exit_decl
4112 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4113 NULL, nothrow_list);
4116 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4117 name as the class:
4119 struct <classname> {
4120 struct _objc_class *isa;
4122 }; */
4124 static void
4125 build_private_template (tree klass)
4127 if (!CLASS_STATIC_TEMPLATE (klass))
4129 tree record = objc_build_struct (klass,
4130 get_class_ivars (klass, false),
4131 CLASS_SUPER_NAME (klass));
4133 /* Set the TREE_USED bit for this struct, so that stab generator
4134 can emit stabs for this struct type. */
4135 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4136 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4140 /* Begin code generation for protocols... */
4142 /* struct _objc_protocol {
4143 struct _objc_class *isa;
4144 char *protocol_name;
4145 struct _objc_protocol **protocol_list;
4146 struct _objc__method_prototype_list *instance_methods;
4147 struct _objc__method_prototype_list *class_methods;
4148 }; */
4150 static void
4151 build_protocol_template (void)
4153 tree field_decl, field_decl_chain;
4155 objc_protocol_template = start_struct (RECORD_TYPE,
4156 get_identifier (UTAG_PROTOCOL));
4158 /* struct _objc_class *isa; */
4159 field_decl = create_field_decl (build_pointer_type
4160 (xref_tag (RECORD_TYPE,
4161 get_identifier (UTAG_CLASS))),
4162 "isa");
4163 field_decl_chain = field_decl;
4165 /* char *protocol_name; */
4166 field_decl = create_field_decl (string_type_node, "protocol_name");
4167 chainon (field_decl_chain, field_decl);
4169 /* struct _objc_protocol **protocol_list; */
4170 field_decl = create_field_decl (build_pointer_type
4171 (build_pointer_type
4172 (objc_protocol_template)),
4173 "protocol_list");
4174 chainon (field_decl_chain, field_decl);
4176 /* struct _objc__method_prototype_list *instance_methods; */
4177 field_decl = create_field_decl (objc_method_proto_list_ptr,
4178 "instance_methods");
4179 chainon (field_decl_chain, field_decl);
4181 /* struct _objc__method_prototype_list *class_methods; */
4182 field_decl = create_field_decl (objc_method_proto_list_ptr,
4183 "class_methods");
4184 chainon (field_decl_chain, field_decl);
4186 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4189 static tree
4190 build_descriptor_table_initializer (tree type, tree entries)
4192 tree initlist = NULL_TREE;
4196 tree eltlist = NULL_TREE;
4198 eltlist
4199 = tree_cons (NULL_TREE,
4200 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4201 eltlist
4202 = tree_cons (NULL_TREE,
4203 add_objc_string (METHOD_ENCODING (entries),
4204 meth_var_types),
4205 eltlist);
4207 initlist
4208 = tree_cons (NULL_TREE,
4209 objc_build_constructor (type, nreverse (eltlist)),
4210 initlist);
4212 entries = TREE_CHAIN (entries);
4214 while (entries);
4216 return objc_build_constructor (build_array_type (type, 0),
4217 nreverse (initlist));
4220 /* struct objc_method_prototype_list {
4221 int count;
4222 struct objc_method_prototype {
4223 SEL name;
4224 char *types;
4225 } list[1];
4226 }; */
4228 static tree
4229 build_method_prototype_list_template (tree list_type, int size)
4231 tree objc_ivar_list_record;
4232 tree field_decl, field_decl_chain;
4234 /* Generate an unnamed struct definition. */
4236 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4238 /* int method_count; */
4239 field_decl = create_field_decl (integer_type_node, "method_count");
4240 field_decl_chain = field_decl;
4242 /* struct objc_method method_list[]; */
4243 field_decl = create_field_decl (build_array_type
4244 (list_type,
4245 build_index_type
4246 (build_int_cst (NULL_TREE, size - 1))),
4247 "method_list");
4248 chainon (field_decl_chain, field_decl);
4250 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4252 return objc_ivar_list_record;
4255 static tree
4256 build_method_prototype_template (void)
4258 tree proto_record;
4259 tree field_decl, field_decl_chain;
4261 proto_record
4262 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4264 /* SEL _cmd; */
4265 field_decl = create_field_decl (objc_selector_type, "_cmd");
4266 field_decl_chain = field_decl;
4268 /* char *method_types; */
4269 field_decl = create_field_decl (string_type_node, "method_types");
4270 chainon (field_decl_chain, field_decl);
4272 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4274 return proto_record;
4277 static tree
4278 objc_method_parm_type (tree type)
4280 type = TREE_VALUE (TREE_TYPE (type));
4281 if (TREE_CODE (type) == TYPE_DECL)
4282 type = TREE_TYPE (type);
4283 return type;
4286 static int
4287 objc_encoded_type_size (tree type)
4289 int sz = int_size_in_bytes (type);
4291 /* Make all integer and enum types at least as large
4292 as an int. */
4293 if (sz > 0 && INTEGRAL_TYPE_P (type))
4294 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4295 /* Treat arrays as pointers, since that's how they're
4296 passed in. */
4297 else if (TREE_CODE (type) == ARRAY_TYPE)
4298 sz = int_size_in_bytes (ptr_type_node);
4299 return sz;
4302 static tree
4303 encode_method_prototype (tree method_decl)
4305 tree parms;
4306 int parm_offset, i;
4307 char buf[40];
4308 tree result;
4310 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4311 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4313 /* Encode return type. */
4314 encode_type (objc_method_parm_type (method_decl),
4315 obstack_object_size (&util_obstack),
4316 OBJC_ENCODE_INLINE_DEFS);
4318 /* Stack size. */
4319 /* The first two arguments (self and _cmd) are pointers; account for
4320 their size. */
4321 i = int_size_in_bytes (ptr_type_node);
4322 parm_offset = 2 * i;
4323 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4324 parms = TREE_CHAIN (parms))
4326 tree type = objc_method_parm_type (parms);
4327 int sz = objc_encoded_type_size (type);
4329 /* If a type size is not known, bail out. */
4330 if (sz < 0)
4332 error ("type %q+D does not have a known size",
4333 type);
4334 /* Pretend that the encoding succeeded; the compilation will
4335 fail nevertheless. */
4336 goto finish_encoding;
4338 parm_offset += sz;
4341 sprintf (buf, "%d@0:%d", parm_offset, i);
4342 obstack_grow (&util_obstack, buf, strlen (buf));
4344 /* Argument types. */
4345 parm_offset = 2 * i;
4346 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4347 parms = TREE_CHAIN (parms))
4349 tree type = objc_method_parm_type (parms);
4351 /* Process argument qualifiers for user supplied arguments. */
4352 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4354 /* Type. */
4355 encode_type (type, obstack_object_size (&util_obstack),
4356 OBJC_ENCODE_INLINE_DEFS);
4358 /* Compute offset. */
4359 sprintf (buf, "%d", parm_offset);
4360 parm_offset += objc_encoded_type_size (type);
4362 obstack_grow (&util_obstack, buf, strlen (buf));
4365 finish_encoding:
4366 obstack_1grow (&util_obstack, '\0');
4367 result = get_identifier (XOBFINISH (&util_obstack, char *));
4368 obstack_free (&util_obstack, util_firstobj);
4369 return result;
4372 static tree
4373 generate_descriptor_table (tree type, const char *name, int size, tree list,
4374 tree proto)
4376 tree decl, initlist;
4378 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4380 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4381 initlist = tree_cons (NULL_TREE, list, initlist);
4383 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4385 return decl;
4388 static void
4389 generate_method_descriptors (tree protocol)
4391 tree initlist, chain, method_list_template;
4392 int size;
4394 if (!objc_method_prototype_template)
4395 objc_method_prototype_template = build_method_prototype_template ();
4397 chain = PROTOCOL_CLS_METHODS (protocol);
4398 if (chain)
4400 size = list_length (chain);
4402 method_list_template
4403 = build_method_prototype_list_template (objc_method_prototype_template,
4404 size);
4406 initlist
4407 = build_descriptor_table_initializer (objc_method_prototype_template,
4408 chain);
4410 UOBJC_CLASS_METHODS_decl
4411 = generate_descriptor_table (method_list_template,
4412 "_OBJC_PROTOCOL_CLASS_METHODS",
4413 size, initlist, protocol);
4415 else
4416 UOBJC_CLASS_METHODS_decl = 0;
4418 chain = PROTOCOL_NST_METHODS (protocol);
4419 if (chain)
4421 size = list_length (chain);
4423 method_list_template
4424 = build_method_prototype_list_template (objc_method_prototype_template,
4425 size);
4426 initlist
4427 = build_descriptor_table_initializer (objc_method_prototype_template,
4428 chain);
4430 UOBJC_INSTANCE_METHODS_decl
4431 = generate_descriptor_table (method_list_template,
4432 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4433 size, initlist, protocol);
4435 else
4436 UOBJC_INSTANCE_METHODS_decl = 0;
4439 static void
4440 generate_protocol_references (tree plist)
4442 tree lproto;
4444 /* Forward declare protocols referenced. */
4445 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4447 tree proto = TREE_VALUE (lproto);
4449 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4450 && PROTOCOL_NAME (proto))
4452 if (! PROTOCOL_FORWARD_DECL (proto))
4453 build_protocol_reference (proto);
4455 if (PROTOCOL_LIST (proto))
4456 generate_protocol_references (PROTOCOL_LIST (proto));
4461 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4462 current class. */
4463 #ifdef OBJCPLUS
4464 static void
4465 objc_generate_cxx_ctor_or_dtor (bool dtor)
4467 tree fn, body, compound_stmt, ivar;
4469 /* - (id) .cxx_construct { ... return self; } */
4470 /* - (void) .cxx_construct { ... } */
4472 objc_set_method_type (MINUS_EXPR);
4473 objc_start_method_definition
4474 (objc_build_method_signature (build_tree_list (NULL_TREE,
4475 dtor
4476 ? void_type_node
4477 : objc_object_type),
4478 get_identifier (dtor
4479 ? TAG_CXX_DESTRUCT
4480 : TAG_CXX_CONSTRUCT),
4481 make_node (TREE_LIST),
4482 false));
4483 body = begin_function_body ();
4484 compound_stmt = begin_compound_stmt (0);
4486 ivar = CLASS_IVARS (implementation_template);
4487 /* Destroy ivars in reverse order. */
4488 if (dtor)
4489 ivar = nreverse (copy_list (ivar));
4491 for (; ivar; ivar = TREE_CHAIN (ivar))
4493 if (TREE_CODE (ivar) == FIELD_DECL)
4495 tree type = TREE_TYPE (ivar);
4497 /* Call the ivar's default constructor or destructor. Do not
4498 call the destructor unless a corresponding constructor call
4499 has also been made (or is not needed). */
4500 if (MAYBE_CLASS_TYPE_P (type)
4501 && (dtor
4502 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4503 && (!TYPE_NEEDS_CONSTRUCTING (type)
4504 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4505 : (TYPE_NEEDS_CONSTRUCTING (type)
4506 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4507 finish_expr_stmt
4508 (build_special_member_call
4509 (build_ivar_reference (DECL_NAME (ivar)),
4510 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4511 NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
4515 /* The constructor returns 'self'. */
4516 if (!dtor)
4517 finish_return_stmt (self_decl);
4519 finish_compound_stmt (compound_stmt);
4520 finish_function_body (body);
4521 fn = current_function_decl;
4522 finish_function ();
4523 objc_finish_method_definition (fn);
4526 /* The following routine will examine the current @interface for any
4527 non-POD C++ ivars requiring non-trivial construction and/or
4528 destruction, and then synthesize special '- .cxx_construct' and/or
4529 '- .cxx_destruct' methods which will run the appropriate
4530 construction or destruction code. Note that ivars inherited from
4531 super-classes are _not_ considered. */
4532 static void
4533 objc_generate_cxx_cdtors (void)
4535 bool need_ctor = false, need_dtor = false;
4536 tree ivar;
4538 /* We do not want to do this for categories, since they do not have
4539 their own ivars. */
4541 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4542 return;
4544 /* First, determine if we even need a constructor and/or destructor. */
4546 for (ivar = CLASS_IVARS (implementation_template); ivar;
4547 ivar = TREE_CHAIN (ivar))
4549 if (TREE_CODE (ivar) == FIELD_DECL)
4551 tree type = TREE_TYPE (ivar);
4553 if (MAYBE_CLASS_TYPE_P (type))
4555 if (TYPE_NEEDS_CONSTRUCTING (type)
4556 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4557 /* NB: If a default constructor is not available, we will not
4558 be able to initialize this ivar; the add_instance_variable()
4559 routine will already have warned about this. */
4560 need_ctor = true;
4562 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4563 && (!TYPE_NEEDS_CONSTRUCTING (type)
4564 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4565 /* NB: If a default constructor is not available, we will not
4566 call the destructor either, for symmetry. */
4567 need_dtor = true;
4572 /* Generate '- .cxx_construct' if needed. */
4574 if (need_ctor)
4575 objc_generate_cxx_ctor_or_dtor (false);
4577 /* Generate '- .cxx_destruct' if needed. */
4579 if (need_dtor)
4580 objc_generate_cxx_ctor_or_dtor (true);
4582 /* The 'imp_list' variable points at an imp_entry record for the current
4583 @implementation. Record the existence of '- .cxx_construct' and/or
4584 '- .cxx_destruct' methods therein; it will be included in the
4585 metadata for the class. */
4586 if (flag_next_runtime)
4587 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4589 #endif
4591 /* For each protocol which was referenced either from a @protocol()
4592 expression, or because a class/category implements it (then a
4593 pointer to the protocol is stored in the struct describing the
4594 class/category), we create a statically allocated instance of the
4595 Protocol class. The code is written in such a way as to generate
4596 as few Protocol objects as possible; we generate a unique Protocol
4597 instance for each protocol, and we don't generate a Protocol
4598 instance if the protocol is never referenced (either from a
4599 @protocol() or from a class/category implementation). These
4600 statically allocated objects can be referred to via the static
4601 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4603 The statically allocated Protocol objects that we generate here
4604 need to be fixed up at runtime in order to be used: the 'isa'
4605 pointer of the objects need to be set up to point to the 'Protocol'
4606 class, as known at runtime.
4608 The NeXT runtime fixes up all protocols at program startup time,
4609 before main() is entered. It uses a low-level trick to look up all
4610 those symbols, then loops on them and fixes them up.
4612 The GNU runtime as well fixes up all protocols before user code
4613 from the module is executed; it requires pointers to those symbols
4614 to be put in the objc_symtab (which is then passed as argument to
4615 the function __objc_exec_class() which the compiler sets up to be
4616 executed automatically when the module is loaded); setup of those
4617 Protocol objects happen in two ways in the GNU runtime: all
4618 Protocol objects referred to by a class or category implementation
4619 are fixed up when the class/category is loaded; all Protocol
4620 objects referred to by a @protocol() expression are added by the
4621 compiler to the list of statically allocated instances to fixup
4622 (the same list holding the statically allocated constant string
4623 objects). Because, as explained above, the compiler generates as
4624 few Protocol objects as possible, some Protocol object might end up
4625 being referenced multiple times when compiled with the GNU runtime,
4626 and end up being fixed up multiple times at runtime initialization.
4627 But that doesn't hurt, it's just a little inefficient. */
4629 static void
4630 generate_protocols (void)
4632 tree p, encoding;
4633 tree decl;
4634 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4636 /* If a protocol was directly referenced, pull in indirect references. */
4637 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4638 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4639 generate_protocol_references (PROTOCOL_LIST (p));
4641 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4643 tree nst_methods = PROTOCOL_NST_METHODS (p);
4644 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4646 /* If protocol wasn't referenced, don't generate any code. */
4647 decl = PROTOCOL_FORWARD_DECL (p);
4649 if (!decl)
4650 continue;
4652 /* Make sure we link in the Protocol class. */
4653 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4655 while (nst_methods)
4657 if (! METHOD_ENCODING (nst_methods))
4659 encoding = encode_method_prototype (nst_methods);
4660 METHOD_ENCODING (nst_methods) = encoding;
4662 nst_methods = TREE_CHAIN (nst_methods);
4665 while (cls_methods)
4667 if (! METHOD_ENCODING (cls_methods))
4669 encoding = encode_method_prototype (cls_methods);
4670 METHOD_ENCODING (cls_methods) = encoding;
4673 cls_methods = TREE_CHAIN (cls_methods);
4675 generate_method_descriptors (p);
4677 if (PROTOCOL_LIST (p))
4678 refs_decl = generate_protocol_list (p);
4679 else
4680 refs_decl = 0;
4682 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4683 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4685 if (refs_decl)
4686 refs_expr = convert (build_pointer_type (build_pointer_type
4687 (objc_protocol_template)),
4688 build_unary_op (input_location,
4689 ADDR_EXPR, refs_decl, 0));
4690 else
4691 refs_expr = build_int_cst (NULL_TREE, 0);
4693 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4694 by generate_method_descriptors, which is called above. */
4695 initlist = build_protocol_initializer (TREE_TYPE (decl),
4696 protocol_name_expr, refs_expr,
4697 UOBJC_INSTANCE_METHODS_decl,
4698 UOBJC_CLASS_METHODS_decl);
4699 finish_var_decl (decl, initlist);
4703 static tree
4704 build_protocol_initializer (tree type, tree protocol_name,
4705 tree protocol_list, tree instance_methods,
4706 tree class_methods)
4708 tree initlist = NULL_TREE, expr;
4709 tree cast_type = build_pointer_type
4710 (xref_tag (RECORD_TYPE,
4711 get_identifier (UTAG_CLASS)));
4713 /* Filling the "isa" in with one allows the runtime system to
4714 detect that the version change...should remove before final release. */
4716 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4717 initlist = tree_cons (NULL_TREE, expr, initlist);
4718 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4719 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4721 if (!instance_methods)
4722 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4723 else
4725 expr = convert (objc_method_proto_list_ptr,
4726 build_unary_op (input_location,
4727 ADDR_EXPR, instance_methods, 0));
4728 initlist = tree_cons (NULL_TREE, expr, initlist);
4731 if (!class_methods)
4732 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4733 else
4735 expr = convert (objc_method_proto_list_ptr,
4736 build_unary_op (input_location,
4737 ADDR_EXPR, class_methods, 0));
4738 initlist = tree_cons (NULL_TREE, expr, initlist);
4741 return objc_build_constructor (type, nreverse (initlist));
4744 /* struct _objc_category {
4745 char *category_name;
4746 char *class_name;
4747 struct _objc_method_list *instance_methods;
4748 struct _objc_method_list *class_methods;
4749 struct _objc_protocol_list *protocols;
4750 }; */
4752 static void
4753 build_category_template (void)
4755 tree field_decl, field_decl_chain;
4757 objc_category_template = start_struct (RECORD_TYPE,
4758 get_identifier (UTAG_CATEGORY));
4760 /* char *category_name; */
4761 field_decl = create_field_decl (string_type_node, "category_name");
4762 field_decl_chain = field_decl;
4764 /* char *class_name; */
4765 field_decl = create_field_decl (string_type_node, "class_name");
4766 chainon (field_decl_chain, field_decl);
4768 /* struct _objc_method_list *instance_methods; */
4769 field_decl = create_field_decl (objc_method_list_ptr,
4770 "instance_methods");
4771 chainon (field_decl_chain, field_decl);
4773 /* struct _objc_method_list *class_methods; */
4774 field_decl = create_field_decl (objc_method_list_ptr,
4775 "class_methods");
4776 chainon (field_decl_chain, field_decl);
4778 /* struct _objc_protocol **protocol_list; */
4779 field_decl = create_field_decl (build_pointer_type
4780 (build_pointer_type
4781 (objc_protocol_template)),
4782 "protocol_list");
4783 chainon (field_decl_chain, field_decl);
4785 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4788 /* struct _objc_selector {
4789 SEL sel_id;
4790 char *sel_type;
4791 }; */
4793 static void
4794 build_selector_template (void)
4797 tree field_decl, field_decl_chain;
4799 objc_selector_template
4800 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4802 /* SEL sel_id; */
4803 field_decl = create_field_decl (objc_selector_type, "sel_id");
4804 field_decl_chain = field_decl;
4806 /* char *sel_type; */
4807 field_decl = create_field_decl (string_type_node, "sel_type");
4808 chainon (field_decl_chain, field_decl);
4810 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4813 /* struct _objc_class {
4814 struct _objc_class *isa;
4815 struct _objc_class *super_class;
4816 char *name;
4817 long version;
4818 long info;
4819 long instance_size;
4820 struct _objc_ivar_list *ivars;
4821 struct _objc_method_list *methods;
4822 #ifdef __NEXT_RUNTIME__
4823 struct objc_cache *cache;
4824 #else
4825 struct sarray *dtable;
4826 struct _objc_class *subclass_list;
4827 struct _objc_class *sibling_class;
4828 #endif
4829 struct _objc_protocol_list *protocols;
4830 #ifdef __NEXT_RUNTIME__
4831 void *sel_id;
4832 #endif
4833 void *gc_object_type;
4834 }; */
4836 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4837 the NeXT/Apple runtime; still, the compiler must generate them to
4838 maintain backward binary compatibility (and to allow for future
4839 expansion). */
4841 static void
4842 build_class_template (void)
4844 tree field_decl, field_decl_chain;
4846 objc_class_template
4847 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4849 /* struct _objc_class *isa; */
4850 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4851 "isa");
4852 field_decl_chain = field_decl;
4854 /* struct _objc_class *super_class; */
4855 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4856 "super_class");
4857 chainon (field_decl_chain, field_decl);
4859 /* char *name; */
4860 field_decl = create_field_decl (string_type_node, "name");
4861 chainon (field_decl_chain, field_decl);
4863 /* long version; */
4864 field_decl = create_field_decl (long_integer_type_node, "version");
4865 chainon (field_decl_chain, field_decl);
4867 /* long info; */
4868 field_decl = create_field_decl (long_integer_type_node, "info");
4869 chainon (field_decl_chain, field_decl);
4871 /* long instance_size; */
4872 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4873 chainon (field_decl_chain, field_decl);
4875 /* struct _objc_ivar_list *ivars; */
4876 field_decl = create_field_decl (objc_ivar_list_ptr,
4877 "ivars");
4878 chainon (field_decl_chain, field_decl);
4880 /* struct _objc_method_list *methods; */
4881 field_decl = create_field_decl (objc_method_list_ptr,
4882 "methods");
4883 chainon (field_decl_chain, field_decl);
4885 if (flag_next_runtime)
4887 /* struct objc_cache *cache; */
4888 field_decl = create_field_decl (build_pointer_type
4889 (xref_tag (RECORD_TYPE,
4890 get_identifier
4891 ("objc_cache"))),
4892 "cache");
4893 chainon (field_decl_chain, field_decl);
4895 else
4897 /* struct sarray *dtable; */
4898 field_decl = create_field_decl (build_pointer_type
4899 (xref_tag (RECORD_TYPE,
4900 get_identifier
4901 ("sarray"))),
4902 "dtable");
4903 chainon (field_decl_chain, field_decl);
4905 /* struct objc_class *subclass_list; */
4906 field_decl = create_field_decl (build_pointer_type
4907 (objc_class_template),
4908 "subclass_list");
4909 chainon (field_decl_chain, field_decl);
4911 /* struct objc_class *sibling_class; */
4912 field_decl = create_field_decl (build_pointer_type
4913 (objc_class_template),
4914 "sibling_class");
4915 chainon (field_decl_chain, field_decl);
4918 /* struct _objc_protocol **protocol_list; */
4919 field_decl = create_field_decl (build_pointer_type
4920 (build_pointer_type
4921 (xref_tag (RECORD_TYPE,
4922 get_identifier
4923 (UTAG_PROTOCOL)))),
4924 "protocol_list");
4925 chainon (field_decl_chain, field_decl);
4927 if (flag_next_runtime)
4929 /* void *sel_id; */
4930 field_decl = create_field_decl (build_pointer_type (void_type_node),
4931 "sel_id");
4932 chainon (field_decl_chain, field_decl);
4935 /* void *gc_object_type; */
4936 field_decl = create_field_decl (build_pointer_type (void_type_node),
4937 "gc_object_type");
4938 chainon (field_decl_chain, field_decl);
4940 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4943 /* Generate appropriate forward declarations for an implementation. */
4945 static void
4946 synth_forward_declarations (void)
4948 tree an_id;
4950 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4951 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4952 objc_class_template);
4954 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4955 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4956 objc_class_template);
4958 /* Pre-build the following entities - for speed/convenience. */
4960 an_id = get_identifier ("super_class");
4961 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4962 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4965 static void
4966 error_with_ivar (const char *message, tree decl)
4968 error ("%J%s %qs", decl,
4969 message, gen_declaration (decl));
4973 static void
4974 check_ivars (tree inter, tree imp)
4976 tree intdecls = CLASS_RAW_IVARS (inter);
4977 tree impdecls = CLASS_RAW_IVARS (imp);
4979 while (1)
4981 tree t1, t2;
4983 #ifdef OBJCPLUS
4984 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4985 intdecls = TREE_CHAIN (intdecls);
4986 #endif
4987 if (intdecls == 0 && impdecls == 0)
4988 break;
4989 if (intdecls == 0 || impdecls == 0)
4991 error ("inconsistent instance variable specification");
4992 break;
4995 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4997 if (!comptypes (t1, t2)
4998 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4999 DECL_INITIAL (impdecls)))
5001 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5003 error_with_ivar ("conflicting instance variable type",
5004 impdecls);
5005 error_with_ivar ("previous declaration of",
5006 intdecls);
5008 else /* both the type and the name don't match */
5010 error ("inconsistent instance variable specification");
5011 break;
5015 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5017 error_with_ivar ("conflicting instance variable name",
5018 impdecls);
5019 error_with_ivar ("previous declaration of",
5020 intdecls);
5023 intdecls = TREE_CHAIN (intdecls);
5024 impdecls = TREE_CHAIN (impdecls);
5028 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5029 This needs to be done just once per compilation. */
5031 /* struct _objc_super {
5032 struct _objc_object *self;
5033 struct _objc_class *super_class;
5034 }; */
5036 static void
5037 build_super_template (void)
5039 tree field_decl, field_decl_chain;
5041 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5043 /* struct _objc_object *self; */
5044 field_decl = create_field_decl (objc_object_type, "self");
5045 field_decl_chain = field_decl;
5047 /* struct _objc_class *super_class; */
5048 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5049 "super_class");
5050 chainon (field_decl_chain, field_decl);
5052 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5055 /* struct _objc_ivar {
5056 char *ivar_name;
5057 char *ivar_type;
5058 int ivar_offset;
5059 }; */
5061 static tree
5062 build_ivar_template (void)
5064 tree objc_ivar_id, objc_ivar_record;
5065 tree field_decl, field_decl_chain;
5067 objc_ivar_id = get_identifier (UTAG_IVAR);
5068 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5070 /* char *ivar_name; */
5071 field_decl = create_field_decl (string_type_node, "ivar_name");
5072 field_decl_chain = field_decl;
5074 /* char *ivar_type; */
5075 field_decl = create_field_decl (string_type_node, "ivar_type");
5076 chainon (field_decl_chain, field_decl);
5078 /* int ivar_offset; */
5079 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5080 chainon (field_decl_chain, field_decl);
5082 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5084 return objc_ivar_record;
5087 /* struct {
5088 int ivar_count;
5089 struct objc_ivar ivar_list[ivar_count];
5090 }; */
5092 static tree
5093 build_ivar_list_template (tree list_type, int size)
5095 tree objc_ivar_list_record;
5096 tree field_decl, field_decl_chain;
5098 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5100 /* int ivar_count; */
5101 field_decl = create_field_decl (integer_type_node, "ivar_count");
5102 field_decl_chain = field_decl;
5104 /* struct objc_ivar ivar_list[]; */
5105 field_decl = create_field_decl (build_array_type
5106 (list_type,
5107 build_index_type
5108 (build_int_cst (NULL_TREE, size - 1))),
5109 "ivar_list");
5110 chainon (field_decl_chain, field_decl);
5112 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5114 return objc_ivar_list_record;
5117 /* struct {
5118 struct _objc__method_prototype_list *method_next;
5119 int method_count;
5120 struct objc_method method_list[method_count];
5121 }; */
5123 static tree
5124 build_method_list_template (tree list_type, int size)
5126 tree objc_ivar_list_record;
5127 tree field_decl, field_decl_chain;
5129 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5131 /* struct _objc__method_prototype_list *method_next; */
5132 field_decl = create_field_decl (objc_method_proto_list_ptr,
5133 "method_next");
5134 field_decl_chain = field_decl;
5136 /* int method_count; */
5137 field_decl = create_field_decl (integer_type_node, "method_count");
5138 chainon (field_decl_chain, field_decl);
5140 /* struct objc_method method_list[]; */
5141 field_decl = create_field_decl (build_array_type
5142 (list_type,
5143 build_index_type
5144 (build_int_cst (NULL_TREE, size - 1))),
5145 "method_list");
5146 chainon (field_decl_chain, field_decl);
5148 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5150 return objc_ivar_list_record;
5153 static tree
5154 build_ivar_list_initializer (tree type, tree field_decl)
5156 tree initlist = NULL_TREE;
5160 tree ivar = NULL_TREE;
5162 /* Set name. */
5163 if (DECL_NAME (field_decl))
5164 ivar = tree_cons (NULL_TREE,
5165 add_objc_string (DECL_NAME (field_decl),
5166 meth_var_names),
5167 ivar);
5168 else
5169 /* Unnamed bit-field ivar (yuck). */
5170 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5172 /* Set type. */
5173 encode_field_decl (field_decl,
5174 obstack_object_size (&util_obstack),
5175 OBJC_ENCODE_DONT_INLINE_DEFS);
5177 /* Null terminate string. */
5178 obstack_1grow (&util_obstack, 0);
5179 ivar
5180 = tree_cons
5181 (NULL_TREE,
5182 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5183 meth_var_types),
5184 ivar);
5185 obstack_free (&util_obstack, util_firstobj);
5187 /* Set offset. */
5188 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5189 initlist = tree_cons (NULL_TREE,
5190 objc_build_constructor (type, nreverse (ivar)),
5191 initlist);
5193 field_decl = TREE_CHAIN (field_decl);
5194 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5196 while (field_decl);
5198 return objc_build_constructor (build_array_type (type, 0),
5199 nreverse (initlist));
5202 static tree
5203 generate_ivars_list (tree type, const char *name, int size, tree list)
5205 tree decl, initlist;
5207 decl = start_var_decl (type, synth_id_with_class_suffix
5208 (name, objc_implementation_context));
5210 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5211 initlist = tree_cons (NULL_TREE, list, initlist);
5213 finish_var_decl (decl,
5214 objc_build_constructor (TREE_TYPE (decl),
5215 nreverse (initlist)));
5217 return decl;
5220 /* Count only the fields occurring in T. */
5222 static int
5223 ivar_list_length (tree t)
5225 int count = 0;
5227 for (; t; t = TREE_CHAIN (t))
5228 if (TREE_CODE (t) == FIELD_DECL)
5229 ++count;
5231 return count;
5234 static void
5235 generate_ivar_lists (void)
5237 tree initlist, ivar_list_template, chain;
5238 int size;
5240 generating_instance_variables = 1;
5242 if (!objc_ivar_template)
5243 objc_ivar_template = build_ivar_template ();
5245 /* Only generate class variables for the root of the inheritance
5246 hierarchy since these will be the same for every class. */
5248 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5249 && (chain = TYPE_FIELDS (objc_class_template)))
5251 size = ivar_list_length (chain);
5253 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5254 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5256 UOBJC_CLASS_VARIABLES_decl
5257 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5258 size, initlist);
5260 else
5261 UOBJC_CLASS_VARIABLES_decl = 0;
5263 chain = CLASS_IVARS (implementation_template);
5264 if (chain)
5266 size = ivar_list_length (chain);
5267 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5268 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5270 UOBJC_INSTANCE_VARIABLES_decl
5271 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5272 size, initlist);
5274 else
5275 UOBJC_INSTANCE_VARIABLES_decl = 0;
5277 generating_instance_variables = 0;
5280 static tree
5281 build_dispatch_table_initializer (tree type, tree entries)
5283 tree initlist = NULL_TREE;
5287 tree elemlist = NULL_TREE;
5289 elemlist = tree_cons (NULL_TREE,
5290 build_selector (METHOD_SEL_NAME (entries)),
5291 NULL_TREE);
5293 /* Generate the method encoding if we don't have one already. */
5294 if (! METHOD_ENCODING (entries))
5295 METHOD_ENCODING (entries) =
5296 encode_method_prototype (entries);
5298 elemlist = tree_cons (NULL_TREE,
5299 add_objc_string (METHOD_ENCODING (entries),
5300 meth_var_types),
5301 elemlist);
5303 elemlist
5304 = tree_cons (NULL_TREE,
5305 convert (ptr_type_node,
5306 build_unary_op (input_location, ADDR_EXPR,
5307 METHOD_DEFINITION (entries), 1)),
5308 elemlist);
5310 initlist = tree_cons (NULL_TREE,
5311 objc_build_constructor (type, nreverse (elemlist)),
5312 initlist);
5314 entries = TREE_CHAIN (entries);
5316 while (entries);
5318 return objc_build_constructor (build_array_type (type, 0),
5319 nreverse (initlist));
5322 /* To accomplish method prototyping without generating all kinds of
5323 inane warnings, the definition of the dispatch table entries were
5324 changed from:
5326 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5328 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5330 static tree
5331 build_method_template (void)
5333 tree _SLT_record;
5334 tree field_decl, field_decl_chain;
5336 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5338 /* SEL _cmd; */
5339 field_decl = create_field_decl (objc_selector_type, "_cmd");
5340 field_decl_chain = field_decl;
5342 /* char *method_types; */
5343 field_decl = create_field_decl (string_type_node, "method_types");
5344 chainon (field_decl_chain, field_decl);
5346 /* void *_imp; */
5347 field_decl = create_field_decl (build_pointer_type (void_type_node),
5348 "_imp");
5349 chainon (field_decl_chain, field_decl);
5351 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5353 return _SLT_record;
5357 static tree
5358 generate_dispatch_table (tree type, const char *name, int size, tree list)
5360 tree decl, initlist;
5362 decl = start_var_decl (type, synth_id_with_class_suffix
5363 (name, objc_implementation_context));
5365 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5366 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5367 initlist = tree_cons (NULL_TREE, list, initlist);
5369 finish_var_decl (decl,
5370 objc_build_constructor (TREE_TYPE (decl),
5371 nreverse (initlist)));
5373 return decl;
5376 static void
5377 mark_referenced_methods (void)
5379 struct imp_entry *impent;
5380 tree chain;
5382 for (impent = imp_list; impent; impent = impent->next)
5384 chain = CLASS_CLS_METHODS (impent->imp_context);
5385 while (chain)
5387 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5388 chain = TREE_CHAIN (chain);
5391 chain = CLASS_NST_METHODS (impent->imp_context);
5392 while (chain)
5394 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5395 chain = TREE_CHAIN (chain);
5400 static void
5401 generate_dispatch_tables (void)
5403 tree initlist, chain, method_list_template;
5404 int size;
5406 if (!objc_method_template)
5407 objc_method_template = build_method_template ();
5409 chain = CLASS_CLS_METHODS (objc_implementation_context);
5410 if (chain)
5412 size = list_length (chain);
5414 method_list_template
5415 = build_method_list_template (objc_method_template, size);
5416 initlist
5417 = build_dispatch_table_initializer (objc_method_template, chain);
5419 UOBJC_CLASS_METHODS_decl
5420 = generate_dispatch_table (method_list_template,
5421 ((TREE_CODE (objc_implementation_context)
5422 == CLASS_IMPLEMENTATION_TYPE)
5423 ? "_OBJC_CLASS_METHODS"
5424 : "_OBJC_CATEGORY_CLASS_METHODS"),
5425 size, initlist);
5427 else
5428 UOBJC_CLASS_METHODS_decl = 0;
5430 chain = CLASS_NST_METHODS (objc_implementation_context);
5431 if (chain)
5433 size = list_length (chain);
5435 method_list_template
5436 = build_method_list_template (objc_method_template, size);
5437 initlist
5438 = build_dispatch_table_initializer (objc_method_template, chain);
5440 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5441 UOBJC_INSTANCE_METHODS_decl
5442 = generate_dispatch_table (method_list_template,
5443 "_OBJC_INSTANCE_METHODS",
5444 size, initlist);
5445 else
5446 /* We have a category. */
5447 UOBJC_INSTANCE_METHODS_decl
5448 = generate_dispatch_table (method_list_template,
5449 "_OBJC_CATEGORY_INSTANCE_METHODS",
5450 size, initlist);
5452 else
5453 UOBJC_INSTANCE_METHODS_decl = 0;
5456 static tree
5457 generate_protocol_list (tree i_or_p)
5459 tree initlist;
5460 tree refs_decl, lproto, e, plist;
5461 int size = 0;
5462 const char *ref_name;
5464 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5465 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5466 plist = CLASS_PROTOCOL_LIST (i_or_p);
5467 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5468 plist = PROTOCOL_LIST (i_or_p);
5469 else
5470 abort ();
5472 /* Compute size. */
5473 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5474 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5475 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5476 size++;
5478 /* Build initializer. */
5479 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5480 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5481 initlist = tree_cons (NULL_TREE, e, initlist);
5483 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5485 tree pval = TREE_VALUE (lproto);
5487 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5488 && PROTOCOL_FORWARD_DECL (pval))
5490 e = build_unary_op (input_location, ADDR_EXPR,
5491 PROTOCOL_FORWARD_DECL (pval), 0);
5492 initlist = tree_cons (NULL_TREE, e, initlist);
5496 /* static struct objc_protocol *refs[n]; */
5498 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5499 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5500 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5501 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5502 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5503 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5504 else
5505 abort ();
5507 refs_decl = start_var_decl
5508 (build_array_type
5509 (build_pointer_type (objc_protocol_template),
5510 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5511 ref_name);
5513 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5514 nreverse (initlist)));
5516 return refs_decl;
5519 static tree
5520 build_category_initializer (tree type, tree cat_name, tree class_name,
5521 tree instance_methods, tree class_methods,
5522 tree protocol_list)
5524 tree initlist = NULL_TREE, expr;
5526 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5527 initlist = tree_cons (NULL_TREE, class_name, initlist);
5529 if (!instance_methods)
5530 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5531 else
5533 expr = convert (objc_method_list_ptr,
5534 build_unary_op (input_location, ADDR_EXPR,
5535 instance_methods, 0));
5536 initlist = tree_cons (NULL_TREE, expr, initlist);
5538 if (!class_methods)
5539 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5540 else
5542 expr = convert (objc_method_list_ptr,
5543 build_unary_op (input_location, ADDR_EXPR,
5544 class_methods, 0));
5545 initlist = tree_cons (NULL_TREE, expr, initlist);
5548 /* protocol_list = */
5549 if (!protocol_list)
5550 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5551 else
5553 expr = convert (build_pointer_type
5554 (build_pointer_type
5555 (objc_protocol_template)),
5556 build_unary_op (input_location, ADDR_EXPR,
5557 protocol_list, 0));
5558 initlist = tree_cons (NULL_TREE, expr, initlist);
5561 return objc_build_constructor (type, nreverse (initlist));
5564 /* struct _objc_class {
5565 struct objc_class *isa;
5566 struct objc_class *super_class;
5567 char *name;
5568 long version;
5569 long info;
5570 long instance_size;
5571 struct objc_ivar_list *ivars;
5572 struct objc_method_list *methods;
5573 if (flag_next_runtime)
5574 struct objc_cache *cache;
5575 else {
5576 struct sarray *dtable;
5577 struct objc_class *subclass_list;
5578 struct objc_class *sibling_class;
5580 struct objc_protocol_list *protocols;
5581 if (flag_next_runtime)
5582 void *sel_id;
5583 void *gc_object_type;
5584 }; */
5586 static tree
5587 build_shared_structure_initializer (tree type, tree isa, tree super,
5588 tree name, tree size, int status,
5589 tree dispatch_table, tree ivar_list,
5590 tree protocol_list)
5592 tree initlist = NULL_TREE, expr;
5594 /* isa = */
5595 initlist = tree_cons (NULL_TREE, isa, initlist);
5597 /* super_class = */
5598 initlist = tree_cons (NULL_TREE, super, initlist);
5600 /* name = */
5601 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5603 /* version = */
5604 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5605 initlist);
5607 /* info = */
5608 initlist = tree_cons (NULL_TREE,
5609 build_int_cst (long_integer_type_node, status),
5610 initlist);
5612 /* instance_size = */
5613 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5614 initlist);
5616 /* objc_ivar_list = */
5617 if (!ivar_list)
5618 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5619 else
5621 expr = convert (objc_ivar_list_ptr,
5622 build_unary_op (input_location, ADDR_EXPR,
5623 ivar_list, 0));
5624 initlist = tree_cons (NULL_TREE, expr, initlist);
5627 /* objc_method_list = */
5628 if (!dispatch_table)
5629 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5630 else
5632 expr = convert (objc_method_list_ptr,
5633 build_unary_op (input_location, ADDR_EXPR,
5634 dispatch_table, 0));
5635 initlist = tree_cons (NULL_TREE, expr, initlist);
5638 if (flag_next_runtime)
5639 /* method_cache = */
5640 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5641 else
5643 /* dtable = */
5644 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5646 /* subclass_list = */
5647 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5649 /* sibling_class = */
5650 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5653 /* protocol_list = */
5654 if (! protocol_list)
5655 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5656 else
5658 expr = convert (build_pointer_type
5659 (build_pointer_type
5660 (objc_protocol_template)),
5661 build_unary_op (input_location, ADDR_EXPR,
5662 protocol_list, 0));
5663 initlist = tree_cons (NULL_TREE, expr, initlist);
5666 if (flag_next_runtime)
5667 /* sel_id = NULL */
5668 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5670 /* gc_object_type = NULL */
5671 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5673 return objc_build_constructor (type, nreverse (initlist));
5676 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5678 static inline tree
5679 lookup_category (tree klass, tree cat_name)
5681 tree category = CLASS_CATEGORY_LIST (klass);
5683 while (category && CLASS_SUPER_NAME (category) != cat_name)
5684 category = CLASS_CATEGORY_LIST (category);
5685 return category;
5688 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5690 static void
5691 generate_category (tree cat)
5693 tree decl;
5694 tree initlist, cat_name_expr, class_name_expr;
5695 tree protocol_decl, category;
5697 add_class_reference (CLASS_NAME (cat));
5698 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5700 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5702 category = lookup_category (implementation_template,
5703 CLASS_SUPER_NAME (cat));
5705 if (category && CLASS_PROTOCOL_LIST (category))
5707 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5708 protocol_decl = generate_protocol_list (category);
5710 else
5711 protocol_decl = 0;
5713 decl = start_var_decl (objc_category_template,
5714 synth_id_with_class_suffix
5715 ("_OBJC_CATEGORY", objc_implementation_context));
5717 initlist = build_category_initializer (TREE_TYPE (decl),
5718 cat_name_expr, class_name_expr,
5719 UOBJC_INSTANCE_METHODS_decl,
5720 UOBJC_CLASS_METHODS_decl,
5721 protocol_decl);
5723 finish_var_decl (decl, initlist);
5726 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5727 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5729 static void
5730 generate_shared_structures (int cls_flags)
5732 tree sc_spec, decl_specs, decl;
5733 tree name_expr, super_expr, root_expr;
5734 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5735 tree cast_type, initlist, protocol_decl;
5737 my_super_id = CLASS_SUPER_NAME (implementation_template);
5738 if (my_super_id)
5740 add_class_reference (my_super_id);
5742 /* Compute "my_root_id" - this is required for code generation.
5743 the "isa" for all meta class structures points to the root of
5744 the inheritance hierarchy (e.g. "__Object")... */
5745 my_root_id = my_super_id;
5748 tree my_root_int = lookup_interface (my_root_id);
5750 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5751 my_root_id = CLASS_SUPER_NAME (my_root_int);
5752 else
5753 break;
5755 while (1);
5757 else
5758 /* No super class. */
5759 my_root_id = CLASS_NAME (implementation_template);
5761 cast_type = build_pointer_type (objc_class_template);
5762 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5763 class_names);
5765 /* Install class `isa' and `super' pointers at runtime. */
5766 if (my_super_id)
5768 super_expr = add_objc_string (my_super_id, class_names);
5769 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5771 else
5772 super_expr = build_int_cst (NULL_TREE, 0);
5774 root_expr = add_objc_string (my_root_id, class_names);
5775 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5777 if (CLASS_PROTOCOL_LIST (implementation_template))
5779 generate_protocol_references
5780 (CLASS_PROTOCOL_LIST (implementation_template));
5781 protocol_decl = generate_protocol_list (implementation_template);
5783 else
5784 protocol_decl = 0;
5786 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5788 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5789 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5791 decl = start_var_decl (objc_class_template,
5792 IDENTIFIER_POINTER
5793 (DECL_NAME (UOBJC_METACLASS_decl)));
5795 initlist
5796 = build_shared_structure_initializer
5797 (TREE_TYPE (decl),
5798 root_expr, super_expr, name_expr,
5799 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5800 2 /*CLS_META*/,
5801 UOBJC_CLASS_METHODS_decl,
5802 UOBJC_CLASS_VARIABLES_decl,
5803 protocol_decl);
5805 finish_var_decl (decl, initlist);
5807 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5809 decl = start_var_decl (objc_class_template,
5810 IDENTIFIER_POINTER
5811 (DECL_NAME (UOBJC_CLASS_decl)));
5813 initlist
5814 = build_shared_structure_initializer
5815 (TREE_TYPE (decl),
5816 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5817 super_expr, name_expr,
5818 convert (integer_type_node,
5819 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5820 (implementation_template))),
5821 1 /*CLS_FACTORY*/ | cls_flags,
5822 UOBJC_INSTANCE_METHODS_decl,
5823 UOBJC_INSTANCE_VARIABLES_decl,
5824 protocol_decl);
5826 finish_var_decl (decl, initlist);
5830 static const char *
5831 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5833 static char string[BUFSIZE];
5835 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5836 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5838 sprintf (string, "%s_%s", preamble,
5839 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5841 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5842 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5844 /* We have a category. */
5845 const char *const class_name
5846 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5847 const char *const class_super_name
5848 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5849 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5851 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5853 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5854 sprintf (string, "%s_%s", preamble, protocol_name);
5856 else
5857 abort ();
5859 return string;
5862 /* If type is empty or only type qualifiers are present, add default
5863 type of id (otherwise grokdeclarator will default to int). */
5865 static tree
5866 adjust_type_for_id_default (tree type)
5868 if (!type)
5869 type = make_node (TREE_LIST);
5871 if (!TREE_VALUE (type))
5872 TREE_VALUE (type) = objc_object_type;
5873 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5874 && TYPED_OBJECT (TREE_VALUE (type)))
5875 error ("can not use an object as parameter to a method");
5877 return type;
5880 /* Usage:
5881 keyworddecl:
5882 selector ':' '(' typename ')' identifier
5884 Purpose:
5885 Transform an Objective-C keyword argument into
5886 the C equivalent parameter declarator.
5888 In: key_name, an "identifier_node" (optional).
5889 arg_type, a "tree_list" (optional).
5890 arg_name, an "identifier_node".
5892 Note: It would be really nice to strongly type the preceding
5893 arguments in the function prototype; however, then I
5894 could not use the "accessor" macros defined in "tree.h".
5896 Out: an instance of "keyword_decl". */
5898 tree
5899 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5901 tree keyword_decl;
5903 /* If no type is specified, default to "id". */
5904 arg_type = adjust_type_for_id_default (arg_type);
5906 keyword_decl = make_node (KEYWORD_DECL);
5908 TREE_TYPE (keyword_decl) = arg_type;
5909 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5910 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5912 return keyword_decl;
5915 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5917 static tree
5918 build_keyword_selector (tree selector)
5920 int len = 0;
5921 tree key_chain, key_name;
5922 char *buf;
5924 /* Scan the selector to see how much space we'll need. */
5925 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5927 if (TREE_CODE (selector) == KEYWORD_DECL)
5928 key_name = KEYWORD_KEY_NAME (key_chain);
5929 else if (TREE_CODE (selector) == TREE_LIST)
5930 key_name = TREE_PURPOSE (key_chain);
5931 else
5932 abort ();
5934 if (key_name)
5935 len += IDENTIFIER_LENGTH (key_name) + 1;
5936 else
5937 /* Just a ':' arg. */
5938 len++;
5941 buf = (char *) alloca (len + 1);
5942 /* Start the buffer out as an empty string. */
5943 buf[0] = '\0';
5945 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5947 if (TREE_CODE (selector) == KEYWORD_DECL)
5948 key_name = KEYWORD_KEY_NAME (key_chain);
5949 else if (TREE_CODE (selector) == TREE_LIST)
5951 key_name = TREE_PURPOSE (key_chain);
5952 /* The keyword decl chain will later be used as a function argument
5953 chain. Unhook the selector itself so as to not confuse other
5954 parts of the compiler. */
5955 TREE_PURPOSE (key_chain) = NULL_TREE;
5957 else
5958 abort ();
5960 if (key_name)
5961 strcat (buf, IDENTIFIER_POINTER (key_name));
5962 strcat (buf, ":");
5965 return get_identifier (buf);
5968 /* Used for declarations and definitions. */
5970 static tree
5971 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5972 tree add_args, bool ellipsis)
5974 tree method_decl;
5976 /* If no type is specified, default to "id". */
5977 ret_type = adjust_type_for_id_default (ret_type);
5979 method_decl = make_node (code);
5980 TREE_TYPE (method_decl) = ret_type;
5982 /* If we have a keyword selector, create an identifier_node that
5983 represents the full selector name (`:' included)... */
5984 if (TREE_CODE (selector) == KEYWORD_DECL)
5986 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5987 METHOD_SEL_ARGS (method_decl) = selector;
5988 METHOD_ADD_ARGS (method_decl) = add_args;
5989 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5991 else
5993 METHOD_SEL_NAME (method_decl) = selector;
5994 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5995 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5998 return method_decl;
6001 #define METHOD_DEF 0
6002 #define METHOD_REF 1
6004 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6005 an argument list for method METH. CONTEXT is either METHOD_DEF or
6006 METHOD_REF, saying whether we are trying to define a method or call
6007 one. SUPERFLAG says this is for a send to super; this makes a
6008 difference for the NeXT calling sequence in which the lookup and
6009 the method call are done together. If METH is null, user-defined
6010 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6012 static tree
6013 get_arg_type_list (tree meth, int context, int superflag)
6015 tree arglist, akey;
6017 /* Receiver type. */
6018 if (flag_next_runtime && superflag)
6019 arglist = build_tree_list (NULL_TREE, objc_super_type);
6020 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6021 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6022 else
6023 arglist = build_tree_list (NULL_TREE, objc_object_type);
6025 /* Selector type - will eventually change to `int'. */
6026 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6028 /* No actual method prototype given -- assume that remaining arguments
6029 are `...'. */
6030 if (!meth)
6031 return arglist;
6033 /* Build a list of argument types. */
6034 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6036 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6038 /* Decay arrays and functions into pointers. */
6039 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6040 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6041 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6042 arg_type = build_pointer_type (arg_type);
6044 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6047 if (METHOD_ADD_ARGS (meth))
6049 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6050 akey; akey = TREE_CHAIN (akey))
6052 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6054 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6057 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6058 goto lack_of_ellipsis;
6060 else
6062 lack_of_ellipsis:
6063 chainon (arglist, OBJC_VOID_AT_END);
6066 return arglist;
6069 static tree
6070 check_duplicates (hash hsh, int methods, int is_class)
6072 tree meth = NULL_TREE;
6074 if (hsh)
6076 meth = hsh->key;
6078 if (hsh->list)
6080 /* We have two or more methods with the same name but
6081 different types. */
6082 attr loop;
6084 /* But just how different are those types? If
6085 -Wno-strict-selector-match is specified, we shall not
6086 complain if the differences are solely among types with
6087 identical size and alignment. */
6088 if (!warn_strict_selector_match)
6090 for (loop = hsh->list; loop; loop = loop->next)
6091 if (!comp_proto_with_proto (meth, loop->value, 0))
6092 goto issue_warning;
6094 return meth;
6097 issue_warning:
6098 warning (0, "multiple %s named %<%c%s%> found",
6099 methods ? "methods" : "selectors",
6100 (is_class ? '+' : '-'),
6101 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6103 warn_with_method (methods ? "using" : "found",
6104 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6105 ? '-'
6106 : '+'),
6107 meth);
6108 for (loop = hsh->list; loop; loop = loop->next)
6109 warn_with_method ("also found",
6110 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6111 ? '-'
6112 : '+'),
6113 loop->value);
6116 return meth;
6119 /* If RECEIVER is a class reference, return the identifier node for
6120 the referenced class. RECEIVER is created by objc_get_class_reference,
6121 so we check the exact form created depending on which runtimes are
6122 used. */
6124 static tree
6125 receiver_is_class_object (tree receiver, int self, int super)
6127 tree chain, exp, arg;
6129 /* The receiver is 'self' or 'super' in the context of a class method. */
6130 if (objc_method_context
6131 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6132 && (self || super))
6133 return (super
6134 ? CLASS_SUPER_NAME (implementation_template)
6135 : CLASS_NAME (implementation_template));
6137 if (flag_next_runtime)
6139 /* The receiver is a variable created by
6140 build_class_reference_decl. */
6141 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6142 /* Look up the identifier. */
6143 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6144 if (TREE_PURPOSE (chain) == receiver)
6145 return TREE_VALUE (chain);
6148 /* The receiver is a function call that returns an id. Check if
6149 it is a call to objc_getClass, if so, pick up the class name. */
6150 if (TREE_CODE (receiver) == CALL_EXPR
6151 && (exp = CALL_EXPR_FN (receiver))
6152 && TREE_CODE (exp) == ADDR_EXPR
6153 && (exp = TREE_OPERAND (exp, 0))
6154 && TREE_CODE (exp) == FUNCTION_DECL
6155 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6156 prototypes for objc_get_class(). Thankfully, they seem to share the
6157 same function type. */
6158 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6159 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6160 /* We have a call to objc_get_class/objc_getClass! */
6161 && (arg = CALL_EXPR_ARG (receiver, 0)))
6163 STRIP_NOPS (arg);
6164 if (TREE_CODE (arg) == ADDR_EXPR
6165 && (arg = TREE_OPERAND (arg, 0))
6166 && TREE_CODE (arg) == STRING_CST)
6167 /* Finally, we have the class name. */
6168 return get_identifier (TREE_STRING_POINTER (arg));
6170 return 0;
6173 /* If we are currently building a message expr, this holds
6174 the identifier of the selector of the message. This is
6175 used when printing warnings about argument mismatches. */
6177 static tree current_objc_message_selector = 0;
6179 tree
6180 objc_message_selector (void)
6182 return current_objc_message_selector;
6185 /* Construct an expression for sending a message.
6186 MESS has the object to send to in TREE_PURPOSE
6187 and the argument list (including selector) in TREE_VALUE.
6189 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6190 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6192 tree
6193 objc_build_message_expr (tree mess)
6195 tree receiver = TREE_PURPOSE (mess);
6196 tree sel_name;
6197 #ifdef OBJCPLUS
6198 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6199 #else
6200 tree args = TREE_VALUE (mess);
6201 #endif
6202 tree method_params = NULL_TREE;
6204 if (TREE_CODE (receiver) == ERROR_MARK)
6205 return error_mark_node;
6207 /* Obtain the full selector name. */
6208 if (TREE_CODE (args) == IDENTIFIER_NODE)
6209 /* A unary selector. */
6210 sel_name = args;
6211 else if (TREE_CODE (args) == TREE_LIST)
6212 sel_name = build_keyword_selector (args);
6213 else
6214 abort ();
6216 /* Build the parameter list to give to the method. */
6217 if (TREE_CODE (args) == TREE_LIST)
6218 #ifdef OBJCPLUS
6219 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6220 #else
6222 tree chain = args, prev = NULL_TREE;
6224 /* We have a keyword selector--check for comma expressions. */
6225 while (chain)
6227 tree element = TREE_VALUE (chain);
6229 /* We have a comma expression, must collapse... */
6230 if (TREE_CODE (element) == TREE_LIST)
6232 if (prev)
6233 TREE_CHAIN (prev) = element;
6234 else
6235 args = element;
6237 prev = chain;
6238 chain = TREE_CHAIN (chain);
6240 method_params = args;
6242 #endif
6244 #ifdef OBJCPLUS
6245 if (processing_template_decl)
6246 /* Must wait until template instantiation time. */
6247 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6248 method_params);
6249 #endif
6251 return objc_finish_message_expr (receiver, sel_name, method_params);
6254 /* Look up method SEL_NAME that would be suitable for receiver
6255 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6256 nonzero), and report on any duplicates. */
6258 static tree
6259 lookup_method_in_hash_lists (tree sel_name, int is_class)
6261 hash method_prototype = NULL;
6263 if (!is_class)
6264 method_prototype = hash_lookup (nst_method_hash_list,
6265 sel_name);
6267 if (!method_prototype)
6269 method_prototype = hash_lookup (cls_method_hash_list,
6270 sel_name);
6271 is_class = 1;
6274 return check_duplicates (method_prototype, 1, is_class);
6277 /* The 'objc_finish_message_expr' routine is called from within
6278 'objc_build_message_expr' for non-template functions. In the case of
6279 C++ template functions, it is called from 'build_expr_from_tree'
6280 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6282 tree
6283 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6285 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6286 tree selector, retval, class_tree;
6287 int self, super, have_cast;
6289 /* Extract the receiver of the message, as well as its type
6290 (where the latter may take the form of a cast or be inferred
6291 from the implementation context). */
6292 rtype = receiver;
6293 while (TREE_CODE (rtype) == COMPOUND_EXPR
6294 || TREE_CODE (rtype) == MODIFY_EXPR
6295 || CONVERT_EXPR_P (rtype)
6296 || TREE_CODE (rtype) == COMPONENT_REF)
6297 rtype = TREE_OPERAND (rtype, 0);
6298 self = (rtype == self_decl);
6299 super = (rtype == UOBJC_SUPER_decl);
6300 rtype = TREE_TYPE (receiver);
6301 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6302 || (TREE_CODE (receiver) == COMPOUND_EXPR
6303 && !IS_SUPER (rtype)));
6305 /* If we are calling [super dealloc], reset our warning flag. */
6306 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6307 should_call_super_dealloc = 0;
6309 /* If the receiver is a class object, retrieve the corresponding
6310 @interface, if one exists. */
6311 class_tree = receiver_is_class_object (receiver, self, super);
6313 /* Now determine the receiver type (if an explicit cast has not been
6314 provided). */
6315 if (!have_cast)
6317 if (class_tree)
6318 rtype = lookup_interface (class_tree);
6319 /* Handle `self' and `super'. */
6320 else if (super)
6322 if (!CLASS_SUPER_NAME (implementation_template))
6324 error ("no super class declared in @interface for %qs",
6325 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6326 return error_mark_node;
6328 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6330 else if (self)
6331 rtype = lookup_interface (CLASS_NAME (implementation_template));
6334 /* If receiver is of type `id' or `Class' (or if the @interface for a
6335 class is not visible), we shall be satisfied with the existence of
6336 any instance or class method. */
6337 if (objc_is_id (rtype))
6339 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6340 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6341 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6342 : NULL_TREE);
6343 rtype = NULL_TREE;
6345 if (rprotos)
6347 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6348 in protocols themselves for the method prototype. */
6349 method_prototype
6350 = lookup_method_in_protocol_list (rprotos, sel_name,
6351 class_tree != NULL_TREE);
6353 /* If messaging 'Class <Proto>' but did not find a class method
6354 prototype, search for an instance method instead, and warn
6355 about having done so. */
6356 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6358 method_prototype
6359 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6361 if (method_prototype)
6362 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6363 IDENTIFIER_POINTER (sel_name),
6364 IDENTIFIER_POINTER (sel_name));
6368 else if (rtype)
6370 tree orig_rtype = rtype, saved_rtype;
6372 if (TREE_CODE (rtype) == POINTER_TYPE)
6373 rtype = TREE_TYPE (rtype);
6374 /* Traverse typedef aliases */
6375 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6376 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6377 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6378 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6379 saved_rtype = rtype;
6380 if (TYPED_OBJECT (rtype))
6382 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6383 rtype = TYPE_OBJC_INTERFACE (rtype);
6385 /* If we could not find an @interface declaration, we must have
6386 only seen a @class declaration; so, we cannot say anything
6387 more intelligent about which methods the receiver will
6388 understand. */
6389 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6390 rtype = NULL_TREE;
6391 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6392 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6394 /* We have a valid ObjC class name. Look up the method name
6395 in the published @interface for the class (and its
6396 superclasses). */
6397 method_prototype
6398 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6400 /* If the method was not found in the @interface, it may still
6401 exist locally as part of the @implementation. */
6402 if (!method_prototype && objc_implementation_context
6403 && CLASS_NAME (objc_implementation_context)
6404 == OBJC_TYPE_NAME (rtype))
6405 method_prototype
6406 = lookup_method
6407 ((class_tree
6408 ? CLASS_CLS_METHODS (objc_implementation_context)
6409 : CLASS_NST_METHODS (objc_implementation_context)),
6410 sel_name);
6412 /* If we haven't found a candidate method by now, try looking for
6413 it in the protocol list. */
6414 if (!method_prototype && rprotos)
6415 method_prototype
6416 = lookup_method_in_protocol_list (rprotos, sel_name,
6417 class_tree != NULL_TREE);
6419 else
6421 warning (0, "invalid receiver type %qs",
6422 gen_type_name (orig_rtype));
6423 /* After issuing the "invalid receiver" warning, perform method
6424 lookup as if we were messaging 'id'. */
6425 rtype = rprotos = NULL_TREE;
6430 /* For 'id' or 'Class' receivers, search in the global hash table
6431 as a last resort. For all receivers, warn if protocol searches
6432 have failed. */
6433 if (!method_prototype)
6435 if (rprotos)
6436 warning (0, "%<%c%s%> not found in protocol(s)",
6437 (class_tree ? '+' : '-'),
6438 IDENTIFIER_POINTER (sel_name));
6440 if (!rtype)
6441 method_prototype
6442 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6445 if (!method_prototype)
6447 static bool warn_missing_methods = false;
6449 if (rtype)
6450 warning (0, "%qs may not respond to %<%c%s%>",
6451 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6452 (class_tree ? '+' : '-'),
6453 IDENTIFIER_POINTER (sel_name));
6454 /* If we are messaging an 'id' or 'Class' object and made it here,
6455 then we have failed to find _any_ instance or class method,
6456 respectively. */
6457 else
6458 warning (0, "no %<%c%s%> method found",
6459 (class_tree ? '+' : '-'),
6460 IDENTIFIER_POINTER (sel_name));
6462 if (!warn_missing_methods)
6464 warning (0, "(Messages without a matching method signature");
6465 warning (0, "will be assumed to return %<id%> and accept");
6466 warning (0, "%<...%> as arguments.)");
6467 warn_missing_methods = true;
6471 /* Save the selector name for printing error messages. */
6472 current_objc_message_selector = sel_name;
6474 /* Build the parameters list for looking up the method.
6475 These are the object itself and the selector. */
6477 if (flag_typed_selectors)
6478 selector = build_typed_selector_reference (sel_name, method_prototype);
6479 else
6480 selector = build_selector_reference (sel_name);
6482 retval = build_objc_method_call (super, method_prototype,
6483 receiver,
6484 selector, method_params);
6486 current_objc_message_selector = 0;
6488 return retval;
6491 /* Build a tree expression to send OBJECT the operation SELECTOR,
6492 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6493 assuming the method has prototype METHOD_PROTOTYPE.
6494 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6495 Use METHOD_PARAMS as list of args to pass to the method.
6496 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6498 static tree
6499 build_objc_method_call (int super_flag, tree method_prototype,
6500 tree lookup_object, tree selector,
6501 tree method_params)
6503 tree sender = (super_flag ? umsg_super_decl :
6504 (!flag_next_runtime || flag_nil_receivers
6505 ? (flag_objc_direct_dispatch
6506 ? umsg_fast_decl
6507 : umsg_decl)
6508 : umsg_nonnil_decl));
6509 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6511 /* If a prototype for the method to be called exists, then cast
6512 the sender's return type and arguments to match that of the method.
6513 Otherwise, leave sender as is. */
6514 tree ret_type
6515 = (method_prototype
6516 ? TREE_VALUE (TREE_TYPE (method_prototype))
6517 : objc_object_type);
6518 tree sender_cast
6519 = build_pointer_type
6520 (build_function_type
6521 (ret_type,
6522 get_arg_type_list
6523 (method_prototype, METHOD_REF, super_flag)));
6524 tree method, t;
6526 lookup_object = build_c_cast (rcv_p, lookup_object);
6528 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6529 lookup_object = save_expr (lookup_object);
6531 if (flag_next_runtime)
6533 /* If we are returning a struct in memory, and the address
6534 of that memory location is passed as a hidden first
6535 argument, then change which messenger entry point this
6536 expr will call. NB: Note that sender_cast remains
6537 unchanged (it already has a struct return type). */
6538 if (!targetm.calls.struct_value_rtx (0, 0)
6539 && (TREE_CODE (ret_type) == RECORD_TYPE
6540 || TREE_CODE (ret_type) == UNION_TYPE)
6541 && targetm.calls.return_in_memory (ret_type, 0))
6542 sender = (super_flag ? umsg_super_stret_decl :
6543 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6545 method_params = tree_cons (NULL_TREE, lookup_object,
6546 tree_cons (NULL_TREE, selector,
6547 method_params));
6548 method = build_fold_addr_expr (sender);
6550 else
6552 /* This is the portable (GNU) way. */
6553 tree object;
6555 /* First, call the lookup function to get a pointer to the method,
6556 then cast the pointer, then call it with the method arguments. */
6558 object = (super_flag ? self_decl : lookup_object);
6560 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6561 t = tree_cons (NULL_TREE, lookup_object, t);
6562 method = build_function_call (sender, t);
6564 /* Pass the object to the method. */
6565 method_params = tree_cons (NULL_TREE, object,
6566 tree_cons (NULL_TREE, selector,
6567 method_params));
6570 /* ??? Selector is not at this point something we can use inside
6571 the compiler itself. Set it to garbage for the nonce. */
6572 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6573 return build_function_call (t, method_params);
6576 static void
6577 build_protocol_reference (tree p)
6579 tree decl;
6580 const char *proto_name;
6582 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6584 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6585 decl = start_var_decl (objc_protocol_template, proto_name);
6587 PROTOCOL_FORWARD_DECL (p) = decl;
6590 /* This function is called by the parser when (and only when) a
6591 @protocol() expression is found, in order to compile it. */
6592 tree
6593 objc_build_protocol_expr (tree protoname)
6595 tree expr;
6596 tree p = lookup_protocol (protoname);
6598 if (!p)
6600 error ("cannot find protocol declaration for %qs",
6601 IDENTIFIER_POINTER (protoname));
6602 return error_mark_node;
6605 if (!PROTOCOL_FORWARD_DECL (p))
6606 build_protocol_reference (p);
6608 expr = build_unary_op (input_location,
6609 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6611 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6612 if we have it, rather than converting it here. */
6613 expr = convert (objc_protocol_type, expr);
6615 /* The @protocol() expression is being compiled into a pointer to a
6616 statically allocated instance of the Protocol class. To become
6617 usable at runtime, the 'isa' pointer of the instance need to be
6618 fixed up at runtime by the runtime library, to point to the
6619 actual 'Protocol' class. */
6621 /* For the GNU runtime, put the static Protocol instance in the list
6622 of statically allocated instances, so that we make sure that its
6623 'isa' pointer is fixed up at runtime by the GNU runtime library
6624 to point to the Protocol class (at runtime, when loading the
6625 module, the GNU runtime library loops on the statically allocated
6626 instances (as found in the defs field in objc_symtab) and fixups
6627 all the 'isa' pointers of those objects). */
6628 if (! flag_next_runtime)
6630 /* This type is a struct containing the fields of a Protocol
6631 object. (Cfr. objc_protocol_type instead is the type of a pointer
6632 to such a struct). */
6633 tree protocol_struct_type = xref_tag
6634 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6635 tree *chain;
6637 /* Look for the list of Protocol statically allocated instances
6638 to fixup at runtime. Create a new list to hold Protocol
6639 statically allocated instances, if the list is not found. At
6640 present there is only another list, holding NSConstantString
6641 static instances to be fixed up at runtime. */
6642 for (chain = &objc_static_instances;
6643 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6644 chain = &TREE_CHAIN (*chain));
6645 if (!*chain)
6647 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6648 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6649 class_names);
6652 /* Add this statically allocated instance to the Protocol list. */
6653 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6654 PROTOCOL_FORWARD_DECL (p),
6655 TREE_PURPOSE (*chain));
6659 return expr;
6662 /* This function is called by the parser when a @selector() expression
6663 is found, in order to compile it. It is only called by the parser
6664 and only to compile a @selector(). */
6665 tree
6666 objc_build_selector_expr (tree selnamelist)
6668 tree selname;
6670 /* Obtain the full selector name. */
6671 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6672 /* A unary selector. */
6673 selname = selnamelist;
6674 else if (TREE_CODE (selnamelist) == TREE_LIST)
6675 selname = build_keyword_selector (selnamelist);
6676 else
6677 abort ();
6679 /* If we are required to check @selector() expressions as they
6680 are found, check that the selector has been declared. */
6681 if (warn_undeclared_selector)
6683 /* Look the selector up in the list of all known class and
6684 instance methods (up to this line) to check that the selector
6685 exists. */
6686 hash hsh;
6688 /* First try with instance methods. */
6689 hsh = hash_lookup (nst_method_hash_list, selname);
6691 /* If not found, try with class methods. */
6692 if (!hsh)
6694 hsh = hash_lookup (cls_method_hash_list, selname);
6697 /* If still not found, print out a warning. */
6698 if (!hsh)
6700 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6705 if (flag_typed_selectors)
6706 return build_typed_selector_reference (selname, 0);
6707 else
6708 return build_selector_reference (selname);
6711 tree
6712 objc_build_encode_expr (tree type)
6714 tree result;
6715 const char *string;
6717 encode_type (type, obstack_object_size (&util_obstack),
6718 OBJC_ENCODE_INLINE_DEFS);
6719 obstack_1grow (&util_obstack, 0); /* null terminate string */
6720 string = XOBFINISH (&util_obstack, const char *);
6722 /* Synthesize a string that represents the encoded struct/union. */
6723 result = my_build_string (strlen (string) + 1, string);
6724 obstack_free (&util_obstack, util_firstobj);
6725 return result;
6728 static tree
6729 build_ivar_reference (tree id)
6731 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6733 /* Historically, a class method that produced objects (factory
6734 method) would assign `self' to the instance that it
6735 allocated. This would effectively turn the class method into
6736 an instance method. Following this assignment, the instance
6737 variables could be accessed. That practice, while safe,
6738 violates the simple rule that a class method should not refer
6739 to an instance variable. It's better to catch the cases
6740 where this is done unknowingly than to support the above
6741 paradigm. */
6742 warning (0, "instance variable %qs accessed in class method",
6743 IDENTIFIER_POINTER (id));
6744 self_decl = convert (objc_instance_type, self_decl); /* cast */
6747 return objc_build_component_ref (build_indirect_ref (input_location,
6748 self_decl, "->"), id);
6751 /* Compute a hash value for a given method SEL_NAME. */
6753 static size_t
6754 hash_func (tree sel_name)
6756 const unsigned char *s
6757 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6758 size_t h = 0;
6760 while (*s)
6761 h = h * 67 + *s++ - 113;
6762 return h;
6765 static void
6766 hash_init (void)
6768 nst_method_hash_list
6769 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6770 cls_method_hash_list
6771 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6773 /* Initialize the hash table used to hold the constant string objects. */
6774 string_htab = htab_create_ggc (31, string_hash,
6775 string_eq, NULL);
6777 /* Initialize the hash table used to hold EH-volatilized types. */
6778 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6779 volatilized_eq, NULL);
6782 /* WARNING!!!! hash_enter is called with a method, and will peek
6783 inside to find its selector! But hash_lookup is given a selector
6784 directly, and looks for the selector that's inside the found
6785 entry's key (method) for comparison. */
6787 static void
6788 hash_enter (hash *hashlist, tree method)
6790 hash obj;
6791 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6793 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6794 obj->list = 0;
6795 obj->next = hashlist[slot];
6796 obj->key = method;
6798 hashlist[slot] = obj; /* append to front */
6801 static hash
6802 hash_lookup (hash *hashlist, tree sel_name)
6804 hash target;
6806 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6808 while (target)
6810 if (sel_name == METHOD_SEL_NAME (target->key))
6811 return target;
6813 target = target->next;
6815 return 0;
6818 static void
6819 hash_add_attr (hash entry, tree value)
6821 attr obj;
6823 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6824 obj->next = entry->list;
6825 obj->value = value;
6827 entry->list = obj; /* append to front */
6830 static tree
6831 lookup_method (tree mchain, tree method)
6833 tree key;
6835 if (TREE_CODE (method) == IDENTIFIER_NODE)
6836 key = method;
6837 else
6838 key = METHOD_SEL_NAME (method);
6840 while (mchain)
6842 if (METHOD_SEL_NAME (mchain) == key)
6843 return mchain;
6845 mchain = TREE_CHAIN (mchain);
6847 return NULL_TREE;
6850 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6851 in INTERFACE, along with any categories and protocols attached thereto.
6852 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6853 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6854 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6855 be found in INTERFACE or any of its superclasses, look for an _instance_
6856 method of the same name in the root class as a last resort.
6858 If a suitable method cannot be found, return NULL_TREE. */
6860 static tree
6861 lookup_method_static (tree interface, tree ident, int flags)
6863 tree meth = NULL_TREE, root_inter = NULL_TREE;
6864 tree inter = interface;
6865 int is_class = (flags & OBJC_LOOKUP_CLASS);
6866 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6868 while (inter)
6870 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6871 tree category = inter;
6873 /* First, look up the method in the class itself. */
6874 if ((meth = lookup_method (chain, ident)))
6875 return meth;
6877 /* Failing that, look for the method in each category of the class. */
6878 while ((category = CLASS_CATEGORY_LIST (category)))
6880 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6882 /* Check directly in each category. */
6883 if ((meth = lookup_method (chain, ident)))
6884 return meth;
6886 /* Failing that, check in each category's protocols. */
6887 if (CLASS_PROTOCOL_LIST (category))
6889 if ((meth = (lookup_method_in_protocol_list
6890 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6891 return meth;
6895 /* If not found in categories, check in protocols of the main class. */
6896 if (CLASS_PROTOCOL_LIST (inter))
6898 if ((meth = (lookup_method_in_protocol_list
6899 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6900 return meth;
6903 /* If we were instructed not to look in superclasses, don't. */
6904 if (no_superclasses)
6905 return NULL_TREE;
6907 /* Failing that, climb up the inheritance hierarchy. */
6908 root_inter = inter;
6909 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6911 while (inter);
6913 /* If no class (factory) method was found, check if an _instance_
6914 method of the same name exists in the root class. This is what
6915 the Objective-C runtime will do. If an instance method was not
6916 found, return 0. */
6917 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6920 /* Add the method to the hash list if it doesn't contain an identical
6921 method already. */
6923 static void
6924 add_method_to_hash_list (hash *hash_list, tree method)
6926 hash hsh;
6928 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6930 /* Install on a global chain. */
6931 hash_enter (hash_list, method);
6933 else
6935 /* Check types against those; if different, add to a list. */
6936 attr loop;
6937 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6938 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6939 already_there |= comp_proto_with_proto (method, loop->value, 1);
6940 if (!already_there)
6941 hash_add_attr (hsh, method);
6945 static tree
6946 objc_add_method (tree klass, tree method, int is_class)
6948 tree mth;
6950 if (!(mth = lookup_method (is_class
6951 ? CLASS_CLS_METHODS (klass)
6952 : CLASS_NST_METHODS (klass), method)))
6954 /* put method on list in reverse order */
6955 if (is_class)
6957 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
6958 CLASS_CLS_METHODS (klass) = method;
6960 else
6962 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
6963 CLASS_NST_METHODS (klass) = method;
6966 else
6968 /* When processing an @interface for a class or category, give hard
6969 errors on methods with identical selectors but differing argument
6970 and/or return types. We do not do this for @implementations, because
6971 C/C++ will do it for us (i.e., there will be duplicate function
6972 definition errors). */
6973 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
6974 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
6975 && !comp_proto_with_proto (method, mth, 1))
6976 error ("duplicate declaration of method %<%c%s%>",
6977 is_class ? '+' : '-',
6978 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6981 if (is_class)
6982 add_method_to_hash_list (cls_method_hash_list, method);
6983 else
6985 add_method_to_hash_list (nst_method_hash_list, method);
6987 /* Instance methods in root classes (and categories thereof)
6988 may act as class methods as a last resort. We also add
6989 instance methods listed in @protocol declarations to
6990 the class hash table, on the assumption that @protocols
6991 may be adopted by root classes or categories. */
6992 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
6993 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
6994 klass = lookup_interface (CLASS_NAME (klass));
6996 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
6997 || !CLASS_SUPER_NAME (klass))
6998 add_method_to_hash_list (cls_method_hash_list, method);
7001 return method;
7004 static tree
7005 add_class (tree class_name, tree name)
7007 struct interface_tuple **slot;
7009 /* Put interfaces on list in reverse order. */
7010 TREE_CHAIN (class_name) = interface_chain;
7011 interface_chain = class_name;
7013 if (interface_htab == NULL)
7014 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7015 slot = (struct interface_tuple **)
7016 htab_find_slot_with_hash (interface_htab, name,
7017 IDENTIFIER_HASH_VALUE (name),
7018 INSERT);
7019 if (!*slot)
7021 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7022 (*slot)->id = name;
7024 (*slot)->class_name = class_name;
7026 return interface_chain;
7029 static void
7030 add_category (tree klass, tree category)
7032 /* Put categories on list in reverse order. */
7033 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7035 if (cat)
7037 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7038 IDENTIFIER_POINTER (CLASS_NAME (klass)),
7039 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7041 else
7043 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7044 CLASS_CATEGORY_LIST (klass) = category;
7048 /* Called after parsing each instance variable declaration. Necessary to
7049 preserve typedefs and implement public/private...
7051 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7053 static tree
7054 add_instance_variable (tree klass, int visibility, tree field_decl)
7056 tree field_type = TREE_TYPE (field_decl);
7057 const char *ivar_name = DECL_NAME (field_decl)
7058 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7059 : "<unnamed>";
7061 #ifdef OBJCPLUS
7062 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7064 error ("illegal reference type specified for instance variable %qs",
7065 ivar_name);
7066 /* Return class as is without adding this ivar. */
7067 return klass;
7069 #endif
7071 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7072 || TYPE_SIZE (field_type) == error_mark_node)
7073 /* 'type[0]' is allowed, but 'type[]' is not! */
7075 error ("instance variable %qs has unknown size", ivar_name);
7076 /* Return class as is without adding this ivar. */
7077 return klass;
7080 #ifdef OBJCPLUS
7081 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7082 need to either (1) warn the user about it or (2) generate suitable
7083 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7084 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7085 if (MAYBE_CLASS_TYPE_P (field_type)
7086 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7087 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7088 || TYPE_POLYMORPHIC_P (field_type)))
7090 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7092 if (flag_objc_call_cxx_cdtors)
7094 /* Since the ObjC runtime will be calling the constructors and
7095 destructors for us, the only thing we can't handle is the lack
7096 of a default constructor. */
7097 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7098 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7100 warning (0, "type %qs has no default constructor to call",
7101 type_name);
7103 /* If we cannot call a constructor, we should also avoid
7104 calling the destructor, for symmetry. */
7105 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7106 warning (0, "destructor for %qs shall not be run either",
7107 type_name);
7110 else
7112 static bool warn_cxx_ivars = false;
7114 if (TYPE_POLYMORPHIC_P (field_type))
7116 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7117 initialize them. */
7118 error ("type %qs has virtual member functions", type_name);
7119 error ("illegal aggregate type %qs specified "
7120 "for instance variable %qs",
7121 type_name, ivar_name);
7122 /* Return class as is without adding this ivar. */
7123 return klass;
7126 /* User-defined constructors and destructors are not known to Obj-C
7127 and hence will not be called. This may or may not be a problem. */
7128 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7129 warning (0, "type %qs has a user-defined constructor", type_name);
7130 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7131 warning (0, "type %qs has a user-defined destructor", type_name);
7133 if (!warn_cxx_ivars)
7135 warning (0, "C++ constructors and destructors will not "
7136 "be invoked for Objective-C fields");
7137 warn_cxx_ivars = true;
7141 #endif
7143 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7144 switch (visibility)
7146 case 0:
7147 TREE_PUBLIC (field_decl) = 0;
7148 TREE_PRIVATE (field_decl) = 0;
7149 TREE_PROTECTED (field_decl) = 1;
7150 break;
7152 case 1:
7153 TREE_PUBLIC (field_decl) = 1;
7154 TREE_PRIVATE (field_decl) = 0;
7155 TREE_PROTECTED (field_decl) = 0;
7156 break;
7158 case 2:
7159 TREE_PUBLIC (field_decl) = 0;
7160 TREE_PRIVATE (field_decl) = 1;
7161 TREE_PROTECTED (field_decl) = 0;
7162 break;
7166 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7168 return klass;
7171 static tree
7172 is_ivar (tree decl_chain, tree ident)
7174 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7175 if (DECL_NAME (decl_chain) == ident)
7176 return decl_chain;
7177 return NULL_TREE;
7180 /* True if the ivar is private and we are not in its implementation. */
7182 static int
7183 is_private (tree decl)
7185 return (TREE_PRIVATE (decl)
7186 && ! is_ivar (CLASS_IVARS (implementation_template),
7187 DECL_NAME (decl)));
7190 /* We have an instance variable reference;, check to see if it is public. */
7193 objc_is_public (tree expr, tree identifier)
7195 tree basetype, decl;
7197 #ifdef OBJCPLUS
7198 if (processing_template_decl)
7199 return 1;
7200 #endif
7202 if (TREE_TYPE (expr) == error_mark_node)
7203 return 1;
7205 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7207 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7209 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7211 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7213 if (!klass)
7215 error ("cannot find interface declaration for %qs",
7216 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7217 return 0;
7220 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7222 if (TREE_PUBLIC (decl))
7223 return 1;
7225 /* Important difference between the Stepstone translator:
7226 all instance variables should be public within the context
7227 of the implementation. */
7228 if (objc_implementation_context
7229 && ((TREE_CODE (objc_implementation_context)
7230 == CLASS_IMPLEMENTATION_TYPE)
7231 || (TREE_CODE (objc_implementation_context)
7232 == CATEGORY_IMPLEMENTATION_TYPE)))
7234 tree curtype = TYPE_MAIN_VARIANT
7235 (CLASS_STATIC_TEMPLATE
7236 (implementation_template));
7238 if (basetype == curtype
7239 || DERIVED_FROM_P (basetype, curtype))
7241 int priv = is_private (decl);
7243 if (priv)
7244 error ("instance variable %qs is declared private",
7245 IDENTIFIER_POINTER (DECL_NAME (decl)));
7247 return !priv;
7251 /* The 2.95.2 compiler sometimes allowed C functions to access
7252 non-@public ivars. We will let this slide for now... */
7253 if (!objc_method_context)
7255 warning (0, "instance variable %qs is %s; "
7256 "this will be a hard error in the future",
7257 IDENTIFIER_POINTER (identifier),
7258 TREE_PRIVATE (decl) ? "@private" : "@protected");
7259 return 1;
7262 error ("instance variable %qs is declared %s",
7263 IDENTIFIER_POINTER (identifier),
7264 TREE_PRIVATE (decl) ? "private" : "protected");
7265 return 0;
7270 return 1;
7273 /* Make sure all entries in CHAIN are also in LIST. */
7275 static int
7276 check_methods (tree chain, tree list, int mtype)
7278 int first = 1;
7280 while (chain)
7282 if (!lookup_method (list, chain))
7284 if (first)
7286 if (TREE_CODE (objc_implementation_context)
7287 == CLASS_IMPLEMENTATION_TYPE)
7288 warning (0, "incomplete implementation of class %qs",
7289 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7290 else if (TREE_CODE (objc_implementation_context)
7291 == CATEGORY_IMPLEMENTATION_TYPE)
7292 warning (0, "incomplete implementation of category %qs",
7293 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7294 first = 0;
7297 warning (0, "method definition for %<%c%s%> not found",
7298 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7301 chain = TREE_CHAIN (chain);
7304 return first;
7307 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7309 static int
7310 conforms_to_protocol (tree klass, tree protocol)
7312 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7314 tree p = CLASS_PROTOCOL_LIST (klass);
7315 while (p && TREE_VALUE (p) != protocol)
7316 p = TREE_CHAIN (p);
7318 if (!p)
7320 tree super = (CLASS_SUPER_NAME (klass)
7321 ? lookup_interface (CLASS_SUPER_NAME (klass))
7322 : NULL_TREE);
7323 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7324 if (!tmp)
7325 return 0;
7329 return 1;
7332 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7333 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7335 static int
7336 check_methods_accessible (tree chain, tree context, int mtype)
7338 int first = 1;
7339 tree list;
7340 tree base_context = context;
7342 while (chain)
7344 context = base_context;
7345 while (context)
7347 if (mtype == '+')
7348 list = CLASS_CLS_METHODS (context);
7349 else
7350 list = CLASS_NST_METHODS (context);
7352 if (lookup_method (list, chain))
7353 break;
7355 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7356 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7357 context = (CLASS_SUPER_NAME (context)
7358 ? lookup_interface (CLASS_SUPER_NAME (context))
7359 : NULL_TREE);
7361 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7362 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7363 context = (CLASS_NAME (context)
7364 ? lookup_interface (CLASS_NAME (context))
7365 : NULL_TREE);
7366 else
7367 abort ();
7370 if (context == NULL_TREE)
7372 if (first)
7374 if (TREE_CODE (objc_implementation_context)
7375 == CLASS_IMPLEMENTATION_TYPE)
7376 warning (0, "incomplete implementation of class %qs",
7377 IDENTIFIER_POINTER
7378 (CLASS_NAME (objc_implementation_context)));
7379 else if (TREE_CODE (objc_implementation_context)
7380 == CATEGORY_IMPLEMENTATION_TYPE)
7381 warning (0, "incomplete implementation of category %qs",
7382 IDENTIFIER_POINTER
7383 (CLASS_SUPER_NAME (objc_implementation_context)));
7384 first = 0;
7386 warning (0, "method definition for %<%c%s%> not found",
7387 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7390 chain = TREE_CHAIN (chain); /* next method... */
7392 return first;
7395 /* Check whether the current interface (accessible via
7396 'objc_implementation_context') actually implements protocol P, along
7397 with any protocols that P inherits. */
7399 static void
7400 check_protocol (tree p, const char *type, const char *name)
7402 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7404 int f1, f2;
7406 /* Ensure that all protocols have bodies! */
7407 if (warn_protocol)
7409 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7410 CLASS_CLS_METHODS (objc_implementation_context),
7411 '+');
7412 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7413 CLASS_NST_METHODS (objc_implementation_context),
7414 '-');
7416 else
7418 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7419 objc_implementation_context,
7420 '+');
7421 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7422 objc_implementation_context,
7423 '-');
7426 if (!f1 || !f2)
7427 warning (0, "%s %qs does not fully implement the %qs protocol",
7428 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7431 /* Check protocols recursively. */
7432 if (PROTOCOL_LIST (p))
7434 tree subs = PROTOCOL_LIST (p);
7435 tree super_class =
7436 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7438 while (subs)
7440 tree sub = TREE_VALUE (subs);
7442 /* If the superclass does not conform to the protocols
7443 inherited by P, then we must! */
7444 if (!super_class || !conforms_to_protocol (super_class, sub))
7445 check_protocol (sub, type, name);
7446 subs = TREE_CHAIN (subs);
7451 /* Check whether the current interface (accessible via
7452 'objc_implementation_context') actually implements the protocols listed
7453 in PROTO_LIST. */
7455 static void
7456 check_protocols (tree proto_list, const char *type, const char *name)
7458 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7460 tree p = TREE_VALUE (proto_list);
7462 check_protocol (p, type, name);
7466 /* Make sure that the class CLASS_NAME is defined
7467 CODE says which kind of thing CLASS_NAME ought to be.
7468 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7469 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7471 static tree
7472 start_class (enum tree_code code, tree class_name, tree super_name,
7473 tree protocol_list)
7475 tree klass, decl;
7477 #ifdef OBJCPLUS
7478 if (current_namespace != global_namespace) {
7479 error ("Objective-C declarations may only appear in global scope");
7481 #endif /* OBJCPLUS */
7483 if (objc_implementation_context)
7485 warning (0, "%<@end%> missing in implementation context");
7486 finish_class (objc_implementation_context);
7487 objc_ivar_chain = NULL_TREE;
7488 objc_implementation_context = NULL_TREE;
7491 klass = make_node (code);
7492 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7494 /* Check for existence of the super class, if one was specified. Note
7495 that we must have seen an @interface, not just a @class. If we
7496 are looking at a @compatibility_alias, traverse it first. */
7497 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7498 && super_name)
7500 tree super = objc_is_class_name (super_name);
7502 if (!super || !lookup_interface (super))
7504 error ("cannot find interface declaration for %qs, superclass of %qs",
7505 IDENTIFIER_POINTER (super ? super : super_name),
7506 IDENTIFIER_POINTER (class_name));
7507 super_name = NULL_TREE;
7509 else
7510 super_name = super;
7513 CLASS_NAME (klass) = class_name;
7514 CLASS_SUPER_NAME (klass) = super_name;
7515 CLASS_CLS_METHODS (klass) = NULL_TREE;
7517 if (! objc_is_class_name (class_name)
7518 && (decl = lookup_name (class_name)))
7520 error ("%qs redeclared as different kind of symbol",
7521 IDENTIFIER_POINTER (class_name));
7522 error ("previous declaration of %q+D",
7523 decl);
7526 if (code == CLASS_IMPLEMENTATION_TYPE)
7529 tree chain;
7531 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7532 if (TREE_VALUE (chain) == class_name)
7534 error ("reimplementation of class %qs",
7535 IDENTIFIER_POINTER (class_name));
7536 return error_mark_node;
7538 implemented_classes = tree_cons (NULL_TREE, class_name,
7539 implemented_classes);
7542 /* Reset for multiple classes per file. */
7543 method_slot = 0;
7545 objc_implementation_context = klass;
7547 /* Lookup the interface for this implementation. */
7549 if (!(implementation_template = lookup_interface (class_name)))
7551 warning (0, "cannot find interface declaration for %qs",
7552 IDENTIFIER_POINTER (class_name));
7553 add_class (implementation_template = objc_implementation_context,
7554 class_name);
7557 /* If a super class has been specified in the implementation,
7558 insure it conforms to the one specified in the interface. */
7560 if (super_name
7561 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7563 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7564 const char *const name =
7565 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7566 error ("conflicting super class name %qs",
7567 IDENTIFIER_POINTER (super_name));
7568 error ("previous declaration of %qs", name);
7571 else if (! super_name)
7573 CLASS_SUPER_NAME (objc_implementation_context)
7574 = CLASS_SUPER_NAME (implementation_template);
7578 else if (code == CLASS_INTERFACE_TYPE)
7580 if (lookup_interface (class_name))
7581 #ifdef OBJCPLUS
7582 error ("duplicate interface declaration for class %qs",
7583 #else
7584 warning (0, "duplicate interface declaration for class %qs",
7585 #endif
7586 IDENTIFIER_POINTER (class_name));
7587 else
7588 add_class (klass, class_name);
7590 if (protocol_list)
7591 CLASS_PROTOCOL_LIST (klass)
7592 = lookup_and_install_protocols (protocol_list);
7595 else if (code == CATEGORY_INTERFACE_TYPE)
7597 tree class_category_is_assoc_with;
7599 /* For a category, class_name is really the name of the class that
7600 the following set of methods will be associated with. We must
7601 find the interface so that can derive the objects template. */
7603 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7605 error ("cannot find interface declaration for %qs",
7606 IDENTIFIER_POINTER (class_name));
7607 exit (FATAL_EXIT_CODE);
7609 else
7610 add_category (class_category_is_assoc_with, klass);
7612 if (protocol_list)
7613 CLASS_PROTOCOL_LIST (klass)
7614 = lookup_and_install_protocols (protocol_list);
7617 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7619 /* Reset for multiple classes per file. */
7620 method_slot = 0;
7622 objc_implementation_context = klass;
7624 /* For a category, class_name is really the name of the class that
7625 the following set of methods will be associated with. We must
7626 find the interface so that can derive the objects template. */
7628 if (!(implementation_template = lookup_interface (class_name)))
7630 error ("cannot find interface declaration for %qs",
7631 IDENTIFIER_POINTER (class_name));
7632 exit (FATAL_EXIT_CODE);
7635 return klass;
7638 static tree
7639 continue_class (tree klass)
7641 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7642 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7644 struct imp_entry *imp_entry;
7646 /* Check consistency of the instance variables. */
7648 if (CLASS_RAW_IVARS (klass))
7649 check_ivars (implementation_template, klass);
7651 /* code generation */
7653 #ifdef OBJCPLUS
7654 push_lang_context (lang_name_c);
7655 #endif
7657 build_private_template (implementation_template);
7658 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7659 objc_instance_type = build_pointer_type (uprivate_record);
7661 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7663 imp_entry->next = imp_list;
7664 imp_entry->imp_context = klass;
7665 imp_entry->imp_template = implementation_template;
7667 synth_forward_declarations ();
7668 imp_entry->class_decl = UOBJC_CLASS_decl;
7669 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7670 imp_entry->has_cxx_cdtors = 0;
7672 /* Append to front and increment count. */
7673 imp_list = imp_entry;
7674 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7675 imp_count++;
7676 else
7677 cat_count++;
7679 #ifdef OBJCPLUS
7680 pop_lang_context ();
7681 #endif /* OBJCPLUS */
7683 return get_class_ivars (implementation_template, true);
7686 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7688 #ifdef OBJCPLUS
7689 push_lang_context (lang_name_c);
7690 #endif /* OBJCPLUS */
7692 build_private_template (klass);
7694 #ifdef OBJCPLUS
7695 pop_lang_context ();
7696 #endif /* OBJCPLUS */
7698 return NULL_TREE;
7701 else
7702 return error_mark_node;
7705 /* This is called once we see the "@end" in an interface/implementation. */
7707 static void
7708 finish_class (tree klass)
7710 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7712 /* All code generation is done in finish_objc. */
7714 if (implementation_template != objc_implementation_context)
7716 /* Ensure that all method listed in the interface contain bodies. */
7717 check_methods (CLASS_CLS_METHODS (implementation_template),
7718 CLASS_CLS_METHODS (objc_implementation_context), '+');
7719 check_methods (CLASS_NST_METHODS (implementation_template),
7720 CLASS_NST_METHODS (objc_implementation_context), '-');
7722 if (CLASS_PROTOCOL_LIST (implementation_template))
7723 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7724 "class",
7725 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7729 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7731 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7733 if (category)
7735 /* Ensure all method listed in the interface contain bodies. */
7736 check_methods (CLASS_CLS_METHODS (category),
7737 CLASS_CLS_METHODS (objc_implementation_context), '+');
7738 check_methods (CLASS_NST_METHODS (category),
7739 CLASS_NST_METHODS (objc_implementation_context), '-');
7741 if (CLASS_PROTOCOL_LIST (category))
7742 check_protocols (CLASS_PROTOCOL_LIST (category),
7743 "category",
7744 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7749 static tree
7750 add_protocol (tree protocol)
7752 /* Put protocol on list in reverse order. */
7753 TREE_CHAIN (protocol) = protocol_chain;
7754 protocol_chain = protocol;
7755 return protocol_chain;
7758 static tree
7759 lookup_protocol (tree ident)
7761 tree chain;
7763 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7764 if (ident == PROTOCOL_NAME (chain))
7765 return chain;
7767 return NULL_TREE;
7770 /* This function forward declares the protocols named by NAMES. If
7771 they are already declared or defined, the function has no effect. */
7773 void
7774 objc_declare_protocols (tree names)
7776 tree list;
7778 #ifdef OBJCPLUS
7779 if (current_namespace != global_namespace) {
7780 error ("Objective-C declarations may only appear in global scope");
7782 #endif /* OBJCPLUS */
7784 for (list = names; list; list = TREE_CHAIN (list))
7786 tree name = TREE_VALUE (list);
7788 if (lookup_protocol (name) == NULL_TREE)
7790 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7792 TYPE_LANG_SLOT_1 (protocol)
7793 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7794 PROTOCOL_NAME (protocol) = name;
7795 PROTOCOL_LIST (protocol) = NULL_TREE;
7796 add_protocol (protocol);
7797 PROTOCOL_DEFINED (protocol) = 0;
7798 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7803 static tree
7804 start_protocol (enum tree_code code, tree name, tree list)
7806 tree protocol;
7808 #ifdef OBJCPLUS
7809 if (current_namespace != global_namespace) {
7810 error ("Objective-C declarations may only appear in global scope");
7812 #endif /* OBJCPLUS */
7814 protocol = lookup_protocol (name);
7816 if (!protocol)
7818 protocol = make_node (code);
7819 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7821 PROTOCOL_NAME (protocol) = name;
7822 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7823 add_protocol (protocol);
7824 PROTOCOL_DEFINED (protocol) = 1;
7825 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7827 check_protocol_recursively (protocol, list);
7829 else if (! PROTOCOL_DEFINED (protocol))
7831 PROTOCOL_DEFINED (protocol) = 1;
7832 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7834 check_protocol_recursively (protocol, list);
7836 else
7838 warning (0, "duplicate declaration for protocol %qs",
7839 IDENTIFIER_POINTER (name));
7841 return protocol;
7845 /* "Encode" a data type into a string, which grows in util_obstack.
7846 ??? What is the FORMAT? Someone please document this! */
7848 static void
7849 encode_type_qualifiers (tree declspecs)
7851 tree spec;
7853 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7855 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7856 obstack_1grow (&util_obstack, 'n');
7857 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7858 obstack_1grow (&util_obstack, 'N');
7859 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7860 obstack_1grow (&util_obstack, 'o');
7861 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7862 obstack_1grow (&util_obstack, 'O');
7863 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7864 obstack_1grow (&util_obstack, 'R');
7865 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7866 obstack_1grow (&util_obstack, 'V');
7870 /* Encode a pointer type. */
7872 static void
7873 encode_pointer (tree type, int curtype, int format)
7875 tree pointer_to = TREE_TYPE (type);
7877 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7879 if (OBJC_TYPE_NAME (pointer_to)
7880 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7882 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7884 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7886 obstack_1grow (&util_obstack, '@');
7887 return;
7889 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7890 && TYPE_OBJC_INTERFACE (pointer_to))
7892 if (generating_instance_variables)
7894 obstack_1grow (&util_obstack, '@');
7895 obstack_1grow (&util_obstack, '"');
7896 obstack_grow (&util_obstack, name, strlen (name));
7897 obstack_1grow (&util_obstack, '"');
7898 return;
7900 else
7902 obstack_1grow (&util_obstack, '@');
7903 return;
7906 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7908 obstack_1grow (&util_obstack, '#');
7909 return;
7911 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7913 obstack_1grow (&util_obstack, ':');
7914 return;
7918 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7919 && TYPE_MODE (pointer_to) == QImode)
7921 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7922 ? OBJC_TYPE_NAME (pointer_to)
7923 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7925 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7927 /* It appears that "r*" means "const char *" rather than
7928 "char *const". */
7929 if (TYPE_READONLY (pointer_to))
7930 obstack_1grow (&util_obstack, 'r');
7932 obstack_1grow (&util_obstack, '*');
7933 return;
7937 /* We have a type that does not get special treatment. */
7939 /* NeXT extension */
7940 obstack_1grow (&util_obstack, '^');
7941 encode_type (pointer_to, curtype, format);
7944 static void
7945 encode_array (tree type, int curtype, int format)
7947 tree an_int_cst = TYPE_SIZE (type);
7948 tree array_of = TREE_TYPE (type);
7949 char buffer[40];
7951 /* An incomplete array is treated like a pointer. */
7952 if (an_int_cst == NULL)
7954 encode_pointer (type, curtype, format);
7955 return;
7958 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7959 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7960 else
7961 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7962 TREE_INT_CST_LOW (an_int_cst)
7963 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7965 obstack_grow (&util_obstack, buffer, strlen (buffer));
7966 encode_type (array_of, curtype, format);
7967 obstack_1grow (&util_obstack, ']');
7968 return;
7971 static void
7972 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7974 tree field = TYPE_FIELDS (type);
7976 for (; field; field = TREE_CHAIN (field))
7978 #ifdef OBJCPLUS
7979 /* C++ static members, and things that are not field at all,
7980 should not appear in the encoding. */
7981 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7982 continue;
7983 #endif
7985 /* Recursively encode fields of embedded base classes. */
7986 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7987 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7989 encode_aggregate_fields (TREE_TYPE (field),
7990 pointed_to, curtype, format);
7991 continue;
7994 if (generating_instance_variables && !pointed_to)
7996 tree fname = DECL_NAME (field);
7998 obstack_1grow (&util_obstack, '"');
8000 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
8001 obstack_grow (&util_obstack,
8002 IDENTIFIER_POINTER (fname),
8003 strlen (IDENTIFIER_POINTER (fname)));
8005 obstack_1grow (&util_obstack, '"');
8008 encode_field_decl (field, curtype, format);
8012 static void
8013 encode_aggregate_within (tree type, int curtype, int format, int left,
8014 int right)
8016 tree name;
8017 /* NB: aggregates that are pointed to have slightly different encoding
8018 rules in that you never encode the names of instance variables. */
8019 int ob_size = obstack_object_size (&util_obstack);
8020 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8021 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8022 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8023 int inline_contents
8024 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8025 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8027 /* Traverse struct aliases; it is important to get the
8028 original struct and its tag name (if any). */
8029 type = TYPE_MAIN_VARIANT (type);
8030 name = OBJC_TYPE_NAME (type);
8031 /* Open parenth/bracket. */
8032 obstack_1grow (&util_obstack, left);
8034 /* Encode the struct/union tag name, or '?' if a tag was
8035 not provided. Typedef aliases do not qualify. */
8036 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8037 #ifdef OBJCPLUS
8038 /* Did this struct have a tag? */
8039 && !TYPE_WAS_ANONYMOUS (type)
8040 #endif
8042 obstack_grow (&util_obstack,
8043 IDENTIFIER_POINTER (name),
8044 strlen (IDENTIFIER_POINTER (name)));
8045 else
8046 obstack_1grow (&util_obstack, '?');
8048 /* Encode the types (and possibly names) of the inner fields,
8049 if required. */
8050 if (inline_contents)
8052 obstack_1grow (&util_obstack, '=');
8053 encode_aggregate_fields (type, pointed_to, curtype, format);
8055 /* Close parenth/bracket. */
8056 obstack_1grow (&util_obstack, right);
8059 static void
8060 encode_aggregate (tree type, int curtype, int format)
8062 enum tree_code code = TREE_CODE (type);
8064 switch (code)
8066 case RECORD_TYPE:
8068 encode_aggregate_within (type, curtype, format, '{', '}');
8069 break;
8071 case UNION_TYPE:
8073 encode_aggregate_within (type, curtype, format, '(', ')');
8074 break;
8077 case ENUMERAL_TYPE:
8078 obstack_1grow (&util_obstack, 'i');
8079 break;
8081 default:
8082 break;
8086 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8087 field type. */
8089 static void
8090 encode_next_bitfield (int width)
8092 char buffer[40];
8093 sprintf (buffer, "b%d", width);
8094 obstack_grow (&util_obstack, buffer, strlen (buffer));
8097 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8098 static void
8099 encode_type (tree type, int curtype, int format)
8101 enum tree_code code = TREE_CODE (type);
8102 char c;
8104 if (type == error_mark_node)
8105 return;
8107 if (TYPE_READONLY (type))
8108 obstack_1grow (&util_obstack, 'r');
8110 if (code == INTEGER_TYPE)
8112 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8114 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8115 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8116 case 32:
8117 if (type == long_unsigned_type_node
8118 || type == long_integer_type_node)
8119 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8120 else
8121 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8122 break;
8123 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8124 default: abort ();
8126 obstack_1grow (&util_obstack, c);
8129 else if (code == REAL_TYPE)
8131 /* Floating point types. */
8132 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8134 case 32: c = 'f'; break;
8135 case 64:
8136 case 96:
8137 case 128: c = 'd'; break;
8138 default: abort ();
8140 obstack_1grow (&util_obstack, c);
8143 else if (code == VOID_TYPE)
8144 obstack_1grow (&util_obstack, 'v');
8146 else if (code == BOOLEAN_TYPE)
8147 obstack_1grow (&util_obstack, 'B');
8149 else if (code == ARRAY_TYPE)
8150 encode_array (type, curtype, format);
8152 else if (code == POINTER_TYPE)
8153 encode_pointer (type, curtype, format);
8155 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8156 encode_aggregate (type, curtype, format);
8158 else if (code == FUNCTION_TYPE) /* '?' */
8159 obstack_1grow (&util_obstack, '?');
8161 else if (code == COMPLEX_TYPE)
8163 obstack_1grow (&util_obstack, 'j');
8164 encode_type (TREE_TYPE (type), curtype, format);
8168 static void
8169 encode_gnu_bitfield (int position, tree type, int size)
8171 enum tree_code code = TREE_CODE (type);
8172 char buffer[40];
8173 char charType = '?';
8175 if (code == INTEGER_TYPE)
8177 if (integer_zerop (TYPE_MIN_VALUE (type)))
8179 /* Unsigned integer types. */
8181 if (TYPE_MODE (type) == QImode)
8182 charType = 'C';
8183 else if (TYPE_MODE (type) == HImode)
8184 charType = 'S';
8185 else if (TYPE_MODE (type) == SImode)
8187 if (type == long_unsigned_type_node)
8188 charType = 'L';
8189 else
8190 charType = 'I';
8192 else if (TYPE_MODE (type) == DImode)
8193 charType = 'Q';
8196 else
8197 /* Signed integer types. */
8199 if (TYPE_MODE (type) == QImode)
8200 charType = 'c';
8201 else if (TYPE_MODE (type) == HImode)
8202 charType = 's';
8203 else if (TYPE_MODE (type) == SImode)
8205 if (type == long_integer_type_node)
8206 charType = 'l';
8207 else
8208 charType = 'i';
8211 else if (TYPE_MODE (type) == DImode)
8212 charType = 'q';
8215 else if (code == ENUMERAL_TYPE)
8216 charType = 'i';
8217 else
8218 abort ();
8220 sprintf (buffer, "b%d%c%d", position, charType, size);
8221 obstack_grow (&util_obstack, buffer, strlen (buffer));
8224 static void
8225 encode_field_decl (tree field_decl, int curtype, int format)
8227 tree type;
8229 #ifdef OBJCPLUS
8230 /* C++ static members, and things that are not fields at all,
8231 should not appear in the encoding. */
8232 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8233 return;
8234 #endif
8236 type = TREE_TYPE (field_decl);
8238 /* Generate the bitfield typing information, if needed. Note the difference
8239 between GNU and NeXT runtimes. */
8240 if (DECL_BIT_FIELD_TYPE (field_decl))
8242 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8244 if (flag_next_runtime)
8245 encode_next_bitfield (size);
8246 else
8247 encode_gnu_bitfield (int_bit_position (field_decl),
8248 DECL_BIT_FIELD_TYPE (field_decl), size);
8250 else
8251 encode_type (TREE_TYPE (field_decl), curtype, format);
8254 static GTY(()) tree objc_parmlist = NULL_TREE;
8256 /* Append PARM to a list of formal parameters of a method, making a necessary
8257 array-to-pointer adjustment along the way. */
8259 static void
8260 objc_push_parm (tree parm)
8262 bool relayout_needed = false;
8264 if (TREE_TYPE (parm) == error_mark_node)
8266 objc_parmlist = chainon (objc_parmlist, parm);
8267 return;
8270 /* Decay arrays and functions into pointers. */
8271 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8273 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8274 relayout_needed = true;
8276 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8278 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8279 relayout_needed = true;
8282 if (relayout_needed)
8283 relayout_decl (parm);
8286 DECL_ARG_TYPE (parm)
8287 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8289 /* Record constancy and volatility. */
8290 c_apply_type_quals_to_decl
8291 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8292 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8293 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8295 objc_parmlist = chainon (objc_parmlist, parm);
8298 /* Retrieve the formal parameter list constructed via preceding calls to
8299 objc_push_parm(). */
8301 #ifdef OBJCPLUS
8302 static tree
8303 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8304 #else
8305 static struct c_arg_info *
8306 objc_get_parm_info (int have_ellipsis)
8307 #endif
8309 #ifdef OBJCPLUS
8310 tree parm_info = objc_parmlist;
8311 objc_parmlist = NULL_TREE;
8313 return parm_info;
8314 #else
8315 tree parm_info = objc_parmlist;
8316 struct c_arg_info *arg_info;
8317 /* The C front-end requires an elaborate song and dance at
8318 this point. */
8319 push_scope ();
8320 declare_parm_level ();
8321 while (parm_info)
8323 tree next = TREE_CHAIN (parm_info);
8325 TREE_CHAIN (parm_info) = NULL_TREE;
8326 parm_info = pushdecl (parm_info);
8327 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8328 parm_info = next;
8330 arg_info = get_parm_info (have_ellipsis);
8331 pop_scope ();
8332 objc_parmlist = NULL_TREE;
8333 return arg_info;
8334 #endif
8337 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8338 method definitions. In the case of instance methods, we can be more
8339 specific as to the type of 'self'. */
8341 static void
8342 synth_self_and_ucmd_args (void)
8344 tree self_type;
8346 if (objc_method_context
8347 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8348 self_type = objc_instance_type;
8349 else
8350 /* Really a `struct objc_class *'. However, we allow people to
8351 assign to self, which changes its type midstream. */
8352 self_type = objc_object_type;
8354 /* id self; */
8355 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8357 /* SEL _cmd; */
8358 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8361 /* Transform an Objective-C method definition into a static C function
8362 definition, synthesizing the first two arguments, "self" and "_cmd",
8363 in the process. */
8365 static void
8366 start_method_def (tree method)
8368 tree parmlist;
8369 #ifdef OBJCPLUS
8370 tree parm_info;
8371 #else
8372 struct c_arg_info *parm_info;
8373 #endif
8374 int have_ellipsis = 0;
8376 /* If we are defining a "dealloc" method in a non-root class, we
8377 will need to check if a [super dealloc] is missing, and warn if
8378 it is. */
8379 if(CLASS_SUPER_NAME (objc_implementation_context)
8380 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8381 should_call_super_dealloc = 1;
8382 else
8383 should_call_super_dealloc = 0;
8385 /* Required to implement _msgSuper. */
8386 objc_method_context = method;
8387 UOBJC_SUPER_decl = NULL_TREE;
8389 /* Generate prototype declarations for arguments..."new-style". */
8390 synth_self_and_ucmd_args ();
8392 /* Generate argument declarations if a keyword_decl. */
8393 parmlist = METHOD_SEL_ARGS (method);
8394 while (parmlist)
8396 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8398 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8399 objc_push_parm (parm);
8400 parmlist = TREE_CHAIN (parmlist);
8403 if (METHOD_ADD_ARGS (method))
8405 tree akey;
8407 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8408 akey; akey = TREE_CHAIN (akey))
8410 objc_push_parm (TREE_VALUE (akey));
8413 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8414 have_ellipsis = 1;
8417 parm_info = objc_get_parm_info (have_ellipsis);
8419 really_start_method (objc_method_context, parm_info);
8422 static void
8423 warn_with_method (const char *message, int mtype, tree method)
8425 /* Add a readable method name to the warning. */
8426 warning (0, "%J%s %<%c%s%>", method,
8427 message, mtype, gen_method_decl (method));
8430 /* Return 1 if TYPE1 is equivalent to TYPE2
8431 for purposes of method overloading. */
8433 static int
8434 objc_types_are_equivalent (tree type1, tree type2)
8436 if (type1 == type2)
8437 return 1;
8439 /* Strip away indirections. */
8440 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8441 && (TREE_CODE (type1) == TREE_CODE (type2)))
8442 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8443 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8444 return 0;
8446 type1 = (TYPE_HAS_OBJC_INFO (type1)
8447 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8448 : NULL_TREE);
8449 type2 = (TYPE_HAS_OBJC_INFO (type2)
8450 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8451 : NULL_TREE);
8453 if (list_length (type1) == list_length (type2))
8455 for (; type2; type2 = TREE_CHAIN (type2))
8456 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8457 return 0;
8458 return 1;
8460 return 0;
8463 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8465 static int
8466 objc_types_share_size_and_alignment (tree type1, tree type2)
8468 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8469 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8472 /* Return 1 if PROTO1 is equivalent to PROTO2
8473 for purposes of method overloading. Ordinarily, the type signatures
8474 should match up exactly, unless STRICT is zero, in which case we
8475 shall allow differences in which the size and alignment of a type
8476 is the same. */
8478 static int
8479 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8481 tree type1, type2;
8483 /* The following test is needed in case there are hashing
8484 collisions. */
8485 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8486 return 0;
8488 /* Compare return types. */
8489 type1 = TREE_VALUE (TREE_TYPE (proto1));
8490 type2 = TREE_VALUE (TREE_TYPE (proto2));
8492 if (!objc_types_are_equivalent (type1, type2)
8493 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8494 return 0;
8496 /* Compare argument types. */
8497 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8498 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8499 type1 && type2;
8500 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8502 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8503 && (strict
8504 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8505 TREE_VALUE (type2))))
8506 return 0;
8509 return (!type1 && !type2);
8512 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8513 this occurs. ObjC method dispatches are _not_ like C++ virtual
8514 member function dispatches, and we account for the difference here. */
8515 tree
8516 #ifdef OBJCPLUS
8517 objc_fold_obj_type_ref (tree ref, tree known_type)
8518 #else
8519 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8520 tree known_type ATTRIBUTE_UNUSED)
8521 #endif
8523 #ifdef OBJCPLUS
8524 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8526 /* If the receiver does not have virtual member functions, there
8527 is nothing we can (or need to) do here. */
8528 if (!v)
8529 return NULL_TREE;
8531 /* Let C++ handle C++ virtual functions. */
8532 return cp_fold_obj_type_ref (ref, known_type);
8533 #else
8534 /* For plain ObjC, we currently do not need to do anything. */
8535 return NULL_TREE;
8536 #endif
8539 static void
8540 objc_start_function (tree name, tree type, tree attrs,
8541 #ifdef OBJCPLUS
8542 tree params
8543 #else
8544 struct c_arg_info *params
8545 #endif
8548 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8550 #ifdef OBJCPLUS
8551 DECL_ARGUMENTS (fndecl) = params;
8552 DECL_INITIAL (fndecl) = error_mark_node;
8553 DECL_EXTERNAL (fndecl) = 0;
8554 TREE_STATIC (fndecl) = 1;
8555 retrofit_lang_decl (fndecl);
8556 cplus_decl_attributes (&fndecl, attrs, 0);
8557 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8558 #else
8559 struct c_label_context_se *nstack_se;
8560 struct c_label_context_vm *nstack_vm;
8561 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8562 nstack_se->labels_def = NULL;
8563 nstack_se->labels_used = NULL;
8564 nstack_se->next = label_context_stack_se;
8565 label_context_stack_se = nstack_se;
8566 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8567 nstack_vm->labels_def = NULL;
8568 nstack_vm->labels_used = NULL;
8569 nstack_vm->scope = 0;
8570 nstack_vm->next = label_context_stack_vm;
8571 label_context_stack_vm = nstack_vm;
8572 current_function_returns_value = 0; /* Assume, until we see it does. */
8573 current_function_returns_null = 0;
8575 decl_attributes (&fndecl, attrs, 0);
8576 announce_function (fndecl);
8577 DECL_INITIAL (fndecl) = error_mark_node;
8578 DECL_EXTERNAL (fndecl) = 0;
8579 TREE_STATIC (fndecl) = 1;
8580 current_function_decl = pushdecl (fndecl);
8581 push_scope ();
8582 declare_parm_level ();
8583 DECL_RESULT (current_function_decl)
8584 = build_decl (RESULT_DECL, NULL_TREE,
8585 TREE_TYPE (TREE_TYPE (current_function_decl)));
8586 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8587 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8588 start_fname_decls ();
8589 store_parm_decls_from (params);
8590 #endif
8592 TREE_USED (current_function_decl) = 1;
8595 /* - Generate an identifier for the function. the format is "_n_cls",
8596 where 1 <= n <= nMethods, and cls is the name the implementation we
8597 are processing.
8598 - Install the return type from the method declaration.
8599 - If we have a prototype, check for type consistency. */
8601 static void
8602 really_start_method (tree method,
8603 #ifdef OBJCPLUS
8604 tree parmlist
8605 #else
8606 struct c_arg_info *parmlist
8607 #endif
8610 tree ret_type, meth_type;
8611 tree method_id;
8612 const char *sel_name, *class_name, *cat_name;
8613 char *buf;
8615 /* Synth the storage class & assemble the return type. */
8616 ret_type = TREE_VALUE (TREE_TYPE (method));
8618 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8619 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8620 cat_name = ((TREE_CODE (objc_implementation_context)
8621 == CLASS_IMPLEMENTATION_TYPE)
8622 ? NULL
8623 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8624 method_slot++;
8626 /* Make sure this is big enough for any plausible method label. */
8627 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8628 + (cat_name ? strlen (cat_name) : 0));
8630 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8631 class_name, cat_name, sel_name, method_slot);
8633 method_id = get_identifier (buf);
8635 #ifdef OBJCPLUS
8636 /* Objective-C methods cannot be overloaded, so we don't need
8637 the type encoding appended. It looks bad anyway... */
8638 push_lang_context (lang_name_c);
8639 #endif
8641 meth_type
8642 = build_function_type (ret_type,
8643 get_arg_type_list (method, METHOD_DEF, 0));
8644 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8646 /* Set self_decl from the first argument. */
8647 self_decl = DECL_ARGUMENTS (current_function_decl);
8649 /* Suppress unused warnings. */
8650 TREE_USED (self_decl) = 1;
8651 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8652 #ifdef OBJCPLUS
8653 pop_lang_context ();
8654 #endif
8656 METHOD_DEFINITION (method) = current_function_decl;
8658 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8660 if (implementation_template != objc_implementation_context)
8662 tree proto
8663 = lookup_method_static (implementation_template,
8664 METHOD_SEL_NAME (method),
8665 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8666 | OBJC_LOOKUP_NO_SUPER));
8668 if (proto)
8670 if (!comp_proto_with_proto (method, proto, 1))
8672 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8674 warn_with_method ("conflicting types for", type, method);
8675 warn_with_method ("previous declaration of", type, proto);
8678 else
8680 /* We have a method @implementation even though we did not
8681 see a corresponding @interface declaration (which is allowed
8682 by Objective-C rules). Go ahead and place the method in
8683 the @interface anyway, so that message dispatch lookups
8684 will see it. */
8685 tree interface = implementation_template;
8687 if (TREE_CODE (objc_implementation_context)
8688 == CATEGORY_IMPLEMENTATION_TYPE)
8689 interface = lookup_category
8690 (interface,
8691 CLASS_SUPER_NAME (objc_implementation_context));
8693 if (interface)
8694 objc_add_method (interface, copy_node (method),
8695 TREE_CODE (method) == CLASS_METHOD_DECL);
8700 static void *UOBJC_SUPER_scope = 0;
8702 /* _n_Method (id self, SEL sel, ...)
8704 struct objc_super _S;
8705 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8706 } */
8708 static tree
8709 get_super_receiver (void)
8711 if (objc_method_context)
8713 tree super_expr, super_expr_list;
8715 if (!UOBJC_SUPER_decl)
8717 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8718 objc_super_template);
8719 /* This prevents `unused variable' warnings when compiling with -Wall. */
8720 TREE_USED (UOBJC_SUPER_decl) = 1;
8721 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8722 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8723 UOBJC_SUPER_scope = objc_get_current_scope ();
8726 /* Set receiver to self. */
8727 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8728 super_expr = build_modify_expr (input_location,
8729 super_expr, NOP_EXPR, self_decl);
8730 super_expr_list = super_expr;
8732 /* Set class to begin searching. */
8733 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8734 get_identifier ("super_class"));
8736 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8738 /* [_cls, __cls]Super are "pre-built" in
8739 synth_forward_declarations. */
8741 super_expr = build_modify_expr (input_location, super_expr, NOP_EXPR,
8742 ((TREE_CODE (objc_method_context)
8743 == INSTANCE_METHOD_DECL)
8744 ? ucls_super_ref
8745 : uucls_super_ref));
8748 else
8749 /* We have a category. */
8751 tree super_name = CLASS_SUPER_NAME (implementation_template);
8752 tree super_class;
8754 /* Barf if super used in a category of Object. */
8755 if (!super_name)
8757 error ("no super class declared in interface for %qs",
8758 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8759 return error_mark_node;
8762 if (flag_next_runtime && !flag_zero_link)
8764 super_class = objc_get_class_reference (super_name);
8765 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8766 /* If we are in a class method, we must retrieve the
8767 _metaclass_ for the current class, pointed at by
8768 the class's "isa" pointer. The following assumes that
8769 "isa" is the first ivar in a class (which it must be). */
8770 super_class
8771 = build_indirect_ref
8772 (input_location,
8773 build_c_cast (build_pointer_type (objc_class_type),
8774 super_class), "unary *");
8776 else
8778 add_class_reference (super_name);
8779 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8780 ? objc_get_class_decl : objc_get_meta_class_decl);
8781 assemble_external (super_class);
8782 super_class
8783 = build_function_call
8784 (super_class,
8785 build_tree_list
8786 (NULL_TREE,
8787 my_build_string_pointer
8788 (IDENTIFIER_LENGTH (super_name) + 1,
8789 IDENTIFIER_POINTER (super_name))));
8792 super_expr
8793 = build_modify_expr (input_location, super_expr, NOP_EXPR,
8794 build_c_cast (TREE_TYPE (super_expr),
8795 super_class));
8798 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8800 super_expr = build_unary_op (input_location,
8801 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8802 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8804 return super_expr_list;
8806 else
8808 error ("[super ...] must appear in a method context");
8809 return error_mark_node;
8813 /* When exiting a scope, sever links to a 'super' declaration (if any)
8814 therein contained. */
8816 void
8817 objc_clear_super_receiver (void)
8819 if (objc_method_context
8820 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8821 UOBJC_SUPER_decl = 0;
8822 UOBJC_SUPER_scope = 0;
8826 void
8827 objc_finish_method_definition (tree fndecl)
8829 /* We cannot validly inline ObjC methods, at least not without a language
8830 extension to declare that a method need not be dynamically
8831 dispatched, so suppress all thoughts of doing so. */
8832 DECL_UNINLINABLE (fndecl) = 1;
8834 #ifndef OBJCPLUS
8835 /* The C++ front-end will have called finish_function() for us. */
8836 finish_function ();
8837 #endif
8839 METHOD_ENCODING (objc_method_context)
8840 = encode_method_prototype (objc_method_context);
8842 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8843 since the optimizer may find "may be used before set" errors. */
8844 objc_method_context = NULL_TREE;
8846 if (should_call_super_dealloc)
8847 warning (0, "method possibly missing a [super dealloc] call");
8850 #if 0
8852 lang_report_error_function (tree decl)
8854 if (objc_method_context)
8856 fprintf (stderr, "In method %qs\n",
8857 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8858 return 1;
8861 else
8862 return 0;
8864 #endif
8866 /* Given a tree DECL node, produce a printable description of it in the given
8867 buffer, overwriting the buffer. */
8869 static char *
8870 gen_declaration (tree decl)
8872 errbuf[0] = '\0';
8874 if (DECL_P (decl))
8876 gen_type_name_0 (TREE_TYPE (decl));
8878 if (DECL_NAME (decl))
8880 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8881 strcat (errbuf, " ");
8883 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8886 if (DECL_INITIAL (decl)
8887 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8888 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8889 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8892 return errbuf;
8895 /* Given a tree TYPE node, produce a printable description of it in the given
8896 buffer, overwriting the buffer. */
8898 static char *
8899 gen_type_name_0 (tree type)
8901 tree orig = type, proto;
8903 if (TYPE_P (type) && TYPE_NAME (type))
8904 type = TYPE_NAME (type);
8905 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8907 tree inner = TREE_TYPE (type);
8909 while (TREE_CODE (inner) == ARRAY_TYPE)
8910 inner = TREE_TYPE (inner);
8912 gen_type_name_0 (inner);
8914 if (!POINTER_TYPE_P (inner))
8915 strcat (errbuf, " ");
8917 if (POINTER_TYPE_P (type))
8918 strcat (errbuf, "*");
8919 else
8920 while (type != inner)
8922 strcat (errbuf, "[");
8924 if (TYPE_DOMAIN (type))
8926 char sz[20];
8928 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8929 (TREE_INT_CST_LOW
8930 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8931 strcat (errbuf, sz);
8934 strcat (errbuf, "]");
8935 type = TREE_TYPE (type);
8938 goto exit_function;
8941 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8942 type = DECL_NAME (type);
8944 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8945 ? IDENTIFIER_POINTER (type)
8946 : "");
8948 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8949 if (objc_is_id (orig))
8950 orig = TREE_TYPE (orig);
8952 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8954 if (proto)
8956 strcat (errbuf, " <");
8958 while (proto) {
8959 strcat (errbuf,
8960 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8961 proto = TREE_CHAIN (proto);
8962 strcat (errbuf, proto ? ", " : ">");
8966 exit_function:
8967 return errbuf;
8970 static char *
8971 gen_type_name (tree type)
8973 errbuf[0] = '\0';
8975 return gen_type_name_0 (type);
8978 /* Given a method tree, put a printable description into the given
8979 buffer (overwriting) and return a pointer to the buffer. */
8981 static char *
8982 gen_method_decl (tree method)
8984 tree chain;
8986 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8987 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8988 strcat (errbuf, ")");
8989 chain = METHOD_SEL_ARGS (method);
8991 if (chain)
8993 /* We have a chain of keyword_decls. */
8996 if (KEYWORD_KEY_NAME (chain))
8997 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8999 strcat (errbuf, ":(");
9000 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9001 strcat (errbuf, ")");
9003 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9004 if ((chain = TREE_CHAIN (chain)))
9005 strcat (errbuf, " ");
9007 while (chain);
9009 if (METHOD_ADD_ARGS (method))
9011 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9013 /* Know we have a chain of parm_decls. */
9014 while (chain)
9016 strcat (errbuf, ", ");
9017 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9018 chain = TREE_CHAIN (chain);
9021 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9022 strcat (errbuf, ", ...");
9026 else
9027 /* We have a unary selector. */
9028 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9030 return errbuf;
9033 /* Debug info. */
9036 /* Dump an @interface declaration of the supplied class CHAIN to the
9037 supplied file FP. Used to implement the -gen-decls option (which
9038 prints out an @interface declaration of all classes compiled in
9039 this run); potentially useful for debugging the compiler too. */
9040 static void
9041 dump_interface (FILE *fp, tree chain)
9043 /* FIXME: A heap overflow here whenever a method (or ivar)
9044 declaration is so long that it doesn't fit in the buffer. The
9045 code and all the related functions should be rewritten to avoid
9046 using fixed size buffers. */
9047 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9048 tree ivar_decls = CLASS_RAW_IVARS (chain);
9049 tree nst_methods = CLASS_NST_METHODS (chain);
9050 tree cls_methods = CLASS_CLS_METHODS (chain);
9052 fprintf (fp, "\n@interface %s", my_name);
9054 /* CLASS_SUPER_NAME is used to store the superclass name for
9055 classes, and the category name for categories. */
9056 if (CLASS_SUPER_NAME (chain))
9058 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9060 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9061 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9063 fprintf (fp, " (%s)\n", name);
9065 else
9067 fprintf (fp, " : %s\n", name);
9070 else
9071 fprintf (fp, "\n");
9073 /* FIXME - the following doesn't seem to work at the moment. */
9074 if (ivar_decls)
9076 fprintf (fp, "{\n");
9079 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9080 ivar_decls = TREE_CHAIN (ivar_decls);
9082 while (ivar_decls);
9083 fprintf (fp, "}\n");
9086 while (nst_methods)
9088 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9089 nst_methods = TREE_CHAIN (nst_methods);
9092 while (cls_methods)
9094 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9095 cls_methods = TREE_CHAIN (cls_methods);
9098 fprintf (fp, "@end\n");
9101 /* Demangle function for Objective-C */
9102 static const char *
9103 objc_demangle (const char *mangled)
9105 char *demangled, *cp;
9107 if (mangled[0] == '_' &&
9108 (mangled[1] == 'i' || mangled[1] == 'c') &&
9109 mangled[2] == '_')
9111 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9112 if (mangled[1] == 'i')
9113 *cp++ = '-'; /* for instance method */
9114 else
9115 *cp++ = '+'; /* for class method */
9116 *cp++ = '['; /* opening left brace */
9117 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9118 while (*cp && *cp == '_')
9119 cp++; /* skip any initial underbars in class name */
9120 cp = strchr(cp, '_'); /* find first non-initial underbar */
9121 if (cp == NULL)
9123 free(demangled); /* not mangled name */
9124 return mangled;
9126 if (cp[1] == '_') /* easy case: no category name */
9128 *cp++ = ' '; /* replace two '_' with one ' ' */
9129 strcpy(cp, mangled + (cp - demangled) + 2);
9131 else
9133 *cp++ = '('; /* less easy case: category name */
9134 cp = strchr(cp, '_');
9135 if (cp == 0)
9137 free(demangled); /* not mangled name */
9138 return mangled;
9140 *cp++ = ')';
9141 *cp++ = ' '; /* overwriting 1st char of method name... */
9142 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9144 while (*cp && *cp == '_')
9145 cp++; /* skip any initial underbars in method name */
9146 for (; *cp; cp++)
9147 if (*cp == '_')
9148 *cp = ':'; /* replace remaining '_' with ':' */
9149 *cp++ = ']'; /* closing right brace */
9150 *cp++ = 0; /* string terminator */
9151 return demangled;
9153 else
9154 return mangled; /* not an objc mangled name */
9157 const char *
9158 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9160 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9163 static void
9164 init_objc (void)
9166 gcc_obstack_init (&util_obstack);
9167 util_firstobj = (char *) obstack_finish (&util_obstack);
9169 errbuf = XNEWVEC (char, 1024 * 10);
9170 hash_init ();
9171 synth_module_prologue ();
9174 static void
9175 finish_objc (void)
9177 struct imp_entry *impent;
9178 tree chain;
9179 /* The internally generated initializers appear to have missing braces.
9180 Don't warn about this. */
9181 int save_warn_missing_braces = warn_missing_braces;
9182 warn_missing_braces = 0;
9184 /* A missing @end may not be detected by the parser. */
9185 if (objc_implementation_context)
9187 warning (0, "%<@end%> missing in implementation context");
9188 finish_class (objc_implementation_context);
9189 objc_ivar_chain = NULL_TREE;
9190 objc_implementation_context = NULL_TREE;
9193 /* Process the static instances here because initialization of objc_symtab
9194 depends on them. */
9195 if (objc_static_instances)
9196 generate_static_references ();
9198 if (imp_list || class_names_chain
9199 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9200 generate_objc_symtab_decl ();
9202 for (impent = imp_list; impent; impent = impent->next)
9204 objc_implementation_context = impent->imp_context;
9205 implementation_template = impent->imp_template;
9207 UOBJC_CLASS_decl = impent->class_decl;
9208 UOBJC_METACLASS_decl = impent->meta_decl;
9210 /* Dump the @interface of each class as we compile it, if the
9211 -gen-decls option is in use. TODO: Dump the classes in the
9212 order they were found, rather than in reverse order as we
9213 are doing now. */
9214 if (flag_gen_declaration)
9216 dump_interface (gen_declaration_file, objc_implementation_context);
9219 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9221 /* all of the following reference the string pool... */
9222 generate_ivar_lists ();
9223 generate_dispatch_tables ();
9224 generate_shared_structures (impent->has_cxx_cdtors
9225 ? CLS_HAS_CXX_STRUCTORS
9226 : 0);
9228 else
9230 generate_dispatch_tables ();
9231 generate_category (objc_implementation_context);
9235 /* If we are using an array of selectors, we must always
9236 finish up the array decl even if no selectors were used. */
9237 if (! flag_next_runtime || sel_ref_chain)
9238 build_selector_translation_table ();
9240 if (protocol_chain)
9241 generate_protocols ();
9243 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9244 generate_objc_image_info ();
9246 /* Arrange for ObjC data structures to be initialized at run time. */
9247 if (objc_implementation_context || class_names_chain || objc_static_instances
9248 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9250 build_module_descriptor ();
9252 if (!flag_next_runtime)
9253 build_module_initializer_routine ();
9256 /* Dump the class references. This forces the appropriate classes
9257 to be linked into the executable image, preserving unix archive
9258 semantics. This can be removed when we move to a more dynamically
9259 linked environment. */
9261 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9263 handle_class_ref (chain);
9264 if (TREE_PURPOSE (chain))
9265 generate_classref_translation_entry (chain);
9268 for (impent = imp_list; impent; impent = impent->next)
9269 handle_impent (impent);
9271 if (warn_selector)
9273 int slot;
9274 hash hsh;
9276 /* Run through the selector hash tables and print a warning for any
9277 selector which has multiple methods. */
9279 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9281 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9282 check_duplicates (hsh, 0, 1);
9283 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9284 check_duplicates (hsh, 0, 1);
9288 warn_missing_braces = save_warn_missing_braces;
9291 /* Subroutines of finish_objc. */
9293 static void
9294 generate_classref_translation_entry (tree chain)
9296 tree expr, decl, type;
9298 decl = TREE_PURPOSE (chain);
9299 type = TREE_TYPE (decl);
9301 expr = add_objc_string (TREE_VALUE (chain), class_names);
9302 expr = convert (type, expr); /* cast! */
9304 /* The decl that is the one that we
9305 forward declared in build_class_reference. */
9306 finish_var_decl (decl, expr);
9307 return;
9310 static void
9311 handle_class_ref (tree chain)
9313 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9314 char *string = (char *) alloca (strlen (name) + 30);
9315 tree decl;
9316 tree exp;
9318 sprintf (string, "%sobjc_class_name_%s",
9319 (flag_next_runtime ? "." : "__"), name);
9321 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9322 if (flag_next_runtime)
9324 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9325 return;
9327 #endif
9329 /* Make a decl for this name, so we can use its address in a tree. */
9330 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9331 DECL_EXTERNAL (decl) = 1;
9332 TREE_PUBLIC (decl) = 1;
9334 pushdecl (decl);
9335 rest_of_decl_compilation (decl, 0, 0);
9337 /* Make a decl for the address. */
9338 sprintf (string, "%sobjc_class_ref_%s",
9339 (flag_next_runtime ? "." : "__"), name);
9340 exp = build1 (ADDR_EXPR, string_type_node, decl);
9341 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9342 DECL_INITIAL (decl) = exp;
9343 TREE_STATIC (decl) = 1;
9344 TREE_USED (decl) = 1;
9345 /* Force the output of the decl as this forces the reference of the class. */
9346 mark_decl_referenced (decl);
9348 pushdecl (decl);
9349 rest_of_decl_compilation (decl, 0, 0);
9352 static void
9353 handle_impent (struct imp_entry *impent)
9355 char *string;
9357 objc_implementation_context = impent->imp_context;
9358 implementation_template = impent->imp_template;
9360 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9362 const char *const class_name =
9363 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9365 string = (char *) alloca (strlen (class_name) + 30);
9367 sprintf (string, "%sobjc_class_name_%s",
9368 (flag_next_runtime ? "." : "__"), class_name);
9370 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9372 const char *const class_name =
9373 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9374 const char *const class_super_name =
9375 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9377 string = (char *) alloca (strlen (class_name)
9378 + strlen (class_super_name) + 30);
9380 /* Do the same for categories. Even though no references to
9381 these symbols are generated automatically by the compiler, it
9382 gives you a handle to pull them into an archive by hand. */
9383 sprintf (string, "*%sobjc_category_name_%s_%s",
9384 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9386 else
9387 return;
9389 #ifdef ASM_DECLARE_CLASS_REFERENCE
9390 if (flag_next_runtime)
9392 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9393 return;
9395 else
9396 #endif
9398 tree decl, init;
9400 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9401 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9402 TREE_PUBLIC (decl) = 1;
9403 TREE_READONLY (decl) = 1;
9404 TREE_USED (decl) = 1;
9405 TREE_CONSTANT (decl) = 1;
9406 DECL_CONTEXT (decl) = 0;
9407 DECL_ARTIFICIAL (decl) = 1;
9408 DECL_INITIAL (decl) = init;
9409 assemble_variable (decl, 1, 0, 0);
9413 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9414 later requires that ObjC translation units participating in F&C be
9415 specially marked. The following routine accomplishes this. */
9417 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9419 static void
9420 generate_objc_image_info (void)
9422 tree decl, initlist;
9423 int flags
9424 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9425 | (flag_objc_gc ? 2 : 0));
9427 decl = start_var_decl (build_array_type
9428 (integer_type_node,
9429 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9430 "_OBJC_IMAGE_INFO");
9432 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9433 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9434 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9436 finish_var_decl (decl, initlist);
9439 /* Look up ID as an instance variable. OTHER contains the result of
9440 the C or C++ lookup, which we may want to use instead. */
9442 tree
9443 objc_lookup_ivar (tree other, tree id)
9445 tree ivar;
9447 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9448 if (!objc_method_context)
9449 return other;
9451 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9452 /* We have a message to super. */
9453 return get_super_receiver ();
9455 /* In a class method, look up an instance variable only as a last
9456 resort. */
9457 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9458 && other && other != error_mark_node)
9459 return other;
9461 /* Look up the ivar, but do not use it if it is not accessible. */
9462 ivar = is_ivar (objc_ivar_chain, id);
9464 if (!ivar || is_private (ivar))
9465 return other;
9467 /* In an instance method, a local variable (or parameter) may hide the
9468 instance variable. */
9469 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9470 && other && other != error_mark_node
9471 #ifdef OBJCPLUS
9472 && CP_DECL_CONTEXT (other) != global_namespace)
9473 #else
9474 && !DECL_FILE_SCOPE_P (other))
9475 #endif
9477 warning (0, "local declaration of %qs hides instance variable",
9478 IDENTIFIER_POINTER (id));
9480 return other;
9483 /* At this point, we are either in an instance method with no obscuring
9484 local definitions, or in a class method with no alternate definitions
9485 at all. */
9486 return build_ivar_reference (id);
9489 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9490 needs to be done if we are calling a function through a cast. */
9492 tree
9493 objc_rewrite_function_call (tree function, tree params)
9495 if (TREE_CODE (function) == NOP_EXPR
9496 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9497 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9498 == FUNCTION_DECL)
9500 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9501 TREE_OPERAND (function, 0),
9502 TREE_VALUE (params), size_zero_node);
9505 return function;
9508 /* Look for the special case of OBJC_TYPE_REF with the address of
9509 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9510 of its cousins). */
9512 enum gimplify_status
9513 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9515 enum gimplify_status r0, r1;
9516 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9517 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9518 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9519 == FUNCTION_DECL)
9521 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9522 value of the OBJ_TYPE_REF, so force them to be emitted
9523 during subexpression evaluation rather than after the
9524 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9525 C to use direct rather than indirect calls when the
9526 object expression has a postincrement. */
9527 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9528 is_gimple_val, fb_rvalue);
9529 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9530 is_gimple_val, fb_rvalue);
9532 return MIN (r0, r1);
9535 #ifdef OBJCPLUS
9536 return cp_gimplify_expr (expr_p, pre_p, post_p);
9537 #else
9538 return c_gimplify_expr (expr_p, pre_p, post_p);
9539 #endif
9542 #include "gt-objc-objc-act.h"