hashtab.h: Update GTY annotations to new syntax
[official-gcc.git] / gcc / objc / objc-act.c
blobd3c5a197203e8762cfdc20bdb7a7d0808bb8934f
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009 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 need in_late_binary_op. */
83 #ifdef OBJCPLUS
84 bool in_late_binary_op = false;
85 #endif /* OBJCPLUS */
87 /* When building Objective-C++, we are not linking against the C front-end
88 and so need to replicate the C tree-construction functions in some way. */
89 #ifdef OBJCPLUS
90 #define OBJCP_REMAP_FUNCTIONS
91 #include "objcp-decl.h"
92 #endif /* OBJCPLUS */
94 /* This is the default way of generating a method name. */
95 /* I am not sure it is really correct.
96 Perhaps there's a danger that it will make name conflicts
97 if method names contain underscores. -- rms. */
98 #ifndef OBJC_GEN_METHOD_LABEL
99 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
100 do { \
101 char *temp; \
102 sprintf ((BUF), "_%s_%s_%s_%s", \
103 ((IS_INST) ? "i" : "c"), \
104 (CLASS_NAME), \
105 ((CAT_NAME)? (CAT_NAME) : ""), \
106 (SEL_NAME)); \
107 for (temp = (BUF); *temp; temp++) \
108 if (*temp == ':') *temp = '_'; \
109 } while (0)
110 #endif
112 /* These need specifying. */
113 #ifndef OBJC_FORWARDING_STACK_OFFSET
114 #define OBJC_FORWARDING_STACK_OFFSET 0
115 #endif
117 #ifndef OBJC_FORWARDING_MIN_OFFSET
118 #define OBJC_FORWARDING_MIN_OFFSET 0
119 #endif
121 /* Set up for use of obstacks. */
123 #include "obstack.h"
125 /* This obstack is used to accumulate the encoding of a data type. */
126 static struct obstack util_obstack;
128 /* This points to the beginning of obstack contents, so we can free
129 the whole contents. */
130 char *util_firstobj;
132 /* The version identifies which language generation and runtime
133 the module (file) was compiled for, and is recorded in the
134 module descriptor. */
136 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
137 #define PROTOCOL_VERSION 2
139 /* (Decide if these can ever be validly changed.) */
140 #define OBJC_ENCODE_INLINE_DEFS 0
141 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
143 /*** Private Interface (procedures) ***/
145 /* Used by compile_file. */
147 static void init_objc (void);
148 static void finish_objc (void);
150 /* Code generation. */
152 static tree objc_build_constructor (tree, tree);
153 static tree build_objc_method_call (int, tree, tree, tree, tree);
154 static tree get_proto_encoding (tree);
155 static tree lookup_interface (tree);
156 static tree objc_add_static_instance (tree, tree);
158 static tree start_class (enum tree_code, tree, tree, tree);
159 static tree continue_class (tree);
160 static void finish_class (tree);
161 static void start_method_def (tree);
162 #ifdef OBJCPLUS
163 static void objc_start_function (tree, tree, tree, tree);
164 #else
165 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
166 #endif
167 static tree start_protocol (enum tree_code, tree, tree);
168 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
169 static tree objc_add_method (tree, tree, int);
170 static tree add_instance_variable (tree, int, tree);
171 static tree build_ivar_reference (tree);
172 static tree is_ivar (tree, tree);
174 static void build_objc_exception_stuff (void);
175 static void build_next_objc_exception_stuff (void);
177 /* We only need the following for ObjC; ObjC++ will use C++'s definition
178 of DERIVED_FROM_P. */
179 #ifndef OBJCPLUS
180 static bool objc_derived_from_p (tree, tree);
181 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
182 #endif
183 static void objc_xref_basetypes (tree, tree);
185 static void build_class_template (void);
186 static void build_selector_template (void);
187 static void build_category_template (void);
188 static void build_super_template (void);
189 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
190 static tree get_class_ivars (tree, bool);
191 static tree generate_protocol_list (tree);
192 static void build_protocol_reference (tree);
194 #ifdef OBJCPLUS
195 static void objc_generate_cxx_cdtors (void);
196 #endif
198 static const char *synth_id_with_class_suffix (const char *, tree);
200 /* Hash tables to manage the global pool of method prototypes. */
202 hash *nst_method_hash_list = 0;
203 hash *cls_method_hash_list = 0;
205 static hash hash_lookup (hash *, tree);
206 static tree lookup_method (tree, tree);
207 static tree lookup_method_static (tree, tree, int);
209 enum string_section
211 class_names, /* class, category, protocol, module names */
212 meth_var_names, /* method and variable names */
213 meth_var_types /* method and variable type descriptors */
216 static tree add_objc_string (tree, enum string_section);
217 static tree build_objc_string_decl (enum string_section);
218 static void build_selector_table_decl (void);
220 /* Protocol additions. */
222 static tree lookup_protocol (tree);
223 static tree lookup_and_install_protocols (tree);
225 /* Type encoding. */
227 static void encode_type_qualifiers (tree);
228 static void encode_type (tree, int, int);
229 static void encode_field_decl (tree, int, int);
231 #ifdef OBJCPLUS
232 static void really_start_method (tree, tree);
233 #else
234 static void really_start_method (tree, struct c_arg_info *);
235 #endif
236 static int comp_proto_with_proto (tree, tree, int);
237 static void objc_push_parm (tree);
238 #ifdef OBJCPLUS
239 static tree objc_get_parm_info (int);
240 #else
241 static struct c_arg_info *objc_get_parm_info (int);
242 #endif
244 /* Utilities for debugging and error diagnostics. */
246 static char *gen_type_name (tree);
247 static char *gen_type_name_0 (tree);
248 static char *gen_method_decl (tree);
249 static char *gen_declaration (tree);
251 /* Everything else. */
253 static tree create_field_decl (tree, const char *);
254 static void add_class_reference (tree);
255 static void build_protocol_template (void);
256 static tree encode_method_prototype (tree);
257 static void generate_classref_translation_entry (tree);
258 static void handle_class_ref (tree);
259 static void generate_struct_by_value_array (void)
260 ATTRIBUTE_NORETURN;
261 static void mark_referenced_methods (void);
262 static void generate_objc_image_info (void);
264 /*** Private Interface (data) ***/
266 /* Reserved tag definitions. */
268 #define OBJECT_TYPEDEF_NAME "id"
269 #define CLASS_TYPEDEF_NAME "Class"
271 #define TAG_OBJECT "objc_object"
272 #define TAG_CLASS "objc_class"
273 #define TAG_SUPER "objc_super"
274 #define TAG_SELECTOR "objc_selector"
276 #define UTAG_CLASS "_objc_class"
277 #define UTAG_IVAR "_objc_ivar"
278 #define UTAG_IVAR_LIST "_objc_ivar_list"
279 #define UTAG_METHOD "_objc_method"
280 #define UTAG_METHOD_LIST "_objc_method_list"
281 #define UTAG_CATEGORY "_objc_category"
282 #define UTAG_MODULE "_objc_module"
283 #define UTAG_SYMTAB "_objc_symtab"
284 #define UTAG_SUPER "_objc_super"
285 #define UTAG_SELECTOR "_objc_selector"
287 #define UTAG_PROTOCOL "_objc_protocol"
288 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
289 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
291 /* Note that the string object global name is only needed for the
292 NeXT runtime. */
293 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
295 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
297 static const char *TAG_GETCLASS;
298 static const char *TAG_GETMETACLASS;
299 static const char *TAG_MSGSEND;
300 static const char *TAG_MSGSENDSUPER;
301 /* The NeXT Objective-C messenger may have two extra entry points, for use
302 when returning a structure. */
303 static const char *TAG_MSGSEND_STRET;
304 static const char *TAG_MSGSENDSUPER_STRET;
305 static const char *default_constant_string_class_name;
307 /* Runtime metadata flags. */
308 #define CLS_FACTORY 0x0001L
309 #define CLS_META 0x0002L
310 #define CLS_HAS_CXX_STRUCTORS 0x2000L
312 #define OBJC_MODIFIER_STATIC 0x00000001
313 #define OBJC_MODIFIER_FINAL 0x00000002
314 #define OBJC_MODIFIER_PUBLIC 0x00000004
315 #define OBJC_MODIFIER_PRIVATE 0x00000008
316 #define OBJC_MODIFIER_PROTECTED 0x00000010
317 #define OBJC_MODIFIER_NATIVE 0x00000020
318 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
319 #define OBJC_MODIFIER_ABSTRACT 0x00000080
320 #define OBJC_MODIFIER_VOLATILE 0x00000100
321 #define OBJC_MODIFIER_TRANSIENT 0x00000200
322 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
324 /* NeXT-specific tags. */
326 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
327 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
328 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
329 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
330 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
331 #define TAG_EXCEPTIONMATCH "objc_exception_match"
332 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
333 #define TAG_SYNCENTER "objc_sync_enter"
334 #define TAG_SYNCEXIT "objc_sync_exit"
335 #define TAG_SETJMP "_setjmp"
336 #define UTAG_EXCDATA "_objc_exception_data"
338 #define TAG_ASSIGNIVAR "objc_assign_ivar"
339 #define TAG_ASSIGNGLOBAL "objc_assign_global"
340 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
342 /* Branch entry points. All that matters here are the addresses;
343 functions with these names do not really exist in libobjc. */
345 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
346 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
348 #define TAG_CXX_CONSTRUCT ".cxx_construct"
349 #define TAG_CXX_DESTRUCT ".cxx_destruct"
351 /* GNU-specific tags. */
353 #define TAG_EXECCLASS "__objc_exec_class"
354 #define TAG_GNUINIT "__objc_gnu_init"
356 /* Flags for lookup_method_static(). */
357 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
358 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
360 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
361 tree objc_global_trees[OCTI_MAX];
363 static void handle_impent (struct imp_entry *);
365 struct imp_entry *imp_list = 0;
366 int imp_count = 0; /* `@implementation' */
367 int cat_count = 0; /* `@category' */
369 enum tree_code objc_inherit_code;
370 int objc_public_flag;
372 /* Use to generate method labels. */
373 static int method_slot = 0;
375 #define BUFSIZE 1024
377 static char *errbuf; /* Buffer for error diagnostics */
379 /* Data imported from tree.c. */
381 extern enum debug_info_type write_symbols;
383 /* Data imported from toplev.c. */
385 extern const char *dump_base_name;
387 static int flag_typed_selectors;
389 /* Store all constructed constant strings in a hash table so that
390 they get uniqued properly. */
392 struct GTY(()) string_descriptor {
393 /* The literal argument . */
394 tree literal;
396 /* The resulting constant string. */
397 tree constructor;
400 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
402 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
403 struct GTY(()) volatilized_type {
404 tree type;
407 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
409 FILE *gen_declaration_file;
411 /* Tells "encode_pointer/encode_aggregate" whether we are generating
412 type descriptors for instance variables (as opposed to methods).
413 Type descriptors for instance variables contain more information
414 than methods (for static typing and embedded structures). */
416 static int generating_instance_variables = 0;
418 /* Some platforms pass small structures through registers versus
419 through an invisible pointer. Determine at what size structure is
420 the transition point between the two possibilities. */
422 static void
423 generate_struct_by_value_array (void)
425 tree type;
426 tree field_decl, field_decl_chain;
427 int i, j;
428 int aggregate_in_mem[32];
429 int found = 0;
431 /* Presumably no platform passes 32 byte structures in a register. */
432 for (i = 1; i < 32; i++)
434 char buffer[5];
436 /* Create an unnamed struct that has `i' character components */
437 type = start_struct (RECORD_TYPE, NULL_TREE);
439 strcpy (buffer, "c1");
440 field_decl = create_field_decl (char_type_node,
441 buffer);
442 field_decl_chain = field_decl;
444 for (j = 1; j < i; j++)
446 sprintf (buffer, "c%d", j + 1);
447 field_decl = create_field_decl (char_type_node,
448 buffer);
449 chainon (field_decl_chain, field_decl);
451 finish_struct (type, field_decl_chain, NULL_TREE);
453 aggregate_in_mem[i] = aggregate_value_p (type, 0);
454 if (!aggregate_in_mem[i])
455 found = 1;
458 /* We found some structures that are returned in registers instead of memory
459 so output the necessary data. */
460 if (found)
462 for (i = 31; i >= 0; i--)
463 if (!aggregate_in_mem[i])
464 break;
465 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
467 /* The first member of the structure is always 0 because we don't handle
468 structures with 0 members */
469 printf ("static int struct_forward_array[] = {\n 0");
471 for (j = 1; j <= i; j++)
472 printf (", %d", aggregate_in_mem[j]);
473 printf ("\n};\n");
476 exit (0);
479 bool
480 objc_init (void)
482 #ifdef OBJCPLUS
483 if (cxx_init () == false)
484 #else
485 if (c_objc_common_init () == false)
486 #endif
487 return false;
489 /* If gen_declaration desired, open the output file. */
490 if (flag_gen_declaration)
492 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
493 gen_declaration_file = fopen (dumpname, "w");
494 if (gen_declaration_file == 0)
495 fatal_error ("can't open %s: %m", dumpname);
496 free (dumpname);
499 if (flag_next_runtime)
501 TAG_GETCLASS = "objc_getClass";
502 TAG_GETMETACLASS = "objc_getMetaClass";
503 TAG_MSGSEND = "objc_msgSend";
504 TAG_MSGSENDSUPER = "objc_msgSendSuper";
505 TAG_MSGSEND_STRET = "objc_msgSend_stret";
506 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
507 default_constant_string_class_name = "NSConstantString";
509 else
511 TAG_GETCLASS = "objc_get_class";
512 TAG_GETMETACLASS = "objc_get_meta_class";
513 TAG_MSGSEND = "objc_msg_lookup";
514 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
515 /* GNU runtime does not provide special functions to support
516 structure-returning methods. */
517 default_constant_string_class_name = "NXConstantString";
518 flag_typed_selectors = 1;
521 init_objc ();
523 if (print_struct_values)
524 generate_struct_by_value_array ();
526 return true;
529 void
530 objc_finish_file (void)
532 mark_referenced_methods ();
534 #ifdef OBJCPLUS
535 /* We need to instantiate templates _before_ we emit ObjC metadata;
536 if we do not, some metadata (such as selectors) may go missing. */
537 at_eof = 1;
538 instantiate_pending_templates (0);
539 #endif
541 /* Finalize Objective-C runtime data. No need to generate tables
542 and code if only checking syntax, or if generating a PCH file. */
543 if (!flag_syntax_only && !pch_file)
544 finish_objc ();
546 if (gen_declaration_file)
547 fclose (gen_declaration_file);
550 /* Return the first occurrence of a method declaration corresponding
551 to sel_name in rproto_list. Search rproto_list recursively.
552 If is_class is 0, search for instance methods, otherwise for class
553 methods. */
554 static tree
555 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
556 int is_class)
558 tree rproto, p;
559 tree fnd = 0;
561 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
563 p = TREE_VALUE (rproto);
565 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
567 if ((fnd = lookup_method (is_class
568 ? PROTOCOL_CLS_METHODS (p)
569 : PROTOCOL_NST_METHODS (p), sel_name)))
571 else if (PROTOCOL_LIST (p))
572 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
573 sel_name, is_class);
575 else
577 ; /* An identifier...if we could not find a protocol. */
580 if (fnd)
581 return fnd;
584 return 0;
587 static tree
588 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
590 tree rproto, p;
592 /* Make sure the protocol is supported by the object on the rhs. */
593 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
595 tree fnd = 0;
596 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
598 p = TREE_VALUE (rproto);
600 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
602 if (lproto == p)
603 fnd = lproto;
605 else if (PROTOCOL_LIST (p))
606 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
609 if (fnd)
610 return fnd;
613 else
615 ; /* An identifier...if we could not find a protocol. */
618 return 0;
621 void
622 objc_start_class_interface (tree klass, tree super_class, tree protos)
624 objc_interface_context
625 = objc_ivar_context
626 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
627 objc_public_flag = 0;
630 void
631 objc_start_category_interface (tree klass, tree categ, tree protos)
633 objc_interface_context
634 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
635 objc_ivar_chain
636 = continue_class (objc_interface_context);
639 void
640 objc_start_protocol (tree name, tree protos)
642 objc_interface_context
643 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
646 void
647 objc_continue_interface (void)
649 objc_ivar_chain
650 = continue_class (objc_interface_context);
653 void
654 objc_finish_interface (void)
656 finish_class (objc_interface_context);
657 objc_interface_context = NULL_TREE;
660 void
661 objc_start_class_implementation (tree klass, tree super_class)
663 objc_implementation_context
664 = objc_ivar_context
665 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
666 objc_public_flag = 0;
669 void
670 objc_start_category_implementation (tree klass, tree categ)
672 objc_implementation_context
673 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
674 objc_ivar_chain
675 = continue_class (objc_implementation_context);
678 void
679 objc_continue_implementation (void)
681 objc_ivar_chain
682 = continue_class (objc_implementation_context);
685 void
686 objc_finish_implementation (void)
688 #ifdef OBJCPLUS
689 if (flag_objc_call_cxx_cdtors)
690 objc_generate_cxx_cdtors ();
691 #endif
693 if (objc_implementation_context)
695 finish_class (objc_implementation_context);
696 objc_ivar_chain = NULL_TREE;
697 objc_implementation_context = NULL_TREE;
699 else
700 warning (0, "%<@end%> must appear in an @implementation context");
703 void
704 objc_set_visibility (int visibility)
706 objc_public_flag = visibility;
709 void
710 objc_set_method_type (enum tree_code type)
712 objc_inherit_code = (type == PLUS_EXPR
713 ? CLASS_METHOD_DECL
714 : INSTANCE_METHOD_DECL);
717 tree
718 objc_build_method_signature (tree rettype, tree selector,
719 tree optparms, bool ellipsis)
721 return build_method_decl (objc_inherit_code, rettype, selector,
722 optparms, ellipsis);
725 void
726 objc_add_method_declaration (tree decl)
728 if (!objc_interface_context)
729 fatal_error ("method declaration not in @interface context");
731 objc_add_method (objc_interface_context,
732 decl,
733 objc_inherit_code == CLASS_METHOD_DECL);
736 void
737 objc_start_method_definition (tree decl)
739 if (!objc_implementation_context)
740 fatal_error ("method definition not in @implementation context");
742 objc_add_method (objc_implementation_context,
743 decl,
744 objc_inherit_code == CLASS_METHOD_DECL);
745 start_method_def (decl);
748 void
749 objc_add_instance_variable (tree decl)
751 (void) add_instance_variable (objc_ivar_context,
752 objc_public_flag,
753 decl);
756 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
757 an '@'. */
760 objc_is_reserved_word (tree ident)
762 unsigned char code = C_RID_CODE (ident);
764 return (OBJC_IS_AT_KEYWORD (code)
765 || code == RID_CLASS || code == RID_PUBLIC
766 || code == RID_PROTECTED || code == RID_PRIVATE
767 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
770 /* Return true if TYPE is 'id'. */
772 static bool
773 objc_is_object_id (tree type)
775 return OBJC_TYPE_NAME (type) == objc_object_id;
778 static bool
779 objc_is_class_id (tree type)
781 return OBJC_TYPE_NAME (type) == objc_class_id;
784 /* Construct a C struct with same name as KLASS, a base struct with tag
785 SUPER_NAME (if any), and FIELDS indicated. */
787 static tree
788 objc_build_struct (tree klass, tree fields, tree super_name)
790 tree name = CLASS_NAME (klass);
791 tree s = start_struct (RECORD_TYPE, name);
792 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
793 tree t, objc_info = NULL_TREE;
795 if (super)
797 /* Prepend a packed variant of the base class into the layout. This
798 is necessary to preserve ObjC ABI compatibility. */
799 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
800 tree field = TYPE_FIELDS (super);
802 while (field && TREE_CHAIN (field)
803 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
804 field = TREE_CHAIN (field);
806 /* For ObjC ABI purposes, the "packed" size of a base class is
807 the sum of the offset and the size (in bits) of the last field
808 in the class. */
809 DECL_SIZE (base)
810 = (field && TREE_CODE (field) == FIELD_DECL
811 ? size_binop (PLUS_EXPR,
812 size_binop (PLUS_EXPR,
813 size_binop
814 (MULT_EXPR,
815 convert (bitsizetype,
816 DECL_FIELD_OFFSET (field)),
817 bitsize_int (BITS_PER_UNIT)),
818 DECL_FIELD_BIT_OFFSET (field)),
819 DECL_SIZE (field))
820 : bitsize_zero_node);
821 DECL_SIZE_UNIT (base)
822 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
823 size_int (BITS_PER_UNIT));
824 DECL_ARTIFICIAL (base) = 1;
825 DECL_ALIGN (base) = 1;
826 DECL_FIELD_CONTEXT (base) = s;
827 #ifdef OBJCPLUS
828 DECL_FIELD_IS_BASE (base) = 1;
830 if (fields)
831 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
832 #endif /* are following the ObjC ABI here. */
833 TREE_CHAIN (base) = fields;
834 fields = base;
837 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
838 in all variants of this RECORD_TYPE to be clobbered, but it is therein
839 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
840 Hence, we must squirrel away the ObjC-specific information before calling
841 finish_struct(), and then reinstate it afterwards. */
843 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
844 objc_info
845 = chainon (objc_info,
846 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
848 /* Point the struct at its related Objective-C class. */
849 INIT_TYPE_OBJC_INFO (s);
850 TYPE_OBJC_INTERFACE (s) = klass;
852 s = finish_struct (s, fields, NULL_TREE);
854 for (t = TYPE_NEXT_VARIANT (s); t;
855 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
857 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
858 /* Replace the IDENTIFIER_NODE with an actual @interface. */
859 TYPE_OBJC_INTERFACE (t) = klass;
862 /* Use TYPE_BINFO structures to point at the super class, if any. */
863 objc_xref_basetypes (s, super);
865 /* Mark this struct as a class template. */
866 CLASS_STATIC_TEMPLATE (klass) = s;
868 return s;
871 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
872 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
873 process. */
874 static tree
875 objc_build_volatilized_type (tree type)
877 tree t;
879 /* Check if we have not constructed the desired variant already. */
880 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
882 /* The type qualifiers must (obviously) match up. */
883 if (!TYPE_VOLATILE (t)
884 || (TYPE_READONLY (t) != TYPE_READONLY (type))
885 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
886 continue;
888 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
889 info, if any) must match up. */
890 if (POINTER_TYPE_P (t)
891 && (TREE_TYPE (t) != TREE_TYPE (type)))
892 continue;
894 /* Everything matches up! */
895 return t;
898 /* Ok, we could not re-use any of the pre-existing variants. Create
899 a new one. */
900 t = build_variant_type_copy (type);
901 TYPE_VOLATILE (t) = 1;
903 /* Set up the canonical type information. */
904 if (TYPE_STRUCTURAL_EQUALITY_P (type))
905 SET_TYPE_STRUCTURAL_EQUALITY (t);
906 else if (TYPE_CANONICAL (type) != type)
907 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
908 else
909 TYPE_CANONICAL (t) = t;
911 return t;
914 /* Mark DECL as being 'volatile' for purposes of Darwin
915 _setjmp()/_longjmp() exception handling. Called from
916 objc_mark_locals_volatile(). */
917 void
918 objc_volatilize_decl (tree decl)
920 /* Do not mess with variables that are 'static' or (already)
921 'volatile'. */
922 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
923 && (TREE_CODE (decl) == VAR_DECL
924 || TREE_CODE (decl) == PARM_DECL))
926 tree t = TREE_TYPE (decl);
927 struct volatilized_type key;
928 void **loc;
930 t = objc_build_volatilized_type (t);
931 key.type = t;
932 loc = htab_find_slot (volatilized_htab, &key, INSERT);
934 if (!*loc)
936 *loc = ggc_alloc (sizeof (key));
937 ((struct volatilized_type *) *loc)->type = t;
940 TREE_TYPE (decl) = t;
941 TREE_THIS_VOLATILE (decl) = 1;
942 TREE_SIDE_EFFECTS (decl) = 1;
943 DECL_REGISTER (decl) = 0;
944 #ifndef OBJCPLUS
945 C_DECL_REGISTER (decl) = 0;
946 #endif
950 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
951 (including its categories and superclasses) or by object type TYP.
952 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
954 static bool
955 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
957 bool class_type = (cls != NULL_TREE);
959 while (cls)
961 tree c;
963 /* Check protocols adopted by the class and its categories. */
964 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
966 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
967 return true;
970 /* Repeat for superclasses. */
971 cls = lookup_interface (CLASS_SUPER_NAME (cls));
974 /* Check for any protocols attached directly to the object type. */
975 if (TYPE_HAS_OBJC_INFO (typ))
977 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
978 return true;
981 if (warn)
983 strcpy (errbuf, class_type ? "class \'" : "type \'");
984 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
985 strcat (errbuf, "\' does not ");
986 /* NB: Types 'id' and 'Class' cannot reasonably be described as
987 "implementing" a given protocol, since they do not have an
988 implementation. */
989 strcat (errbuf, class_type ? "implement" : "conform to");
990 strcat (errbuf, " the \'");
991 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
992 strcat (errbuf, "\' protocol");
993 warning (0, errbuf);
996 return false;
999 /* Check if class RCLS and instance struct type RTYP conform to at least the
1000 same protocols that LCLS and LTYP conform to. */
1002 static bool
1003 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1005 tree p;
1006 bool have_lproto = false;
1008 while (lcls)
1010 /* NB: We do _not_ look at categories defined for LCLS; these may or
1011 may not get loaded in, and therefore it is unreasonable to require
1012 that RCLS/RTYP must implement any of their protocols. */
1013 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1015 have_lproto = true;
1017 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1018 return warn;
1021 /* Repeat for superclasses. */
1022 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1025 /* Check for any protocols attached directly to the object type. */
1026 if (TYPE_HAS_OBJC_INFO (ltyp))
1028 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1030 have_lproto = true;
1032 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1033 return warn;
1037 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1038 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1039 away with simply checking for 'id' or 'Class' (!RCLS), since this
1040 routine will not get called in other cases. */
1041 return have_lproto || (rcls != NULL_TREE);
1044 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1045 an instance of RTYP to an instance of LTYP or to compare the two
1046 (if ARGNO is equal to -3), per ObjC type system rules. Before
1047 returning 'true', this routine may issue warnings related to, e.g.,
1048 protocol conformance. When returning 'false', the routine must
1049 produce absolutely no warnings; the C or C++ front-end will do so
1050 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1051 the routine must return 'false'.
1053 The ARGNO parameter is encoded as follows:
1054 >= 1 Parameter number (CALLEE contains function being called);
1055 0 Return value;
1056 -1 Assignment;
1057 -2 Initialization;
1058 -3 Comparison (LTYP and RTYP may match in either direction). */
1060 bool
1061 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1063 tree lcls, rcls, lproto, rproto;
1064 bool pointers_compatible;
1066 /* We must be dealing with pointer types */
1067 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1068 return false;
1072 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1073 rtyp = TREE_TYPE (rtyp);
1075 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1077 /* Past this point, we are only interested in ObjC class instances,
1078 or 'id' or 'Class'. */
1079 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1080 return false;
1082 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1083 && !TYPE_HAS_OBJC_INFO (ltyp))
1084 return false;
1086 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1087 && !TYPE_HAS_OBJC_INFO (rtyp))
1088 return false;
1090 /* Past this point, we are committed to returning 'true' to the caller.
1091 However, we can still warn about type and/or protocol mismatches. */
1093 if (TYPE_HAS_OBJC_INFO (ltyp))
1095 lcls = TYPE_OBJC_INTERFACE (ltyp);
1096 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1098 else
1099 lcls = lproto = NULL_TREE;
1101 if (TYPE_HAS_OBJC_INFO (rtyp))
1103 rcls = TYPE_OBJC_INTERFACE (rtyp);
1104 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1106 else
1107 rcls = rproto = NULL_TREE;
1109 /* If we could not find an @interface declaration, we must have
1110 only seen a @class declaration; for purposes of type comparison,
1111 treat it as a stand-alone (root) class. */
1113 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1114 lcls = NULL_TREE;
1116 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1117 rcls = NULL_TREE;
1119 /* If either type is an unqualified 'id', we're done. */
1120 if ((!lproto && objc_is_object_id (ltyp))
1121 || (!rproto && objc_is_object_id (rtyp)))
1122 return true;
1124 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1126 /* If the underlying types are the same, and at most one of them has
1127 a protocol list, we do not need to issue any diagnostics. */
1128 if (pointers_compatible && (!lproto || !rproto))
1129 return true;
1131 /* If exactly one of the types is 'Class', issue a diagnostic; any
1132 exceptions of this rule have already been handled. */
1133 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1134 pointers_compatible = false;
1135 /* Otherwise, check for inheritance relations. */
1136 else
1138 if (!pointers_compatible)
1139 pointers_compatible
1140 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1142 if (!pointers_compatible)
1143 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1145 if (!pointers_compatible && argno == -3)
1146 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1149 /* If the pointers match modulo protocols, check for protocol conformance
1150 mismatches. */
1151 if (pointers_compatible)
1153 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1154 argno != -3);
1156 if (!pointers_compatible && argno == -3)
1157 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1158 argno != -3);
1161 if (!pointers_compatible)
1163 /* NB: For the time being, we shall make our warnings look like their
1164 C counterparts. In the future, we may wish to make them more
1165 ObjC-specific. */
1166 switch (argno)
1168 case -3:
1169 warning (0, "comparison of distinct Objective-C types lacks a cast");
1170 break;
1172 case -2:
1173 warning (0, "initialization from distinct Objective-C type");
1174 break;
1176 case -1:
1177 warning (0, "assignment from distinct Objective-C type");
1178 break;
1180 case 0:
1181 warning (0, "distinct Objective-C type in return");
1182 break;
1184 default:
1185 warning (0, "passing argument %d of %qE from distinct "
1186 "Objective-C type", argno, callee);
1187 break;
1191 return true;
1194 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1195 lives in the volatilized hash table, ignore the 'volatile' bit when
1196 making the comparison. */
1198 bool
1199 objc_type_quals_match (tree ltyp, tree rtyp)
1201 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1202 struct volatilized_type key;
1204 key.type = ltyp;
1206 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1207 lquals &= ~TYPE_QUAL_VOLATILE;
1209 key.type = rtyp;
1211 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1212 rquals &= ~TYPE_QUAL_VOLATILE;
1214 return (lquals == rquals);
1217 #ifndef OBJCPLUS
1218 /* Determine if CHILD is derived from PARENT. The routine assumes that
1219 both parameters are RECORD_TYPEs, and is non-reflexive. */
1221 static bool
1222 objc_derived_from_p (tree parent, tree child)
1224 parent = TYPE_MAIN_VARIANT (parent);
1226 for (child = TYPE_MAIN_VARIANT (child);
1227 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1229 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1230 (TYPE_BINFO (child),
1231 0)));
1233 if (child == parent)
1234 return true;
1237 return false;
1239 #endif
1241 static tree
1242 objc_build_component_ref (tree datum, tree component)
1244 /* If COMPONENT is NULL, the caller is referring to the anonymous
1245 base class field. */
1246 if (!component)
1248 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1250 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1253 /* The 'build_component_ref' routine has been removed from the C++
1254 front-end, but 'finish_class_member_access_expr' seems to be
1255 a worthy substitute. */
1256 #ifdef OBJCPLUS
1257 return finish_class_member_access_expr (datum, component, false,
1258 tf_warning_or_error);
1259 #else
1260 return build_component_ref (datum, component);
1261 #endif
1264 /* Recursively copy inheritance information rooted at BINFO. To do this,
1265 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1267 static tree
1268 objc_copy_binfo (tree binfo)
1270 tree btype = BINFO_TYPE (binfo);
1271 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1272 tree base_binfo;
1273 int ix;
1275 BINFO_TYPE (binfo2) = btype;
1276 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1277 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1279 /* Recursively copy base binfos of BINFO. */
1280 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1282 tree base_binfo2 = objc_copy_binfo (base_binfo);
1284 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1285 BINFO_BASE_APPEND (binfo2, base_binfo2);
1288 return binfo2;
1291 /* Record superclass information provided in BASETYPE for ObjC class REF.
1292 This is loosely based on cp/decl.c:xref_basetypes(). */
1294 static void
1295 objc_xref_basetypes (tree ref, tree basetype)
1297 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1299 TYPE_BINFO (ref) = binfo;
1300 BINFO_OFFSET (binfo) = size_zero_node;
1301 BINFO_TYPE (binfo) = ref;
1303 if (basetype)
1305 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1307 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1308 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1309 BINFO_BASE_APPEND (binfo, base_binfo);
1310 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1314 static hashval_t
1315 volatilized_hash (const void *ptr)
1317 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1319 return htab_hash_pointer(typ);
1322 static int
1323 volatilized_eq (const void *ptr1, const void *ptr2)
1325 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1326 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1328 return typ1 == typ2;
1331 /* Called from finish_decl. */
1333 void
1334 objc_check_decl (tree decl)
1336 tree type = TREE_TYPE (decl);
1338 if (TREE_CODE (type) != RECORD_TYPE)
1339 return;
1340 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1341 error ("statically allocated instance of Objective-C class %qs",
1342 IDENTIFIER_POINTER (type));
1345 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1346 either name an Objective-C class, or refer to the special 'id' or 'Class'
1347 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1349 tree
1350 objc_get_protocol_qualified_type (tree interface, tree protocols)
1352 /* If INTERFACE is not provided, default to 'id'. */
1353 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1354 bool is_ptr = (type != NULL_TREE);
1356 if (!is_ptr)
1358 type = objc_is_class_name (interface);
1360 if (type)
1361 type = xref_tag (RECORD_TYPE, type);
1362 else
1363 return interface;
1366 if (protocols)
1368 type = build_variant_type_copy (type);
1370 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1371 to the pointee. */
1372 if (is_ptr)
1374 tree orig_pointee_type = TREE_TYPE (type);
1375 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1377 /* Set up the canonical type information. */
1378 TYPE_CANONICAL (type)
1379 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1381 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1382 type = TREE_TYPE (type);
1385 /* Look up protocols and install in lang specific list. */
1386 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1387 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1389 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1390 return the pointer to the new pointee variant. */
1391 if (is_ptr)
1392 type = TYPE_POINTER_TO (type);
1393 else
1394 TYPE_OBJC_INTERFACE (type)
1395 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1398 return type;
1401 /* Check for circular dependencies in protocols. The arguments are
1402 PROTO, the protocol to check, and LIST, a list of protocol it
1403 conforms to. */
1405 static void
1406 check_protocol_recursively (tree proto, tree list)
1408 tree p;
1410 for (p = list; p; p = TREE_CHAIN (p))
1412 tree pp = TREE_VALUE (p);
1414 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1415 pp = lookup_protocol (pp);
1417 if (pp == proto)
1418 fatal_error ("protocol %qs has circular dependency",
1419 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1420 if (pp)
1421 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1425 /* Look up PROTOCOLS, and return a list of those that are found.
1426 If none are found, return NULL. */
1428 static tree
1429 lookup_and_install_protocols (tree protocols)
1431 tree proto;
1432 tree return_value = NULL_TREE;
1434 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1436 tree ident = TREE_VALUE (proto);
1437 tree p = lookup_protocol (ident);
1439 if (p)
1440 return_value = chainon (return_value,
1441 build_tree_list (NULL_TREE, p));
1442 else if (ident != error_mark_node)
1443 error ("cannot find protocol declaration for %qs",
1444 IDENTIFIER_POINTER (ident));
1447 return return_value;
1450 /* Create a declaration for field NAME of a given TYPE. */
1452 static tree
1453 create_field_decl (tree type, const char *name)
1455 return build_decl (FIELD_DECL, get_identifier (name), type);
1458 /* Create a global, static declaration for variable NAME of a given TYPE. The
1459 finish_var_decl() routine will need to be called on it afterwards. */
1461 static tree
1462 start_var_decl (tree type, const char *name)
1464 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1466 TREE_STATIC (var) = 1;
1467 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1468 DECL_IGNORED_P (var) = 1;
1469 DECL_ARTIFICIAL (var) = 1;
1470 DECL_CONTEXT (var) = NULL_TREE;
1471 #ifdef OBJCPLUS
1472 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1473 #endif
1475 return var;
1478 /* Finish off the variable declaration created by start_var_decl(). */
1480 static void
1481 finish_var_decl (tree var, tree initializer)
1483 finish_decl (var, initializer, NULL_TREE, NULL_TREE);
1484 /* Ensure that the variable actually gets output. */
1485 mark_decl_referenced (var);
1486 /* Mark the decl to avoid "defined but not used" warning. */
1487 TREE_USED (var) = 1;
1490 /* Find the decl for the constant string class reference. This is only
1491 used for the NeXT runtime. */
1493 static tree
1494 setup_string_decl (void)
1496 char *name;
1497 size_t length;
1499 /* %s in format will provide room for terminating null */
1500 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1501 + strlen (constant_string_class_name);
1502 name = XNEWVEC (char, length);
1503 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1504 constant_string_class_name);
1505 constant_string_global_id = get_identifier (name);
1506 string_class_decl = lookup_name (constant_string_global_id);
1508 return string_class_decl;
1511 /* Purpose: "play" parser, creating/installing representations
1512 of the declarations that are required by Objective-C.
1514 Model:
1516 type_spec--------->sc_spec
1517 (tree_list) (tree_list)
1520 identifier_node identifier_node */
1522 static void
1523 synth_module_prologue (void)
1525 tree type;
1526 enum debug_info_type save_write_symbols = write_symbols;
1527 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1529 /* Suppress outputting debug symbols, because
1530 dbxout_init hasn't been called yet. */
1531 write_symbols = NO_DEBUG;
1532 debug_hooks = &do_nothing_debug_hooks;
1534 #ifdef OBJCPLUS
1535 push_lang_context (lang_name_c); /* extern "C" */
1536 #endif
1538 /* The following are also defined in <objc/objc.h> and friends. */
1540 objc_object_id = get_identifier (TAG_OBJECT);
1541 objc_class_id = get_identifier (TAG_CLASS);
1543 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1544 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1546 objc_object_type = build_pointer_type (objc_object_reference);
1547 objc_class_type = build_pointer_type (objc_class_reference);
1549 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1550 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1552 /* Declare the 'id' and 'Class' typedefs. */
1554 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1555 objc_object_name,
1556 objc_object_type));
1557 TREE_NO_WARNING (type) = 1;
1558 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1559 objc_class_name,
1560 objc_class_type));
1561 TREE_NO_WARNING (type) = 1;
1563 /* Forward-declare '@interface Protocol'. */
1565 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1566 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1567 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1568 type));
1570 /* Declare type of selector-objects that represent an operation name. */
1572 if (flag_next_runtime)
1573 /* `struct objc_selector *' */
1574 objc_selector_type
1575 = build_pointer_type (xref_tag (RECORD_TYPE,
1576 get_identifier (TAG_SELECTOR)));
1577 else
1578 /* `const struct objc_selector *' */
1579 objc_selector_type
1580 = build_pointer_type
1581 (build_qualified_type (xref_tag (RECORD_TYPE,
1582 get_identifier (TAG_SELECTOR)),
1583 TYPE_QUAL_CONST));
1585 /* Declare receiver type used for dispatching messages to 'super'. */
1587 /* `struct objc_super *' */
1588 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1589 get_identifier (TAG_SUPER)));
1591 /* Declare pointers to method and ivar lists. */
1592 objc_method_list_ptr = build_pointer_type
1593 (xref_tag (RECORD_TYPE,
1594 get_identifier (UTAG_METHOD_LIST)));
1595 objc_method_proto_list_ptr
1596 = build_pointer_type (xref_tag (RECORD_TYPE,
1597 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1598 objc_ivar_list_ptr = build_pointer_type
1599 (xref_tag (RECORD_TYPE,
1600 get_identifier (UTAG_IVAR_LIST)));
1602 /* TREE_NOTHROW is cleared for the message-sending functions,
1603 because the function that gets called can throw in Obj-C++, or
1604 could itself call something that can throw even in Obj-C. */
1606 if (flag_next_runtime)
1608 /* NB: In order to call one of the ..._stret (struct-returning)
1609 functions, the function *MUST* first be cast to a signature that
1610 corresponds to the actual ObjC method being invoked. This is
1611 what is done by the build_objc_method_call() routine below. */
1613 /* id objc_msgSend (id, SEL, ...); */
1614 /* id objc_msgSendNonNil (id, SEL, ...); */
1615 /* id objc_msgSend_stret (id, SEL, ...); */
1616 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1617 type
1618 = build_function_type (objc_object_type,
1619 tree_cons (NULL_TREE, objc_object_type,
1620 tree_cons (NULL_TREE, objc_selector_type,
1621 NULL_TREE)));
1622 umsg_decl = add_builtin_function (TAG_MSGSEND,
1623 type, 0, NOT_BUILT_IN,
1624 NULL, NULL_TREE);
1625 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1626 type, 0, NOT_BUILT_IN,
1627 NULL, NULL_TREE);
1628 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1629 type, 0, NOT_BUILT_IN,
1630 NULL, NULL_TREE);
1631 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1632 type, 0, NOT_BUILT_IN,
1633 NULL, NULL_TREE);
1635 /* These can throw, because the function that gets called can throw
1636 in Obj-C++, or could itself call something that can throw even
1637 in Obj-C. */
1638 TREE_NOTHROW (umsg_decl) = 0;
1639 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1640 TREE_NOTHROW (umsg_stret_decl) = 0;
1641 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1643 /* id objc_msgSend_Fast (id, SEL, ...)
1644 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1645 #ifdef OFFS_MSGSEND_FAST
1646 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1647 type, 0, NOT_BUILT_IN,
1648 NULL, NULL_TREE);
1649 TREE_NOTHROW (umsg_fast_decl) = 0;
1650 DECL_ATTRIBUTES (umsg_fast_decl)
1651 = tree_cons (get_identifier ("hard_coded_address"),
1652 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1653 NULL_TREE);
1654 #else
1655 /* No direct dispatch available. */
1656 umsg_fast_decl = umsg_decl;
1657 #endif
1659 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1660 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1661 type
1662 = build_function_type (objc_object_type,
1663 tree_cons (NULL_TREE, objc_super_type,
1664 tree_cons (NULL_TREE, objc_selector_type,
1665 NULL_TREE)));
1666 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1667 type, 0, NOT_BUILT_IN,
1668 NULL, NULL_TREE);
1669 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1670 type, 0, NOT_BUILT_IN, 0,
1671 NULL_TREE);
1672 TREE_NOTHROW (umsg_super_decl) = 0;
1673 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1675 else
1677 /* GNU runtime messenger entry points. */
1679 /* typedef id (*IMP)(id, SEL, ...); */
1680 tree IMP_type
1681 = build_pointer_type
1682 (build_function_type (objc_object_type,
1683 tree_cons (NULL_TREE, objc_object_type,
1684 tree_cons (NULL_TREE, objc_selector_type,
1685 NULL_TREE))));
1687 /* IMP objc_msg_lookup (id, SEL); */
1688 type
1689 = build_function_type (IMP_type,
1690 tree_cons (NULL_TREE, objc_object_type,
1691 tree_cons (NULL_TREE, objc_selector_type,
1692 OBJC_VOID_AT_END)));
1693 umsg_decl = add_builtin_function (TAG_MSGSEND,
1694 type, 0, NOT_BUILT_IN,
1695 NULL, NULL_TREE);
1696 TREE_NOTHROW (umsg_decl) = 0;
1698 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1699 type
1700 = build_function_type (IMP_type,
1701 tree_cons (NULL_TREE, objc_super_type,
1702 tree_cons (NULL_TREE, objc_selector_type,
1703 OBJC_VOID_AT_END)));
1704 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1705 type, 0, NOT_BUILT_IN,
1706 NULL, NULL_TREE);
1707 TREE_NOTHROW (umsg_super_decl) = 0;
1709 /* The following GNU runtime entry point is called to initialize
1710 each module:
1712 __objc_exec_class (void *); */
1713 type
1714 = build_function_type (void_type_node,
1715 tree_cons (NULL_TREE, ptr_type_node,
1716 OBJC_VOID_AT_END));
1717 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1718 type, 0, NOT_BUILT_IN,
1719 NULL, NULL_TREE);
1722 /* id objc_getClass (const char *); */
1724 type = build_function_type (objc_object_type,
1725 tree_cons (NULL_TREE,
1726 const_string_type_node,
1727 OBJC_VOID_AT_END));
1729 objc_get_class_decl
1730 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1731 NULL, NULL_TREE);
1733 /* id objc_getMetaClass (const char *); */
1735 objc_get_meta_class_decl
1736 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1738 build_class_template ();
1739 build_super_template ();
1740 build_protocol_template ();
1741 build_category_template ();
1742 build_objc_exception_stuff ();
1744 if (flag_next_runtime)
1745 build_next_objc_exception_stuff ();
1747 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1749 if (! flag_next_runtime)
1750 build_selector_table_decl ();
1752 /* Forward declare constant_string_id and constant_string_type. */
1753 if (!constant_string_class_name)
1754 constant_string_class_name = default_constant_string_class_name;
1756 constant_string_id = get_identifier (constant_string_class_name);
1757 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1759 /* Pre-build the following entities - for speed/convenience. */
1760 self_id = get_identifier ("self");
1761 ucmd_id = get_identifier ("_cmd");
1763 #ifdef OBJCPLUS
1764 pop_lang_context ();
1765 #endif
1767 write_symbols = save_write_symbols;
1768 debug_hooks = save_hooks;
1771 /* Ensure that the ivar list for NSConstantString/NXConstantString
1772 (or whatever was specified via `-fconstant-string-class')
1773 contains fields at least as large as the following three, so that
1774 the runtime can stomp on them with confidence:
1776 struct STRING_OBJECT_CLASS_NAME
1778 Object isa;
1779 char *cString;
1780 unsigned int length;
1781 }; */
1783 static int
1784 check_string_class_template (void)
1786 tree field_decl = objc_get_class_ivars (constant_string_id);
1788 #define AT_LEAST_AS_LARGE_AS(F, T) \
1789 (F && TREE_CODE (F) == FIELD_DECL \
1790 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1791 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1793 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1794 return 0;
1796 field_decl = TREE_CHAIN (field_decl);
1797 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1798 return 0;
1800 field_decl = TREE_CHAIN (field_decl);
1801 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1803 #undef AT_LEAST_AS_LARGE_AS
1806 /* Avoid calling `check_string_class_template ()' more than once. */
1807 static GTY(()) int string_layout_checked;
1809 /* Construct an internal string layout to be used as a template for
1810 creating NSConstantString/NXConstantString instances. */
1812 static tree
1813 objc_build_internal_const_str_type (void)
1815 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1816 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1817 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1819 TREE_CHAIN (field) = fields; fields = field;
1820 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1821 TREE_CHAIN (field) = fields; fields = field;
1822 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1823 reverse order! */
1824 finish_builtin_struct (type, "__builtin_ObjCString",
1825 fields, NULL_TREE);
1827 return type;
1830 /* Custom build_string which sets TREE_TYPE! */
1832 static tree
1833 my_build_string (int len, const char *str)
1835 return fix_string_type (build_string (len, str));
1838 /* Build a string with contents STR and length LEN and convert it to a
1839 pointer. */
1841 static tree
1842 my_build_string_pointer (int len, const char *str)
1844 tree string = my_build_string (len, str);
1845 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1846 return build1 (ADDR_EXPR, ptrtype, string);
1849 static hashval_t
1850 string_hash (const void *ptr)
1852 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1853 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1854 int i, len = TREE_STRING_LENGTH (str);
1855 hashval_t h = len;
1857 for (i = 0; i < len; i++)
1858 h = ((h * 613) + p[i]);
1860 return h;
1863 static int
1864 string_eq (const void *ptr1, const void *ptr2)
1866 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1867 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1868 int len1 = TREE_STRING_LENGTH (str1);
1870 return (len1 == TREE_STRING_LENGTH (str2)
1871 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1872 len1));
1875 /* Given a chain of STRING_CST's, build a static instance of
1876 NXConstantString which points at the concatenation of those
1877 strings. We place the string object in the __string_objects
1878 section of the __OBJC segment. The Objective-C runtime will
1879 initialize the isa pointers of the string objects to point at the
1880 NXConstantString class object. */
1882 tree
1883 objc_build_string_object (tree string)
1885 tree initlist, constructor, constant_string_class;
1886 int length;
1887 tree fields, addr;
1888 struct string_descriptor *desc, key;
1889 void **loc;
1891 /* Prep the string argument. */
1892 string = fix_string_type (string);
1893 TREE_SET_CODE (string, STRING_CST);
1894 length = TREE_STRING_LENGTH (string) - 1;
1896 /* Check whether the string class being used actually exists and has the
1897 correct ivar layout. */
1898 if (!string_layout_checked)
1900 string_layout_checked = -1;
1901 constant_string_class = lookup_interface (constant_string_id);
1902 internal_const_str_type = objc_build_internal_const_str_type ();
1904 if (!constant_string_class
1905 || !(constant_string_type
1906 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1907 error ("cannot find interface declaration for %qs",
1908 IDENTIFIER_POINTER (constant_string_id));
1909 /* The NSConstantString/NXConstantString ivar layout is now known. */
1910 else if (!check_string_class_template ())
1911 error ("interface %qs does not have valid constant string layout",
1912 IDENTIFIER_POINTER (constant_string_id));
1913 /* For the NeXT runtime, we can generate a literal reference
1914 to the string class, don't need to run a constructor. */
1915 else if (flag_next_runtime && !setup_string_decl ())
1916 error ("cannot find reference tag for class %qs",
1917 IDENTIFIER_POINTER (constant_string_id));
1918 else
1920 string_layout_checked = 1; /* Success! */
1921 add_class_reference (constant_string_id);
1925 if (string_layout_checked == -1)
1926 return error_mark_node;
1928 /* Perhaps we already constructed a constant string just like this one? */
1929 key.literal = string;
1930 loc = htab_find_slot (string_htab, &key, INSERT);
1931 desc = (struct string_descriptor *) *loc;
1933 if (!desc)
1935 tree var;
1936 *loc = desc = GGC_NEW (struct string_descriptor);
1937 desc->literal = string;
1939 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1940 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1941 fields = TYPE_FIELDS (internal_const_str_type);
1942 initlist
1943 = build_tree_list (fields,
1944 flag_next_runtime
1945 ? build_unary_op (input_location,
1946 ADDR_EXPR, string_class_decl, 0)
1947 : build_int_cst (NULL_TREE, 0));
1948 fields = TREE_CHAIN (fields);
1949 initlist = tree_cons (fields, build_unary_op (input_location,
1950 ADDR_EXPR, string, 1),
1951 initlist);
1952 fields = TREE_CHAIN (fields);
1953 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1954 initlist);
1955 constructor = objc_build_constructor (internal_const_str_type,
1956 nreverse (initlist));
1958 if (!flag_next_runtime)
1959 constructor
1960 = objc_add_static_instance (constructor, constant_string_type);
1961 else
1963 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1964 DECL_INITIAL (var) = constructor;
1965 TREE_STATIC (var) = 1;
1966 pushdecl_top_level (var);
1967 constructor = var;
1969 desc->constructor = constructor;
1972 addr = convert (build_pointer_type (constant_string_type),
1973 build_unary_op (input_location,
1974 ADDR_EXPR, desc->constructor, 1));
1976 return addr;
1979 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1981 static GTY(()) int num_static_inst;
1983 static tree
1984 objc_add_static_instance (tree constructor, tree class_decl)
1986 tree *chain, decl;
1987 char buf[256];
1989 /* Find the list of static instances for the CLASS_DECL. Create one if
1990 not found. */
1991 for (chain = &objc_static_instances;
1992 *chain && TREE_VALUE (*chain) != class_decl;
1993 chain = &TREE_CHAIN (*chain));
1994 if (!*chain)
1996 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1997 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2000 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2001 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
2002 DECL_COMMON (decl) = 1;
2003 TREE_STATIC (decl) = 1;
2004 DECL_ARTIFICIAL (decl) = 1;
2005 TREE_USED (decl) = 1;
2006 DECL_INITIAL (decl) = constructor;
2008 /* We may be writing something else just now.
2009 Postpone till end of input. */
2010 DECL_DEFER_OUTPUT (decl) = 1;
2011 pushdecl_top_level (decl);
2012 rest_of_decl_compilation (decl, 1, 0);
2014 /* Add the DECL to the head of this CLASS' list. */
2015 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2017 return decl;
2020 /* Build a static constant CONSTRUCTOR
2021 with type TYPE and elements ELTS. */
2023 static tree
2024 objc_build_constructor (tree type, tree elts)
2026 tree constructor = build_constructor_from_list (type, elts);
2028 TREE_CONSTANT (constructor) = 1;
2029 TREE_STATIC (constructor) = 1;
2030 TREE_READONLY (constructor) = 1;
2032 #ifdef OBJCPLUS
2033 /* Adjust for impedance mismatch. We should figure out how to build
2034 CONSTRUCTORs that consistently please both the C and C++ gods. */
2035 if (!TREE_PURPOSE (elts))
2036 TREE_TYPE (constructor) = init_list_type_node;
2037 #endif
2039 return constructor;
2042 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2044 /* Predefine the following data type:
2046 struct _objc_symtab
2048 long sel_ref_cnt;
2049 SEL *refs;
2050 short cls_def_cnt;
2051 short cat_def_cnt;
2052 void *defs[cls_def_cnt + cat_def_cnt];
2053 }; */
2055 static void
2056 build_objc_symtab_template (void)
2058 tree field_decl, field_decl_chain;
2060 objc_symtab_template
2061 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2063 /* long sel_ref_cnt; */
2064 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2065 field_decl_chain = field_decl;
2067 /* SEL *refs; */
2068 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2069 "refs");
2070 chainon (field_decl_chain, field_decl);
2072 /* short cls_def_cnt; */
2073 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2074 chainon (field_decl_chain, field_decl);
2076 /* short cat_def_cnt; */
2077 field_decl = create_field_decl (short_integer_type_node,
2078 "cat_def_cnt");
2079 chainon (field_decl_chain, field_decl);
2081 if (imp_count || cat_count || !flag_next_runtime)
2083 /* void *defs[imp_count + cat_count (+ 1)]; */
2084 /* NB: The index is one less than the size of the array. */
2085 int index = imp_count + cat_count
2086 + (flag_next_runtime? -1: 0);
2087 field_decl = create_field_decl
2088 (build_array_type
2089 (ptr_type_node,
2090 build_index_type (build_int_cst (NULL_TREE, index))),
2091 "defs");
2092 chainon (field_decl_chain, field_decl);
2095 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2098 /* Create the initial value for the `defs' field of _objc_symtab.
2099 This is a CONSTRUCTOR. */
2101 static tree
2102 init_def_list (tree type)
2104 tree expr, initlist = NULL_TREE;
2105 struct imp_entry *impent;
2107 if (imp_count)
2108 for (impent = imp_list; impent; impent = impent->next)
2110 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2112 expr = build_unary_op (input_location,
2113 ADDR_EXPR, impent->class_decl, 0);
2114 initlist = tree_cons (NULL_TREE, expr, initlist);
2118 if (cat_count)
2119 for (impent = imp_list; impent; impent = impent->next)
2121 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2123 expr = build_unary_op (input_location,
2124 ADDR_EXPR, impent->class_decl, 0);
2125 initlist = tree_cons (NULL_TREE, expr, initlist);
2129 if (!flag_next_runtime)
2131 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2132 tree expr;
2134 if (static_instances_decl)
2135 expr = build_unary_op (input_location,
2136 ADDR_EXPR, static_instances_decl, 0);
2137 else
2138 expr = build_int_cst (NULL_TREE, 0);
2140 initlist = tree_cons (NULL_TREE, expr, initlist);
2143 return objc_build_constructor (type, nreverse (initlist));
2146 /* Construct the initial value for all of _objc_symtab. */
2148 static tree
2149 init_objc_symtab (tree type)
2151 tree initlist;
2153 /* sel_ref_cnt = { ..., 5, ... } */
2155 initlist = build_tree_list (NULL_TREE,
2156 build_int_cst (long_integer_type_node, 0));
2158 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2160 if (flag_next_runtime || ! sel_ref_chain)
2161 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2162 else
2163 initlist
2164 = tree_cons (NULL_TREE,
2165 convert (build_pointer_type (objc_selector_type),
2166 build_unary_op (input_location, ADDR_EXPR,
2167 UOBJC_SELECTOR_TABLE_decl, 1)),
2168 initlist);
2170 /* cls_def_cnt = { ..., 5, ... } */
2172 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2174 /* cat_def_cnt = { ..., 5, ... } */
2176 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2178 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2180 if (imp_count || cat_count || !flag_next_runtime)
2183 tree field = TYPE_FIELDS (type);
2184 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2186 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2187 initlist);
2190 return objc_build_constructor (type, nreverse (initlist));
2193 /* Generate forward declarations for metadata such as
2194 'OBJC_CLASS_...'. */
2196 static tree
2197 build_metadata_decl (const char *name, tree type)
2199 tree decl;
2201 /* struct TYPE NAME_<name>; */
2202 decl = start_var_decl (type, synth_id_with_class_suffix
2203 (name,
2204 objc_implementation_context));
2206 return decl;
2209 /* Push forward-declarations of all the categories so that
2210 init_def_list can use them in a CONSTRUCTOR. */
2212 static void
2213 forward_declare_categories (void)
2215 struct imp_entry *impent;
2216 tree sav = objc_implementation_context;
2218 for (impent = imp_list; impent; impent = impent->next)
2220 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2222 /* Set an invisible arg to synth_id_with_class_suffix. */
2223 objc_implementation_context = impent->imp_context;
2224 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2225 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2226 objc_category_template);
2229 objc_implementation_context = sav;
2232 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2233 and initialized appropriately. */
2235 static void
2236 generate_objc_symtab_decl (void)
2238 /* forward declare categories */
2239 if (cat_count)
2240 forward_declare_categories ();
2242 build_objc_symtab_template ();
2243 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2244 finish_var_decl (UOBJC_SYMBOLS_decl,
2245 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2248 static tree
2249 init_module_descriptor (tree type)
2251 tree initlist, expr;
2253 /* version = { 1, ... } */
2255 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2256 initlist = build_tree_list (NULL_TREE, expr);
2258 /* size = { ..., sizeof (struct _objc_module), ... } */
2260 expr = convert (long_integer_type_node,
2261 size_in_bytes (objc_module_template));
2262 initlist = tree_cons (NULL_TREE, expr, initlist);
2264 /* Don't provide any file name for security reasons. */
2265 /* name = { ..., "", ... } */
2267 expr = add_objc_string (get_identifier (""), class_names);
2268 initlist = tree_cons (NULL_TREE, expr, initlist);
2270 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2272 if (UOBJC_SYMBOLS_decl)
2273 expr = build_unary_op (input_location,
2274 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2275 else
2276 expr = build_int_cst (NULL_TREE, 0);
2277 initlist = tree_cons (NULL_TREE, expr, initlist);
2279 return objc_build_constructor (type, nreverse (initlist));
2282 /* Write out the data structures to describe Objective C classes defined.
2284 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2286 static void
2287 build_module_descriptor (void)
2289 tree field_decl, field_decl_chain;
2291 #ifdef OBJCPLUS
2292 push_lang_context (lang_name_c); /* extern "C" */
2293 #endif
2295 objc_module_template
2296 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2298 /* long version; */
2299 field_decl = create_field_decl (long_integer_type_node, "version");
2300 field_decl_chain = field_decl;
2302 /* long size; */
2303 field_decl = create_field_decl (long_integer_type_node, "size");
2304 chainon (field_decl_chain, field_decl);
2306 /* char *name; */
2307 field_decl = create_field_decl (string_type_node, "name");
2308 chainon (field_decl_chain, field_decl);
2310 /* struct _objc_symtab *symtab; */
2311 field_decl
2312 = create_field_decl (build_pointer_type
2313 (xref_tag (RECORD_TYPE,
2314 get_identifier (UTAG_SYMTAB))),
2315 "symtab");
2316 chainon (field_decl_chain, field_decl);
2318 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2320 /* Create an instance of "_objc_module". */
2321 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2322 finish_var_decl (UOBJC_MODULES_decl,
2323 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2325 #ifdef OBJCPLUS
2326 pop_lang_context ();
2327 #endif
2330 /* The GNU runtime requires us to provide a static initializer function
2331 for each module:
2333 static void __objc_gnu_init (void) {
2334 __objc_exec_class (&L_OBJC_MODULES);
2335 } */
2337 static void
2338 build_module_initializer_routine (void)
2340 tree body;
2342 #ifdef OBJCPLUS
2343 push_lang_context (lang_name_c); /* extern "C" */
2344 #endif
2346 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2347 objc_start_function (get_identifier (TAG_GNUINIT),
2348 build_function_type (void_type_node,
2349 OBJC_VOID_AT_END),
2350 NULL_TREE, objc_get_parm_info (0));
2352 body = c_begin_compound_stmt (true);
2353 add_stmt (build_function_call
2354 (execclass_decl,
2355 build_tree_list
2356 (NULL_TREE,
2357 build_unary_op (input_location, ADDR_EXPR,
2358 UOBJC_MODULES_decl, 0))));
2359 add_stmt (c_end_compound_stmt (body, true));
2361 TREE_PUBLIC (current_function_decl) = 0;
2363 #ifndef OBJCPLUS
2364 /* For Objective-C++, we will need to call __objc_gnu_init
2365 from objc_generate_static_init_call() below. */
2366 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2367 #endif
2369 GNU_INIT_decl = current_function_decl;
2370 finish_function ();
2372 #ifdef OBJCPLUS
2373 pop_lang_context ();
2374 #endif
2377 #ifdef OBJCPLUS
2378 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2379 to be called by the module initializer routine. */
2382 objc_static_init_needed_p (void)
2384 return (GNU_INIT_decl != NULL_TREE);
2387 /* Generate a call to the __objc_gnu_init initializer function. */
2389 tree
2390 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2392 add_stmt (build_stmt (EXPR_STMT,
2393 build_function_call (GNU_INIT_decl, NULL_TREE)));
2395 return ctors;
2397 #endif /* OBJCPLUS */
2399 /* Return the DECL of the string IDENT in the SECTION. */
2401 static tree
2402 get_objc_string_decl (tree ident, enum string_section section)
2404 tree chain;
2406 if (section == class_names)
2407 chain = class_names_chain;
2408 else if (section == meth_var_names)
2409 chain = meth_var_names_chain;
2410 else if (section == meth_var_types)
2411 chain = meth_var_types_chain;
2412 else
2413 abort ();
2415 for (; chain != 0; chain = TREE_CHAIN (chain))
2416 if (TREE_VALUE (chain) == ident)
2417 return (TREE_PURPOSE (chain));
2419 abort ();
2420 return NULL_TREE;
2423 /* Output references to all statically allocated objects. Return the DECL
2424 for the array built. */
2426 static void
2427 generate_static_references (void)
2429 tree decls = NULL_TREE, expr = NULL_TREE;
2430 tree class_name, klass, decl, initlist;
2431 tree cl_chain, in_chain, type
2432 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2433 int num_inst, num_class;
2434 char buf[256];
2436 if (flag_next_runtime)
2437 abort ();
2439 for (cl_chain = objc_static_instances, num_class = 0;
2440 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2442 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2443 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2445 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2446 decl = start_var_decl (type, buf);
2448 /* Output {class_name, ...}. */
2449 klass = TREE_VALUE (cl_chain);
2450 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2451 initlist = build_tree_list (NULL_TREE,
2452 build_unary_op (input_location,
2453 ADDR_EXPR, class_name, 1));
2455 /* Output {..., instance, ...}. */
2456 for (in_chain = TREE_PURPOSE (cl_chain);
2457 in_chain; in_chain = TREE_CHAIN (in_chain))
2459 expr = build_unary_op (input_location,
2460 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2461 initlist = tree_cons (NULL_TREE, expr, initlist);
2464 /* Output {..., NULL}. */
2465 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2467 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2468 finish_var_decl (decl, expr);
2469 decls
2470 = tree_cons (NULL_TREE, build_unary_op (input_location,
2471 ADDR_EXPR, decl, 1), decls);
2474 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2475 expr = objc_build_constructor (type, nreverse (decls));
2476 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2477 finish_var_decl (static_instances_decl, expr);
2480 static GTY(()) int selector_reference_idx;
2482 static tree
2483 build_selector_reference_decl (void)
2485 tree decl;
2486 char buf[256];
2488 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2489 decl = start_var_decl (objc_selector_type, buf);
2491 return decl;
2494 static void
2495 build_selector_table_decl (void)
2497 tree temp;
2499 if (flag_typed_selectors)
2501 build_selector_template ();
2502 temp = build_array_type (objc_selector_template, NULL_TREE);
2504 else
2505 temp = build_array_type (objc_selector_type, NULL_TREE);
2507 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2510 /* Just a handy wrapper for add_objc_string. */
2512 static tree
2513 build_selector (tree ident)
2515 return convert (objc_selector_type,
2516 add_objc_string (ident, meth_var_names));
2519 static void
2520 build_selector_translation_table (void)
2522 tree chain, initlist = NULL_TREE;
2523 int offset = 0;
2524 tree decl = NULL_TREE;
2526 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2528 tree expr;
2530 if (warn_selector && objc_implementation_context)
2532 tree method_chain;
2533 bool found = false;
2534 for (method_chain = meth_var_names_chain;
2535 method_chain;
2536 method_chain = TREE_CHAIN (method_chain))
2538 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2540 found = true;
2541 break;
2544 if (!found)
2546 location_t *loc;
2547 if (flag_next_runtime && TREE_PURPOSE (chain))
2548 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2549 else
2550 loc = &input_location;
2551 warning (0, "%Hcreating selector for nonexistent method %qE",
2552 loc, TREE_VALUE (chain));
2556 expr = build_selector (TREE_VALUE (chain));
2557 /* add one for the '\0' character */
2558 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2560 if (flag_next_runtime)
2562 decl = TREE_PURPOSE (chain);
2563 finish_var_decl (decl, expr);
2565 else
2567 if (flag_typed_selectors)
2569 tree eltlist = NULL_TREE;
2570 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2571 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2572 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2573 expr = objc_build_constructor (objc_selector_template,
2574 nreverse (eltlist));
2577 initlist = tree_cons (NULL_TREE, expr, initlist);
2581 if (! flag_next_runtime)
2583 /* Cause the selector table (previously forward-declared)
2584 to be actually output. */
2585 initlist = tree_cons (NULL_TREE,
2586 flag_typed_selectors
2587 ? objc_build_constructor
2588 (objc_selector_template,
2589 tree_cons (NULL_TREE,
2590 build_int_cst (NULL_TREE, 0),
2591 tree_cons (NULL_TREE,
2592 build_int_cst (NULL_TREE, 0),
2593 NULL_TREE)))
2594 : build_int_cst (NULL_TREE, 0), initlist);
2595 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2596 nreverse (initlist));
2597 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2601 static tree
2602 get_proto_encoding (tree proto)
2604 tree encoding;
2605 if (proto)
2607 if (! METHOD_ENCODING (proto))
2609 encoding = encode_method_prototype (proto);
2610 METHOD_ENCODING (proto) = encoding;
2612 else
2613 encoding = METHOD_ENCODING (proto);
2615 return add_objc_string (encoding, meth_var_types);
2617 else
2618 return build_int_cst (NULL_TREE, 0);
2621 /* sel_ref_chain is a list whose "value" fields will be instances of
2622 identifier_node that represent the selector. */
2624 static tree
2625 build_typed_selector_reference (tree ident, tree prototype)
2627 tree *chain = &sel_ref_chain;
2628 tree expr;
2629 int index = 0;
2631 while (*chain)
2633 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2634 goto return_at_index;
2636 index++;
2637 chain = &TREE_CHAIN (*chain);
2640 *chain = tree_cons (prototype, ident, NULL_TREE);
2642 return_at_index:
2643 expr = build_unary_op (input_location, ADDR_EXPR,
2644 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2645 build_int_cst (NULL_TREE, index),
2646 input_location),
2648 return convert (objc_selector_type, expr);
2651 static tree
2652 build_selector_reference (tree ident)
2654 tree *chain = &sel_ref_chain;
2655 tree expr;
2656 int index = 0;
2658 while (*chain)
2660 if (TREE_VALUE (*chain) == ident)
2661 return (flag_next_runtime
2662 ? TREE_PURPOSE (*chain)
2663 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2664 build_int_cst (NULL_TREE, index),
2665 input_location));
2667 index++;
2668 chain = &TREE_CHAIN (*chain);
2671 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2673 *chain = tree_cons (expr, ident, NULL_TREE);
2675 return (flag_next_runtime
2676 ? expr
2677 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2678 build_int_cst (NULL_TREE, index),
2679 input_location));
2682 static GTY(()) int class_reference_idx;
2684 static tree
2685 build_class_reference_decl (void)
2687 tree decl;
2688 char buf[256];
2690 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2691 decl = start_var_decl (objc_class_type, buf);
2693 return decl;
2696 /* Create a class reference, but don't create a variable to reference
2697 it. */
2699 static void
2700 add_class_reference (tree ident)
2702 tree chain;
2704 if ((chain = cls_ref_chain))
2706 tree tail;
2709 if (ident == TREE_VALUE (chain))
2710 return;
2712 tail = chain;
2713 chain = TREE_CHAIN (chain);
2715 while (chain);
2717 /* Append to the end of the list */
2718 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2720 else
2721 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2724 /* Get a class reference, creating it if necessary. Also create the
2725 reference variable. */
2727 tree
2728 objc_get_class_reference (tree ident)
2730 tree orig_ident = (DECL_P (ident)
2731 ? DECL_NAME (ident)
2732 : TYPE_P (ident)
2733 ? OBJC_TYPE_NAME (ident)
2734 : ident);
2735 bool local_scope = false;
2737 #ifdef OBJCPLUS
2738 if (processing_template_decl)
2739 /* Must wait until template instantiation time. */
2740 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2741 #endif
2743 if (TREE_CODE (ident) == TYPE_DECL)
2744 ident = (DECL_ORIGINAL_TYPE (ident)
2745 ? DECL_ORIGINAL_TYPE (ident)
2746 : TREE_TYPE (ident));
2748 #ifdef OBJCPLUS
2749 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2750 && TYPE_CONTEXT (ident) != global_namespace)
2751 local_scope = true;
2752 #endif
2754 if (local_scope || !(ident = objc_is_class_name (ident)))
2756 error ("%qs is not an Objective-C class name or alias",
2757 IDENTIFIER_POINTER (orig_ident));
2758 return error_mark_node;
2761 if (flag_next_runtime && !flag_zero_link)
2763 tree *chain;
2764 tree decl;
2766 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2767 if (TREE_VALUE (*chain) == ident)
2769 if (! TREE_PURPOSE (*chain))
2770 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2772 return TREE_PURPOSE (*chain);
2775 decl = build_class_reference_decl ();
2776 *chain = tree_cons (decl, ident, NULL_TREE);
2777 return decl;
2779 else
2781 tree params;
2783 add_class_reference (ident);
2785 params = build_tree_list (NULL_TREE,
2786 my_build_string_pointer
2787 (IDENTIFIER_LENGTH (ident) + 1,
2788 IDENTIFIER_POINTER (ident)));
2790 assemble_external (objc_get_class_decl);
2791 return build_function_call (objc_get_class_decl, params);
2795 /* For each string section we have a chain which maps identifier nodes
2796 to decls for the strings. */
2798 static tree
2799 add_objc_string (tree ident, enum string_section section)
2801 tree *chain, decl, type, string_expr;
2803 if (section == class_names)
2804 chain = &class_names_chain;
2805 else if (section == meth_var_names)
2806 chain = &meth_var_names_chain;
2807 else if (section == meth_var_types)
2808 chain = &meth_var_types_chain;
2809 else
2810 abort ();
2812 while (*chain)
2814 if (TREE_VALUE (*chain) == ident)
2815 return convert (string_type_node,
2816 build_unary_op (input_location,
2817 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2819 chain = &TREE_CHAIN (*chain);
2822 decl = build_objc_string_decl (section);
2824 type = build_array_type
2825 (char_type_node,
2826 build_index_type
2827 (build_int_cst (NULL_TREE,
2828 IDENTIFIER_LENGTH (ident))));
2829 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2830 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2831 IDENTIFIER_POINTER (ident));
2832 finish_var_decl (decl, string_expr);
2834 *chain = tree_cons (decl, ident, NULL_TREE);
2836 return convert (string_type_node, build_unary_op (input_location,
2837 ADDR_EXPR, decl, 1));
2840 static GTY(()) int class_names_idx;
2841 static GTY(()) int meth_var_names_idx;
2842 static GTY(()) int meth_var_types_idx;
2844 static tree
2845 build_objc_string_decl (enum string_section section)
2847 tree decl, ident;
2848 char buf[256];
2850 if (section == class_names)
2851 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2852 else if (section == meth_var_names)
2853 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2854 else if (section == meth_var_types)
2855 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2857 ident = get_identifier (buf);
2859 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2860 DECL_EXTERNAL (decl) = 1;
2861 TREE_PUBLIC (decl) = 0;
2862 TREE_USED (decl) = 1;
2863 TREE_CONSTANT (decl) = 1;
2864 DECL_CONTEXT (decl) = 0;
2865 DECL_ARTIFICIAL (decl) = 1;
2866 #ifdef OBJCPLUS
2867 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2868 #endif
2870 make_decl_rtl (decl);
2871 pushdecl_top_level (decl);
2873 return decl;
2877 void
2878 objc_declare_alias (tree alias_ident, tree class_ident)
2880 tree underlying_class;
2882 #ifdef OBJCPLUS
2883 if (current_namespace != global_namespace) {
2884 error ("Objective-C declarations may only appear in global scope");
2886 #endif /* OBJCPLUS */
2888 if (!(underlying_class = objc_is_class_name (class_ident)))
2889 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2890 else if (objc_is_class_name (alias_ident))
2891 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2892 else
2894 /* Implement @compatibility_alias as a typedef. */
2895 #ifdef OBJCPLUS
2896 push_lang_context (lang_name_c); /* extern "C" */
2897 #endif
2898 lang_hooks.decls.pushdecl (build_decl
2899 (TYPE_DECL,
2900 alias_ident,
2901 xref_tag (RECORD_TYPE, underlying_class)));
2902 #ifdef OBJCPLUS
2903 pop_lang_context ();
2904 #endif
2905 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2909 void
2910 objc_declare_class (tree ident_list)
2912 tree list;
2913 #ifdef OBJCPLUS
2914 if (current_namespace != global_namespace) {
2915 error ("Objective-C declarations may only appear in global scope");
2917 #endif /* OBJCPLUS */
2919 for (list = ident_list; list; list = TREE_CHAIN (list))
2921 tree ident = TREE_VALUE (list);
2923 if (! objc_is_class_name (ident))
2925 tree record = lookup_name (ident), type = record;
2927 if (record)
2929 if (TREE_CODE (record) == TYPE_DECL)
2930 type = DECL_ORIGINAL_TYPE (record);
2932 if (!TYPE_HAS_OBJC_INFO (type)
2933 || !TYPE_OBJC_INTERFACE (type))
2935 error ("%qs redeclared as different kind of symbol",
2936 IDENTIFIER_POINTER (ident));
2937 error ("previous declaration of %q+D",
2938 record);
2942 record = xref_tag (RECORD_TYPE, ident);
2943 INIT_TYPE_OBJC_INFO (record);
2944 TYPE_OBJC_INTERFACE (record) = ident;
2945 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2950 tree
2951 objc_is_class_name (tree ident)
2953 tree chain;
2955 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2956 && identifier_global_value (ident))
2957 ident = identifier_global_value (ident);
2958 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2959 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2961 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2962 ident = OBJC_TYPE_NAME (ident);
2963 #ifdef OBJCPLUS
2964 if (ident && TREE_CODE (ident) == TYPE_DECL)
2965 ident = DECL_NAME (ident);
2966 #endif
2967 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2968 return NULL_TREE;
2970 if (lookup_interface (ident))
2971 return ident;
2973 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2975 if (ident == TREE_VALUE (chain))
2976 return ident;
2979 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2981 if (ident == TREE_VALUE (chain))
2982 return TREE_PURPOSE (chain);
2985 return 0;
2988 /* Check whether TYPE is either 'id' or 'Class'. */
2990 tree
2991 objc_is_id (tree type)
2993 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2994 && identifier_global_value (type))
2995 type = identifier_global_value (type);
2997 if (type && TREE_CODE (type) == TYPE_DECL)
2998 type = TREE_TYPE (type);
3000 /* NB: This function may be called before the ObjC front-end has
3001 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3002 return (objc_object_type && type
3003 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3004 ? type
3005 : NULL_TREE);
3008 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3009 class instance. This is needed by other parts of the compiler to
3010 handle ObjC types gracefully. */
3012 tree
3013 objc_is_object_ptr (tree type)
3015 tree ret;
3017 type = TYPE_MAIN_VARIANT (type);
3018 if (!POINTER_TYPE_P (type))
3019 return 0;
3021 ret = objc_is_id (type);
3022 if (!ret)
3023 ret = objc_is_class_name (TREE_TYPE (type));
3025 return ret;
3028 static int
3029 objc_is_gcable_type (tree type, int or_strong_p)
3031 tree name;
3033 if (!TYPE_P (type))
3034 return 0;
3035 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3036 return 1;
3037 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3038 return 1;
3039 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3040 return 0;
3041 type = TREE_TYPE (type);
3042 if (TREE_CODE (type) != RECORD_TYPE)
3043 return 0;
3044 name = TYPE_NAME (type);
3045 return (objc_is_class_name (name) != NULL_TREE);
3048 static tree
3049 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3051 if (expr == oldexpr)
3052 return newexpr;
3054 switch (TREE_CODE (expr))
3056 case COMPONENT_REF:
3057 return objc_build_component_ref
3058 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3059 oldexpr,
3060 newexpr),
3061 DECL_NAME (TREE_OPERAND (expr, 1)));
3062 case ARRAY_REF:
3063 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3064 oldexpr,
3065 newexpr),
3066 TREE_OPERAND (expr, 1),
3067 input_location);
3068 case INDIRECT_REF:
3069 return build_indirect_ref (input_location,
3070 objc_substitute_decl (TREE_OPERAND (expr, 0),
3071 oldexpr,
3072 newexpr), "->");
3073 default:
3074 return expr;
3078 static tree
3079 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3081 tree func_params;
3082 /* The LHS parameter contains the expression 'outervar->memberspec';
3083 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3084 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3086 tree offs
3087 = objc_substitute_decl
3088 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3089 tree func
3090 = (flag_objc_direct_dispatch
3091 ? objc_assign_ivar_fast_decl
3092 : objc_assign_ivar_decl);
3094 offs = convert (integer_type_node, build_unary_op (input_location,
3095 ADDR_EXPR, offs, 0));
3096 offs = fold (offs);
3097 func_params = tree_cons (NULL_TREE,
3098 convert (objc_object_type, rhs),
3099 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3100 tree_cons (NULL_TREE, offs,
3101 NULL_TREE)));
3103 assemble_external (func);
3104 return build_function_call (func, func_params);
3107 static tree
3108 objc_build_global_assignment (tree lhs, tree rhs)
3110 tree func_params = tree_cons (NULL_TREE,
3111 convert (objc_object_type, rhs),
3112 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3113 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3114 NULL_TREE));
3116 assemble_external (objc_assign_global_decl);
3117 return build_function_call (objc_assign_global_decl, func_params);
3120 static tree
3121 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3123 tree func_params = tree_cons (NULL_TREE,
3124 convert (objc_object_type, rhs),
3125 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3126 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3127 NULL_TREE));
3129 assemble_external (objc_assign_strong_cast_decl);
3130 return build_function_call (objc_assign_strong_cast_decl, func_params);
3133 static int
3134 objc_is_gcable_p (tree expr)
3136 return (TREE_CODE (expr) == COMPONENT_REF
3137 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3138 : TREE_CODE (expr) == ARRAY_REF
3139 ? (objc_is_gcable_p (TREE_TYPE (expr))
3140 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3141 : TREE_CODE (expr) == ARRAY_TYPE
3142 ? objc_is_gcable_p (TREE_TYPE (expr))
3143 : TYPE_P (expr)
3144 ? objc_is_gcable_type (expr, 1)
3145 : (objc_is_gcable_p (TREE_TYPE (expr))
3146 || (DECL_P (expr)
3147 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3150 static int
3151 objc_is_ivar_reference_p (tree expr)
3153 return (TREE_CODE (expr) == ARRAY_REF
3154 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3155 : TREE_CODE (expr) == COMPONENT_REF
3156 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3157 : 0);
3160 static int
3161 objc_is_global_reference_p (tree expr)
3163 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3164 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3165 : DECL_P (expr)
3166 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3167 : 0);
3170 tree
3171 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3173 tree result = NULL_TREE, outer;
3174 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3176 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3177 will have been transformed to the form '*(type *)&expr'. */
3178 if (TREE_CODE (lhs) == INDIRECT_REF)
3180 outer = TREE_OPERAND (lhs, 0);
3182 while (!strong_cast_p
3183 && (CONVERT_EXPR_P (outer)
3184 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3186 tree lhstype = TREE_TYPE (outer);
3188 /* Descend down the cast chain, and record the first objc_gc
3189 attribute found. */
3190 if (POINTER_TYPE_P (lhstype))
3192 tree attr
3193 = lookup_attribute ("objc_gc",
3194 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3196 if (attr)
3197 strong_cast_p = 1;
3200 outer = TREE_OPERAND (outer, 0);
3204 /* If we have a __strong cast, it trumps all else. */
3205 if (strong_cast_p)
3207 if (modifycode != NOP_EXPR)
3208 goto invalid_pointer_arithmetic;
3210 if (warn_assign_intercept)
3211 warning (0, "strong-cast assignment has been intercepted");
3213 result = objc_build_strong_cast_assignment (lhs, rhs);
3215 goto exit_point;
3218 /* the lhs must be of a suitable type, regardless of its underlying
3219 structure. */
3220 if (!objc_is_gcable_p (lhs))
3221 goto exit_point;
3223 outer = lhs;
3225 while (outer
3226 && (TREE_CODE (outer) == COMPONENT_REF
3227 || TREE_CODE (outer) == ARRAY_REF))
3228 outer = TREE_OPERAND (outer, 0);
3230 if (TREE_CODE (outer) == INDIRECT_REF)
3232 outer = TREE_OPERAND (outer, 0);
3233 indirect_p = 1;
3236 outer_gc_p = objc_is_gcable_p (outer);
3238 /* Handle ivar assignments. */
3239 if (objc_is_ivar_reference_p (lhs))
3241 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3242 doesn't cut it here), the best we can do here is suggest a cast. */
3243 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3245 /* We may still be able to use the global write barrier... */
3246 if (!indirect_p && objc_is_global_reference_p (outer))
3247 goto global_reference;
3249 suggest_cast:
3250 if (modifycode == NOP_EXPR)
3252 if (warn_assign_intercept)
3253 warning (0, "strong-cast may possibly be needed");
3256 goto exit_point;
3259 if (modifycode != NOP_EXPR)
3260 goto invalid_pointer_arithmetic;
3262 if (warn_assign_intercept)
3263 warning (0, "instance variable assignment has been intercepted");
3265 result = objc_build_ivar_assignment (outer, lhs, rhs);
3267 goto exit_point;
3270 /* Likewise, intercept assignment to global/static variables if their type is
3271 GC-marked. */
3272 if (objc_is_global_reference_p (outer))
3274 if (indirect_p)
3275 goto suggest_cast;
3277 global_reference:
3278 if (modifycode != NOP_EXPR)
3280 invalid_pointer_arithmetic:
3281 if (outer_gc_p)
3282 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3284 goto exit_point;
3287 if (warn_assign_intercept)
3288 warning (0, "global/static variable assignment has been intercepted");
3290 result = objc_build_global_assignment (lhs, rhs);
3293 /* In all other cases, fall back to the normal mechanism. */
3294 exit_point:
3295 return result;
3298 struct GTY(()) interface_tuple {
3299 tree id;
3300 tree class_name;
3303 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3305 static hashval_t
3306 hash_interface (const void *p)
3308 const struct interface_tuple *d = (const struct interface_tuple *) p;
3309 return IDENTIFIER_HASH_VALUE (d->id);
3312 static int
3313 eq_interface (const void *p1, const void *p2)
3315 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3316 return d->id == p2;
3319 static tree
3320 lookup_interface (tree ident)
3322 #ifdef OBJCPLUS
3323 if (ident && TREE_CODE (ident) == TYPE_DECL)
3324 ident = DECL_NAME (ident);
3325 #endif
3327 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3328 return NULL_TREE;
3331 struct interface_tuple **slot;
3332 tree i = NULL_TREE;
3334 if (interface_htab)
3336 slot = (struct interface_tuple **)
3337 htab_find_slot_with_hash (interface_htab, ident,
3338 IDENTIFIER_HASH_VALUE (ident),
3339 NO_INSERT);
3340 if (slot && *slot)
3341 i = (*slot)->class_name;
3343 return i;
3347 /* Implement @defs (<classname>) within struct bodies. */
3349 tree
3350 objc_get_class_ivars (tree class_name)
3352 tree interface = lookup_interface (class_name);
3354 if (interface)
3355 return get_class_ivars (interface, true);
3357 error ("cannot find interface declaration for %qs",
3358 IDENTIFIER_POINTER (class_name));
3360 return error_mark_node;
3363 /* Used by: build_private_template, continue_class,
3364 and for @defs constructs. */
3366 static tree
3367 get_class_ivars (tree interface, bool inherited)
3369 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3371 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3372 by the current class (i.e., they do not include super-class ivars).
3373 However, the CLASS_IVARS list will be side-effected by a call to
3374 finish_struct(), which will fill in field offsets. */
3375 if (!CLASS_IVARS (interface))
3376 CLASS_IVARS (interface) = ivar_chain;
3378 if (!inherited)
3379 return ivar_chain;
3381 while (CLASS_SUPER_NAME (interface))
3383 /* Prepend super-class ivars. */
3384 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3385 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3386 ivar_chain);
3389 return ivar_chain;
3392 static tree
3393 objc_create_temporary_var (tree type)
3395 tree decl;
3397 decl = build_decl (VAR_DECL, NULL_TREE, type);
3398 TREE_USED (decl) = 1;
3399 DECL_ARTIFICIAL (decl) = 1;
3400 DECL_IGNORED_P (decl) = 1;
3401 DECL_CONTEXT (decl) = current_function_decl;
3403 return decl;
3406 /* Exception handling constructs. We begin by having the parser do most
3407 of the work and passing us blocks. What we do next depends on whether
3408 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3409 We abstract all of this in a handful of appropriately named routines. */
3411 /* Stack of open try blocks. */
3413 struct objc_try_context
3415 struct objc_try_context *outer;
3417 /* Statements (or statement lists) as processed by the parser. */
3418 tree try_body;
3419 tree finally_body;
3421 /* Some file position locations. */
3422 location_t try_locus;
3423 location_t end_try_locus;
3424 location_t end_catch_locus;
3425 location_t finally_locus;
3426 location_t end_finally_locus;
3428 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3429 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3430 tree catch_list;
3432 /* The CATCH_EXPR of an open @catch clause. */
3433 tree current_catch;
3435 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3436 tree caught_decl;
3437 tree stack_decl;
3438 tree rethrow_decl;
3441 static struct objc_try_context *cur_try_context;
3443 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3444 that represents TYPE. For Objective-C, this is just the class name. */
3445 /* ??? Isn't there a class object or some such? Is it easy to get? */
3447 #ifndef OBJCPLUS
3448 static tree
3449 objc_eh_runtime_type (tree type)
3451 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3453 #endif
3455 /* Initialize exception handling. */
3457 static void
3458 objc_init_exceptions (void)
3460 static bool done = false;
3461 if (done)
3462 return;
3463 done = true;
3465 if (flag_objc_sjlj_exceptions)
3467 /* On Darwin, ObjC exceptions require a sufficiently recent
3468 version of the runtime, so the user must ask for them explicitly. */
3469 if (!flag_objc_exceptions)
3470 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3471 "exception syntax");
3473 #ifndef OBJCPLUS
3474 else
3476 c_eh_initialized_p = true;
3477 eh_personality_libfunc
3478 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3479 ? "__gnu_objc_personality_sj0"
3480 : "__gnu_objc_personality_v0");
3481 default_init_unwind_resume_libfunc ();
3482 using_eh_for_cleanups ();
3483 lang_eh_runtime_type = objc_eh_runtime_type;
3485 #endif
3488 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3489 we'll arrange for it to be initialized (and associated with a binding)
3490 later. */
3492 static tree
3493 objc_build_exc_ptr (void)
3495 if (flag_objc_sjlj_exceptions)
3497 tree var = cur_try_context->caught_decl;
3498 if (!var)
3500 var = objc_create_temporary_var (objc_object_type);
3501 cur_try_context->caught_decl = var;
3503 return var;
3505 else
3506 return build0 (EXC_PTR_EXPR, objc_object_type);
3509 /* Build "objc_exception_try_exit(&_stack)". */
3511 static tree
3512 next_sjlj_build_try_exit (void)
3514 tree t;
3515 t = build_fold_addr_expr (cur_try_context->stack_decl);
3516 t = tree_cons (NULL, t, NULL);
3517 t = build_function_call (objc_exception_try_exit_decl, t);
3518 return t;
3521 /* Build
3522 objc_exception_try_enter (&_stack);
3523 if (_setjmp(&_stack.buf))
3525 else
3527 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3528 empty, ready for the caller to fill them in. */
3530 static tree
3531 next_sjlj_build_enter_and_setjmp (void)
3533 tree t, enter, sj, cond;
3535 t = build_fold_addr_expr (cur_try_context->stack_decl);
3536 t = tree_cons (NULL, t, NULL);
3537 enter = build_function_call (objc_exception_try_enter_decl, t);
3539 t = objc_build_component_ref (cur_try_context->stack_decl,
3540 get_identifier ("buf"));
3541 t = build_fold_addr_expr (t);
3542 #ifdef OBJCPLUS
3543 /* Convert _setjmp argument to type that is expected. */
3544 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3545 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3546 else
3547 t = convert (ptr_type_node, t);
3548 #else
3549 t = convert (ptr_type_node, t);
3550 #endif
3551 t = tree_cons (NULL, t, NULL);
3552 sj = build_function_call (objc_setjmp_decl, t);
3554 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3555 cond = c_common_truthvalue_conversion (input_location, cond);
3557 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3560 /* Build:
3562 DECL = objc_exception_extract(&_stack); */
3564 static tree
3565 next_sjlj_build_exc_extract (tree decl)
3567 tree t;
3569 t = build_fold_addr_expr (cur_try_context->stack_decl);
3570 t = tree_cons (NULL, t, NULL);
3571 t = build_function_call (objc_exception_extract_decl, t);
3572 t = convert (TREE_TYPE (decl), t);
3573 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3575 return t;
3578 /* Build
3579 if (objc_exception_match(obj_get_class(TYPE), _caught)
3580 BODY
3581 else if (...)
3583 else
3585 _rethrow = _caught;
3586 objc_exception_try_exit(&_stack);
3588 from the sequence of CATCH_EXPRs in the current try context. */
3590 static tree
3591 next_sjlj_build_catch_list (void)
3593 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3594 tree catch_seq, t;
3595 tree *last = &catch_seq;
3596 bool saw_id = false;
3598 for (; !tsi_end_p (i); tsi_next (&i))
3600 tree stmt = tsi_stmt (i);
3601 tree type = CATCH_TYPES (stmt);
3602 tree body = CATCH_BODY (stmt);
3604 if (type == NULL)
3606 *last = body;
3607 saw_id = true;
3608 break;
3610 else
3612 tree args, cond;
3614 if (type == error_mark_node)
3615 cond = error_mark_node;
3616 else
3618 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3619 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3620 args = tree_cons (NULL, t, args);
3621 t = build_function_call (objc_exception_match_decl, args);
3622 cond = c_common_truthvalue_conversion (input_location, t);
3624 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3625 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3627 *last = t;
3628 last = &COND_EXPR_ELSE (t);
3632 if (!saw_id)
3634 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3635 cur_try_context->caught_decl);
3636 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3637 append_to_statement_list (t, last);
3639 t = next_sjlj_build_try_exit ();
3640 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3641 append_to_statement_list (t, last);
3644 return catch_seq;
3647 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3648 exception handling. We aim to build:
3651 struct _objc_exception_data _stack;
3652 id _rethrow = 0;
3655 objc_exception_try_enter (&_stack);
3656 if (_setjmp(&_stack.buf))
3658 id _caught = objc_exception_extract(&_stack);
3659 objc_exception_try_enter (&_stack);
3660 if (_setjmp(&_stack.buf))
3661 _rethrow = objc_exception_extract(&_stack);
3662 else
3663 CATCH-LIST
3665 else
3666 TRY-BLOCK
3668 finally
3670 if (!_rethrow)
3671 objc_exception_try_exit(&_stack);
3672 FINALLY-BLOCK
3673 if (_rethrow)
3674 objc_exception_throw(_rethrow);
3678 If CATCH-LIST is empty, we can omit all of the block containing
3679 "_caught" except for the setting of _rethrow. Note the use of
3680 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3681 but handles goto and other exits from the block. */
3683 static tree
3684 next_sjlj_build_try_catch_finally (void)
3686 tree rethrow_decl, stack_decl, t;
3687 tree catch_seq, try_fin, bind;
3689 /* Create the declarations involved. */
3690 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3691 stack_decl = objc_create_temporary_var (t);
3692 cur_try_context->stack_decl = stack_decl;
3694 rethrow_decl = objc_create_temporary_var (objc_object_type);
3695 cur_try_context->rethrow_decl = rethrow_decl;
3696 TREE_CHAIN (rethrow_decl) = stack_decl;
3698 /* Build the outermost variable binding level. */
3699 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3700 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3701 TREE_SIDE_EFFECTS (bind) = 1;
3703 /* Initialize rethrow_decl. */
3704 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3705 convert (objc_object_type, null_pointer_node));
3706 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3707 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3709 /* Build the outermost TRY_FINALLY_EXPR. */
3710 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3711 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3712 TREE_SIDE_EFFECTS (try_fin) = 1;
3713 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3715 /* Create the complete catch sequence. */
3716 if (cur_try_context->catch_list)
3718 tree caught_decl = objc_build_exc_ptr ();
3719 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3720 TREE_SIDE_EFFECTS (catch_seq) = 1;
3722 t = next_sjlj_build_exc_extract (caught_decl);
3723 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3725 t = next_sjlj_build_enter_and_setjmp ();
3726 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3727 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3728 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3730 else
3731 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3732 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3734 /* Build the main register-and-try if statement. */
3735 t = next_sjlj_build_enter_and_setjmp ();
3736 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3737 COND_EXPR_THEN (t) = catch_seq;
3738 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3739 TREE_OPERAND (try_fin, 0) = t;
3741 /* Build the complete FINALLY statement list. */
3742 t = next_sjlj_build_try_exit ();
3743 t = build_stmt (COND_EXPR,
3744 c_common_truthvalue_conversion
3745 (input_location, rethrow_decl),
3746 NULL, t);
3747 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3748 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3750 append_to_statement_list (cur_try_context->finally_body,
3751 &TREE_OPERAND (try_fin, 1));
3753 t = tree_cons (NULL, rethrow_decl, NULL);
3754 t = build_function_call (objc_exception_throw_decl, t);
3755 t = build_stmt (COND_EXPR,
3756 c_common_truthvalue_conversion (input_location,
3757 rethrow_decl),
3758 t, NULL);
3759 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3760 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3762 return bind;
3765 /* Called just after parsing the @try and its associated BODY. We now
3766 must prepare for the tricky bits -- handling the catches and finally. */
3768 void
3769 objc_begin_try_stmt (location_t try_locus, tree body)
3771 struct objc_try_context *c = XCNEW (struct objc_try_context);
3772 c->outer = cur_try_context;
3773 c->try_body = body;
3774 c->try_locus = try_locus;
3775 c->end_try_locus = input_location;
3776 cur_try_context = c;
3778 objc_init_exceptions ();
3780 if (flag_objc_sjlj_exceptions)
3781 objc_mark_locals_volatile (NULL);
3784 /* Called just after parsing "@catch (parm)". Open a binding level,
3785 enter DECL into the binding level, and initialize it. Leave the
3786 binding level open while the body of the compound statement is parsed. */
3788 void
3789 objc_begin_catch_clause (tree decl)
3791 tree compound, type, t;
3793 /* Begin a new scope that the entire catch clause will live in. */
3794 compound = c_begin_compound_stmt (true);
3796 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3797 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3798 lang_hooks.decls.pushdecl (decl);
3800 /* Since a decl is required here by syntax, don't warn if its unused. */
3801 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3802 be what the previous objc implementation did. */
3803 TREE_USED (decl) = 1;
3805 /* Verify that the type of the catch is valid. It must be a pointer
3806 to an Objective-C class, or "id" (which is catch-all). */
3807 type = TREE_TYPE (decl);
3809 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3810 type = NULL;
3811 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3813 error ("@catch parameter is not a known Objective-C class type");
3814 type = error_mark_node;
3816 else if (cur_try_context->catch_list)
3818 /* Examine previous @catch clauses and see if we've already
3819 caught the type in question. */
3820 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3821 for (; !tsi_end_p (i); tsi_next (&i))
3823 tree stmt = tsi_stmt (i);
3824 t = CATCH_TYPES (stmt);
3825 if (t == error_mark_node)
3826 continue;
3827 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3829 warning (0, "exception of type %<%T%> will be caught",
3830 TREE_TYPE (type));
3831 warning (0, "%H by earlier handler for %<%T%>",
3832 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3833 break;
3838 /* Record the data for the catch in the try context so that we can
3839 finalize it later. */
3840 t = build_stmt (CATCH_EXPR, type, compound);
3841 cur_try_context->current_catch = t;
3843 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3844 t = objc_build_exc_ptr ();
3845 t = convert (TREE_TYPE (decl), t);
3846 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3847 add_stmt (t);
3850 /* Called just after parsing the closing brace of a @catch clause. Close
3851 the open binding level, and record a CATCH_EXPR for it. */
3853 void
3854 objc_finish_catch_clause (void)
3856 tree c = cur_try_context->current_catch;
3857 cur_try_context->current_catch = NULL;
3858 cur_try_context->end_catch_locus = input_location;
3860 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3861 append_to_statement_list (c, &cur_try_context->catch_list);
3864 /* Called after parsing a @finally clause and its associated BODY.
3865 Record the body for later placement. */
3867 void
3868 objc_build_finally_clause (location_t finally_locus, tree body)
3870 cur_try_context->finally_body = body;
3871 cur_try_context->finally_locus = finally_locus;
3872 cur_try_context->end_finally_locus = input_location;
3875 /* Called to finalize a @try construct. */
3877 tree
3878 objc_finish_try_stmt (void)
3880 struct objc_try_context *c = cur_try_context;
3881 tree stmt;
3883 if (c->catch_list == NULL && c->finally_body == NULL)
3884 error ("%<@try%> without %<@catch%> or %<@finally%>");
3886 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3887 if (flag_objc_sjlj_exceptions)
3889 bool save = in_late_binary_op;
3890 in_late_binary_op = true;
3891 if (!cur_try_context->finally_body)
3893 cur_try_context->finally_locus = input_location;
3894 cur_try_context->end_finally_locus = input_location;
3896 stmt = next_sjlj_build_try_catch_finally ();
3897 in_late_binary_op = save;
3899 else
3901 /* Otherwise, nest the CATCH inside a FINALLY. */
3902 stmt = c->try_body;
3903 if (c->catch_list)
3905 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3906 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3908 if (c->finally_body)
3910 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3911 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3914 add_stmt (stmt);
3916 cur_try_context = c->outer;
3917 free (c);
3918 return stmt;
3921 tree
3922 objc_build_throw_stmt (tree throw_expr)
3924 tree args;
3926 objc_init_exceptions ();
3928 if (throw_expr == NULL)
3930 /* If we're not inside a @catch block, there is no "current
3931 exception" to be rethrown. */
3932 if (cur_try_context == NULL
3933 || cur_try_context->current_catch == NULL)
3935 error ("%<@throw%> (rethrow) used outside of a @catch block");
3936 return NULL_TREE;
3939 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3940 value that we get from the runtime. */
3941 throw_expr = objc_build_exc_ptr ();
3944 /* A throw is just a call to the runtime throw function with the
3945 object as a parameter. */
3946 args = tree_cons (NULL, throw_expr, NULL);
3947 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3950 tree
3951 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3953 tree args, call;
3955 /* First lock the mutex. */
3956 mutex = save_expr (mutex);
3957 args = tree_cons (NULL, mutex, NULL);
3958 call = build_function_call (objc_sync_enter_decl, args);
3959 SET_EXPR_LOCATION (call, start_locus);
3960 add_stmt (call);
3962 /* Build the mutex unlock. */
3963 args = tree_cons (NULL, mutex, NULL);
3964 call = build_function_call (objc_sync_exit_decl, args);
3965 SET_EXPR_LOCATION (call, input_location);
3967 /* Put the that and the body in a TRY_FINALLY. */
3968 objc_begin_try_stmt (start_locus, body);
3969 objc_build_finally_clause (input_location, call);
3970 return objc_finish_try_stmt ();
3974 /* Predefine the following data type:
3976 struct _objc_exception_data
3978 int buf[OBJC_JBLEN];
3979 void *pointers[4];
3980 }; */
3982 /* The following yuckiness should prevent users from having to #include
3983 <setjmp.h> in their code... */
3985 /* Define to a harmless positive value so the below code doesn't die. */
3986 #ifndef OBJC_JBLEN
3987 #define OBJC_JBLEN 18
3988 #endif
3990 static void
3991 build_next_objc_exception_stuff (void)
3993 tree field_decl, field_decl_chain, index, temp_type;
3995 objc_exception_data_template
3996 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3998 /* int buf[OBJC_JBLEN]; */
4000 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
4001 field_decl = create_field_decl (build_array_type (integer_type_node, index),
4002 "buf");
4003 field_decl_chain = field_decl;
4005 /* void *pointers[4]; */
4007 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
4008 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
4009 "pointers");
4010 chainon (field_decl_chain, field_decl);
4012 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
4014 /* int _setjmp(...); */
4015 /* If the user includes <setjmp.h>, this shall be superseded by
4016 'int _setjmp(jmp_buf);' */
4017 temp_type = build_function_type (integer_type_node, NULL_TREE);
4018 objc_setjmp_decl
4019 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4021 /* id objc_exception_extract(struct _objc_exception_data *); */
4022 temp_type
4023 = build_function_type (objc_object_type,
4024 tree_cons (NULL_TREE,
4025 build_pointer_type (objc_exception_data_template),
4026 OBJC_VOID_AT_END));
4027 objc_exception_extract_decl
4028 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4029 NULL_TREE);
4030 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4031 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4032 temp_type
4033 = build_function_type (void_type_node,
4034 tree_cons (NULL_TREE,
4035 build_pointer_type (objc_exception_data_template),
4036 OBJC_VOID_AT_END));
4037 objc_exception_try_enter_decl
4038 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4039 NULL_TREE);
4040 objc_exception_try_exit_decl
4041 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4042 NULL_TREE);
4044 /* int objc_exception_match(id, id); */
4045 temp_type
4046 = build_function_type (integer_type_node,
4047 tree_cons (NULL_TREE, objc_object_type,
4048 tree_cons (NULL_TREE, objc_object_type,
4049 OBJC_VOID_AT_END)));
4050 objc_exception_match_decl
4051 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4052 NULL_TREE);
4054 /* id objc_assign_ivar (id, id, unsigned int); */
4055 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4056 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4057 temp_type
4058 = build_function_type (objc_object_type,
4059 tree_cons
4060 (NULL_TREE, objc_object_type,
4061 tree_cons (NULL_TREE, objc_object_type,
4062 tree_cons (NULL_TREE,
4063 unsigned_type_node,
4064 OBJC_VOID_AT_END))));
4065 objc_assign_ivar_decl
4066 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4067 NULL, NULL_TREE);
4068 #ifdef OFFS_ASSIGNIVAR_FAST
4069 objc_assign_ivar_fast_decl
4070 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4071 NOT_BUILT_IN, NULL, NULL_TREE);
4072 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4073 = tree_cons (get_identifier ("hard_coded_address"),
4074 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4075 NULL_TREE);
4076 #else
4077 /* Default to slower ivar method. */
4078 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4079 #endif
4081 /* id objc_assign_global (id, id *); */
4082 /* id objc_assign_strongCast (id, id *); */
4083 temp_type = build_function_type (objc_object_type,
4084 tree_cons (NULL_TREE, objc_object_type,
4085 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4086 OBJC_VOID_AT_END)));
4087 objc_assign_global_decl
4088 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4089 NULL_TREE);
4090 objc_assign_strong_cast_decl
4091 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4092 NULL_TREE);
4095 static void
4096 build_objc_exception_stuff (void)
4098 tree noreturn_list, nothrow_list, temp_type;
4100 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4101 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4103 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4104 /* void objc_sync_enter(id); */
4105 /* void objc_sync_exit(id); */
4106 temp_type = build_function_type (void_type_node,
4107 tree_cons (NULL_TREE, objc_object_type,
4108 OBJC_VOID_AT_END));
4109 objc_exception_throw_decl
4110 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4111 noreturn_list);
4112 objc_sync_enter_decl
4113 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4114 NULL, nothrow_list);
4115 objc_sync_exit_decl
4116 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4117 NULL, nothrow_list);
4120 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4121 name as the class:
4123 struct <classname> {
4124 struct _objc_class *isa;
4126 }; */
4128 static void
4129 build_private_template (tree klass)
4131 if (!CLASS_STATIC_TEMPLATE (klass))
4133 tree record = objc_build_struct (klass,
4134 get_class_ivars (klass, false),
4135 CLASS_SUPER_NAME (klass));
4137 /* Set the TREE_USED bit for this struct, so that stab generator
4138 can emit stabs for this struct type. */
4139 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4140 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4144 /* Begin code generation for protocols... */
4146 /* struct _objc_protocol {
4147 struct _objc_class *isa;
4148 char *protocol_name;
4149 struct _objc_protocol **protocol_list;
4150 struct _objc__method_prototype_list *instance_methods;
4151 struct _objc__method_prototype_list *class_methods;
4152 }; */
4154 static void
4155 build_protocol_template (void)
4157 tree field_decl, field_decl_chain;
4159 objc_protocol_template = start_struct (RECORD_TYPE,
4160 get_identifier (UTAG_PROTOCOL));
4162 /* struct _objc_class *isa; */
4163 field_decl = create_field_decl (build_pointer_type
4164 (xref_tag (RECORD_TYPE,
4165 get_identifier (UTAG_CLASS))),
4166 "isa");
4167 field_decl_chain = field_decl;
4169 /* char *protocol_name; */
4170 field_decl = create_field_decl (string_type_node, "protocol_name");
4171 chainon (field_decl_chain, field_decl);
4173 /* struct _objc_protocol **protocol_list; */
4174 field_decl = create_field_decl (build_pointer_type
4175 (build_pointer_type
4176 (objc_protocol_template)),
4177 "protocol_list");
4178 chainon (field_decl_chain, field_decl);
4180 /* struct _objc__method_prototype_list *instance_methods; */
4181 field_decl = create_field_decl (objc_method_proto_list_ptr,
4182 "instance_methods");
4183 chainon (field_decl_chain, field_decl);
4185 /* struct _objc__method_prototype_list *class_methods; */
4186 field_decl = create_field_decl (objc_method_proto_list_ptr,
4187 "class_methods");
4188 chainon (field_decl_chain, field_decl);
4190 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4193 static tree
4194 build_descriptor_table_initializer (tree type, tree entries)
4196 tree initlist = NULL_TREE;
4200 tree eltlist = NULL_TREE;
4202 eltlist
4203 = tree_cons (NULL_TREE,
4204 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4205 eltlist
4206 = tree_cons (NULL_TREE,
4207 add_objc_string (METHOD_ENCODING (entries),
4208 meth_var_types),
4209 eltlist);
4211 initlist
4212 = tree_cons (NULL_TREE,
4213 objc_build_constructor (type, nreverse (eltlist)),
4214 initlist);
4216 entries = TREE_CHAIN (entries);
4218 while (entries);
4220 return objc_build_constructor (build_array_type (type, 0),
4221 nreverse (initlist));
4224 /* struct objc_method_prototype_list {
4225 int count;
4226 struct objc_method_prototype {
4227 SEL name;
4228 char *types;
4229 } list[1];
4230 }; */
4232 static tree
4233 build_method_prototype_list_template (tree list_type, int size)
4235 tree objc_ivar_list_record;
4236 tree field_decl, field_decl_chain;
4238 /* Generate an unnamed struct definition. */
4240 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4242 /* int method_count; */
4243 field_decl = create_field_decl (integer_type_node, "method_count");
4244 field_decl_chain = field_decl;
4246 /* struct objc_method method_list[]; */
4247 field_decl = create_field_decl (build_array_type
4248 (list_type,
4249 build_index_type
4250 (build_int_cst (NULL_TREE, size - 1))),
4251 "method_list");
4252 chainon (field_decl_chain, field_decl);
4254 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4256 return objc_ivar_list_record;
4259 static tree
4260 build_method_prototype_template (void)
4262 tree proto_record;
4263 tree field_decl, field_decl_chain;
4265 proto_record
4266 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4268 /* SEL _cmd; */
4269 field_decl = create_field_decl (objc_selector_type, "_cmd");
4270 field_decl_chain = field_decl;
4272 /* char *method_types; */
4273 field_decl = create_field_decl (string_type_node, "method_types");
4274 chainon (field_decl_chain, field_decl);
4276 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4278 return proto_record;
4281 static tree
4282 objc_method_parm_type (tree type)
4284 type = TREE_VALUE (TREE_TYPE (type));
4285 if (TREE_CODE (type) == TYPE_DECL)
4286 type = TREE_TYPE (type);
4287 return type;
4290 static int
4291 objc_encoded_type_size (tree type)
4293 int sz = int_size_in_bytes (type);
4295 /* Make all integer and enum types at least as large
4296 as an int. */
4297 if (sz > 0 && INTEGRAL_TYPE_P (type))
4298 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4299 /* Treat arrays as pointers, since that's how they're
4300 passed in. */
4301 else if (TREE_CODE (type) == ARRAY_TYPE)
4302 sz = int_size_in_bytes (ptr_type_node);
4303 return sz;
4306 static tree
4307 encode_method_prototype (tree method_decl)
4309 tree parms;
4310 int parm_offset, i;
4311 char buf[40];
4312 tree result;
4314 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4315 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4317 /* Encode return type. */
4318 encode_type (objc_method_parm_type (method_decl),
4319 obstack_object_size (&util_obstack),
4320 OBJC_ENCODE_INLINE_DEFS);
4322 /* Stack size. */
4323 /* The first two arguments (self and _cmd) are pointers; account for
4324 their size. */
4325 i = int_size_in_bytes (ptr_type_node);
4326 parm_offset = 2 * i;
4327 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4328 parms = TREE_CHAIN (parms))
4330 tree type = objc_method_parm_type (parms);
4331 int sz = objc_encoded_type_size (type);
4333 /* If a type size is not known, bail out. */
4334 if (sz < 0)
4336 error ("type %q+D does not have a known size",
4337 type);
4338 /* Pretend that the encoding succeeded; the compilation will
4339 fail nevertheless. */
4340 goto finish_encoding;
4342 parm_offset += sz;
4345 sprintf (buf, "%d@0:%d", parm_offset, i);
4346 obstack_grow (&util_obstack, buf, strlen (buf));
4348 /* Argument types. */
4349 parm_offset = 2 * i;
4350 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4351 parms = TREE_CHAIN (parms))
4353 tree type = objc_method_parm_type (parms);
4355 /* Process argument qualifiers for user supplied arguments. */
4356 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4358 /* Type. */
4359 encode_type (type, obstack_object_size (&util_obstack),
4360 OBJC_ENCODE_INLINE_DEFS);
4362 /* Compute offset. */
4363 sprintf (buf, "%d", parm_offset);
4364 parm_offset += objc_encoded_type_size (type);
4366 obstack_grow (&util_obstack, buf, strlen (buf));
4369 finish_encoding:
4370 obstack_1grow (&util_obstack, '\0');
4371 result = get_identifier (XOBFINISH (&util_obstack, char *));
4372 obstack_free (&util_obstack, util_firstobj);
4373 return result;
4376 static tree
4377 generate_descriptor_table (tree type, const char *name, int size, tree list,
4378 tree proto)
4380 tree decl, initlist;
4382 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4384 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4385 initlist = tree_cons (NULL_TREE, list, initlist);
4387 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4389 return decl;
4392 static void
4393 generate_method_descriptors (tree protocol)
4395 tree initlist, chain, method_list_template;
4396 int size;
4398 if (!objc_method_prototype_template)
4399 objc_method_prototype_template = build_method_prototype_template ();
4401 chain = PROTOCOL_CLS_METHODS (protocol);
4402 if (chain)
4404 size = list_length (chain);
4406 method_list_template
4407 = build_method_prototype_list_template (objc_method_prototype_template,
4408 size);
4410 initlist
4411 = build_descriptor_table_initializer (objc_method_prototype_template,
4412 chain);
4414 UOBJC_CLASS_METHODS_decl
4415 = generate_descriptor_table (method_list_template,
4416 "_OBJC_PROTOCOL_CLASS_METHODS",
4417 size, initlist, protocol);
4419 else
4420 UOBJC_CLASS_METHODS_decl = 0;
4422 chain = PROTOCOL_NST_METHODS (protocol);
4423 if (chain)
4425 size = list_length (chain);
4427 method_list_template
4428 = build_method_prototype_list_template (objc_method_prototype_template,
4429 size);
4430 initlist
4431 = build_descriptor_table_initializer (objc_method_prototype_template,
4432 chain);
4434 UOBJC_INSTANCE_METHODS_decl
4435 = generate_descriptor_table (method_list_template,
4436 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4437 size, initlist, protocol);
4439 else
4440 UOBJC_INSTANCE_METHODS_decl = 0;
4443 static void
4444 generate_protocol_references (tree plist)
4446 tree lproto;
4448 /* Forward declare protocols referenced. */
4449 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4451 tree proto = TREE_VALUE (lproto);
4453 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4454 && PROTOCOL_NAME (proto))
4456 if (! PROTOCOL_FORWARD_DECL (proto))
4457 build_protocol_reference (proto);
4459 if (PROTOCOL_LIST (proto))
4460 generate_protocol_references (PROTOCOL_LIST (proto));
4465 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4466 current class. */
4467 #ifdef OBJCPLUS
4468 static void
4469 objc_generate_cxx_ctor_or_dtor (bool dtor)
4471 tree fn, body, compound_stmt, ivar;
4473 /* - (id) .cxx_construct { ... return self; } */
4474 /* - (void) .cxx_construct { ... } */
4476 objc_set_method_type (MINUS_EXPR);
4477 objc_start_method_definition
4478 (objc_build_method_signature (build_tree_list (NULL_TREE,
4479 dtor
4480 ? void_type_node
4481 : objc_object_type),
4482 get_identifier (dtor
4483 ? TAG_CXX_DESTRUCT
4484 : TAG_CXX_CONSTRUCT),
4485 make_node (TREE_LIST),
4486 false));
4487 body = begin_function_body ();
4488 compound_stmt = begin_compound_stmt (0);
4490 ivar = CLASS_IVARS (implementation_template);
4491 /* Destroy ivars in reverse order. */
4492 if (dtor)
4493 ivar = nreverse (copy_list (ivar));
4495 for (; ivar; ivar = TREE_CHAIN (ivar))
4497 if (TREE_CODE (ivar) == FIELD_DECL)
4499 tree type = TREE_TYPE (ivar);
4501 /* Call the ivar's default constructor or destructor. Do not
4502 call the destructor unless a corresponding constructor call
4503 has also been made (or is not needed). */
4504 if (MAYBE_CLASS_TYPE_P (type)
4505 && (dtor
4506 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4507 && (!TYPE_NEEDS_CONSTRUCTING (type)
4508 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4509 : (TYPE_NEEDS_CONSTRUCTING (type)
4510 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4511 finish_expr_stmt
4512 (build_special_member_call
4513 (build_ivar_reference (DECL_NAME (ivar)),
4514 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4515 NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
4519 /* The constructor returns 'self'. */
4520 if (!dtor)
4521 finish_return_stmt (self_decl);
4523 finish_compound_stmt (compound_stmt);
4524 finish_function_body (body);
4525 fn = current_function_decl;
4526 finish_function ();
4527 objc_finish_method_definition (fn);
4530 /* The following routine will examine the current @interface for any
4531 non-POD C++ ivars requiring non-trivial construction and/or
4532 destruction, and then synthesize special '- .cxx_construct' and/or
4533 '- .cxx_destruct' methods which will run the appropriate
4534 construction or destruction code. Note that ivars inherited from
4535 super-classes are _not_ considered. */
4536 static void
4537 objc_generate_cxx_cdtors (void)
4539 bool need_ctor = false, need_dtor = false;
4540 tree ivar;
4542 /* We do not want to do this for categories, since they do not have
4543 their own ivars. */
4545 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4546 return;
4548 /* First, determine if we even need a constructor and/or destructor. */
4550 for (ivar = CLASS_IVARS (implementation_template); ivar;
4551 ivar = TREE_CHAIN (ivar))
4553 if (TREE_CODE (ivar) == FIELD_DECL)
4555 tree type = TREE_TYPE (ivar);
4557 if (MAYBE_CLASS_TYPE_P (type))
4559 if (TYPE_NEEDS_CONSTRUCTING (type)
4560 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4561 /* NB: If a default constructor is not available, we will not
4562 be able to initialize this ivar; the add_instance_variable()
4563 routine will already have warned about this. */
4564 need_ctor = true;
4566 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4567 && (!TYPE_NEEDS_CONSTRUCTING (type)
4568 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4569 /* NB: If a default constructor is not available, we will not
4570 call the destructor either, for symmetry. */
4571 need_dtor = true;
4576 /* Generate '- .cxx_construct' if needed. */
4578 if (need_ctor)
4579 objc_generate_cxx_ctor_or_dtor (false);
4581 /* Generate '- .cxx_destruct' if needed. */
4583 if (need_dtor)
4584 objc_generate_cxx_ctor_or_dtor (true);
4586 /* The 'imp_list' variable points at an imp_entry record for the current
4587 @implementation. Record the existence of '- .cxx_construct' and/or
4588 '- .cxx_destruct' methods therein; it will be included in the
4589 metadata for the class. */
4590 if (flag_next_runtime)
4591 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4593 #endif
4595 /* For each protocol which was referenced either from a @protocol()
4596 expression, or because a class/category implements it (then a
4597 pointer to the protocol is stored in the struct describing the
4598 class/category), we create a statically allocated instance of the
4599 Protocol class. The code is written in such a way as to generate
4600 as few Protocol objects as possible; we generate a unique Protocol
4601 instance for each protocol, and we don't generate a Protocol
4602 instance if the protocol is never referenced (either from a
4603 @protocol() or from a class/category implementation). These
4604 statically allocated objects can be referred to via the static
4605 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4607 The statically allocated Protocol objects that we generate here
4608 need to be fixed up at runtime in order to be used: the 'isa'
4609 pointer of the objects need to be set up to point to the 'Protocol'
4610 class, as known at runtime.
4612 The NeXT runtime fixes up all protocols at program startup time,
4613 before main() is entered. It uses a low-level trick to look up all
4614 those symbols, then loops on them and fixes them up.
4616 The GNU runtime as well fixes up all protocols before user code
4617 from the module is executed; it requires pointers to those symbols
4618 to be put in the objc_symtab (which is then passed as argument to
4619 the function __objc_exec_class() which the compiler sets up to be
4620 executed automatically when the module is loaded); setup of those
4621 Protocol objects happen in two ways in the GNU runtime: all
4622 Protocol objects referred to by a class or category implementation
4623 are fixed up when the class/category is loaded; all Protocol
4624 objects referred to by a @protocol() expression are added by the
4625 compiler to the list of statically allocated instances to fixup
4626 (the same list holding the statically allocated constant string
4627 objects). Because, as explained above, the compiler generates as
4628 few Protocol objects as possible, some Protocol object might end up
4629 being referenced multiple times when compiled with the GNU runtime,
4630 and end up being fixed up multiple times at runtime initialization.
4631 But that doesn't hurt, it's just a little inefficient. */
4633 static void
4634 generate_protocols (void)
4636 tree p, encoding;
4637 tree decl;
4638 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4640 /* If a protocol was directly referenced, pull in indirect references. */
4641 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4642 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4643 generate_protocol_references (PROTOCOL_LIST (p));
4645 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4647 tree nst_methods = PROTOCOL_NST_METHODS (p);
4648 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4650 /* If protocol wasn't referenced, don't generate any code. */
4651 decl = PROTOCOL_FORWARD_DECL (p);
4653 if (!decl)
4654 continue;
4656 /* Make sure we link in the Protocol class. */
4657 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4659 while (nst_methods)
4661 if (! METHOD_ENCODING (nst_methods))
4663 encoding = encode_method_prototype (nst_methods);
4664 METHOD_ENCODING (nst_methods) = encoding;
4666 nst_methods = TREE_CHAIN (nst_methods);
4669 while (cls_methods)
4671 if (! METHOD_ENCODING (cls_methods))
4673 encoding = encode_method_prototype (cls_methods);
4674 METHOD_ENCODING (cls_methods) = encoding;
4677 cls_methods = TREE_CHAIN (cls_methods);
4679 generate_method_descriptors (p);
4681 if (PROTOCOL_LIST (p))
4682 refs_decl = generate_protocol_list (p);
4683 else
4684 refs_decl = 0;
4686 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4687 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4689 if (refs_decl)
4690 refs_expr = convert (build_pointer_type (build_pointer_type
4691 (objc_protocol_template)),
4692 build_unary_op (input_location,
4693 ADDR_EXPR, refs_decl, 0));
4694 else
4695 refs_expr = build_int_cst (NULL_TREE, 0);
4697 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4698 by generate_method_descriptors, which is called above. */
4699 initlist = build_protocol_initializer (TREE_TYPE (decl),
4700 protocol_name_expr, refs_expr,
4701 UOBJC_INSTANCE_METHODS_decl,
4702 UOBJC_CLASS_METHODS_decl);
4703 finish_var_decl (decl, initlist);
4707 static tree
4708 build_protocol_initializer (tree type, tree protocol_name,
4709 tree protocol_list, tree instance_methods,
4710 tree class_methods)
4712 tree initlist = NULL_TREE, expr;
4713 tree cast_type = build_pointer_type
4714 (xref_tag (RECORD_TYPE,
4715 get_identifier (UTAG_CLASS)));
4717 /* Filling the "isa" in with one allows the runtime system to
4718 detect that the version change...should remove before final release. */
4720 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4721 initlist = tree_cons (NULL_TREE, expr, initlist);
4722 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4723 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4725 if (!instance_methods)
4726 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4727 else
4729 expr = convert (objc_method_proto_list_ptr,
4730 build_unary_op (input_location,
4731 ADDR_EXPR, instance_methods, 0));
4732 initlist = tree_cons (NULL_TREE, expr, initlist);
4735 if (!class_methods)
4736 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4737 else
4739 expr = convert (objc_method_proto_list_ptr,
4740 build_unary_op (input_location,
4741 ADDR_EXPR, class_methods, 0));
4742 initlist = tree_cons (NULL_TREE, expr, initlist);
4745 return objc_build_constructor (type, nreverse (initlist));
4748 /* struct _objc_category {
4749 char *category_name;
4750 char *class_name;
4751 struct _objc_method_list *instance_methods;
4752 struct _objc_method_list *class_methods;
4753 struct _objc_protocol_list *protocols;
4754 }; */
4756 static void
4757 build_category_template (void)
4759 tree field_decl, field_decl_chain;
4761 objc_category_template = start_struct (RECORD_TYPE,
4762 get_identifier (UTAG_CATEGORY));
4764 /* char *category_name; */
4765 field_decl = create_field_decl (string_type_node, "category_name");
4766 field_decl_chain = field_decl;
4768 /* char *class_name; */
4769 field_decl = create_field_decl (string_type_node, "class_name");
4770 chainon (field_decl_chain, field_decl);
4772 /* struct _objc_method_list *instance_methods; */
4773 field_decl = create_field_decl (objc_method_list_ptr,
4774 "instance_methods");
4775 chainon (field_decl_chain, field_decl);
4777 /* struct _objc_method_list *class_methods; */
4778 field_decl = create_field_decl (objc_method_list_ptr,
4779 "class_methods");
4780 chainon (field_decl_chain, field_decl);
4782 /* struct _objc_protocol **protocol_list; */
4783 field_decl = create_field_decl (build_pointer_type
4784 (build_pointer_type
4785 (objc_protocol_template)),
4786 "protocol_list");
4787 chainon (field_decl_chain, field_decl);
4789 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4792 /* struct _objc_selector {
4793 SEL sel_id;
4794 char *sel_type;
4795 }; */
4797 static void
4798 build_selector_template (void)
4801 tree field_decl, field_decl_chain;
4803 objc_selector_template
4804 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4806 /* SEL sel_id; */
4807 field_decl = create_field_decl (objc_selector_type, "sel_id");
4808 field_decl_chain = field_decl;
4810 /* char *sel_type; */
4811 field_decl = create_field_decl (string_type_node, "sel_type");
4812 chainon (field_decl_chain, field_decl);
4814 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4817 /* struct _objc_class {
4818 struct _objc_class *isa;
4819 struct _objc_class *super_class;
4820 char *name;
4821 long version;
4822 long info;
4823 long instance_size;
4824 struct _objc_ivar_list *ivars;
4825 struct _objc_method_list *methods;
4826 #ifdef __NEXT_RUNTIME__
4827 struct objc_cache *cache;
4828 #else
4829 struct sarray *dtable;
4830 struct _objc_class *subclass_list;
4831 struct _objc_class *sibling_class;
4832 #endif
4833 struct _objc_protocol_list *protocols;
4834 #ifdef __NEXT_RUNTIME__
4835 void *sel_id;
4836 #endif
4837 void *gc_object_type;
4838 }; */
4840 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4841 the NeXT/Apple runtime; still, the compiler must generate them to
4842 maintain backward binary compatibility (and to allow for future
4843 expansion). */
4845 static void
4846 build_class_template (void)
4848 tree field_decl, field_decl_chain;
4850 objc_class_template
4851 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4853 /* struct _objc_class *isa; */
4854 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4855 "isa");
4856 field_decl_chain = field_decl;
4858 /* struct _objc_class *super_class; */
4859 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4860 "super_class");
4861 chainon (field_decl_chain, field_decl);
4863 /* char *name; */
4864 field_decl = create_field_decl (string_type_node, "name");
4865 chainon (field_decl_chain, field_decl);
4867 /* long version; */
4868 field_decl = create_field_decl (long_integer_type_node, "version");
4869 chainon (field_decl_chain, field_decl);
4871 /* long info; */
4872 field_decl = create_field_decl (long_integer_type_node, "info");
4873 chainon (field_decl_chain, field_decl);
4875 /* long instance_size; */
4876 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4877 chainon (field_decl_chain, field_decl);
4879 /* struct _objc_ivar_list *ivars; */
4880 field_decl = create_field_decl (objc_ivar_list_ptr,
4881 "ivars");
4882 chainon (field_decl_chain, field_decl);
4884 /* struct _objc_method_list *methods; */
4885 field_decl = create_field_decl (objc_method_list_ptr,
4886 "methods");
4887 chainon (field_decl_chain, field_decl);
4889 if (flag_next_runtime)
4891 /* struct objc_cache *cache; */
4892 field_decl = create_field_decl (build_pointer_type
4893 (xref_tag (RECORD_TYPE,
4894 get_identifier
4895 ("objc_cache"))),
4896 "cache");
4897 chainon (field_decl_chain, field_decl);
4899 else
4901 /* struct sarray *dtable; */
4902 field_decl = create_field_decl (build_pointer_type
4903 (xref_tag (RECORD_TYPE,
4904 get_identifier
4905 ("sarray"))),
4906 "dtable");
4907 chainon (field_decl_chain, field_decl);
4909 /* struct objc_class *subclass_list; */
4910 field_decl = create_field_decl (build_pointer_type
4911 (objc_class_template),
4912 "subclass_list");
4913 chainon (field_decl_chain, field_decl);
4915 /* struct objc_class *sibling_class; */
4916 field_decl = create_field_decl (build_pointer_type
4917 (objc_class_template),
4918 "sibling_class");
4919 chainon (field_decl_chain, field_decl);
4922 /* struct _objc_protocol **protocol_list; */
4923 field_decl = create_field_decl (build_pointer_type
4924 (build_pointer_type
4925 (xref_tag (RECORD_TYPE,
4926 get_identifier
4927 (UTAG_PROTOCOL)))),
4928 "protocol_list");
4929 chainon (field_decl_chain, field_decl);
4931 if (flag_next_runtime)
4933 /* void *sel_id; */
4934 field_decl = create_field_decl (build_pointer_type (void_type_node),
4935 "sel_id");
4936 chainon (field_decl_chain, field_decl);
4939 /* void *gc_object_type; */
4940 field_decl = create_field_decl (build_pointer_type (void_type_node),
4941 "gc_object_type");
4942 chainon (field_decl_chain, field_decl);
4944 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4947 /* Generate appropriate forward declarations for an implementation. */
4949 static void
4950 synth_forward_declarations (void)
4952 tree an_id;
4954 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4955 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4956 objc_class_template);
4958 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4959 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4960 objc_class_template);
4962 /* Pre-build the following entities - for speed/convenience. */
4964 an_id = get_identifier ("super_class");
4965 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4966 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4969 static void
4970 error_with_ivar (const char *message, tree decl)
4972 error ("%J%s %qs", decl,
4973 message, gen_declaration (decl));
4977 static void
4978 check_ivars (tree inter, tree imp)
4980 tree intdecls = CLASS_RAW_IVARS (inter);
4981 tree impdecls = CLASS_RAW_IVARS (imp);
4983 while (1)
4985 tree t1, t2;
4987 #ifdef OBJCPLUS
4988 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4989 intdecls = TREE_CHAIN (intdecls);
4990 #endif
4991 if (intdecls == 0 && impdecls == 0)
4992 break;
4993 if (intdecls == 0 || impdecls == 0)
4995 error ("inconsistent instance variable specification");
4996 break;
4999 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5001 if (!comptypes (t1, t2)
5002 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5003 DECL_INITIAL (impdecls)))
5005 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5007 error_with_ivar ("conflicting instance variable type",
5008 impdecls);
5009 error_with_ivar ("previous declaration of",
5010 intdecls);
5012 else /* both the type and the name don't match */
5014 error ("inconsistent instance variable specification");
5015 break;
5019 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5021 error_with_ivar ("conflicting instance variable name",
5022 impdecls);
5023 error_with_ivar ("previous declaration of",
5024 intdecls);
5027 intdecls = TREE_CHAIN (intdecls);
5028 impdecls = TREE_CHAIN (impdecls);
5032 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5033 This needs to be done just once per compilation. */
5035 /* struct _objc_super {
5036 struct _objc_object *self;
5037 struct _objc_class *super_class;
5038 }; */
5040 static void
5041 build_super_template (void)
5043 tree field_decl, field_decl_chain;
5045 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5047 /* struct _objc_object *self; */
5048 field_decl = create_field_decl (objc_object_type, "self");
5049 field_decl_chain = field_decl;
5051 /* struct _objc_class *super_class; */
5052 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5053 "super_class");
5054 chainon (field_decl_chain, field_decl);
5056 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5059 /* struct _objc_ivar {
5060 char *ivar_name;
5061 char *ivar_type;
5062 int ivar_offset;
5063 }; */
5065 static tree
5066 build_ivar_template (void)
5068 tree objc_ivar_id, objc_ivar_record;
5069 tree field_decl, field_decl_chain;
5071 objc_ivar_id = get_identifier (UTAG_IVAR);
5072 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5074 /* char *ivar_name; */
5075 field_decl = create_field_decl (string_type_node, "ivar_name");
5076 field_decl_chain = field_decl;
5078 /* char *ivar_type; */
5079 field_decl = create_field_decl (string_type_node, "ivar_type");
5080 chainon (field_decl_chain, field_decl);
5082 /* int ivar_offset; */
5083 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5084 chainon (field_decl_chain, field_decl);
5086 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5088 return objc_ivar_record;
5091 /* struct {
5092 int ivar_count;
5093 struct objc_ivar ivar_list[ivar_count];
5094 }; */
5096 static tree
5097 build_ivar_list_template (tree list_type, int size)
5099 tree objc_ivar_list_record;
5100 tree field_decl, field_decl_chain;
5102 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5104 /* int ivar_count; */
5105 field_decl = create_field_decl (integer_type_node, "ivar_count");
5106 field_decl_chain = field_decl;
5108 /* struct objc_ivar ivar_list[]; */
5109 field_decl = create_field_decl (build_array_type
5110 (list_type,
5111 build_index_type
5112 (build_int_cst (NULL_TREE, size - 1))),
5113 "ivar_list");
5114 chainon (field_decl_chain, field_decl);
5116 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5118 return objc_ivar_list_record;
5121 /* struct {
5122 struct _objc__method_prototype_list *method_next;
5123 int method_count;
5124 struct objc_method method_list[method_count];
5125 }; */
5127 static tree
5128 build_method_list_template (tree list_type, int size)
5130 tree objc_ivar_list_record;
5131 tree field_decl, field_decl_chain;
5133 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5135 /* struct _objc__method_prototype_list *method_next; */
5136 field_decl = create_field_decl (objc_method_proto_list_ptr,
5137 "method_next");
5138 field_decl_chain = field_decl;
5140 /* int method_count; */
5141 field_decl = create_field_decl (integer_type_node, "method_count");
5142 chainon (field_decl_chain, field_decl);
5144 /* struct objc_method method_list[]; */
5145 field_decl = create_field_decl (build_array_type
5146 (list_type,
5147 build_index_type
5148 (build_int_cst (NULL_TREE, size - 1))),
5149 "method_list");
5150 chainon (field_decl_chain, field_decl);
5152 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5154 return objc_ivar_list_record;
5157 static tree
5158 build_ivar_list_initializer (tree type, tree field_decl)
5160 tree initlist = NULL_TREE;
5164 tree ivar = NULL_TREE;
5166 /* Set name. */
5167 if (DECL_NAME (field_decl))
5168 ivar = tree_cons (NULL_TREE,
5169 add_objc_string (DECL_NAME (field_decl),
5170 meth_var_names),
5171 ivar);
5172 else
5173 /* Unnamed bit-field ivar (yuck). */
5174 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5176 /* Set type. */
5177 encode_field_decl (field_decl,
5178 obstack_object_size (&util_obstack),
5179 OBJC_ENCODE_DONT_INLINE_DEFS);
5181 /* Null terminate string. */
5182 obstack_1grow (&util_obstack, 0);
5183 ivar
5184 = tree_cons
5185 (NULL_TREE,
5186 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5187 meth_var_types),
5188 ivar);
5189 obstack_free (&util_obstack, util_firstobj);
5191 /* Set offset. */
5192 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5193 initlist = tree_cons (NULL_TREE,
5194 objc_build_constructor (type, nreverse (ivar)),
5195 initlist);
5197 field_decl = TREE_CHAIN (field_decl);
5198 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5200 while (field_decl);
5202 return objc_build_constructor (build_array_type (type, 0),
5203 nreverse (initlist));
5206 static tree
5207 generate_ivars_list (tree type, const char *name, int size, tree list)
5209 tree decl, initlist;
5211 decl = start_var_decl (type, synth_id_with_class_suffix
5212 (name, objc_implementation_context));
5214 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5215 initlist = tree_cons (NULL_TREE, list, initlist);
5217 finish_var_decl (decl,
5218 objc_build_constructor (TREE_TYPE (decl),
5219 nreverse (initlist)));
5221 return decl;
5224 /* Count only the fields occurring in T. */
5226 static int
5227 ivar_list_length (tree t)
5229 int count = 0;
5231 for (; t; t = TREE_CHAIN (t))
5232 if (TREE_CODE (t) == FIELD_DECL)
5233 ++count;
5235 return count;
5238 static void
5239 generate_ivar_lists (void)
5241 tree initlist, ivar_list_template, chain;
5242 int size;
5244 generating_instance_variables = 1;
5246 if (!objc_ivar_template)
5247 objc_ivar_template = build_ivar_template ();
5249 /* Only generate class variables for the root of the inheritance
5250 hierarchy since these will be the same for every class. */
5252 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5253 && (chain = TYPE_FIELDS (objc_class_template)))
5255 size = ivar_list_length (chain);
5257 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5258 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5260 UOBJC_CLASS_VARIABLES_decl
5261 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5262 size, initlist);
5264 else
5265 UOBJC_CLASS_VARIABLES_decl = 0;
5267 chain = CLASS_IVARS (implementation_template);
5268 if (chain)
5270 size = ivar_list_length (chain);
5271 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5272 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5274 UOBJC_INSTANCE_VARIABLES_decl
5275 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5276 size, initlist);
5278 else
5279 UOBJC_INSTANCE_VARIABLES_decl = 0;
5281 generating_instance_variables = 0;
5284 static tree
5285 build_dispatch_table_initializer (tree type, tree entries)
5287 tree initlist = NULL_TREE;
5291 tree elemlist = NULL_TREE;
5293 elemlist = tree_cons (NULL_TREE,
5294 build_selector (METHOD_SEL_NAME (entries)),
5295 NULL_TREE);
5297 /* Generate the method encoding if we don't have one already. */
5298 if (! METHOD_ENCODING (entries))
5299 METHOD_ENCODING (entries) =
5300 encode_method_prototype (entries);
5302 elemlist = tree_cons (NULL_TREE,
5303 add_objc_string (METHOD_ENCODING (entries),
5304 meth_var_types),
5305 elemlist);
5307 elemlist
5308 = tree_cons (NULL_TREE,
5309 convert (ptr_type_node,
5310 build_unary_op (input_location, ADDR_EXPR,
5311 METHOD_DEFINITION (entries), 1)),
5312 elemlist);
5314 initlist = tree_cons (NULL_TREE,
5315 objc_build_constructor (type, nreverse (elemlist)),
5316 initlist);
5318 entries = TREE_CHAIN (entries);
5320 while (entries);
5322 return objc_build_constructor (build_array_type (type, 0),
5323 nreverse (initlist));
5326 /* To accomplish method prototyping without generating all kinds of
5327 inane warnings, the definition of the dispatch table entries were
5328 changed from:
5330 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5332 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5334 static tree
5335 build_method_template (void)
5337 tree _SLT_record;
5338 tree field_decl, field_decl_chain;
5340 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5342 /* SEL _cmd; */
5343 field_decl = create_field_decl (objc_selector_type, "_cmd");
5344 field_decl_chain = field_decl;
5346 /* char *method_types; */
5347 field_decl = create_field_decl (string_type_node, "method_types");
5348 chainon (field_decl_chain, field_decl);
5350 /* void *_imp; */
5351 field_decl = create_field_decl (build_pointer_type (void_type_node),
5352 "_imp");
5353 chainon (field_decl_chain, field_decl);
5355 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5357 return _SLT_record;
5361 static tree
5362 generate_dispatch_table (tree type, const char *name, int size, tree list)
5364 tree decl, initlist;
5366 decl = start_var_decl (type, synth_id_with_class_suffix
5367 (name, objc_implementation_context));
5369 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5370 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5371 initlist = tree_cons (NULL_TREE, list, initlist);
5373 finish_var_decl (decl,
5374 objc_build_constructor (TREE_TYPE (decl),
5375 nreverse (initlist)));
5377 return decl;
5380 static void
5381 mark_referenced_methods (void)
5383 struct imp_entry *impent;
5384 tree chain;
5386 for (impent = imp_list; impent; impent = impent->next)
5388 chain = CLASS_CLS_METHODS (impent->imp_context);
5389 while (chain)
5391 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5392 chain = TREE_CHAIN (chain);
5395 chain = CLASS_NST_METHODS (impent->imp_context);
5396 while (chain)
5398 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5399 chain = TREE_CHAIN (chain);
5404 static void
5405 generate_dispatch_tables (void)
5407 tree initlist, chain, method_list_template;
5408 int size;
5410 if (!objc_method_template)
5411 objc_method_template = build_method_template ();
5413 chain = CLASS_CLS_METHODS (objc_implementation_context);
5414 if (chain)
5416 size = list_length (chain);
5418 method_list_template
5419 = build_method_list_template (objc_method_template, size);
5420 initlist
5421 = build_dispatch_table_initializer (objc_method_template, chain);
5423 UOBJC_CLASS_METHODS_decl
5424 = generate_dispatch_table (method_list_template,
5425 ((TREE_CODE (objc_implementation_context)
5426 == CLASS_IMPLEMENTATION_TYPE)
5427 ? "_OBJC_CLASS_METHODS"
5428 : "_OBJC_CATEGORY_CLASS_METHODS"),
5429 size, initlist);
5431 else
5432 UOBJC_CLASS_METHODS_decl = 0;
5434 chain = CLASS_NST_METHODS (objc_implementation_context);
5435 if (chain)
5437 size = list_length (chain);
5439 method_list_template
5440 = build_method_list_template (objc_method_template, size);
5441 initlist
5442 = build_dispatch_table_initializer (objc_method_template, chain);
5444 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5445 UOBJC_INSTANCE_METHODS_decl
5446 = generate_dispatch_table (method_list_template,
5447 "_OBJC_INSTANCE_METHODS",
5448 size, initlist);
5449 else
5450 /* We have a category. */
5451 UOBJC_INSTANCE_METHODS_decl
5452 = generate_dispatch_table (method_list_template,
5453 "_OBJC_CATEGORY_INSTANCE_METHODS",
5454 size, initlist);
5456 else
5457 UOBJC_INSTANCE_METHODS_decl = 0;
5460 static tree
5461 generate_protocol_list (tree i_or_p)
5463 tree initlist;
5464 tree refs_decl, lproto, e, plist;
5465 int size = 0;
5466 const char *ref_name;
5468 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5469 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5470 plist = CLASS_PROTOCOL_LIST (i_or_p);
5471 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5472 plist = PROTOCOL_LIST (i_or_p);
5473 else
5474 abort ();
5476 /* Compute size. */
5477 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5478 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5479 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5480 size++;
5482 /* Build initializer. */
5483 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5484 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5485 initlist = tree_cons (NULL_TREE, e, initlist);
5487 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5489 tree pval = TREE_VALUE (lproto);
5491 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5492 && PROTOCOL_FORWARD_DECL (pval))
5494 e = build_unary_op (input_location, ADDR_EXPR,
5495 PROTOCOL_FORWARD_DECL (pval), 0);
5496 initlist = tree_cons (NULL_TREE, e, initlist);
5500 /* static struct objc_protocol *refs[n]; */
5502 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5503 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5504 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5505 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5506 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5507 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5508 else
5509 abort ();
5511 refs_decl = start_var_decl
5512 (build_array_type
5513 (build_pointer_type (objc_protocol_template),
5514 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5515 ref_name);
5517 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5518 nreverse (initlist)));
5520 return refs_decl;
5523 static tree
5524 build_category_initializer (tree type, tree cat_name, tree class_name,
5525 tree instance_methods, tree class_methods,
5526 tree protocol_list)
5528 tree initlist = NULL_TREE, expr;
5530 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5531 initlist = tree_cons (NULL_TREE, class_name, initlist);
5533 if (!instance_methods)
5534 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5535 else
5537 expr = convert (objc_method_list_ptr,
5538 build_unary_op (input_location, ADDR_EXPR,
5539 instance_methods, 0));
5540 initlist = tree_cons (NULL_TREE, expr, initlist);
5542 if (!class_methods)
5543 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5544 else
5546 expr = convert (objc_method_list_ptr,
5547 build_unary_op (input_location, ADDR_EXPR,
5548 class_methods, 0));
5549 initlist = tree_cons (NULL_TREE, expr, initlist);
5552 /* protocol_list = */
5553 if (!protocol_list)
5554 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5555 else
5557 expr = convert (build_pointer_type
5558 (build_pointer_type
5559 (objc_protocol_template)),
5560 build_unary_op (input_location, ADDR_EXPR,
5561 protocol_list, 0));
5562 initlist = tree_cons (NULL_TREE, expr, initlist);
5565 return objc_build_constructor (type, nreverse (initlist));
5568 /* struct _objc_class {
5569 struct objc_class *isa;
5570 struct objc_class *super_class;
5571 char *name;
5572 long version;
5573 long info;
5574 long instance_size;
5575 struct objc_ivar_list *ivars;
5576 struct objc_method_list *methods;
5577 if (flag_next_runtime)
5578 struct objc_cache *cache;
5579 else {
5580 struct sarray *dtable;
5581 struct objc_class *subclass_list;
5582 struct objc_class *sibling_class;
5584 struct objc_protocol_list *protocols;
5585 if (flag_next_runtime)
5586 void *sel_id;
5587 void *gc_object_type;
5588 }; */
5590 static tree
5591 build_shared_structure_initializer (tree type, tree isa, tree super,
5592 tree name, tree size, int status,
5593 tree dispatch_table, tree ivar_list,
5594 tree protocol_list)
5596 tree initlist = NULL_TREE, expr;
5598 /* isa = */
5599 initlist = tree_cons (NULL_TREE, isa, initlist);
5601 /* super_class = */
5602 initlist = tree_cons (NULL_TREE, super, initlist);
5604 /* name = */
5605 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5607 /* version = */
5608 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5609 initlist);
5611 /* info = */
5612 initlist = tree_cons (NULL_TREE,
5613 build_int_cst (long_integer_type_node, status),
5614 initlist);
5616 /* instance_size = */
5617 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5618 initlist);
5620 /* objc_ivar_list = */
5621 if (!ivar_list)
5622 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5623 else
5625 expr = convert (objc_ivar_list_ptr,
5626 build_unary_op (input_location, ADDR_EXPR,
5627 ivar_list, 0));
5628 initlist = tree_cons (NULL_TREE, expr, initlist);
5631 /* objc_method_list = */
5632 if (!dispatch_table)
5633 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5634 else
5636 expr = convert (objc_method_list_ptr,
5637 build_unary_op (input_location, ADDR_EXPR,
5638 dispatch_table, 0));
5639 initlist = tree_cons (NULL_TREE, expr, initlist);
5642 if (flag_next_runtime)
5643 /* method_cache = */
5644 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5645 else
5647 /* dtable = */
5648 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5650 /* subclass_list = */
5651 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5653 /* sibling_class = */
5654 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5657 /* protocol_list = */
5658 if (! protocol_list)
5659 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5660 else
5662 expr = convert (build_pointer_type
5663 (build_pointer_type
5664 (objc_protocol_template)),
5665 build_unary_op (input_location, ADDR_EXPR,
5666 protocol_list, 0));
5667 initlist = tree_cons (NULL_TREE, expr, initlist);
5670 if (flag_next_runtime)
5671 /* sel_id = NULL */
5672 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5674 /* gc_object_type = NULL */
5675 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5677 return objc_build_constructor (type, nreverse (initlist));
5680 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5682 static inline tree
5683 lookup_category (tree klass, tree cat_name)
5685 tree category = CLASS_CATEGORY_LIST (klass);
5687 while (category && CLASS_SUPER_NAME (category) != cat_name)
5688 category = CLASS_CATEGORY_LIST (category);
5689 return category;
5692 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5694 static void
5695 generate_category (tree cat)
5697 tree decl;
5698 tree initlist, cat_name_expr, class_name_expr;
5699 tree protocol_decl, category;
5701 add_class_reference (CLASS_NAME (cat));
5702 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5704 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5706 category = lookup_category (implementation_template,
5707 CLASS_SUPER_NAME (cat));
5709 if (category && CLASS_PROTOCOL_LIST (category))
5711 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5712 protocol_decl = generate_protocol_list (category);
5714 else
5715 protocol_decl = 0;
5717 decl = start_var_decl (objc_category_template,
5718 synth_id_with_class_suffix
5719 ("_OBJC_CATEGORY", objc_implementation_context));
5721 initlist = build_category_initializer (TREE_TYPE (decl),
5722 cat_name_expr, class_name_expr,
5723 UOBJC_INSTANCE_METHODS_decl,
5724 UOBJC_CLASS_METHODS_decl,
5725 protocol_decl);
5727 finish_var_decl (decl, initlist);
5730 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5731 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5733 static void
5734 generate_shared_structures (int cls_flags)
5736 tree sc_spec, decl_specs, decl;
5737 tree name_expr, super_expr, root_expr;
5738 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5739 tree cast_type, initlist, protocol_decl;
5741 my_super_id = CLASS_SUPER_NAME (implementation_template);
5742 if (my_super_id)
5744 add_class_reference (my_super_id);
5746 /* Compute "my_root_id" - this is required for code generation.
5747 the "isa" for all meta class structures points to the root of
5748 the inheritance hierarchy (e.g. "__Object")... */
5749 my_root_id = my_super_id;
5752 tree my_root_int = lookup_interface (my_root_id);
5754 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5755 my_root_id = CLASS_SUPER_NAME (my_root_int);
5756 else
5757 break;
5759 while (1);
5761 else
5762 /* No super class. */
5763 my_root_id = CLASS_NAME (implementation_template);
5765 cast_type = build_pointer_type (objc_class_template);
5766 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5767 class_names);
5769 /* Install class `isa' and `super' pointers at runtime. */
5770 if (my_super_id)
5772 super_expr = add_objc_string (my_super_id, class_names);
5773 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5775 else
5776 super_expr = build_int_cst (NULL_TREE, 0);
5778 root_expr = add_objc_string (my_root_id, class_names);
5779 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5781 if (CLASS_PROTOCOL_LIST (implementation_template))
5783 generate_protocol_references
5784 (CLASS_PROTOCOL_LIST (implementation_template));
5785 protocol_decl = generate_protocol_list (implementation_template);
5787 else
5788 protocol_decl = 0;
5790 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5792 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5793 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5795 decl = start_var_decl (objc_class_template,
5796 IDENTIFIER_POINTER
5797 (DECL_NAME (UOBJC_METACLASS_decl)));
5799 initlist
5800 = build_shared_structure_initializer
5801 (TREE_TYPE (decl),
5802 root_expr, super_expr, name_expr,
5803 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5804 2 /*CLS_META*/,
5805 UOBJC_CLASS_METHODS_decl,
5806 UOBJC_CLASS_VARIABLES_decl,
5807 protocol_decl);
5809 finish_var_decl (decl, initlist);
5811 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5813 decl = start_var_decl (objc_class_template,
5814 IDENTIFIER_POINTER
5815 (DECL_NAME (UOBJC_CLASS_decl)));
5817 initlist
5818 = build_shared_structure_initializer
5819 (TREE_TYPE (decl),
5820 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5821 super_expr, name_expr,
5822 convert (integer_type_node,
5823 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5824 (implementation_template))),
5825 1 /*CLS_FACTORY*/ | cls_flags,
5826 UOBJC_INSTANCE_METHODS_decl,
5827 UOBJC_INSTANCE_VARIABLES_decl,
5828 protocol_decl);
5830 finish_var_decl (decl, initlist);
5834 static const char *
5835 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5837 static char string[BUFSIZE];
5839 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5840 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5842 sprintf (string, "%s_%s", preamble,
5843 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5845 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5846 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5848 /* We have a category. */
5849 const char *const class_name
5850 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5851 const char *const class_super_name
5852 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5853 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5855 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5857 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5858 sprintf (string, "%s_%s", preamble, protocol_name);
5860 else
5861 abort ();
5863 return string;
5866 /* If type is empty or only type qualifiers are present, add default
5867 type of id (otherwise grokdeclarator will default to int). */
5869 static tree
5870 adjust_type_for_id_default (tree type)
5872 if (!type)
5873 type = make_node (TREE_LIST);
5875 if (!TREE_VALUE (type))
5876 TREE_VALUE (type) = objc_object_type;
5877 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5878 && TYPED_OBJECT (TREE_VALUE (type)))
5879 error ("can not use an object as parameter to a method");
5881 return type;
5884 /* Usage:
5885 keyworddecl:
5886 selector ':' '(' typename ')' identifier
5888 Purpose:
5889 Transform an Objective-C keyword argument into
5890 the C equivalent parameter declarator.
5892 In: key_name, an "identifier_node" (optional).
5893 arg_type, a "tree_list" (optional).
5894 arg_name, an "identifier_node".
5896 Note: It would be really nice to strongly type the preceding
5897 arguments in the function prototype; however, then I
5898 could not use the "accessor" macros defined in "tree.h".
5900 Out: an instance of "keyword_decl". */
5902 tree
5903 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5905 tree keyword_decl;
5907 /* If no type is specified, default to "id". */
5908 arg_type = adjust_type_for_id_default (arg_type);
5910 keyword_decl = make_node (KEYWORD_DECL);
5912 TREE_TYPE (keyword_decl) = arg_type;
5913 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5914 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5916 return keyword_decl;
5919 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5921 static tree
5922 build_keyword_selector (tree selector)
5924 int len = 0;
5925 tree key_chain, key_name;
5926 char *buf;
5928 /* Scan the selector to see how much space we'll need. */
5929 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5931 if (TREE_CODE (selector) == KEYWORD_DECL)
5932 key_name = KEYWORD_KEY_NAME (key_chain);
5933 else if (TREE_CODE (selector) == TREE_LIST)
5934 key_name = TREE_PURPOSE (key_chain);
5935 else
5936 abort ();
5938 if (key_name)
5939 len += IDENTIFIER_LENGTH (key_name) + 1;
5940 else
5941 /* Just a ':' arg. */
5942 len++;
5945 buf = (char *) alloca (len + 1);
5946 /* Start the buffer out as an empty string. */
5947 buf[0] = '\0';
5949 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5951 if (TREE_CODE (selector) == KEYWORD_DECL)
5952 key_name = KEYWORD_KEY_NAME (key_chain);
5953 else if (TREE_CODE (selector) == TREE_LIST)
5955 key_name = TREE_PURPOSE (key_chain);
5956 /* The keyword decl chain will later be used as a function argument
5957 chain. Unhook the selector itself so as to not confuse other
5958 parts of the compiler. */
5959 TREE_PURPOSE (key_chain) = NULL_TREE;
5961 else
5962 abort ();
5964 if (key_name)
5965 strcat (buf, IDENTIFIER_POINTER (key_name));
5966 strcat (buf, ":");
5969 return get_identifier (buf);
5972 /* Used for declarations and definitions. */
5974 static tree
5975 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5976 tree add_args, bool ellipsis)
5978 tree method_decl;
5980 /* If no type is specified, default to "id". */
5981 ret_type = adjust_type_for_id_default (ret_type);
5983 method_decl = make_node (code);
5984 TREE_TYPE (method_decl) = ret_type;
5986 /* If we have a keyword selector, create an identifier_node that
5987 represents the full selector name (`:' included)... */
5988 if (TREE_CODE (selector) == KEYWORD_DECL)
5990 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5991 METHOD_SEL_ARGS (method_decl) = selector;
5992 METHOD_ADD_ARGS (method_decl) = add_args;
5993 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5995 else
5997 METHOD_SEL_NAME (method_decl) = selector;
5998 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5999 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6002 return method_decl;
6005 #define METHOD_DEF 0
6006 #define METHOD_REF 1
6008 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6009 an argument list for method METH. CONTEXT is either METHOD_DEF or
6010 METHOD_REF, saying whether we are trying to define a method or call
6011 one. SUPERFLAG says this is for a send to super; this makes a
6012 difference for the NeXT calling sequence in which the lookup and
6013 the method call are done together. If METH is null, user-defined
6014 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6016 static tree
6017 get_arg_type_list (tree meth, int context, int superflag)
6019 tree arglist, akey;
6021 /* Receiver type. */
6022 if (flag_next_runtime && superflag)
6023 arglist = build_tree_list (NULL_TREE, objc_super_type);
6024 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6025 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6026 else
6027 arglist = build_tree_list (NULL_TREE, objc_object_type);
6029 /* Selector type - will eventually change to `int'. */
6030 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6032 /* No actual method prototype given -- assume that remaining arguments
6033 are `...'. */
6034 if (!meth)
6035 return arglist;
6037 /* Build a list of argument types. */
6038 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6040 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6042 /* Decay arrays and functions into pointers. */
6043 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6044 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6045 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6046 arg_type = build_pointer_type (arg_type);
6048 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6051 if (METHOD_ADD_ARGS (meth))
6053 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6054 akey; akey = TREE_CHAIN (akey))
6056 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6058 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6061 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6062 goto lack_of_ellipsis;
6064 else
6066 lack_of_ellipsis:
6067 chainon (arglist, OBJC_VOID_AT_END);
6070 return arglist;
6073 static tree
6074 check_duplicates (hash hsh, int methods, int is_class)
6076 tree meth = NULL_TREE;
6078 if (hsh)
6080 meth = hsh->key;
6082 if (hsh->list)
6084 /* We have two or more methods with the same name but
6085 different types. */
6086 attr loop;
6088 /* But just how different are those types? If
6089 -Wno-strict-selector-match is specified, we shall not
6090 complain if the differences are solely among types with
6091 identical size and alignment. */
6092 if (!warn_strict_selector_match)
6094 for (loop = hsh->list; loop; loop = loop->next)
6095 if (!comp_proto_with_proto (meth, loop->value, 0))
6096 goto issue_warning;
6098 return meth;
6101 issue_warning:
6102 if (methods)
6104 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6106 warning (0, "multiple methods named %<%c%s%> found",
6107 (is_class ? '+' : '-'),
6108 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6109 inform (0, "%Jusing %<%c%s%>", meth,
6110 (type ? '-' : '+'),
6111 gen_method_decl (meth));
6113 else
6115 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6117 warning (0, "multiple selectors named %<%c%s%> found",
6118 (is_class ? '+' : '-'),
6119 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6120 inform (0, "%Jfound %<%c%s%>", meth,
6121 (type ? '-' : '+'),
6122 gen_method_decl (meth));
6125 for (loop = hsh->list; loop; loop = loop->next)
6127 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6129 inform (0, "%Jalso found %<%c%s%>", loop->value,
6130 (type ? '-' : '+'),
6131 gen_method_decl (loop->value));
6135 return meth;
6138 /* If RECEIVER is a class reference, return the identifier node for
6139 the referenced class. RECEIVER is created by objc_get_class_reference,
6140 so we check the exact form created depending on which runtimes are
6141 used. */
6143 static tree
6144 receiver_is_class_object (tree receiver, int self, int super)
6146 tree chain, exp, arg;
6148 /* The receiver is 'self' or 'super' in the context of a class method. */
6149 if (objc_method_context
6150 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6151 && (self || super))
6152 return (super
6153 ? CLASS_SUPER_NAME (implementation_template)
6154 : CLASS_NAME (implementation_template));
6156 if (flag_next_runtime)
6158 /* The receiver is a variable created by
6159 build_class_reference_decl. */
6160 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6161 /* Look up the identifier. */
6162 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6163 if (TREE_PURPOSE (chain) == receiver)
6164 return TREE_VALUE (chain);
6167 /* The receiver is a function call that returns an id. Check if
6168 it is a call to objc_getClass, if so, pick up the class name. */
6169 if (TREE_CODE (receiver) == CALL_EXPR
6170 && (exp = CALL_EXPR_FN (receiver))
6171 && TREE_CODE (exp) == ADDR_EXPR
6172 && (exp = TREE_OPERAND (exp, 0))
6173 && TREE_CODE (exp) == FUNCTION_DECL
6174 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6175 prototypes for objc_get_class(). Thankfully, they seem to share the
6176 same function type. */
6177 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6178 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6179 /* We have a call to objc_get_class/objc_getClass! */
6180 && (arg = CALL_EXPR_ARG (receiver, 0)))
6182 STRIP_NOPS (arg);
6183 if (TREE_CODE (arg) == ADDR_EXPR
6184 && (arg = TREE_OPERAND (arg, 0))
6185 && TREE_CODE (arg) == STRING_CST)
6186 /* Finally, we have the class name. */
6187 return get_identifier (TREE_STRING_POINTER (arg));
6189 return 0;
6192 /* If we are currently building a message expr, this holds
6193 the identifier of the selector of the message. This is
6194 used when printing warnings about argument mismatches. */
6196 static tree current_objc_message_selector = 0;
6198 tree
6199 objc_message_selector (void)
6201 return current_objc_message_selector;
6204 /* Construct an expression for sending a message.
6205 MESS has the object to send to in TREE_PURPOSE
6206 and the argument list (including selector) in TREE_VALUE.
6208 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6209 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6211 tree
6212 objc_build_message_expr (tree mess)
6214 tree receiver = TREE_PURPOSE (mess);
6215 tree sel_name;
6216 #ifdef OBJCPLUS
6217 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6218 #else
6219 tree args = TREE_VALUE (mess);
6220 #endif
6221 tree method_params = NULL_TREE;
6223 if (TREE_CODE (receiver) == ERROR_MARK)
6224 return error_mark_node;
6226 /* Obtain the full selector name. */
6227 if (TREE_CODE (args) == IDENTIFIER_NODE)
6228 /* A unary selector. */
6229 sel_name = args;
6230 else if (TREE_CODE (args) == TREE_LIST)
6231 sel_name = build_keyword_selector (args);
6232 else
6233 abort ();
6235 /* Build the parameter list to give to the method. */
6236 if (TREE_CODE (args) == TREE_LIST)
6237 #ifdef OBJCPLUS
6238 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6239 #else
6241 tree chain = args, prev = NULL_TREE;
6243 /* We have a keyword selector--check for comma expressions. */
6244 while (chain)
6246 tree element = TREE_VALUE (chain);
6248 /* We have a comma expression, must collapse... */
6249 if (TREE_CODE (element) == TREE_LIST)
6251 if (prev)
6252 TREE_CHAIN (prev) = element;
6253 else
6254 args = element;
6256 prev = chain;
6257 chain = TREE_CHAIN (chain);
6259 method_params = args;
6261 #endif
6263 #ifdef OBJCPLUS
6264 if (processing_template_decl)
6265 /* Must wait until template instantiation time. */
6266 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6267 method_params);
6268 #endif
6270 return objc_finish_message_expr (receiver, sel_name, method_params);
6273 /* Look up method SEL_NAME that would be suitable for receiver
6274 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6275 nonzero), and report on any duplicates. */
6277 static tree
6278 lookup_method_in_hash_lists (tree sel_name, int is_class)
6280 hash method_prototype = NULL;
6282 if (!is_class)
6283 method_prototype = hash_lookup (nst_method_hash_list,
6284 sel_name);
6286 if (!method_prototype)
6288 method_prototype = hash_lookup (cls_method_hash_list,
6289 sel_name);
6290 is_class = 1;
6293 return check_duplicates (method_prototype, 1, is_class);
6296 /* The 'objc_finish_message_expr' routine is called from within
6297 'objc_build_message_expr' for non-template functions. In the case of
6298 C++ template functions, it is called from 'build_expr_from_tree'
6299 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6301 tree
6302 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6304 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6305 tree selector, retval, class_tree;
6306 int self, super, have_cast;
6308 /* Extract the receiver of the message, as well as its type
6309 (where the latter may take the form of a cast or be inferred
6310 from the implementation context). */
6311 rtype = receiver;
6312 while (TREE_CODE (rtype) == COMPOUND_EXPR
6313 || TREE_CODE (rtype) == MODIFY_EXPR
6314 || CONVERT_EXPR_P (rtype)
6315 || TREE_CODE (rtype) == COMPONENT_REF)
6316 rtype = TREE_OPERAND (rtype, 0);
6317 self = (rtype == self_decl);
6318 super = (rtype == UOBJC_SUPER_decl);
6319 rtype = TREE_TYPE (receiver);
6320 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6321 || (TREE_CODE (receiver) == COMPOUND_EXPR
6322 && !IS_SUPER (rtype)));
6324 /* If we are calling [super dealloc], reset our warning flag. */
6325 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6326 should_call_super_dealloc = 0;
6328 /* If the receiver is a class object, retrieve the corresponding
6329 @interface, if one exists. */
6330 class_tree = receiver_is_class_object (receiver, self, super);
6332 /* Now determine the receiver type (if an explicit cast has not been
6333 provided). */
6334 if (!have_cast)
6336 if (class_tree)
6337 rtype = lookup_interface (class_tree);
6338 /* Handle `self' and `super'. */
6339 else if (super)
6341 if (!CLASS_SUPER_NAME (implementation_template))
6343 error ("no super class declared in @interface for %qs",
6344 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6345 return error_mark_node;
6347 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6349 else if (self)
6350 rtype = lookup_interface (CLASS_NAME (implementation_template));
6353 /* If receiver is of type `id' or `Class' (or if the @interface for a
6354 class is not visible), we shall be satisfied with the existence of
6355 any instance or class method. */
6356 if (objc_is_id (rtype))
6358 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6359 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6360 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6361 : NULL_TREE);
6362 rtype = NULL_TREE;
6364 if (rprotos)
6366 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6367 in protocols themselves for the method prototype. */
6368 method_prototype
6369 = lookup_method_in_protocol_list (rprotos, sel_name,
6370 class_tree != NULL_TREE);
6372 /* If messaging 'Class <Proto>' but did not find a class method
6373 prototype, search for an instance method instead, and warn
6374 about having done so. */
6375 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6377 method_prototype
6378 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6380 if (method_prototype)
6381 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6382 IDENTIFIER_POINTER (sel_name),
6383 IDENTIFIER_POINTER (sel_name));
6387 else if (rtype)
6389 tree orig_rtype = rtype, saved_rtype;
6391 if (TREE_CODE (rtype) == POINTER_TYPE)
6392 rtype = TREE_TYPE (rtype);
6393 /* Traverse typedef aliases */
6394 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6395 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6396 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6397 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6398 saved_rtype = rtype;
6399 if (TYPED_OBJECT (rtype))
6401 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6402 rtype = TYPE_OBJC_INTERFACE (rtype);
6404 /* If we could not find an @interface declaration, we must have
6405 only seen a @class declaration; so, we cannot say anything
6406 more intelligent about which methods the receiver will
6407 understand. */
6408 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6409 rtype = NULL_TREE;
6410 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6411 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6413 /* We have a valid ObjC class name. Look up the method name
6414 in the published @interface for the class (and its
6415 superclasses). */
6416 method_prototype
6417 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6419 /* If the method was not found in the @interface, it may still
6420 exist locally as part of the @implementation. */
6421 if (!method_prototype && objc_implementation_context
6422 && CLASS_NAME (objc_implementation_context)
6423 == OBJC_TYPE_NAME (rtype))
6424 method_prototype
6425 = lookup_method
6426 ((class_tree
6427 ? CLASS_CLS_METHODS (objc_implementation_context)
6428 : CLASS_NST_METHODS (objc_implementation_context)),
6429 sel_name);
6431 /* If we haven't found a candidate method by now, try looking for
6432 it in the protocol list. */
6433 if (!method_prototype && rprotos)
6434 method_prototype
6435 = lookup_method_in_protocol_list (rprotos, sel_name,
6436 class_tree != NULL_TREE);
6438 else
6440 warning (0, "invalid receiver type %qs",
6441 gen_type_name (orig_rtype));
6442 /* After issuing the "invalid receiver" warning, perform method
6443 lookup as if we were messaging 'id'. */
6444 rtype = rprotos = NULL_TREE;
6449 /* For 'id' or 'Class' receivers, search in the global hash table
6450 as a last resort. For all receivers, warn if protocol searches
6451 have failed. */
6452 if (!method_prototype)
6454 if (rprotos)
6455 warning (0, "%<%c%s%> not found in protocol(s)",
6456 (class_tree ? '+' : '-'),
6457 IDENTIFIER_POINTER (sel_name));
6459 if (!rtype)
6460 method_prototype
6461 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6464 if (!method_prototype)
6466 static bool warn_missing_methods = false;
6468 if (rtype)
6469 warning (0, "%qs may not respond to %<%c%s%>",
6470 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6471 (class_tree ? '+' : '-'),
6472 IDENTIFIER_POINTER (sel_name));
6473 /* If we are messaging an 'id' or 'Class' object and made it here,
6474 then we have failed to find _any_ instance or class method,
6475 respectively. */
6476 else
6477 warning (0, "no %<%c%s%> method found",
6478 (class_tree ? '+' : '-'),
6479 IDENTIFIER_POINTER (sel_name));
6481 if (!warn_missing_methods)
6483 warning (0, "(Messages without a matching method signature");
6484 warning (0, "will be assumed to return %<id%> and accept");
6485 warning (0, "%<...%> as arguments.)");
6486 warn_missing_methods = true;
6490 /* Save the selector name for printing error messages. */
6491 current_objc_message_selector = sel_name;
6493 /* Build the parameters list for looking up the method.
6494 These are the object itself and the selector. */
6496 if (flag_typed_selectors)
6497 selector = build_typed_selector_reference (sel_name, method_prototype);
6498 else
6499 selector = build_selector_reference (sel_name);
6501 retval = build_objc_method_call (super, method_prototype,
6502 receiver,
6503 selector, method_params);
6505 current_objc_message_selector = 0;
6507 return retval;
6510 /* Build a tree expression to send OBJECT the operation SELECTOR,
6511 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6512 assuming the method has prototype METHOD_PROTOTYPE.
6513 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6514 Use METHOD_PARAMS as list of args to pass to the method.
6515 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6517 static tree
6518 build_objc_method_call (int super_flag, tree method_prototype,
6519 tree lookup_object, tree selector,
6520 tree method_params)
6522 tree sender = (super_flag ? umsg_super_decl :
6523 (!flag_next_runtime || flag_nil_receivers
6524 ? (flag_objc_direct_dispatch
6525 ? umsg_fast_decl
6526 : umsg_decl)
6527 : umsg_nonnil_decl));
6528 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6530 /* If a prototype for the method to be called exists, then cast
6531 the sender's return type and arguments to match that of the method.
6532 Otherwise, leave sender as is. */
6533 tree ret_type
6534 = (method_prototype
6535 ? TREE_VALUE (TREE_TYPE (method_prototype))
6536 : objc_object_type);
6537 tree sender_cast
6538 = build_pointer_type
6539 (build_function_type
6540 (ret_type,
6541 get_arg_type_list
6542 (method_prototype, METHOD_REF, super_flag)));
6543 tree method, t;
6545 lookup_object = build_c_cast (rcv_p, lookup_object);
6547 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6548 lookup_object = save_expr (lookup_object);
6550 if (flag_next_runtime)
6552 /* If we are returning a struct in memory, and the address
6553 of that memory location is passed as a hidden first
6554 argument, then change which messenger entry point this
6555 expr will call. NB: Note that sender_cast remains
6556 unchanged (it already has a struct return type). */
6557 if (!targetm.calls.struct_value_rtx (0, 0)
6558 && (TREE_CODE (ret_type) == RECORD_TYPE
6559 || TREE_CODE (ret_type) == UNION_TYPE)
6560 && targetm.calls.return_in_memory (ret_type, 0))
6561 sender = (super_flag ? umsg_super_stret_decl :
6562 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6564 method_params = tree_cons (NULL_TREE, lookup_object,
6565 tree_cons (NULL_TREE, selector,
6566 method_params));
6567 method = build_fold_addr_expr (sender);
6569 else
6571 /* This is the portable (GNU) way. */
6572 tree object;
6574 /* First, call the lookup function to get a pointer to the method,
6575 then cast the pointer, then call it with the method arguments. */
6577 object = (super_flag ? self_decl : lookup_object);
6579 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6580 t = tree_cons (NULL_TREE, lookup_object, t);
6581 method = build_function_call (sender, t);
6583 /* Pass the object to the method. */
6584 method_params = tree_cons (NULL_TREE, object,
6585 tree_cons (NULL_TREE, selector,
6586 method_params));
6589 /* ??? Selector is not at this point something we can use inside
6590 the compiler itself. Set it to garbage for the nonce. */
6591 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6592 return build_function_call (t, method_params);
6595 static void
6596 build_protocol_reference (tree p)
6598 tree decl;
6599 const char *proto_name;
6601 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6603 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6604 decl = start_var_decl (objc_protocol_template, proto_name);
6606 PROTOCOL_FORWARD_DECL (p) = decl;
6609 /* This function is called by the parser when (and only when) a
6610 @protocol() expression is found, in order to compile it. */
6611 tree
6612 objc_build_protocol_expr (tree protoname)
6614 tree expr;
6615 tree p = lookup_protocol (protoname);
6617 if (!p)
6619 error ("cannot find protocol declaration for %qs",
6620 IDENTIFIER_POINTER (protoname));
6621 return error_mark_node;
6624 if (!PROTOCOL_FORWARD_DECL (p))
6625 build_protocol_reference (p);
6627 expr = build_unary_op (input_location,
6628 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6630 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6631 if we have it, rather than converting it here. */
6632 expr = convert (objc_protocol_type, expr);
6634 /* The @protocol() expression is being compiled into a pointer to a
6635 statically allocated instance of the Protocol class. To become
6636 usable at runtime, the 'isa' pointer of the instance need to be
6637 fixed up at runtime by the runtime library, to point to the
6638 actual 'Protocol' class. */
6640 /* For the GNU runtime, put the static Protocol instance in the list
6641 of statically allocated instances, so that we make sure that its
6642 'isa' pointer is fixed up at runtime by the GNU runtime library
6643 to point to the Protocol class (at runtime, when loading the
6644 module, the GNU runtime library loops on the statically allocated
6645 instances (as found in the defs field in objc_symtab) and fixups
6646 all the 'isa' pointers of those objects). */
6647 if (! flag_next_runtime)
6649 /* This type is a struct containing the fields of a Protocol
6650 object. (Cfr. objc_protocol_type instead is the type of a pointer
6651 to such a struct). */
6652 tree protocol_struct_type = xref_tag
6653 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6654 tree *chain;
6656 /* Look for the list of Protocol statically allocated instances
6657 to fixup at runtime. Create a new list to hold Protocol
6658 statically allocated instances, if the list is not found. At
6659 present there is only another list, holding NSConstantString
6660 static instances to be fixed up at runtime. */
6661 for (chain = &objc_static_instances;
6662 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6663 chain = &TREE_CHAIN (*chain));
6664 if (!*chain)
6666 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6667 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6668 class_names);
6671 /* Add this statically allocated instance to the Protocol list. */
6672 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6673 PROTOCOL_FORWARD_DECL (p),
6674 TREE_PURPOSE (*chain));
6678 return expr;
6681 /* This function is called by the parser when a @selector() expression
6682 is found, in order to compile it. It is only called by the parser
6683 and only to compile a @selector(). */
6684 tree
6685 objc_build_selector_expr (tree selnamelist)
6687 tree selname;
6689 /* Obtain the full selector name. */
6690 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6691 /* A unary selector. */
6692 selname = selnamelist;
6693 else if (TREE_CODE (selnamelist) == TREE_LIST)
6694 selname = build_keyword_selector (selnamelist);
6695 else
6696 abort ();
6698 /* If we are required to check @selector() expressions as they
6699 are found, check that the selector has been declared. */
6700 if (warn_undeclared_selector)
6702 /* Look the selector up in the list of all known class and
6703 instance methods (up to this line) to check that the selector
6704 exists. */
6705 hash hsh;
6707 /* First try with instance methods. */
6708 hsh = hash_lookup (nst_method_hash_list, selname);
6710 /* If not found, try with class methods. */
6711 if (!hsh)
6713 hsh = hash_lookup (cls_method_hash_list, selname);
6716 /* If still not found, print out a warning. */
6717 if (!hsh)
6719 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6724 if (flag_typed_selectors)
6725 return build_typed_selector_reference (selname, 0);
6726 else
6727 return build_selector_reference (selname);
6730 tree
6731 objc_build_encode_expr (tree type)
6733 tree result;
6734 const char *string;
6736 encode_type (type, obstack_object_size (&util_obstack),
6737 OBJC_ENCODE_INLINE_DEFS);
6738 obstack_1grow (&util_obstack, 0); /* null terminate string */
6739 string = XOBFINISH (&util_obstack, const char *);
6741 /* Synthesize a string that represents the encoded struct/union. */
6742 result = my_build_string (strlen (string) + 1, string);
6743 obstack_free (&util_obstack, util_firstobj);
6744 return result;
6747 static tree
6748 build_ivar_reference (tree id)
6750 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6752 /* Historically, a class method that produced objects (factory
6753 method) would assign `self' to the instance that it
6754 allocated. This would effectively turn the class method into
6755 an instance method. Following this assignment, the instance
6756 variables could be accessed. That practice, while safe,
6757 violates the simple rule that a class method should not refer
6758 to an instance variable. It's better to catch the cases
6759 where this is done unknowingly than to support the above
6760 paradigm. */
6761 warning (0, "instance variable %qs accessed in class method",
6762 IDENTIFIER_POINTER (id));
6763 self_decl = convert (objc_instance_type, self_decl); /* cast */
6766 return objc_build_component_ref (build_indirect_ref (input_location,
6767 self_decl, "->"), id);
6770 /* Compute a hash value for a given method SEL_NAME. */
6772 static size_t
6773 hash_func (tree sel_name)
6775 const unsigned char *s
6776 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6777 size_t h = 0;
6779 while (*s)
6780 h = h * 67 + *s++ - 113;
6781 return h;
6784 static void
6785 hash_init (void)
6787 nst_method_hash_list
6788 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6789 cls_method_hash_list
6790 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6792 /* Initialize the hash table used to hold the constant string objects. */
6793 string_htab = htab_create_ggc (31, string_hash,
6794 string_eq, NULL);
6796 /* Initialize the hash table used to hold EH-volatilized types. */
6797 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6798 volatilized_eq, NULL);
6801 /* WARNING!!!! hash_enter is called with a method, and will peek
6802 inside to find its selector! But hash_lookup is given a selector
6803 directly, and looks for the selector that's inside the found
6804 entry's key (method) for comparison. */
6806 static void
6807 hash_enter (hash *hashlist, tree method)
6809 hash obj;
6810 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6812 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6813 obj->list = 0;
6814 obj->next = hashlist[slot];
6815 obj->key = method;
6817 hashlist[slot] = obj; /* append to front */
6820 static hash
6821 hash_lookup (hash *hashlist, tree sel_name)
6823 hash target;
6825 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6827 while (target)
6829 if (sel_name == METHOD_SEL_NAME (target->key))
6830 return target;
6832 target = target->next;
6834 return 0;
6837 static void
6838 hash_add_attr (hash entry, tree value)
6840 attr obj;
6842 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6843 obj->next = entry->list;
6844 obj->value = value;
6846 entry->list = obj; /* append to front */
6849 static tree
6850 lookup_method (tree mchain, tree method)
6852 tree key;
6854 if (TREE_CODE (method) == IDENTIFIER_NODE)
6855 key = method;
6856 else
6857 key = METHOD_SEL_NAME (method);
6859 while (mchain)
6861 if (METHOD_SEL_NAME (mchain) == key)
6862 return mchain;
6864 mchain = TREE_CHAIN (mchain);
6866 return NULL_TREE;
6869 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6870 in INTERFACE, along with any categories and protocols attached thereto.
6871 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6872 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6873 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6874 be found in INTERFACE or any of its superclasses, look for an _instance_
6875 method of the same name in the root class as a last resort.
6877 If a suitable method cannot be found, return NULL_TREE. */
6879 static tree
6880 lookup_method_static (tree interface, tree ident, int flags)
6882 tree meth = NULL_TREE, root_inter = NULL_TREE;
6883 tree inter = interface;
6884 int is_class = (flags & OBJC_LOOKUP_CLASS);
6885 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6887 while (inter)
6889 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6890 tree category = inter;
6892 /* First, look up the method in the class itself. */
6893 if ((meth = lookup_method (chain, ident)))
6894 return meth;
6896 /* Failing that, look for the method in each category of the class. */
6897 while ((category = CLASS_CATEGORY_LIST (category)))
6899 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6901 /* Check directly in each category. */
6902 if ((meth = lookup_method (chain, ident)))
6903 return meth;
6905 /* Failing that, check in each category's protocols. */
6906 if (CLASS_PROTOCOL_LIST (category))
6908 if ((meth = (lookup_method_in_protocol_list
6909 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6910 return meth;
6914 /* If not found in categories, check in protocols of the main class. */
6915 if (CLASS_PROTOCOL_LIST (inter))
6917 if ((meth = (lookup_method_in_protocol_list
6918 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6919 return meth;
6922 /* If we were instructed not to look in superclasses, don't. */
6923 if (no_superclasses)
6924 return NULL_TREE;
6926 /* Failing that, climb up the inheritance hierarchy. */
6927 root_inter = inter;
6928 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6930 while (inter);
6932 /* If no class (factory) method was found, check if an _instance_
6933 method of the same name exists in the root class. This is what
6934 the Objective-C runtime will do. If an instance method was not
6935 found, return 0. */
6936 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6939 /* Add the method to the hash list if it doesn't contain an identical
6940 method already. */
6942 static void
6943 add_method_to_hash_list (hash *hash_list, tree method)
6945 hash hsh;
6947 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6949 /* Install on a global chain. */
6950 hash_enter (hash_list, method);
6952 else
6954 /* Check types against those; if different, add to a list. */
6955 attr loop;
6956 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6957 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6958 already_there |= comp_proto_with_proto (method, loop->value, 1);
6959 if (!already_there)
6960 hash_add_attr (hsh, method);
6964 static tree
6965 objc_add_method (tree klass, tree method, int is_class)
6967 tree mth;
6969 if (!(mth = lookup_method (is_class
6970 ? CLASS_CLS_METHODS (klass)
6971 : CLASS_NST_METHODS (klass), method)))
6973 /* put method on list in reverse order */
6974 if (is_class)
6976 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
6977 CLASS_CLS_METHODS (klass) = method;
6979 else
6981 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
6982 CLASS_NST_METHODS (klass) = method;
6985 else
6987 /* When processing an @interface for a class or category, give hard
6988 errors on methods with identical selectors but differing argument
6989 and/or return types. We do not do this for @implementations, because
6990 C/C++ will do it for us (i.e., there will be duplicate function
6991 definition errors). */
6992 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
6993 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
6994 && !comp_proto_with_proto (method, mth, 1))
6995 error ("duplicate declaration of method %<%c%s%>",
6996 is_class ? '+' : '-',
6997 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
7000 if (is_class)
7001 add_method_to_hash_list (cls_method_hash_list, method);
7002 else
7004 add_method_to_hash_list (nst_method_hash_list, method);
7006 /* Instance methods in root classes (and categories thereof)
7007 may act as class methods as a last resort. We also add
7008 instance methods listed in @protocol declarations to
7009 the class hash table, on the assumption that @protocols
7010 may be adopted by root classes or categories. */
7011 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7012 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7013 klass = lookup_interface (CLASS_NAME (klass));
7015 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7016 || !CLASS_SUPER_NAME (klass))
7017 add_method_to_hash_list (cls_method_hash_list, method);
7020 return method;
7023 static tree
7024 add_class (tree class_name, tree name)
7026 struct interface_tuple **slot;
7028 /* Put interfaces on list in reverse order. */
7029 TREE_CHAIN (class_name) = interface_chain;
7030 interface_chain = class_name;
7032 if (interface_htab == NULL)
7033 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7034 slot = (struct interface_tuple **)
7035 htab_find_slot_with_hash (interface_htab, name,
7036 IDENTIFIER_HASH_VALUE (name),
7037 INSERT);
7038 if (!*slot)
7040 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7041 (*slot)->id = name;
7043 (*slot)->class_name = class_name;
7045 return interface_chain;
7048 static void
7049 add_category (tree klass, tree category)
7051 /* Put categories on list in reverse order. */
7052 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7054 if (cat)
7056 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7057 IDENTIFIER_POINTER (CLASS_NAME (klass)),
7058 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7060 else
7062 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7063 CLASS_CATEGORY_LIST (klass) = category;
7067 /* Called after parsing each instance variable declaration. Necessary to
7068 preserve typedefs and implement public/private...
7070 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7072 static tree
7073 add_instance_variable (tree klass, int visibility, tree field_decl)
7075 tree field_type = TREE_TYPE (field_decl);
7076 const char *ivar_name = DECL_NAME (field_decl)
7077 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7078 : "<unnamed>";
7080 #ifdef OBJCPLUS
7081 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7083 error ("illegal reference type specified for instance variable %qs",
7084 ivar_name);
7085 /* Return class as is without adding this ivar. */
7086 return klass;
7088 #endif
7090 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7091 || TYPE_SIZE (field_type) == error_mark_node)
7092 /* 'type[0]' is allowed, but 'type[]' is not! */
7094 error ("instance variable %qs has unknown size", ivar_name);
7095 /* Return class as is without adding this ivar. */
7096 return klass;
7099 #ifdef OBJCPLUS
7100 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7101 need to either (1) warn the user about it or (2) generate suitable
7102 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7103 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7104 if (MAYBE_CLASS_TYPE_P (field_type)
7105 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7106 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7107 || TYPE_POLYMORPHIC_P (field_type)))
7109 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7111 if (flag_objc_call_cxx_cdtors)
7113 /* Since the ObjC runtime will be calling the constructors and
7114 destructors for us, the only thing we can't handle is the lack
7115 of a default constructor. */
7116 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7117 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7119 warning (0, "type %qs has no default constructor to call",
7120 type_name);
7122 /* If we cannot call a constructor, we should also avoid
7123 calling the destructor, for symmetry. */
7124 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7125 warning (0, "destructor for %qs shall not be run either",
7126 type_name);
7129 else
7131 static bool warn_cxx_ivars = false;
7133 if (TYPE_POLYMORPHIC_P (field_type))
7135 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7136 initialize them. */
7137 error ("type %qs has virtual member functions", type_name);
7138 error ("illegal aggregate type %qs specified "
7139 "for instance variable %qs",
7140 type_name, ivar_name);
7141 /* Return class as is without adding this ivar. */
7142 return klass;
7145 /* User-defined constructors and destructors are not known to Obj-C
7146 and hence will not be called. This may or may not be a problem. */
7147 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7148 warning (0, "type %qs has a user-defined constructor", type_name);
7149 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7150 warning (0, "type %qs has a user-defined destructor", type_name);
7152 if (!warn_cxx_ivars)
7154 warning (0, "C++ constructors and destructors will not "
7155 "be invoked for Objective-C fields");
7156 warn_cxx_ivars = true;
7160 #endif
7162 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7163 switch (visibility)
7165 case 0:
7166 TREE_PUBLIC (field_decl) = 0;
7167 TREE_PRIVATE (field_decl) = 0;
7168 TREE_PROTECTED (field_decl) = 1;
7169 break;
7171 case 1:
7172 TREE_PUBLIC (field_decl) = 1;
7173 TREE_PRIVATE (field_decl) = 0;
7174 TREE_PROTECTED (field_decl) = 0;
7175 break;
7177 case 2:
7178 TREE_PUBLIC (field_decl) = 0;
7179 TREE_PRIVATE (field_decl) = 1;
7180 TREE_PROTECTED (field_decl) = 0;
7181 break;
7185 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7187 return klass;
7190 static tree
7191 is_ivar (tree decl_chain, tree ident)
7193 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7194 if (DECL_NAME (decl_chain) == ident)
7195 return decl_chain;
7196 return NULL_TREE;
7199 /* True if the ivar is private and we are not in its implementation. */
7201 static int
7202 is_private (tree decl)
7204 return (TREE_PRIVATE (decl)
7205 && ! is_ivar (CLASS_IVARS (implementation_template),
7206 DECL_NAME (decl)));
7209 /* We have an instance variable reference;, check to see if it is public. */
7212 objc_is_public (tree expr, tree identifier)
7214 tree basetype, decl;
7216 #ifdef OBJCPLUS
7217 if (processing_template_decl)
7218 return 1;
7219 #endif
7221 if (TREE_TYPE (expr) == error_mark_node)
7222 return 1;
7224 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7226 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7228 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7230 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7232 if (!klass)
7234 error ("cannot find interface declaration for %qs",
7235 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7236 return 0;
7239 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7241 if (TREE_PUBLIC (decl))
7242 return 1;
7244 /* Important difference between the Stepstone translator:
7245 all instance variables should be public within the context
7246 of the implementation. */
7247 if (objc_implementation_context
7248 && ((TREE_CODE (objc_implementation_context)
7249 == CLASS_IMPLEMENTATION_TYPE)
7250 || (TREE_CODE (objc_implementation_context)
7251 == CATEGORY_IMPLEMENTATION_TYPE)))
7253 tree curtype = TYPE_MAIN_VARIANT
7254 (CLASS_STATIC_TEMPLATE
7255 (implementation_template));
7257 if (basetype == curtype
7258 || DERIVED_FROM_P (basetype, curtype))
7260 int priv = is_private (decl);
7262 if (priv)
7263 error ("instance variable %qs is declared private",
7264 IDENTIFIER_POINTER (DECL_NAME (decl)));
7266 return !priv;
7270 /* The 2.95.2 compiler sometimes allowed C functions to access
7271 non-@public ivars. We will let this slide for now... */
7272 if (!objc_method_context)
7274 warning (0, "instance variable %qs is %s; "
7275 "this will be a hard error in the future",
7276 IDENTIFIER_POINTER (identifier),
7277 TREE_PRIVATE (decl) ? "@private" : "@protected");
7278 return 1;
7281 error ("instance variable %qs is declared %s",
7282 IDENTIFIER_POINTER (identifier),
7283 TREE_PRIVATE (decl) ? "private" : "protected");
7284 return 0;
7289 return 1;
7292 /* Make sure all entries in CHAIN are also in LIST. */
7294 static int
7295 check_methods (tree chain, tree list, int mtype)
7297 int first = 1;
7299 while (chain)
7301 if (!lookup_method (list, chain))
7303 if (first)
7305 if (TREE_CODE (objc_implementation_context)
7306 == CLASS_IMPLEMENTATION_TYPE)
7307 warning (0, "incomplete implementation of class %qs",
7308 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7309 else if (TREE_CODE (objc_implementation_context)
7310 == CATEGORY_IMPLEMENTATION_TYPE)
7311 warning (0, "incomplete implementation of category %qs",
7312 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7313 first = 0;
7316 warning (0, "method definition for %<%c%s%> not found",
7317 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7320 chain = TREE_CHAIN (chain);
7323 return first;
7326 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7328 static int
7329 conforms_to_protocol (tree klass, tree protocol)
7331 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7333 tree p = CLASS_PROTOCOL_LIST (klass);
7334 while (p && TREE_VALUE (p) != protocol)
7335 p = TREE_CHAIN (p);
7337 if (!p)
7339 tree super = (CLASS_SUPER_NAME (klass)
7340 ? lookup_interface (CLASS_SUPER_NAME (klass))
7341 : NULL_TREE);
7342 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7343 if (!tmp)
7344 return 0;
7348 return 1;
7351 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7352 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7354 static int
7355 check_methods_accessible (tree chain, tree context, int mtype)
7357 int first = 1;
7358 tree list;
7359 tree base_context = context;
7361 while (chain)
7363 context = base_context;
7364 while (context)
7366 if (mtype == '+')
7367 list = CLASS_CLS_METHODS (context);
7368 else
7369 list = CLASS_NST_METHODS (context);
7371 if (lookup_method (list, chain))
7372 break;
7374 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7375 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7376 context = (CLASS_SUPER_NAME (context)
7377 ? lookup_interface (CLASS_SUPER_NAME (context))
7378 : NULL_TREE);
7380 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7381 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7382 context = (CLASS_NAME (context)
7383 ? lookup_interface (CLASS_NAME (context))
7384 : NULL_TREE);
7385 else
7386 abort ();
7389 if (context == NULL_TREE)
7391 if (first)
7393 if (TREE_CODE (objc_implementation_context)
7394 == CLASS_IMPLEMENTATION_TYPE)
7395 warning (0, "incomplete implementation of class %qs",
7396 IDENTIFIER_POINTER
7397 (CLASS_NAME (objc_implementation_context)));
7398 else if (TREE_CODE (objc_implementation_context)
7399 == CATEGORY_IMPLEMENTATION_TYPE)
7400 warning (0, "incomplete implementation of category %qs",
7401 IDENTIFIER_POINTER
7402 (CLASS_SUPER_NAME (objc_implementation_context)));
7403 first = 0;
7405 warning (0, "method definition for %<%c%s%> not found",
7406 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7409 chain = TREE_CHAIN (chain); /* next method... */
7411 return first;
7414 /* Check whether the current interface (accessible via
7415 'objc_implementation_context') actually implements protocol P, along
7416 with any protocols that P inherits. */
7418 static void
7419 check_protocol (tree p, const char *type, const char *name)
7421 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7423 int f1, f2;
7425 /* Ensure that all protocols have bodies! */
7426 if (warn_protocol)
7428 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7429 CLASS_CLS_METHODS (objc_implementation_context),
7430 '+');
7431 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7432 CLASS_NST_METHODS (objc_implementation_context),
7433 '-');
7435 else
7437 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7438 objc_implementation_context,
7439 '+');
7440 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7441 objc_implementation_context,
7442 '-');
7445 if (!f1 || !f2)
7446 warning (0, "%s %qs does not fully implement the %qs protocol",
7447 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7450 /* Check protocols recursively. */
7451 if (PROTOCOL_LIST (p))
7453 tree subs = PROTOCOL_LIST (p);
7454 tree super_class =
7455 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7457 while (subs)
7459 tree sub = TREE_VALUE (subs);
7461 /* If the superclass does not conform to the protocols
7462 inherited by P, then we must! */
7463 if (!super_class || !conforms_to_protocol (super_class, sub))
7464 check_protocol (sub, type, name);
7465 subs = TREE_CHAIN (subs);
7470 /* Check whether the current interface (accessible via
7471 'objc_implementation_context') actually implements the protocols listed
7472 in PROTO_LIST. */
7474 static void
7475 check_protocols (tree proto_list, const char *type, const char *name)
7477 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7479 tree p = TREE_VALUE (proto_list);
7481 check_protocol (p, type, name);
7485 /* Make sure that the class CLASS_NAME is defined
7486 CODE says which kind of thing CLASS_NAME ought to be.
7487 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7488 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7490 static tree
7491 start_class (enum tree_code code, tree class_name, tree super_name,
7492 tree protocol_list)
7494 tree klass, decl;
7496 #ifdef OBJCPLUS
7497 if (current_namespace != global_namespace) {
7498 error ("Objective-C declarations may only appear in global scope");
7500 #endif /* OBJCPLUS */
7502 if (objc_implementation_context)
7504 warning (0, "%<@end%> missing in implementation context");
7505 finish_class (objc_implementation_context);
7506 objc_ivar_chain = NULL_TREE;
7507 objc_implementation_context = NULL_TREE;
7510 klass = make_node (code);
7511 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7513 /* Check for existence of the super class, if one was specified. Note
7514 that we must have seen an @interface, not just a @class. If we
7515 are looking at a @compatibility_alias, traverse it first. */
7516 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7517 && super_name)
7519 tree super = objc_is_class_name (super_name);
7521 if (!super || !lookup_interface (super))
7523 error ("cannot find interface declaration for %qs, superclass of %qs",
7524 IDENTIFIER_POINTER (super ? super : super_name),
7525 IDENTIFIER_POINTER (class_name));
7526 super_name = NULL_TREE;
7528 else
7529 super_name = super;
7532 CLASS_NAME (klass) = class_name;
7533 CLASS_SUPER_NAME (klass) = super_name;
7534 CLASS_CLS_METHODS (klass) = NULL_TREE;
7536 if (! objc_is_class_name (class_name)
7537 && (decl = lookup_name (class_name)))
7539 error ("%qs redeclared as different kind of symbol",
7540 IDENTIFIER_POINTER (class_name));
7541 error ("previous declaration of %q+D",
7542 decl);
7545 if (code == CLASS_IMPLEMENTATION_TYPE)
7548 tree chain;
7550 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7551 if (TREE_VALUE (chain) == class_name)
7553 error ("reimplementation of class %qs",
7554 IDENTIFIER_POINTER (class_name));
7555 return error_mark_node;
7557 implemented_classes = tree_cons (NULL_TREE, class_name,
7558 implemented_classes);
7561 /* Reset for multiple classes per file. */
7562 method_slot = 0;
7564 objc_implementation_context = klass;
7566 /* Lookup the interface for this implementation. */
7568 if (!(implementation_template = lookup_interface (class_name)))
7570 warning (0, "cannot find interface declaration for %qs",
7571 IDENTIFIER_POINTER (class_name));
7572 add_class (implementation_template = objc_implementation_context,
7573 class_name);
7576 /* If a super class has been specified in the implementation,
7577 insure it conforms to the one specified in the interface. */
7579 if (super_name
7580 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7582 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7583 const char *const name =
7584 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7585 error ("conflicting super class name %qs",
7586 IDENTIFIER_POINTER (super_name));
7587 error ("previous declaration of %qs", name);
7590 else if (! super_name)
7592 CLASS_SUPER_NAME (objc_implementation_context)
7593 = CLASS_SUPER_NAME (implementation_template);
7597 else if (code == CLASS_INTERFACE_TYPE)
7599 if (lookup_interface (class_name))
7600 #ifdef OBJCPLUS
7601 error ("duplicate interface declaration for class %qs",
7602 #else
7603 warning (0, "duplicate interface declaration for class %qs",
7604 #endif
7605 IDENTIFIER_POINTER (class_name));
7606 else
7607 add_class (klass, class_name);
7609 if (protocol_list)
7610 CLASS_PROTOCOL_LIST (klass)
7611 = lookup_and_install_protocols (protocol_list);
7614 else if (code == CATEGORY_INTERFACE_TYPE)
7616 tree class_category_is_assoc_with;
7618 /* For a category, class_name is really the name of the class that
7619 the following set of methods will be associated with. We must
7620 find the interface so that can derive the objects template. */
7622 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7624 error ("cannot find interface declaration for %qs",
7625 IDENTIFIER_POINTER (class_name));
7626 exit (FATAL_EXIT_CODE);
7628 else
7629 add_category (class_category_is_assoc_with, klass);
7631 if (protocol_list)
7632 CLASS_PROTOCOL_LIST (klass)
7633 = lookup_and_install_protocols (protocol_list);
7636 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7638 /* Reset for multiple classes per file. */
7639 method_slot = 0;
7641 objc_implementation_context = klass;
7643 /* For a category, class_name is really the name of the class that
7644 the following set of methods will be associated with. We must
7645 find the interface so that can derive the objects template. */
7647 if (!(implementation_template = lookup_interface (class_name)))
7649 error ("cannot find interface declaration for %qs",
7650 IDENTIFIER_POINTER (class_name));
7651 exit (FATAL_EXIT_CODE);
7654 return klass;
7657 static tree
7658 continue_class (tree klass)
7660 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7661 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7663 struct imp_entry *imp_entry;
7665 /* Check consistency of the instance variables. */
7667 if (CLASS_RAW_IVARS (klass))
7668 check_ivars (implementation_template, klass);
7670 /* code generation */
7672 #ifdef OBJCPLUS
7673 push_lang_context (lang_name_c);
7674 #endif
7676 build_private_template (implementation_template);
7677 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7678 objc_instance_type = build_pointer_type (uprivate_record);
7680 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7682 imp_entry->next = imp_list;
7683 imp_entry->imp_context = klass;
7684 imp_entry->imp_template = implementation_template;
7686 synth_forward_declarations ();
7687 imp_entry->class_decl = UOBJC_CLASS_decl;
7688 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7689 imp_entry->has_cxx_cdtors = 0;
7691 /* Append to front and increment count. */
7692 imp_list = imp_entry;
7693 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7694 imp_count++;
7695 else
7696 cat_count++;
7698 #ifdef OBJCPLUS
7699 pop_lang_context ();
7700 #endif /* OBJCPLUS */
7702 return get_class_ivars (implementation_template, true);
7705 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7707 #ifdef OBJCPLUS
7708 push_lang_context (lang_name_c);
7709 #endif /* OBJCPLUS */
7711 build_private_template (klass);
7713 #ifdef OBJCPLUS
7714 pop_lang_context ();
7715 #endif /* OBJCPLUS */
7717 return NULL_TREE;
7720 else
7721 return error_mark_node;
7724 /* This is called once we see the "@end" in an interface/implementation. */
7726 static void
7727 finish_class (tree klass)
7729 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7731 /* All code generation is done in finish_objc. */
7733 if (implementation_template != objc_implementation_context)
7735 /* Ensure that all method listed in the interface contain bodies. */
7736 check_methods (CLASS_CLS_METHODS (implementation_template),
7737 CLASS_CLS_METHODS (objc_implementation_context), '+');
7738 check_methods (CLASS_NST_METHODS (implementation_template),
7739 CLASS_NST_METHODS (objc_implementation_context), '-');
7741 if (CLASS_PROTOCOL_LIST (implementation_template))
7742 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7743 "class",
7744 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7748 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7750 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7752 if (category)
7754 /* Ensure all method listed in the interface contain bodies. */
7755 check_methods (CLASS_CLS_METHODS (category),
7756 CLASS_CLS_METHODS (objc_implementation_context), '+');
7757 check_methods (CLASS_NST_METHODS (category),
7758 CLASS_NST_METHODS (objc_implementation_context), '-');
7760 if (CLASS_PROTOCOL_LIST (category))
7761 check_protocols (CLASS_PROTOCOL_LIST (category),
7762 "category",
7763 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7768 static tree
7769 add_protocol (tree protocol)
7771 /* Put protocol on list in reverse order. */
7772 TREE_CHAIN (protocol) = protocol_chain;
7773 protocol_chain = protocol;
7774 return protocol_chain;
7777 static tree
7778 lookup_protocol (tree ident)
7780 tree chain;
7782 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7783 if (ident == PROTOCOL_NAME (chain))
7784 return chain;
7786 return NULL_TREE;
7789 /* This function forward declares the protocols named by NAMES. If
7790 they are already declared or defined, the function has no effect. */
7792 void
7793 objc_declare_protocols (tree names)
7795 tree list;
7797 #ifdef OBJCPLUS
7798 if (current_namespace != global_namespace) {
7799 error ("Objective-C declarations may only appear in global scope");
7801 #endif /* OBJCPLUS */
7803 for (list = names; list; list = TREE_CHAIN (list))
7805 tree name = TREE_VALUE (list);
7807 if (lookup_protocol (name) == NULL_TREE)
7809 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7811 TYPE_LANG_SLOT_1 (protocol)
7812 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7813 PROTOCOL_NAME (protocol) = name;
7814 PROTOCOL_LIST (protocol) = NULL_TREE;
7815 add_protocol (protocol);
7816 PROTOCOL_DEFINED (protocol) = 0;
7817 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7822 static tree
7823 start_protocol (enum tree_code code, tree name, tree list)
7825 tree protocol;
7827 #ifdef OBJCPLUS
7828 if (current_namespace != global_namespace) {
7829 error ("Objective-C declarations may only appear in global scope");
7831 #endif /* OBJCPLUS */
7833 protocol = lookup_protocol (name);
7835 if (!protocol)
7837 protocol = make_node (code);
7838 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7840 PROTOCOL_NAME (protocol) = name;
7841 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7842 add_protocol (protocol);
7843 PROTOCOL_DEFINED (protocol) = 1;
7844 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7846 check_protocol_recursively (protocol, list);
7848 else if (! PROTOCOL_DEFINED (protocol))
7850 PROTOCOL_DEFINED (protocol) = 1;
7851 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7853 check_protocol_recursively (protocol, list);
7855 else
7857 warning (0, "duplicate declaration for protocol %qs",
7858 IDENTIFIER_POINTER (name));
7860 return protocol;
7864 /* "Encode" a data type into a string, which grows in util_obstack.
7865 ??? What is the FORMAT? Someone please document this! */
7867 static void
7868 encode_type_qualifiers (tree declspecs)
7870 tree spec;
7872 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7874 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7875 obstack_1grow (&util_obstack, 'n');
7876 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7877 obstack_1grow (&util_obstack, 'N');
7878 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7879 obstack_1grow (&util_obstack, 'o');
7880 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7881 obstack_1grow (&util_obstack, 'O');
7882 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7883 obstack_1grow (&util_obstack, 'R');
7884 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7885 obstack_1grow (&util_obstack, 'V');
7889 /* Encode a pointer type. */
7891 static void
7892 encode_pointer (tree type, int curtype, int format)
7894 tree pointer_to = TREE_TYPE (type);
7896 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7898 if (OBJC_TYPE_NAME (pointer_to)
7899 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7901 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7903 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7905 obstack_1grow (&util_obstack, '@');
7906 return;
7908 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7909 && TYPE_OBJC_INTERFACE (pointer_to))
7911 if (generating_instance_variables)
7913 obstack_1grow (&util_obstack, '@');
7914 obstack_1grow (&util_obstack, '"');
7915 obstack_grow (&util_obstack, name, strlen (name));
7916 obstack_1grow (&util_obstack, '"');
7917 return;
7919 else
7921 obstack_1grow (&util_obstack, '@');
7922 return;
7925 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7927 obstack_1grow (&util_obstack, '#');
7928 return;
7930 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7932 obstack_1grow (&util_obstack, ':');
7933 return;
7937 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7938 && TYPE_MODE (pointer_to) == QImode)
7940 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7941 ? OBJC_TYPE_NAME (pointer_to)
7942 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7944 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7946 /* It appears that "r*" means "const char *" rather than
7947 "char *const". */
7948 if (TYPE_READONLY (pointer_to))
7949 obstack_1grow (&util_obstack, 'r');
7951 obstack_1grow (&util_obstack, '*');
7952 return;
7956 /* We have a type that does not get special treatment. */
7958 /* NeXT extension */
7959 obstack_1grow (&util_obstack, '^');
7960 encode_type (pointer_to, curtype, format);
7963 static void
7964 encode_array (tree type, int curtype, int format)
7966 tree an_int_cst = TYPE_SIZE (type);
7967 tree array_of = TREE_TYPE (type);
7968 char buffer[40];
7970 /* An incomplete array is treated like a pointer. */
7971 if (an_int_cst == NULL)
7973 encode_pointer (type, curtype, format);
7974 return;
7977 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7978 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7979 else
7980 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7981 TREE_INT_CST_LOW (an_int_cst)
7982 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7984 obstack_grow (&util_obstack, buffer, strlen (buffer));
7985 encode_type (array_of, curtype, format);
7986 obstack_1grow (&util_obstack, ']');
7987 return;
7990 static void
7991 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7993 tree field = TYPE_FIELDS (type);
7995 for (; field; field = TREE_CHAIN (field))
7997 #ifdef OBJCPLUS
7998 /* C++ static members, and things that are not field at all,
7999 should not appear in the encoding. */
8000 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
8001 continue;
8002 #endif
8004 /* Recursively encode fields of embedded base classes. */
8005 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
8006 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
8008 encode_aggregate_fields (TREE_TYPE (field),
8009 pointed_to, curtype, format);
8010 continue;
8013 if (generating_instance_variables && !pointed_to)
8015 tree fname = DECL_NAME (field);
8017 obstack_1grow (&util_obstack, '"');
8019 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
8020 obstack_grow (&util_obstack,
8021 IDENTIFIER_POINTER (fname),
8022 strlen (IDENTIFIER_POINTER (fname)));
8024 obstack_1grow (&util_obstack, '"');
8027 encode_field_decl (field, curtype, format);
8031 static void
8032 encode_aggregate_within (tree type, int curtype, int format, int left,
8033 int right)
8035 tree name;
8036 /* NB: aggregates that are pointed to have slightly different encoding
8037 rules in that you never encode the names of instance variables. */
8038 int ob_size = obstack_object_size (&util_obstack);
8039 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8040 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8041 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8042 int inline_contents
8043 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8044 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8046 /* Traverse struct aliases; it is important to get the
8047 original struct and its tag name (if any). */
8048 type = TYPE_MAIN_VARIANT (type);
8049 name = OBJC_TYPE_NAME (type);
8050 /* Open parenth/bracket. */
8051 obstack_1grow (&util_obstack, left);
8053 /* Encode the struct/union tag name, or '?' if a tag was
8054 not provided. Typedef aliases do not qualify. */
8055 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8056 #ifdef OBJCPLUS
8057 /* Did this struct have a tag? */
8058 && !TYPE_WAS_ANONYMOUS (type)
8059 #endif
8061 obstack_grow (&util_obstack,
8062 IDENTIFIER_POINTER (name),
8063 strlen (IDENTIFIER_POINTER (name)));
8064 else
8065 obstack_1grow (&util_obstack, '?');
8067 /* Encode the types (and possibly names) of the inner fields,
8068 if required. */
8069 if (inline_contents)
8071 obstack_1grow (&util_obstack, '=');
8072 encode_aggregate_fields (type, pointed_to, curtype, format);
8074 /* Close parenth/bracket. */
8075 obstack_1grow (&util_obstack, right);
8078 static void
8079 encode_aggregate (tree type, int curtype, int format)
8081 enum tree_code code = TREE_CODE (type);
8083 switch (code)
8085 case RECORD_TYPE:
8087 encode_aggregate_within (type, curtype, format, '{', '}');
8088 break;
8090 case UNION_TYPE:
8092 encode_aggregate_within (type, curtype, format, '(', ')');
8093 break;
8096 case ENUMERAL_TYPE:
8097 obstack_1grow (&util_obstack, 'i');
8098 break;
8100 default:
8101 break;
8105 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8106 field type. */
8108 static void
8109 encode_next_bitfield (int width)
8111 char buffer[40];
8112 sprintf (buffer, "b%d", width);
8113 obstack_grow (&util_obstack, buffer, strlen (buffer));
8116 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8117 static void
8118 encode_type (tree type, int curtype, int format)
8120 enum tree_code code = TREE_CODE (type);
8121 char c;
8123 if (type == error_mark_node)
8124 return;
8126 if (TYPE_READONLY (type))
8127 obstack_1grow (&util_obstack, 'r');
8129 if (code == INTEGER_TYPE)
8131 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8133 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8134 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8135 case 32:
8136 if (type == long_unsigned_type_node
8137 || type == long_integer_type_node)
8138 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8139 else
8140 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8141 break;
8142 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8143 default: abort ();
8145 obstack_1grow (&util_obstack, c);
8148 else if (code == REAL_TYPE)
8150 /* Floating point types. */
8151 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8153 case 32: c = 'f'; break;
8154 case 64:
8155 case 96:
8156 case 128: c = 'd'; break;
8157 default: abort ();
8159 obstack_1grow (&util_obstack, c);
8162 else if (code == VOID_TYPE)
8163 obstack_1grow (&util_obstack, 'v');
8165 else if (code == BOOLEAN_TYPE)
8166 obstack_1grow (&util_obstack, 'B');
8168 else if (code == ARRAY_TYPE)
8169 encode_array (type, curtype, format);
8171 else if (code == POINTER_TYPE)
8172 encode_pointer (type, curtype, format);
8174 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8175 encode_aggregate (type, curtype, format);
8177 else if (code == FUNCTION_TYPE) /* '?' */
8178 obstack_1grow (&util_obstack, '?');
8180 else if (code == COMPLEX_TYPE)
8182 obstack_1grow (&util_obstack, 'j');
8183 encode_type (TREE_TYPE (type), curtype, format);
8187 static void
8188 encode_gnu_bitfield (int position, tree type, int size)
8190 enum tree_code code = TREE_CODE (type);
8191 char buffer[40];
8192 char charType = '?';
8194 if (code == INTEGER_TYPE)
8196 if (integer_zerop (TYPE_MIN_VALUE (type)))
8198 /* Unsigned integer types. */
8200 if (TYPE_MODE (type) == QImode)
8201 charType = 'C';
8202 else if (TYPE_MODE (type) == HImode)
8203 charType = 'S';
8204 else if (TYPE_MODE (type) == SImode)
8206 if (type == long_unsigned_type_node)
8207 charType = 'L';
8208 else
8209 charType = 'I';
8211 else if (TYPE_MODE (type) == DImode)
8212 charType = 'Q';
8215 else
8216 /* Signed integer types. */
8218 if (TYPE_MODE (type) == QImode)
8219 charType = 'c';
8220 else if (TYPE_MODE (type) == HImode)
8221 charType = 's';
8222 else if (TYPE_MODE (type) == SImode)
8224 if (type == long_integer_type_node)
8225 charType = 'l';
8226 else
8227 charType = 'i';
8230 else if (TYPE_MODE (type) == DImode)
8231 charType = 'q';
8234 else if (code == ENUMERAL_TYPE)
8235 charType = 'i';
8236 else
8237 abort ();
8239 sprintf (buffer, "b%d%c%d", position, charType, size);
8240 obstack_grow (&util_obstack, buffer, strlen (buffer));
8243 static void
8244 encode_field_decl (tree field_decl, int curtype, int format)
8246 tree type;
8248 #ifdef OBJCPLUS
8249 /* C++ static members, and things that are not fields at all,
8250 should not appear in the encoding. */
8251 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8252 return;
8253 #endif
8255 type = TREE_TYPE (field_decl);
8257 /* Generate the bitfield typing information, if needed. Note the difference
8258 between GNU and NeXT runtimes. */
8259 if (DECL_BIT_FIELD_TYPE (field_decl))
8261 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8263 if (flag_next_runtime)
8264 encode_next_bitfield (size);
8265 else
8266 encode_gnu_bitfield (int_bit_position (field_decl),
8267 DECL_BIT_FIELD_TYPE (field_decl), size);
8269 else
8270 encode_type (TREE_TYPE (field_decl), curtype, format);
8273 static GTY(()) tree objc_parmlist = NULL_TREE;
8275 /* Append PARM to a list of formal parameters of a method, making a necessary
8276 array-to-pointer adjustment along the way. */
8278 static void
8279 objc_push_parm (tree parm)
8281 bool relayout_needed = false;
8283 if (TREE_TYPE (parm) == error_mark_node)
8285 objc_parmlist = chainon (objc_parmlist, parm);
8286 return;
8289 /* Decay arrays and functions into pointers. */
8290 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8292 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8293 relayout_needed = true;
8295 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8297 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8298 relayout_needed = true;
8301 if (relayout_needed)
8302 relayout_decl (parm);
8305 DECL_ARG_TYPE (parm)
8306 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8308 /* Record constancy and volatility. */
8309 c_apply_type_quals_to_decl
8310 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8311 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8312 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8314 objc_parmlist = chainon (objc_parmlist, parm);
8317 /* Retrieve the formal parameter list constructed via preceding calls to
8318 objc_push_parm(). */
8320 #ifdef OBJCPLUS
8321 static tree
8322 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8323 #else
8324 static struct c_arg_info *
8325 objc_get_parm_info (int have_ellipsis)
8326 #endif
8328 #ifdef OBJCPLUS
8329 tree parm_info = objc_parmlist;
8330 objc_parmlist = NULL_TREE;
8332 return parm_info;
8333 #else
8334 tree parm_info = objc_parmlist;
8335 struct c_arg_info *arg_info;
8336 /* The C front-end requires an elaborate song and dance at
8337 this point. */
8338 push_scope ();
8339 declare_parm_level ();
8340 while (parm_info)
8342 tree next = TREE_CHAIN (parm_info);
8344 TREE_CHAIN (parm_info) = NULL_TREE;
8345 parm_info = pushdecl (parm_info);
8346 finish_decl (parm_info, NULL_TREE, NULL_TREE, NULL_TREE);
8347 parm_info = next;
8349 arg_info = get_parm_info (have_ellipsis);
8350 pop_scope ();
8351 objc_parmlist = NULL_TREE;
8352 return arg_info;
8353 #endif
8356 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8357 method definitions. In the case of instance methods, we can be more
8358 specific as to the type of 'self'. */
8360 static void
8361 synth_self_and_ucmd_args (void)
8363 tree self_type;
8365 if (objc_method_context
8366 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8367 self_type = objc_instance_type;
8368 else
8369 /* Really a `struct objc_class *'. However, we allow people to
8370 assign to self, which changes its type midstream. */
8371 self_type = objc_object_type;
8373 /* id self; */
8374 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8376 /* SEL _cmd; */
8377 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8380 /* Transform an Objective-C method definition into a static C function
8381 definition, synthesizing the first two arguments, "self" and "_cmd",
8382 in the process. */
8384 static void
8385 start_method_def (tree method)
8387 tree parmlist;
8388 #ifdef OBJCPLUS
8389 tree parm_info;
8390 #else
8391 struct c_arg_info *parm_info;
8392 #endif
8393 int have_ellipsis = 0;
8395 /* If we are defining a "dealloc" method in a non-root class, we
8396 will need to check if a [super dealloc] is missing, and warn if
8397 it is. */
8398 if(CLASS_SUPER_NAME (objc_implementation_context)
8399 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8400 should_call_super_dealloc = 1;
8401 else
8402 should_call_super_dealloc = 0;
8404 /* Required to implement _msgSuper. */
8405 objc_method_context = method;
8406 UOBJC_SUPER_decl = NULL_TREE;
8408 /* Generate prototype declarations for arguments..."new-style". */
8409 synth_self_and_ucmd_args ();
8411 /* Generate argument declarations if a keyword_decl. */
8412 parmlist = METHOD_SEL_ARGS (method);
8413 while (parmlist)
8415 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8417 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8418 objc_push_parm (parm);
8419 parmlist = TREE_CHAIN (parmlist);
8422 if (METHOD_ADD_ARGS (method))
8424 tree akey;
8426 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8427 akey; akey = TREE_CHAIN (akey))
8429 objc_push_parm (TREE_VALUE (akey));
8432 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8433 have_ellipsis = 1;
8436 parm_info = objc_get_parm_info (have_ellipsis);
8438 really_start_method (objc_method_context, parm_info);
8441 /* Return 1 if TYPE1 is equivalent to TYPE2
8442 for purposes of method overloading. */
8444 static int
8445 objc_types_are_equivalent (tree type1, tree type2)
8447 if (type1 == type2)
8448 return 1;
8450 /* Strip away indirections. */
8451 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8452 && (TREE_CODE (type1) == TREE_CODE (type2)))
8453 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8454 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8455 return 0;
8457 type1 = (TYPE_HAS_OBJC_INFO (type1)
8458 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8459 : NULL_TREE);
8460 type2 = (TYPE_HAS_OBJC_INFO (type2)
8461 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8462 : NULL_TREE);
8464 if (list_length (type1) == list_length (type2))
8466 for (; type2; type2 = TREE_CHAIN (type2))
8467 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8468 return 0;
8469 return 1;
8471 return 0;
8474 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8476 static int
8477 objc_types_share_size_and_alignment (tree type1, tree type2)
8479 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8480 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8483 /* Return 1 if PROTO1 is equivalent to PROTO2
8484 for purposes of method overloading. Ordinarily, the type signatures
8485 should match up exactly, unless STRICT is zero, in which case we
8486 shall allow differences in which the size and alignment of a type
8487 is the same. */
8489 static int
8490 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8492 tree type1, type2;
8494 /* The following test is needed in case there are hashing
8495 collisions. */
8496 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8497 return 0;
8499 /* Compare return types. */
8500 type1 = TREE_VALUE (TREE_TYPE (proto1));
8501 type2 = TREE_VALUE (TREE_TYPE (proto2));
8503 if (!objc_types_are_equivalent (type1, type2)
8504 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8505 return 0;
8507 /* Compare argument types. */
8508 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8509 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8510 type1 && type2;
8511 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8513 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8514 && (strict
8515 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8516 TREE_VALUE (type2))))
8517 return 0;
8520 return (!type1 && !type2);
8523 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8524 this occurs. ObjC method dispatches are _not_ like C++ virtual
8525 member function dispatches, and we account for the difference here. */
8526 tree
8527 #ifdef OBJCPLUS
8528 objc_fold_obj_type_ref (tree ref, tree known_type)
8529 #else
8530 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8531 tree known_type ATTRIBUTE_UNUSED)
8532 #endif
8534 #ifdef OBJCPLUS
8535 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8537 /* If the receiver does not have virtual member functions, there
8538 is nothing we can (or need to) do here. */
8539 if (!v)
8540 return NULL_TREE;
8542 /* Let C++ handle C++ virtual functions. */
8543 return cp_fold_obj_type_ref (ref, known_type);
8544 #else
8545 /* For plain ObjC, we currently do not need to do anything. */
8546 return NULL_TREE;
8547 #endif
8550 static void
8551 objc_start_function (tree name, tree type, tree attrs,
8552 #ifdef OBJCPLUS
8553 tree params
8554 #else
8555 struct c_arg_info *params
8556 #endif
8559 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8561 #ifdef OBJCPLUS
8562 DECL_ARGUMENTS (fndecl) = params;
8563 DECL_INITIAL (fndecl) = error_mark_node;
8564 DECL_EXTERNAL (fndecl) = 0;
8565 TREE_STATIC (fndecl) = 1;
8566 retrofit_lang_decl (fndecl);
8567 cplus_decl_attributes (&fndecl, attrs, 0);
8568 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8569 #else
8570 struct c_label_context_se *nstack_se;
8571 struct c_label_context_vm *nstack_vm;
8572 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8573 nstack_se->labels_def = NULL;
8574 nstack_se->labels_used = NULL;
8575 nstack_se->next = label_context_stack_se;
8576 label_context_stack_se = nstack_se;
8577 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8578 nstack_vm->labels_def = NULL;
8579 nstack_vm->labels_used = NULL;
8580 nstack_vm->scope = 0;
8581 nstack_vm->next = label_context_stack_vm;
8582 label_context_stack_vm = nstack_vm;
8583 current_function_returns_value = 0; /* Assume, until we see it does. */
8584 current_function_returns_null = 0;
8586 decl_attributes (&fndecl, attrs, 0);
8587 announce_function (fndecl);
8588 DECL_INITIAL (fndecl) = error_mark_node;
8589 DECL_EXTERNAL (fndecl) = 0;
8590 TREE_STATIC (fndecl) = 1;
8591 current_function_decl = pushdecl (fndecl);
8592 push_scope ();
8593 declare_parm_level ();
8594 DECL_RESULT (current_function_decl)
8595 = build_decl (RESULT_DECL, NULL_TREE,
8596 TREE_TYPE (TREE_TYPE (current_function_decl)));
8597 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8598 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8599 start_fname_decls ();
8600 store_parm_decls_from (params);
8601 #endif
8603 TREE_USED (current_function_decl) = 1;
8606 /* - Generate an identifier for the function. the format is "_n_cls",
8607 where 1 <= n <= nMethods, and cls is the name the implementation we
8608 are processing.
8609 - Install the return type from the method declaration.
8610 - If we have a prototype, check for type consistency. */
8612 static void
8613 really_start_method (tree method,
8614 #ifdef OBJCPLUS
8615 tree parmlist
8616 #else
8617 struct c_arg_info *parmlist
8618 #endif
8621 tree ret_type, meth_type;
8622 tree method_id;
8623 const char *sel_name, *class_name, *cat_name;
8624 char *buf;
8626 /* Synth the storage class & assemble the return type. */
8627 ret_type = TREE_VALUE (TREE_TYPE (method));
8629 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8630 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8631 cat_name = ((TREE_CODE (objc_implementation_context)
8632 == CLASS_IMPLEMENTATION_TYPE)
8633 ? NULL
8634 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8635 method_slot++;
8637 /* Make sure this is big enough for any plausible method label. */
8638 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8639 + (cat_name ? strlen (cat_name) : 0));
8641 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8642 class_name, cat_name, sel_name, method_slot);
8644 method_id = get_identifier (buf);
8646 #ifdef OBJCPLUS
8647 /* Objective-C methods cannot be overloaded, so we don't need
8648 the type encoding appended. It looks bad anyway... */
8649 push_lang_context (lang_name_c);
8650 #endif
8652 meth_type
8653 = build_function_type (ret_type,
8654 get_arg_type_list (method, METHOD_DEF, 0));
8655 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8657 /* Set self_decl from the first argument. */
8658 self_decl = DECL_ARGUMENTS (current_function_decl);
8660 /* Suppress unused warnings. */
8661 TREE_USED (self_decl) = 1;
8662 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8663 #ifdef OBJCPLUS
8664 pop_lang_context ();
8665 #endif
8667 METHOD_DEFINITION (method) = current_function_decl;
8669 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8671 if (implementation_template != objc_implementation_context)
8673 tree proto
8674 = lookup_method_static (implementation_template,
8675 METHOD_SEL_NAME (method),
8676 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8677 | OBJC_LOOKUP_NO_SUPER));
8679 if (proto)
8681 if (!comp_proto_with_proto (method, proto, 1))
8683 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8685 warning (0, "%Jconflicting types for %<%c%s%>", method,
8686 (type ? '-' : '+'),
8687 gen_method_decl (method));
8688 inform (0, "%Jprevious declaration of %<%c%s%>", proto,
8689 (type ? '-' : '+'),
8690 gen_method_decl (proto));
8693 else
8695 /* We have a method @implementation even though we did not
8696 see a corresponding @interface declaration (which is allowed
8697 by Objective-C rules). Go ahead and place the method in
8698 the @interface anyway, so that message dispatch lookups
8699 will see it. */
8700 tree interface = implementation_template;
8702 if (TREE_CODE (objc_implementation_context)
8703 == CATEGORY_IMPLEMENTATION_TYPE)
8704 interface = lookup_category
8705 (interface,
8706 CLASS_SUPER_NAME (objc_implementation_context));
8708 if (interface)
8709 objc_add_method (interface, copy_node (method),
8710 TREE_CODE (method) == CLASS_METHOD_DECL);
8715 static void *UOBJC_SUPER_scope = 0;
8717 /* _n_Method (id self, SEL sel, ...)
8719 struct objc_super _S;
8720 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8721 } */
8723 static tree
8724 get_super_receiver (void)
8726 if (objc_method_context)
8728 tree super_expr, super_expr_list;
8730 if (!UOBJC_SUPER_decl)
8732 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8733 objc_super_template);
8734 /* This prevents `unused variable' warnings when compiling with -Wall. */
8735 TREE_USED (UOBJC_SUPER_decl) = 1;
8736 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8737 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE, NULL_TREE);
8738 UOBJC_SUPER_scope = objc_get_current_scope ();
8741 /* Set receiver to self. */
8742 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8743 super_expr = build_modify_expr (input_location,
8744 super_expr, NOP_EXPR, self_decl,
8745 NULL_TREE);
8746 super_expr_list = super_expr;
8748 /* Set class to begin searching. */
8749 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8750 get_identifier ("super_class"));
8752 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8754 /* [_cls, __cls]Super are "pre-built" in
8755 synth_forward_declarations. */
8757 super_expr = build_modify_expr (input_location, super_expr, NOP_EXPR,
8758 ((TREE_CODE (objc_method_context)
8759 == INSTANCE_METHOD_DECL)
8760 ? ucls_super_ref
8761 : uucls_super_ref),
8762 NULL_TREE);
8765 else
8766 /* We have a category. */
8768 tree super_name = CLASS_SUPER_NAME (implementation_template);
8769 tree super_class;
8771 /* Barf if super used in a category of Object. */
8772 if (!super_name)
8774 error ("no super class declared in interface for %qs",
8775 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8776 return error_mark_node;
8779 if (flag_next_runtime && !flag_zero_link)
8781 super_class = objc_get_class_reference (super_name);
8782 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8783 /* If we are in a class method, we must retrieve the
8784 _metaclass_ for the current class, pointed at by
8785 the class's "isa" pointer. The following assumes that
8786 "isa" is the first ivar in a class (which it must be). */
8787 super_class
8788 = build_indirect_ref
8789 (input_location,
8790 build_c_cast (build_pointer_type (objc_class_type),
8791 super_class), "unary *");
8793 else
8795 add_class_reference (super_name);
8796 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8797 ? objc_get_class_decl : objc_get_meta_class_decl);
8798 assemble_external (super_class);
8799 super_class
8800 = build_function_call
8801 (super_class,
8802 build_tree_list
8803 (NULL_TREE,
8804 my_build_string_pointer
8805 (IDENTIFIER_LENGTH (super_name) + 1,
8806 IDENTIFIER_POINTER (super_name))));
8809 super_expr
8810 = build_modify_expr (input_location, super_expr, NOP_EXPR,
8811 build_c_cast (TREE_TYPE (super_expr),
8812 super_class),
8813 NULL_TREE);
8816 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8818 super_expr = build_unary_op (input_location,
8819 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8820 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8822 return super_expr_list;
8824 else
8826 error ("[super ...] must appear in a method context");
8827 return error_mark_node;
8831 /* When exiting a scope, sever links to a 'super' declaration (if any)
8832 therein contained. */
8834 void
8835 objc_clear_super_receiver (void)
8837 if (objc_method_context
8838 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8839 UOBJC_SUPER_decl = 0;
8840 UOBJC_SUPER_scope = 0;
8844 void
8845 objc_finish_method_definition (tree fndecl)
8847 /* We cannot validly inline ObjC methods, at least not without a language
8848 extension to declare that a method need not be dynamically
8849 dispatched, so suppress all thoughts of doing so. */
8850 DECL_UNINLINABLE (fndecl) = 1;
8852 #ifndef OBJCPLUS
8853 /* The C++ front-end will have called finish_function() for us. */
8854 finish_function ();
8855 #endif
8857 METHOD_ENCODING (objc_method_context)
8858 = encode_method_prototype (objc_method_context);
8860 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8861 since the optimizer may find "may be used before set" errors. */
8862 objc_method_context = NULL_TREE;
8864 if (should_call_super_dealloc)
8865 warning (0, "method possibly missing a [super dealloc] call");
8868 #if 0
8870 lang_report_error_function (tree decl)
8872 if (objc_method_context)
8874 fprintf (stderr, "In method %qs\n",
8875 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8876 return 1;
8879 else
8880 return 0;
8882 #endif
8884 /* Given a tree DECL node, produce a printable description of it in the given
8885 buffer, overwriting the buffer. */
8887 static char *
8888 gen_declaration (tree decl)
8890 errbuf[0] = '\0';
8892 if (DECL_P (decl))
8894 gen_type_name_0 (TREE_TYPE (decl));
8896 if (DECL_NAME (decl))
8898 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8899 strcat (errbuf, " ");
8901 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8904 if (DECL_INITIAL (decl)
8905 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8906 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8907 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8910 return errbuf;
8913 /* Given a tree TYPE node, produce a printable description of it in the given
8914 buffer, overwriting the buffer. */
8916 static char *
8917 gen_type_name_0 (tree type)
8919 tree orig = type, proto;
8921 if (TYPE_P (type) && TYPE_NAME (type))
8922 type = TYPE_NAME (type);
8923 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8925 tree inner = TREE_TYPE (type);
8927 while (TREE_CODE (inner) == ARRAY_TYPE)
8928 inner = TREE_TYPE (inner);
8930 gen_type_name_0 (inner);
8932 if (!POINTER_TYPE_P (inner))
8933 strcat (errbuf, " ");
8935 if (POINTER_TYPE_P (type))
8936 strcat (errbuf, "*");
8937 else
8938 while (type != inner)
8940 strcat (errbuf, "[");
8942 if (TYPE_DOMAIN (type))
8944 char sz[20];
8946 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8947 (TREE_INT_CST_LOW
8948 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8949 strcat (errbuf, sz);
8952 strcat (errbuf, "]");
8953 type = TREE_TYPE (type);
8956 goto exit_function;
8959 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8960 type = DECL_NAME (type);
8962 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8963 ? IDENTIFIER_POINTER (type)
8964 : "");
8966 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8967 if (objc_is_id (orig))
8968 orig = TREE_TYPE (orig);
8970 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8972 if (proto)
8974 strcat (errbuf, " <");
8976 while (proto) {
8977 strcat (errbuf,
8978 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8979 proto = TREE_CHAIN (proto);
8980 strcat (errbuf, proto ? ", " : ">");
8984 exit_function:
8985 return errbuf;
8988 static char *
8989 gen_type_name (tree type)
8991 errbuf[0] = '\0';
8993 return gen_type_name_0 (type);
8996 /* Given a method tree, put a printable description into the given
8997 buffer (overwriting) and return a pointer to the buffer. */
8999 static char *
9000 gen_method_decl (tree method)
9002 tree chain;
9004 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
9005 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
9006 strcat (errbuf, ")");
9007 chain = METHOD_SEL_ARGS (method);
9009 if (chain)
9011 /* We have a chain of keyword_decls. */
9014 if (KEYWORD_KEY_NAME (chain))
9015 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
9017 strcat (errbuf, ":(");
9018 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9019 strcat (errbuf, ")");
9021 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9022 if ((chain = TREE_CHAIN (chain)))
9023 strcat (errbuf, " ");
9025 while (chain);
9027 if (METHOD_ADD_ARGS (method))
9029 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9031 /* Know we have a chain of parm_decls. */
9032 while (chain)
9034 strcat (errbuf, ", ");
9035 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9036 chain = TREE_CHAIN (chain);
9039 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9040 strcat (errbuf, ", ...");
9044 else
9045 /* We have a unary selector. */
9046 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9048 return errbuf;
9051 /* Debug info. */
9054 /* Dump an @interface declaration of the supplied class CHAIN to the
9055 supplied file FP. Used to implement the -gen-decls option (which
9056 prints out an @interface declaration of all classes compiled in
9057 this run); potentially useful for debugging the compiler too. */
9058 static void
9059 dump_interface (FILE *fp, tree chain)
9061 /* FIXME: A heap overflow here whenever a method (or ivar)
9062 declaration is so long that it doesn't fit in the buffer. The
9063 code and all the related functions should be rewritten to avoid
9064 using fixed size buffers. */
9065 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9066 tree ivar_decls = CLASS_RAW_IVARS (chain);
9067 tree nst_methods = CLASS_NST_METHODS (chain);
9068 tree cls_methods = CLASS_CLS_METHODS (chain);
9070 fprintf (fp, "\n@interface %s", my_name);
9072 /* CLASS_SUPER_NAME is used to store the superclass name for
9073 classes, and the category name for categories. */
9074 if (CLASS_SUPER_NAME (chain))
9076 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9078 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9079 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9081 fprintf (fp, " (%s)\n", name);
9083 else
9085 fprintf (fp, " : %s\n", name);
9088 else
9089 fprintf (fp, "\n");
9091 /* FIXME - the following doesn't seem to work at the moment. */
9092 if (ivar_decls)
9094 fprintf (fp, "{\n");
9097 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9098 ivar_decls = TREE_CHAIN (ivar_decls);
9100 while (ivar_decls);
9101 fprintf (fp, "}\n");
9104 while (nst_methods)
9106 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9107 nst_methods = TREE_CHAIN (nst_methods);
9110 while (cls_methods)
9112 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9113 cls_methods = TREE_CHAIN (cls_methods);
9116 fprintf (fp, "@end\n");
9119 /* Demangle function for Objective-C */
9120 static const char *
9121 objc_demangle (const char *mangled)
9123 char *demangled, *cp;
9125 if (mangled[0] == '_' &&
9126 (mangled[1] == 'i' || mangled[1] == 'c') &&
9127 mangled[2] == '_')
9129 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9130 if (mangled[1] == 'i')
9131 *cp++ = '-'; /* for instance method */
9132 else
9133 *cp++ = '+'; /* for class method */
9134 *cp++ = '['; /* opening left brace */
9135 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9136 while (*cp && *cp == '_')
9137 cp++; /* skip any initial underbars in class name */
9138 cp = strchr(cp, '_'); /* find first non-initial underbar */
9139 if (cp == NULL)
9141 free(demangled); /* not mangled name */
9142 return mangled;
9144 if (cp[1] == '_') /* easy case: no category name */
9146 *cp++ = ' '; /* replace two '_' with one ' ' */
9147 strcpy(cp, mangled + (cp - demangled) + 2);
9149 else
9151 *cp++ = '('; /* less easy case: category name */
9152 cp = strchr(cp, '_');
9153 if (cp == 0)
9155 free(demangled); /* not mangled name */
9156 return mangled;
9158 *cp++ = ')';
9159 *cp++ = ' '; /* overwriting 1st char of method name... */
9160 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9162 while (*cp && *cp == '_')
9163 cp++; /* skip any initial underbars in method name */
9164 for (; *cp; cp++)
9165 if (*cp == '_')
9166 *cp = ':'; /* replace remaining '_' with ':' */
9167 *cp++ = ']'; /* closing right brace */
9168 *cp++ = 0; /* string terminator */
9169 return demangled;
9171 else
9172 return mangled; /* not an objc mangled name */
9175 const char *
9176 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9178 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9181 static void
9182 init_objc (void)
9184 gcc_obstack_init (&util_obstack);
9185 util_firstobj = (char *) obstack_finish (&util_obstack);
9187 errbuf = XNEWVEC (char, 1024 * 10);
9188 hash_init ();
9189 synth_module_prologue ();
9192 static void
9193 finish_objc (void)
9195 struct imp_entry *impent;
9196 tree chain;
9197 /* The internally generated initializers appear to have missing braces.
9198 Don't warn about this. */
9199 int save_warn_missing_braces = warn_missing_braces;
9200 warn_missing_braces = 0;
9202 /* A missing @end may not be detected by the parser. */
9203 if (objc_implementation_context)
9205 warning (0, "%<@end%> missing in implementation context");
9206 finish_class (objc_implementation_context);
9207 objc_ivar_chain = NULL_TREE;
9208 objc_implementation_context = NULL_TREE;
9211 /* Process the static instances here because initialization of objc_symtab
9212 depends on them. */
9213 if (objc_static_instances)
9214 generate_static_references ();
9216 if (imp_list || class_names_chain
9217 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9218 generate_objc_symtab_decl ();
9220 for (impent = imp_list; impent; impent = impent->next)
9222 objc_implementation_context = impent->imp_context;
9223 implementation_template = impent->imp_template;
9225 UOBJC_CLASS_decl = impent->class_decl;
9226 UOBJC_METACLASS_decl = impent->meta_decl;
9228 /* Dump the @interface of each class as we compile it, if the
9229 -gen-decls option is in use. TODO: Dump the classes in the
9230 order they were found, rather than in reverse order as we
9231 are doing now. */
9232 if (flag_gen_declaration)
9234 dump_interface (gen_declaration_file, objc_implementation_context);
9237 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9239 /* all of the following reference the string pool... */
9240 generate_ivar_lists ();
9241 generate_dispatch_tables ();
9242 generate_shared_structures (impent->has_cxx_cdtors
9243 ? CLS_HAS_CXX_STRUCTORS
9244 : 0);
9246 else
9248 generate_dispatch_tables ();
9249 generate_category (objc_implementation_context);
9253 /* If we are using an array of selectors, we must always
9254 finish up the array decl even if no selectors were used. */
9255 if (! flag_next_runtime || sel_ref_chain)
9256 build_selector_translation_table ();
9258 if (protocol_chain)
9259 generate_protocols ();
9261 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9262 generate_objc_image_info ();
9264 /* Arrange for ObjC data structures to be initialized at run time. */
9265 if (objc_implementation_context || class_names_chain || objc_static_instances
9266 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9268 build_module_descriptor ();
9270 if (!flag_next_runtime)
9271 build_module_initializer_routine ();
9274 /* Dump the class references. This forces the appropriate classes
9275 to be linked into the executable image, preserving unix archive
9276 semantics. This can be removed when we move to a more dynamically
9277 linked environment. */
9279 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9281 handle_class_ref (chain);
9282 if (TREE_PURPOSE (chain))
9283 generate_classref_translation_entry (chain);
9286 for (impent = imp_list; impent; impent = impent->next)
9287 handle_impent (impent);
9289 if (warn_selector)
9291 int slot;
9292 hash hsh;
9294 /* Run through the selector hash tables and print a warning for any
9295 selector which has multiple methods. */
9297 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9299 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9300 check_duplicates (hsh, 0, 1);
9301 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9302 check_duplicates (hsh, 0, 1);
9306 warn_missing_braces = save_warn_missing_braces;
9309 /* Subroutines of finish_objc. */
9311 static void
9312 generate_classref_translation_entry (tree chain)
9314 tree expr, decl, type;
9316 decl = TREE_PURPOSE (chain);
9317 type = TREE_TYPE (decl);
9319 expr = add_objc_string (TREE_VALUE (chain), class_names);
9320 expr = convert (type, expr); /* cast! */
9322 /* The decl that is the one that we
9323 forward declared in build_class_reference. */
9324 finish_var_decl (decl, expr);
9325 return;
9328 static void
9329 handle_class_ref (tree chain)
9331 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9332 char *string = (char *) alloca (strlen (name) + 30);
9333 tree decl;
9334 tree exp;
9336 sprintf (string, "%sobjc_class_name_%s",
9337 (flag_next_runtime ? "." : "__"), name);
9339 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9340 if (flag_next_runtime)
9342 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9343 return;
9345 #endif
9347 /* Make a decl for this name, so we can use its address in a tree. */
9348 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9349 DECL_EXTERNAL (decl) = 1;
9350 TREE_PUBLIC (decl) = 1;
9352 pushdecl (decl);
9353 rest_of_decl_compilation (decl, 0, 0);
9355 /* Make a decl for the address. */
9356 sprintf (string, "%sobjc_class_ref_%s",
9357 (flag_next_runtime ? "." : "__"), name);
9358 exp = build1 (ADDR_EXPR, string_type_node, decl);
9359 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9360 DECL_INITIAL (decl) = exp;
9361 TREE_STATIC (decl) = 1;
9362 TREE_USED (decl) = 1;
9363 /* Force the output of the decl as this forces the reference of the class. */
9364 mark_decl_referenced (decl);
9366 pushdecl (decl);
9367 rest_of_decl_compilation (decl, 0, 0);
9370 static void
9371 handle_impent (struct imp_entry *impent)
9373 char *string;
9375 objc_implementation_context = impent->imp_context;
9376 implementation_template = impent->imp_template;
9378 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9380 const char *const class_name =
9381 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9383 string = (char *) alloca (strlen (class_name) + 30);
9385 sprintf (string, "%sobjc_class_name_%s",
9386 (flag_next_runtime ? "." : "__"), class_name);
9388 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9390 const char *const class_name =
9391 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9392 const char *const class_super_name =
9393 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9395 string = (char *) alloca (strlen (class_name)
9396 + strlen (class_super_name) + 30);
9398 /* Do the same for categories. Even though no references to
9399 these symbols are generated automatically by the compiler, it
9400 gives you a handle to pull them into an archive by hand. */
9401 sprintf (string, "*%sobjc_category_name_%s_%s",
9402 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9404 else
9405 return;
9407 #ifdef ASM_DECLARE_CLASS_REFERENCE
9408 if (flag_next_runtime)
9410 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9411 return;
9413 else
9414 #endif
9416 tree decl, init;
9418 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9419 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9420 TREE_PUBLIC (decl) = 1;
9421 TREE_READONLY (decl) = 1;
9422 TREE_USED (decl) = 1;
9423 TREE_CONSTANT (decl) = 1;
9424 DECL_CONTEXT (decl) = 0;
9425 DECL_ARTIFICIAL (decl) = 1;
9426 DECL_INITIAL (decl) = init;
9427 assemble_variable (decl, 1, 0, 0);
9431 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9432 later requires that ObjC translation units participating in F&C be
9433 specially marked. The following routine accomplishes this. */
9435 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9437 static void
9438 generate_objc_image_info (void)
9440 tree decl, initlist;
9441 int flags
9442 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9443 | (flag_objc_gc ? 2 : 0));
9445 decl = start_var_decl (build_array_type
9446 (integer_type_node,
9447 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9448 "_OBJC_IMAGE_INFO");
9450 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9451 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9452 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9454 finish_var_decl (decl, initlist);
9457 /* Look up ID as an instance variable. OTHER contains the result of
9458 the C or C++ lookup, which we may want to use instead. */
9460 tree
9461 objc_lookup_ivar (tree other, tree id)
9463 tree ivar;
9465 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9466 if (!objc_method_context)
9467 return other;
9469 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9470 /* We have a message to super. */
9471 return get_super_receiver ();
9473 /* In a class method, look up an instance variable only as a last
9474 resort. */
9475 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9476 && other && other != error_mark_node)
9477 return other;
9479 /* Look up the ivar, but do not use it if it is not accessible. */
9480 ivar = is_ivar (objc_ivar_chain, id);
9482 if (!ivar || is_private (ivar))
9483 return other;
9485 /* In an instance method, a local variable (or parameter) may hide the
9486 instance variable. */
9487 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9488 && other && other != error_mark_node
9489 #ifdef OBJCPLUS
9490 && CP_DECL_CONTEXT (other) != global_namespace)
9491 #else
9492 && !DECL_FILE_SCOPE_P (other))
9493 #endif
9495 warning (0, "local declaration of %qs hides instance variable",
9496 IDENTIFIER_POINTER (id));
9498 return other;
9501 /* At this point, we are either in an instance method with no obscuring
9502 local definitions, or in a class method with no alternate definitions
9503 at all. */
9504 return build_ivar_reference (id);
9507 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9508 needs to be done if we are calling a function through a cast. */
9510 tree
9511 objc_rewrite_function_call (tree function, tree first_param)
9513 if (TREE_CODE (function) == NOP_EXPR
9514 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9515 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9516 == FUNCTION_DECL)
9518 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9519 TREE_OPERAND (function, 0),
9520 first_param, size_zero_node);
9523 return function;
9526 /* Look for the special case of OBJC_TYPE_REF with the address of
9527 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9528 of its cousins). */
9530 enum gimplify_status
9531 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9533 enum gimplify_status r0, r1;
9534 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9535 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9536 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9537 == FUNCTION_DECL)
9539 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9540 value of the OBJ_TYPE_REF, so force them to be emitted
9541 during subexpression evaluation rather than after the
9542 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9543 C to use direct rather than indirect calls when the
9544 object expression has a postincrement. */
9545 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9546 is_gimple_val, fb_rvalue);
9547 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9548 is_gimple_val, fb_rvalue);
9550 return MIN (r0, r1);
9553 #ifdef OBJCPLUS
9554 return cp_gimplify_expr (expr_p, pre_p, post_p);
9555 #else
9556 return c_gimplify_expr (expr_p, pre_p, post_p);
9557 #endif
9560 #include "gt-objc-objc-act.h"