Updated for libbid move.
[official-gcc.git] / gcc / objc / objc-act.c
blob19475e2f8d8dc74748c0eca823a22001792bdedd
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
57 #include "c-common.h"
58 #include "c-pragma.h"
59 #include "flags.h"
60 #include "langhooks.h"
61 #include "objc-act.h"
62 #include "input.h"
63 #include "except.h"
64 #include "function.h"
65 #include "output.h"
66 #include "toplev.h"
67 #include "ggc.h"
68 #include "varray.h"
69 #include "debug.h"
70 #include "target.h"
71 #include "diagnostic.h"
72 #include "cgraph.h"
73 #include "tree-iterator.h"
74 #include "libfuncs.h"
75 #include "hashtab.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
84 #ifdef OBJCPLUS
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
87 #endif /* OBJCPLUS */
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
95 do { \
96 char *temp; \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
99 (CLASS_NAME), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
101 (SEL_NAME)); \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
104 } while (0)
105 #endif
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
110 #endif
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
114 #endif
116 /* Set up for use of obstacks. */
118 #include "obstack.h"
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
125 char *util_firstobj;
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
157 #ifdef OBJCPLUS
158 static void objc_start_function (tree, tree, tree, tree);
159 #else
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
161 #endif
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
174 #ifndef OBJCPLUS
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
177 #endif
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
189 #ifdef OBJCPLUS
190 static void objc_generate_cxx_cdtors (void);
191 #endif
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
204 enum string_section
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
220 /* Type encoding. */
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
226 #ifdef OBJCPLUS
227 static void really_start_method (tree, tree);
228 #else
229 static void really_start_method (tree, struct c_arg_info *);
230 #endif
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
233 #ifdef OBJCPLUS
234 static tree objc_get_parm_info (int);
235 #else
236 static struct c_arg_info *objc_get_parm_info (int);
237 #endif
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
256 ATTRIBUTE_NORETURN;
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
288 NeXT runtime. */
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
371 #define BUFSIZE 1024
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
391 tree literal;
393 /* The resulting constant string. */
394 tree constructor;
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
402 tree type;
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
420 static void
421 generate_struct_by_value_array (void)
423 tree type;
424 tree field_decl, field_decl_chain;
425 int i, j;
426 int aggregate_in_mem[32];
427 int found = 0;
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
432 char buffer[5];
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
439 buffer);
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
446 buffer);
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
453 found = 1;
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
458 if (found)
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
462 break;
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
471 printf ("\n};\n");
474 exit (0);
477 bool
478 objc_init (void)
480 #ifdef OBJCPLUS
481 if (cxx_init () == false)
482 #else
483 if (c_objc_common_init () == false)
484 #endif
485 return false;
487 #ifndef USE_MAPPED_LOCATION
488 /* Force the line number back to 0; check_newline will have
489 raised it to 1, which will make the builtin functions appear
490 not to be built in. */
491 input_line = 0;
492 #endif
494 /* If gen_declaration desired, open the output file. */
495 if (flag_gen_declaration)
497 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
498 gen_declaration_file = fopen (dumpname, "w");
499 if (gen_declaration_file == 0)
500 fatal_error ("can't open %s: %m", dumpname);
501 free (dumpname);
504 if (flag_next_runtime)
506 TAG_GETCLASS = "objc_getClass";
507 TAG_GETMETACLASS = "objc_getMetaClass";
508 TAG_MSGSEND = "objc_msgSend";
509 TAG_MSGSENDSUPER = "objc_msgSendSuper";
510 TAG_MSGSEND_STRET = "objc_msgSend_stret";
511 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
512 default_constant_string_class_name = "NSConstantString";
514 else
516 TAG_GETCLASS = "objc_get_class";
517 TAG_GETMETACLASS = "objc_get_meta_class";
518 TAG_MSGSEND = "objc_msg_lookup";
519 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
520 /* GNU runtime does not provide special functions to support
521 structure-returning methods. */
522 default_constant_string_class_name = "NXConstantString";
523 flag_typed_selectors = 1;
526 init_objc ();
528 if (print_struct_values)
529 generate_struct_by_value_array ();
531 return true;
534 void
535 objc_finish_file (void)
537 mark_referenced_methods ();
539 #ifdef OBJCPLUS
540 /* We need to instantiate templates _before_ we emit ObjC metadata;
541 if we do not, some metadata (such as selectors) may go missing. */
542 at_eof = 1;
543 instantiate_pending_templates (0);
544 #endif
546 /* Finalize Objective-C runtime data. No need to generate tables
547 and code if only checking syntax, or if generating a PCH file. */
548 if (!flag_syntax_only && !pch_file)
549 finish_objc ();
551 if (gen_declaration_file)
552 fclose (gen_declaration_file);
555 /* Return the first occurrence of a method declaration corresponding
556 to sel_name in rproto_list. Search rproto_list recursively.
557 If is_class is 0, search for instance methods, otherwise for class
558 methods. */
559 static tree
560 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
561 int is_class)
563 tree rproto, p;
564 tree fnd = 0;
566 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
568 p = TREE_VALUE (rproto);
570 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
572 if ((fnd = lookup_method (is_class
573 ? PROTOCOL_CLS_METHODS (p)
574 : PROTOCOL_NST_METHODS (p), sel_name)))
576 else if (PROTOCOL_LIST (p))
577 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
578 sel_name, is_class);
580 else
582 ; /* An identifier...if we could not find a protocol. */
585 if (fnd)
586 return fnd;
589 return 0;
592 static tree
593 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
595 tree rproto, p;
597 /* Make sure the protocol is supported by the object on the rhs. */
598 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
600 tree fnd = 0;
601 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
603 p = TREE_VALUE (rproto);
605 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
607 if (lproto == p)
608 fnd = lproto;
610 else if (PROTOCOL_LIST (p))
611 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
614 if (fnd)
615 return fnd;
618 else
620 ; /* An identifier...if we could not find a protocol. */
623 return 0;
626 void
627 objc_start_class_interface (tree class, tree super_class, tree protos)
629 objc_interface_context
630 = objc_ivar_context
631 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
632 objc_public_flag = 0;
635 void
636 objc_start_category_interface (tree class, tree categ, tree protos)
638 objc_interface_context
639 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
640 objc_ivar_chain
641 = continue_class (objc_interface_context);
644 void
645 objc_start_protocol (tree name, tree protos)
647 objc_interface_context
648 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
651 void
652 objc_continue_interface (void)
654 objc_ivar_chain
655 = continue_class (objc_interface_context);
658 void
659 objc_finish_interface (void)
661 finish_class (objc_interface_context);
662 objc_interface_context = NULL_TREE;
665 void
666 objc_start_class_implementation (tree class, tree super_class)
668 objc_implementation_context
669 = objc_ivar_context
670 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
671 objc_public_flag = 0;
674 void
675 objc_start_category_implementation (tree class, tree categ)
677 objc_implementation_context
678 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
679 objc_ivar_chain
680 = continue_class (objc_implementation_context);
683 void
684 objc_continue_implementation (void)
686 objc_ivar_chain
687 = continue_class (objc_implementation_context);
690 void
691 objc_finish_implementation (void)
693 #ifdef OBJCPLUS
694 if (flag_objc_call_cxx_cdtors)
695 objc_generate_cxx_cdtors ();
696 #endif
698 if (objc_implementation_context)
700 finish_class (objc_implementation_context);
701 objc_ivar_chain = NULL_TREE;
702 objc_implementation_context = NULL_TREE;
704 else
705 warning (0, "%<@end%> must appear in an @implementation context");
708 void
709 objc_set_visibility (int visibility)
711 objc_public_flag = visibility;
714 void
715 objc_set_method_type (enum tree_code type)
717 objc_inherit_code = (type == PLUS_EXPR
718 ? CLASS_METHOD_DECL
719 : INSTANCE_METHOD_DECL);
722 tree
723 objc_build_method_signature (tree rettype, tree selector,
724 tree optparms, bool ellipsis)
726 return build_method_decl (objc_inherit_code, rettype, selector,
727 optparms, ellipsis);
730 void
731 objc_add_method_declaration (tree decl)
733 if (!objc_interface_context)
734 fatal_error ("method declaration not in @interface context");
736 objc_add_method (objc_interface_context,
737 decl,
738 objc_inherit_code == CLASS_METHOD_DECL);
741 void
742 objc_start_method_definition (tree decl)
744 if (!objc_implementation_context)
745 fatal_error ("method definition not in @implementation context");
747 objc_add_method (objc_implementation_context,
748 decl,
749 objc_inherit_code == CLASS_METHOD_DECL);
750 start_method_def (decl);
753 void
754 objc_add_instance_variable (tree decl)
756 (void) add_instance_variable (objc_ivar_context,
757 objc_public_flag,
758 decl);
761 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
762 an '@'. */
765 objc_is_reserved_word (tree ident)
767 unsigned char code = C_RID_CODE (ident);
769 return (OBJC_IS_AT_KEYWORD (code)
770 #ifdef OBJCPLUS
771 || code == RID_CLASS || code == RID_PUBLIC
772 || code == RID_PROTECTED || code == RID_PRIVATE
773 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
774 #endif
778 /* Return true if TYPE is 'id'. */
780 static bool
781 objc_is_object_id (tree type)
783 return OBJC_TYPE_NAME (type) == objc_object_id;
786 static bool
787 objc_is_class_id (tree type)
789 return OBJC_TYPE_NAME (type) == objc_class_id;
792 /* Construct a C struct with same name as CLASS, a base struct with tag
793 SUPER_NAME (if any), and FIELDS indicated. */
795 static tree
796 objc_build_struct (tree class, tree fields, tree super_name)
798 tree name = CLASS_NAME (class);
799 tree s = start_struct (RECORD_TYPE, name);
800 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
801 tree t, objc_info = NULL_TREE;
803 if (super)
805 /* Prepend a packed variant of the base class into the layout. This
806 is necessary to preserve ObjC ABI compatibility. */
807 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
808 tree field = TYPE_FIELDS (super);
810 while (field && TREE_CHAIN (field)
811 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
812 field = TREE_CHAIN (field);
814 /* For ObjC ABI purposes, the "packed" size of a base class is the
815 the sum of the offset and the size (in bits) of the last field
816 in the class. */
817 DECL_SIZE (base)
818 = (field && TREE_CODE (field) == FIELD_DECL
819 ? size_binop (PLUS_EXPR,
820 size_binop (PLUS_EXPR,
821 size_binop
822 (MULT_EXPR,
823 convert (bitsizetype,
824 DECL_FIELD_OFFSET (field)),
825 bitsize_int (BITS_PER_UNIT)),
826 DECL_FIELD_BIT_OFFSET (field)),
827 DECL_SIZE (field))
828 : bitsize_zero_node);
829 DECL_SIZE_UNIT (base)
830 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
831 size_int (BITS_PER_UNIT));
832 DECL_ARTIFICIAL (base) = 1;
833 DECL_ALIGN (base) = 1;
834 DECL_FIELD_CONTEXT (base) = s;
835 #ifdef OBJCPLUS
836 DECL_FIELD_IS_BASE (base) = 1;
838 if (fields)
839 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
840 #endif /* are following the ObjC ABI here. */
841 TREE_CHAIN (base) = fields;
842 fields = base;
845 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
846 in all variants of this RECORD_TYPE to be clobbered, but it is therein
847 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
848 Hence, we must squirrel away the ObjC-specific information before calling
849 finish_struct(), and then reinstate it afterwards. */
851 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
852 objc_info
853 = chainon (objc_info,
854 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
856 /* Point the struct at its related Objective-C class. */
857 INIT_TYPE_OBJC_INFO (s);
858 TYPE_OBJC_INTERFACE (s) = class;
860 s = finish_struct (s, fields, NULL_TREE);
862 for (t = TYPE_NEXT_VARIANT (s); t;
863 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
865 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
866 /* Replace the IDENTIFIER_NODE with an actual @interface. */
867 TYPE_OBJC_INTERFACE (t) = class;
870 /* Use TYPE_BINFO structures to point at the super class, if any. */
871 objc_xref_basetypes (s, super);
873 /* Mark this struct as a class template. */
874 CLASS_STATIC_TEMPLATE (class) = s;
876 return s;
879 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
880 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
881 process. */
882 static tree
883 objc_build_volatilized_type (tree type)
885 tree t;
887 /* Check if we have not constructed the desired variant already. */
888 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
890 /* The type qualifiers must (obviously) match up. */
891 if (!TYPE_VOLATILE (t)
892 || (TYPE_READONLY (t) != TYPE_READONLY (type))
893 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
894 continue;
896 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
897 info, if any) must match up. */
898 if (POINTER_TYPE_P (t)
899 && (TREE_TYPE (t) != TREE_TYPE (type)))
900 continue;
902 /* Everything matches up! */
903 return t;
906 /* Ok, we could not re-use any of the pre-existing variants. Create
907 a new one. */
908 t = build_variant_type_copy (type);
909 TYPE_VOLATILE (t) = 1;
911 /* Set up the canonical type information. */
912 if (TYPE_STRUCTURAL_EQUALITY_P (type))
913 SET_TYPE_STRUCTURAL_EQUALITY (t);
914 else if (TYPE_CANONICAL (type) != type)
915 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
916 else
917 TYPE_CANONICAL (t) = t;
919 return t;
922 /* Mark DECL as being 'volatile' for purposes of Darwin
923 _setjmp()/_longjmp() exception handling. Called from
924 objc_mark_locals_volatile(). */
925 void
926 objc_volatilize_decl (tree decl)
928 /* Do not mess with variables that are 'static' or (already)
929 'volatile'. */
930 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
931 && (TREE_CODE (decl) == VAR_DECL
932 || TREE_CODE (decl) == PARM_DECL))
934 tree t = TREE_TYPE (decl);
935 struct volatilized_type key;
936 void **loc;
938 t = objc_build_volatilized_type (t);
939 key.type = t;
940 loc = htab_find_slot (volatilized_htab, &key, INSERT);
942 if (!*loc)
944 *loc = ggc_alloc (sizeof (key));
945 ((struct volatilized_type *) *loc)->type = t;
948 TREE_TYPE (decl) = t;
949 TREE_THIS_VOLATILE (decl) = 1;
950 TREE_SIDE_EFFECTS (decl) = 1;
951 DECL_REGISTER (decl) = 0;
952 #ifndef OBJCPLUS
953 C_DECL_REGISTER (decl) = 0;
954 #endif
958 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
959 (including its categories and superclasses) or by object type TYP.
960 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
962 static bool
963 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
965 bool class_type = (cls != NULL_TREE);
967 while (cls)
969 tree c;
971 /* Check protocols adopted by the class and its categories. */
972 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
974 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
975 return true;
978 /* Repeat for superclasses. */
979 cls = lookup_interface (CLASS_SUPER_NAME (cls));
982 /* Check for any protocols attached directly to the object type. */
983 if (TYPE_HAS_OBJC_INFO (typ))
985 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
986 return true;
989 if (warn)
991 strcpy (errbuf, class_type ? "class \'" : "type \'");
992 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
993 strcat (errbuf, "\' does not ");
994 /* NB: Types 'id' and 'Class' cannot reasonably be described as
995 "implementing" a given protocol, since they do not have an
996 implementation. */
997 strcat (errbuf, class_type ? "implement" : "conform to");
998 strcat (errbuf, " the \'");
999 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
1000 strcat (errbuf, "\' protocol");
1001 warning (0, errbuf);
1004 return false;
1007 /* Check if class RCLS and instance struct type RTYP conform to at least the
1008 same protocols that LCLS and LTYP conform to. */
1010 static bool
1011 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1013 tree p;
1014 bool have_lproto = false;
1016 while (lcls)
1018 /* NB: We do _not_ look at categories defined for LCLS; these may or
1019 may not get loaded in, and therefore it is unreasonable to require
1020 that RCLS/RTYP must implement any of their protocols. */
1021 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1023 have_lproto = true;
1025 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1026 return warn;
1029 /* Repeat for superclasses. */
1030 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1033 /* Check for any protocols attached directly to the object type. */
1034 if (TYPE_HAS_OBJC_INFO (ltyp))
1036 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1038 have_lproto = true;
1040 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1041 return warn;
1045 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1046 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1047 away with simply checking for 'id' or 'Class' (!RCLS), since this
1048 routine will not get called in other cases. */
1049 return have_lproto || (rcls != NULL_TREE);
1052 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1053 an instance of RTYP to an instance of LTYP or to compare the two
1054 (if ARGNO is equal to -3), per ObjC type system rules. Before
1055 returning 'true', this routine may issue warnings related to, e.g.,
1056 protocol conformance. When returning 'false', the routine must
1057 produce absolutely no warnings; the C or C++ front-end will do so
1058 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1059 the routine must return 'false'.
1061 The ARGNO parameter is encoded as follows:
1062 >= 1 Parameter number (CALLEE contains function being called);
1063 0 Return value;
1064 -1 Assignment;
1065 -2 Initialization;
1066 -3 Comparison (LTYP and RTYP may match in either direction). */
1068 bool
1069 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1071 tree lcls, rcls, lproto, rproto;
1072 bool pointers_compatible;
1074 /* We must be dealing with pointer types */
1075 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1076 return false;
1080 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1081 rtyp = TREE_TYPE (rtyp);
1083 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1085 /* Past this point, we are only interested in ObjC class instances,
1086 or 'id' or 'Class'. */
1087 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1088 return false;
1090 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1091 && !TYPE_HAS_OBJC_INFO (ltyp))
1092 return false;
1094 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1095 && !TYPE_HAS_OBJC_INFO (rtyp))
1096 return false;
1098 /* Past this point, we are committed to returning 'true' to the caller.
1099 However, we can still warn about type and/or protocol mismatches. */
1101 if (TYPE_HAS_OBJC_INFO (ltyp))
1103 lcls = TYPE_OBJC_INTERFACE (ltyp);
1104 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1106 else
1107 lcls = lproto = NULL_TREE;
1109 if (TYPE_HAS_OBJC_INFO (rtyp))
1111 rcls = TYPE_OBJC_INTERFACE (rtyp);
1112 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1114 else
1115 rcls = rproto = NULL_TREE;
1117 /* If we could not find an @interface declaration, we must have
1118 only seen a @class declaration; for purposes of type comparison,
1119 treat it as a stand-alone (root) class. */
1121 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1122 lcls = NULL_TREE;
1124 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1125 rcls = NULL_TREE;
1127 /* If either type is an unqualified 'id', we're done. */
1128 if ((!lproto && objc_is_object_id (ltyp))
1129 || (!rproto && objc_is_object_id (rtyp)))
1130 return true;
1132 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1134 /* If the underlying types are the same, and at most one of them has
1135 a protocol list, we do not need to issue any diagnostics. */
1136 if (pointers_compatible && (!lproto || !rproto))
1137 return true;
1139 /* If exactly one of the types is 'Class', issue a diagnostic; any
1140 exceptions of this rule have already been handled. */
1141 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1142 pointers_compatible = false;
1143 /* Otherwise, check for inheritance relations. */
1144 else
1146 if (!pointers_compatible)
1147 pointers_compatible
1148 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1150 if (!pointers_compatible)
1151 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1153 if (!pointers_compatible && argno == -3)
1154 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1157 /* If the pointers match modulo protocols, check for protocol conformance
1158 mismatches. */
1159 if (pointers_compatible)
1161 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1162 argno != -3);
1164 if (!pointers_compatible && argno == -3)
1165 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1166 argno != -3);
1169 if (!pointers_compatible)
1171 /* NB: For the time being, we shall make our warnings look like their
1172 C counterparts. In the future, we may wish to make them more
1173 ObjC-specific. */
1174 switch (argno)
1176 case -3:
1177 warning (0, "comparison of distinct Objective-C types lacks a cast");
1178 break;
1180 case -2:
1181 warning (0, "initialization from distinct Objective-C type");
1182 break;
1184 case -1:
1185 warning (0, "assignment from distinct Objective-C type");
1186 break;
1188 case 0:
1189 warning (0, "distinct Objective-C type in return");
1190 break;
1192 default:
1193 warning (0, "passing argument %d of %qE from distinct "
1194 "Objective-C type", argno, callee);
1195 break;
1199 return true;
1202 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1203 lives in the volatilized hash table, ignore the 'volatile' bit when
1204 making the comparison. */
1206 bool
1207 objc_type_quals_match (tree ltyp, tree rtyp)
1209 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1210 struct volatilized_type key;
1212 key.type = ltyp;
1214 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1215 lquals &= ~TYPE_QUAL_VOLATILE;
1217 key.type = rtyp;
1219 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1220 rquals &= ~TYPE_QUAL_VOLATILE;
1222 return (lquals == rquals);
1225 #ifndef OBJCPLUS
1226 /* Determine if CHILD is derived from PARENT. The routine assumes that
1227 both parameters are RECORD_TYPEs, and is non-reflexive. */
1229 static bool
1230 objc_derived_from_p (tree parent, tree child)
1232 parent = TYPE_MAIN_VARIANT (parent);
1234 for (child = TYPE_MAIN_VARIANT (child);
1235 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1237 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1238 (TYPE_BINFO (child),
1239 0)));
1241 if (child == parent)
1242 return true;
1245 return false;
1247 #endif
1249 static tree
1250 objc_build_component_ref (tree datum, tree component)
1252 /* If COMPONENT is NULL, the caller is referring to the anonymous
1253 base class field. */
1254 if (!component)
1256 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1258 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1261 /* The 'build_component_ref' routine has been removed from the C++
1262 front-end, but 'finish_class_member_access_expr' seems to be
1263 a worthy substitute. */
1264 #ifdef OBJCPLUS
1265 return finish_class_member_access_expr (datum, component, false);
1266 #else
1267 return build_component_ref (datum, component);
1268 #endif
1271 /* Recursively copy inheritance information rooted at BINFO. To do this,
1272 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1274 static tree
1275 objc_copy_binfo (tree binfo)
1277 tree btype = BINFO_TYPE (binfo);
1278 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1279 tree base_binfo;
1280 int ix;
1282 BINFO_TYPE (binfo2) = btype;
1283 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1284 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1286 /* Recursively copy base binfos of BINFO. */
1287 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1289 tree base_binfo2 = objc_copy_binfo (base_binfo);
1291 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1292 BINFO_BASE_APPEND (binfo2, base_binfo2);
1295 return binfo2;
1298 /* Record superclass information provided in BASETYPE for ObjC class REF.
1299 This is loosely based on cp/decl.c:xref_basetypes(). */
1301 static void
1302 objc_xref_basetypes (tree ref, tree basetype)
1304 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1306 TYPE_BINFO (ref) = binfo;
1307 BINFO_OFFSET (binfo) = size_zero_node;
1308 BINFO_TYPE (binfo) = ref;
1310 if (basetype)
1312 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1314 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1315 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1316 BINFO_BASE_APPEND (binfo, base_binfo);
1317 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1321 static hashval_t
1322 volatilized_hash (const void *ptr)
1324 tree typ = ((struct volatilized_type *)ptr)->type;
1326 return htab_hash_pointer(typ);
1329 static int
1330 volatilized_eq (const void *ptr1, const void *ptr2)
1332 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1333 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1335 return typ1 == typ2;
1338 /* Called from finish_decl. */
1340 void
1341 objc_check_decl (tree decl)
1343 tree type = TREE_TYPE (decl);
1345 if (TREE_CODE (type) != RECORD_TYPE)
1346 return;
1347 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1348 error ("statically allocated instance of Objective-C class %qs",
1349 IDENTIFIER_POINTER (type));
1352 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1353 either name an Objective-C class, or refer to the special 'id' or 'Class'
1354 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1356 tree
1357 objc_get_protocol_qualified_type (tree interface, tree protocols)
1359 /* If INTERFACE is not provided, default to 'id'. */
1360 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1361 bool is_ptr = (type != NULL_TREE);
1363 if (!is_ptr)
1365 type = objc_is_class_name (interface);
1367 if (type)
1368 type = xref_tag (RECORD_TYPE, type);
1369 else
1370 return interface;
1373 if (protocols)
1375 type = build_variant_type_copy (type);
1377 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1378 to the pointee. */
1379 if (is_ptr)
1381 tree orig_pointee_type = TREE_TYPE (type);
1382 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1384 /* Set up the canonical type information. */
1385 TYPE_CANONICAL (type)
1386 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1388 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1389 type = TREE_TYPE (type);
1392 /* Look up protocols and install in lang specific list. */
1393 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1394 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1396 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1397 return the pointer to the new pointee variant. */
1398 if (is_ptr)
1399 type = TYPE_POINTER_TO (type);
1400 else
1401 TYPE_OBJC_INTERFACE (type)
1402 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1405 return type;
1408 /* Check for circular dependencies in protocols. The arguments are
1409 PROTO, the protocol to check, and LIST, a list of protocol it
1410 conforms to. */
1412 static void
1413 check_protocol_recursively (tree proto, tree list)
1415 tree p;
1417 for (p = list; p; p = TREE_CHAIN (p))
1419 tree pp = TREE_VALUE (p);
1421 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1422 pp = lookup_protocol (pp);
1424 if (pp == proto)
1425 fatal_error ("protocol %qs has circular dependency",
1426 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1427 if (pp)
1428 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1432 /* Look up PROTOCOLS, and return a list of those that are found.
1433 If none are found, return NULL. */
1435 static tree
1436 lookup_and_install_protocols (tree protocols)
1438 tree proto;
1439 tree return_value = NULL_TREE;
1441 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1443 tree ident = TREE_VALUE (proto);
1444 tree p = lookup_protocol (ident);
1446 if (p)
1447 return_value = chainon (return_value,
1448 build_tree_list (NULL_TREE, p));
1449 else if (ident != error_mark_node)
1450 error ("cannot find protocol declaration for %qs",
1451 IDENTIFIER_POINTER (ident));
1454 return return_value;
1457 /* Create a declaration for field NAME of a given TYPE. */
1459 static tree
1460 create_field_decl (tree type, const char *name)
1462 return build_decl (FIELD_DECL, get_identifier (name), type);
1465 /* Create a global, static declaration for variable NAME of a given TYPE. The
1466 finish_var_decl() routine will need to be called on it afterwards. */
1468 static tree
1469 start_var_decl (tree type, const char *name)
1471 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1473 TREE_STATIC (var) = 1;
1474 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1475 DECL_IGNORED_P (var) = 1;
1476 DECL_ARTIFICIAL (var) = 1;
1477 DECL_CONTEXT (var) = NULL_TREE;
1478 #ifdef OBJCPLUS
1479 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1480 #endif
1482 return var;
1485 /* Finish off the variable declaration created by start_var_decl(). */
1487 static void
1488 finish_var_decl (tree var, tree initializer)
1490 finish_decl (var, initializer, NULL_TREE);
1491 /* Ensure that the variable actually gets output. */
1492 mark_decl_referenced (var);
1493 /* Mark the decl to avoid "defined but not used" warning. */
1494 TREE_USED (var) = 1;
1497 /* Find the decl for the constant string class reference. This is only
1498 used for the NeXT runtime. */
1500 static tree
1501 setup_string_decl (void)
1503 char *name;
1504 size_t length;
1506 /* %s in format will provide room for terminating null */
1507 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1508 + strlen (constant_string_class_name);
1509 name = xmalloc (length);
1510 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1511 constant_string_class_name);
1512 constant_string_global_id = get_identifier (name);
1513 string_class_decl = lookup_name (constant_string_global_id);
1515 return string_class_decl;
1518 /* Purpose: "play" parser, creating/installing representations
1519 of the declarations that are required by Objective-C.
1521 Model:
1523 type_spec--------->sc_spec
1524 (tree_list) (tree_list)
1527 identifier_node identifier_node */
1529 static void
1530 synth_module_prologue (void)
1532 tree type;
1533 enum debug_info_type save_write_symbols = write_symbols;
1534 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1536 /* Suppress outputting debug symbols, because
1537 dbxout_init hasn'r been called yet. */
1538 write_symbols = NO_DEBUG;
1539 debug_hooks = &do_nothing_debug_hooks;
1541 #ifdef OBJCPLUS
1542 push_lang_context (lang_name_c); /* extern "C" */
1543 #endif
1545 /* The following are also defined in <objc/objc.h> and friends. */
1547 objc_object_id = get_identifier (TAG_OBJECT);
1548 objc_class_id = get_identifier (TAG_CLASS);
1550 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1551 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1553 objc_object_type = build_pointer_type (objc_object_reference);
1554 objc_class_type = build_pointer_type (objc_class_reference);
1556 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1557 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1559 /* Declare the 'id' and 'Class' typedefs. */
1561 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1562 objc_object_name,
1563 objc_object_type));
1564 DECL_IN_SYSTEM_HEADER (type) = 1;
1565 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1566 objc_class_name,
1567 objc_class_type));
1568 DECL_IN_SYSTEM_HEADER (type) = 1;
1570 /* Forward-declare '@interface Protocol'. */
1572 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1573 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1574 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1575 type));
1577 /* Declare type of selector-objects that represent an operation name. */
1579 if (flag_next_runtime)
1580 /* `struct objc_selector *' */
1581 objc_selector_type
1582 = build_pointer_type (xref_tag (RECORD_TYPE,
1583 get_identifier (TAG_SELECTOR)));
1584 else
1585 /* `const struct objc_selector *' */
1586 objc_selector_type
1587 = build_pointer_type
1588 (build_qualified_type (xref_tag (RECORD_TYPE,
1589 get_identifier (TAG_SELECTOR)),
1590 TYPE_QUAL_CONST));
1592 /* Declare receiver type used for dispatching messages to 'super'. */
1594 /* `struct objc_super *' */
1595 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1596 get_identifier (TAG_SUPER)));
1598 /* Declare pointers to method and ivar lists. */
1599 objc_method_list_ptr = build_pointer_type
1600 (xref_tag (RECORD_TYPE,
1601 get_identifier (UTAG_METHOD_LIST)));
1602 objc_method_proto_list_ptr
1603 = build_pointer_type (xref_tag (RECORD_TYPE,
1604 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1605 objc_ivar_list_ptr = build_pointer_type
1606 (xref_tag (RECORD_TYPE,
1607 get_identifier (UTAG_IVAR_LIST)));
1609 /* TREE_NOTHROW is cleared for the message-sending functions,
1610 because the function that gets called can throw in Obj-C++, or
1611 could itself call something that can throw even in Obj-C. */
1613 if (flag_next_runtime)
1615 /* NB: In order to call one of the ..._stret (struct-returning)
1616 functions, the function *MUST* first be cast to a signature that
1617 corresponds to the actual ObjC method being invoked. This is
1618 what is done by the build_objc_method_call() routine below. */
1620 /* id objc_msgSend (id, SEL, ...); */
1621 /* id objc_msgSendNonNil (id, SEL, ...); */
1622 /* id objc_msgSend_stret (id, SEL, ...); */
1623 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1624 type
1625 = build_function_type (objc_object_type,
1626 tree_cons (NULL_TREE, objc_object_type,
1627 tree_cons (NULL_TREE, objc_selector_type,
1628 NULL_TREE)));
1629 umsg_decl = add_builtin_function (TAG_MSGSEND,
1630 type, 0, NOT_BUILT_IN,
1631 NULL, NULL_TREE);
1632 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1633 type, 0, NOT_BUILT_IN,
1634 NULL, NULL_TREE);
1635 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1636 type, 0, NOT_BUILT_IN,
1637 NULL, NULL_TREE);
1638 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1639 type, 0, NOT_BUILT_IN,
1640 NULL, NULL_TREE);
1642 /* These can throw, because the function that gets called can throw
1643 in Obj-C++, or could itself call something that can throw even
1644 in Obj-C. */
1645 TREE_NOTHROW (umsg_decl) = 0;
1646 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1647 TREE_NOTHROW (umsg_stret_decl) = 0;
1648 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1650 /* id objc_msgSend_Fast (id, SEL, ...)
1651 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1652 #ifdef OFFS_MSGSEND_FAST
1653 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1654 type, 0, NOT_BUILT_IN,
1655 NULL, NULL_TREE);
1656 TREE_NOTHROW (umsg_fast_decl) = 0;
1657 DECL_ATTRIBUTES (umsg_fast_decl)
1658 = tree_cons (get_identifier ("hard_coded_address"),
1659 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1660 NULL_TREE);
1661 #else
1662 /* No direct dispatch available. */
1663 umsg_fast_decl = umsg_decl;
1664 #endif
1666 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1667 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1668 type
1669 = build_function_type (objc_object_type,
1670 tree_cons (NULL_TREE, objc_super_type,
1671 tree_cons (NULL_TREE, objc_selector_type,
1672 NULL_TREE)));
1673 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1674 type, 0, NOT_BUILT_IN,
1675 NULL, NULL_TREE);
1676 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1677 type, 0, NOT_BUILT_IN, 0,
1678 NULL_TREE);
1679 TREE_NOTHROW (umsg_super_decl) = 0;
1680 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1682 else
1684 /* GNU runtime messenger entry points. */
1686 /* typedef id (*IMP)(id, SEL, ...); */
1687 tree IMP_type
1688 = build_pointer_type
1689 (build_function_type (objc_object_type,
1690 tree_cons (NULL_TREE, objc_object_type,
1691 tree_cons (NULL_TREE, objc_selector_type,
1692 NULL_TREE))));
1694 /* IMP objc_msg_lookup (id, SEL); */
1695 type
1696 = build_function_type (IMP_type,
1697 tree_cons (NULL_TREE, objc_object_type,
1698 tree_cons (NULL_TREE, objc_selector_type,
1699 OBJC_VOID_AT_END)));
1700 umsg_decl = add_builtin_function (TAG_MSGSEND,
1701 type, 0, NOT_BUILT_IN,
1702 NULL, NULL_TREE);
1703 TREE_NOTHROW (umsg_decl) = 0;
1705 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1706 type
1707 = build_function_type (IMP_type,
1708 tree_cons (NULL_TREE, objc_super_type,
1709 tree_cons (NULL_TREE, objc_selector_type,
1710 OBJC_VOID_AT_END)));
1711 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1712 type, 0, NOT_BUILT_IN,
1713 NULL, NULL_TREE);
1714 TREE_NOTHROW (umsg_super_decl) = 0;
1716 /* The following GNU runtime entry point is called to initialize
1717 each module:
1719 __objc_exec_class (void *); */
1720 type
1721 = build_function_type (void_type_node,
1722 tree_cons (NULL_TREE, ptr_type_node,
1723 OBJC_VOID_AT_END));
1724 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1725 type, 0, NOT_BUILT_IN,
1726 NULL, NULL_TREE);
1729 /* id objc_getClass (const char *); */
1731 type = build_function_type (objc_object_type,
1732 tree_cons (NULL_TREE,
1733 const_string_type_node,
1734 OBJC_VOID_AT_END));
1736 objc_get_class_decl
1737 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1738 NULL, NULL_TREE);
1740 /* id objc_getMetaClass (const char *); */
1742 objc_get_meta_class_decl
1743 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1745 build_class_template ();
1746 build_super_template ();
1747 build_protocol_template ();
1748 build_category_template ();
1749 build_objc_exception_stuff ();
1751 if (flag_next_runtime)
1752 build_next_objc_exception_stuff ();
1754 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1756 if (! flag_next_runtime)
1757 build_selector_table_decl ();
1759 /* Forward declare constant_string_id and constant_string_type. */
1760 if (!constant_string_class_name)
1761 constant_string_class_name = default_constant_string_class_name;
1763 constant_string_id = get_identifier (constant_string_class_name);
1764 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1766 /* Pre-build the following entities - for speed/convenience. */
1767 self_id = get_identifier ("self");
1768 ucmd_id = get_identifier ("_cmd");
1770 #ifdef OBJCPLUS
1771 pop_lang_context ();
1772 #endif
1774 write_symbols = save_write_symbols;
1775 debug_hooks = save_hooks;
1778 /* Ensure that the ivar list for NSConstantString/NXConstantString
1779 (or whatever was specified via `-fconstant-string-class')
1780 contains fields at least as large as the following three, so that
1781 the runtime can stomp on them with confidence:
1783 struct STRING_OBJECT_CLASS_NAME
1785 Object isa;
1786 char *cString;
1787 unsigned int length;
1788 }; */
1790 static int
1791 check_string_class_template (void)
1793 tree field_decl = objc_get_class_ivars (constant_string_id);
1795 #define AT_LEAST_AS_LARGE_AS(F, T) \
1796 (F && TREE_CODE (F) == FIELD_DECL \
1797 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1798 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1800 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1801 return 0;
1803 field_decl = TREE_CHAIN (field_decl);
1804 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1805 return 0;
1807 field_decl = TREE_CHAIN (field_decl);
1808 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1810 #undef AT_LEAST_AS_LARGE_AS
1813 /* Avoid calling `check_string_class_template ()' more than once. */
1814 static GTY(()) int string_layout_checked;
1816 /* Construct an internal string layout to be used as a template for
1817 creating NSConstantString/NXConstantString instances. */
1819 static tree
1820 objc_build_internal_const_str_type (void)
1822 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1823 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1824 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1826 TREE_CHAIN (field) = fields; fields = field;
1827 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1828 TREE_CHAIN (field) = fields; fields = field;
1829 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1830 reverse order! */
1831 finish_builtin_struct (type, "__builtin_ObjCString",
1832 fields, NULL_TREE);
1834 return type;
1837 /* Custom build_string which sets TREE_TYPE! */
1839 static tree
1840 my_build_string (int len, const char *str)
1842 return fix_string_type (build_string (len, str));
1845 /* Build a string with contents STR and length LEN and convert it to a
1846 pointer. */
1848 static tree
1849 my_build_string_pointer (int len, const char *str)
1851 tree string = my_build_string (len, str);
1852 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1853 return build1 (ADDR_EXPR, ptrtype, string);
1856 static hashval_t
1857 string_hash (const void *ptr)
1859 tree str = ((struct string_descriptor *)ptr)->literal;
1860 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1861 int i, len = TREE_STRING_LENGTH (str);
1862 hashval_t h = len;
1864 for (i = 0; i < len; i++)
1865 h = ((h * 613) + p[i]);
1867 return h;
1870 static int
1871 string_eq (const void *ptr1, const void *ptr2)
1873 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1874 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1875 int len1 = TREE_STRING_LENGTH (str1);
1877 return (len1 == TREE_STRING_LENGTH (str2)
1878 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1879 len1));
1882 /* Given a chain of STRING_CST's, build a static instance of
1883 NXConstantString which points at the concatenation of those
1884 strings. We place the string object in the __string_objects
1885 section of the __OBJC segment. The Objective-C runtime will
1886 initialize the isa pointers of the string objects to point at the
1887 NXConstantString class object. */
1889 tree
1890 objc_build_string_object (tree string)
1892 tree initlist, constructor, constant_string_class;
1893 int length;
1894 tree fields, addr;
1895 struct string_descriptor *desc, key;
1896 void **loc;
1898 /* Prep the string argument. */
1899 string = fix_string_type (string);
1900 TREE_SET_CODE (string, STRING_CST);
1901 length = TREE_STRING_LENGTH (string) - 1;
1903 /* Check whether the string class being used actually exists and has the
1904 correct ivar layout. */
1905 if (!string_layout_checked)
1907 string_layout_checked = -1;
1908 constant_string_class = lookup_interface (constant_string_id);
1909 internal_const_str_type = objc_build_internal_const_str_type ();
1911 if (!constant_string_class
1912 || !(constant_string_type
1913 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1914 error ("cannot find interface declaration for %qs",
1915 IDENTIFIER_POINTER (constant_string_id));
1916 /* The NSConstantString/NXConstantString ivar layout is now known. */
1917 else if (!check_string_class_template ())
1918 error ("interface %qs does not have valid constant string layout",
1919 IDENTIFIER_POINTER (constant_string_id));
1920 /* For the NeXT runtime, we can generate a literal reference
1921 to the string class, don't need to run a constructor. */
1922 else if (flag_next_runtime && !setup_string_decl ())
1923 error ("cannot find reference tag for class %qs",
1924 IDENTIFIER_POINTER (constant_string_id));
1925 else
1927 string_layout_checked = 1; /* Success! */
1928 add_class_reference (constant_string_id);
1932 if (string_layout_checked == -1)
1933 return error_mark_node;
1935 /* Perhaps we already constructed a constant string just like this one? */
1936 key.literal = string;
1937 loc = htab_find_slot (string_htab, &key, INSERT);
1938 desc = *loc;
1940 if (!desc)
1942 tree var;
1943 *loc = desc = ggc_alloc (sizeof (*desc));
1944 desc->literal = string;
1946 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1947 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1948 fields = TYPE_FIELDS (internal_const_str_type);
1949 initlist
1950 = build_tree_list (fields,
1951 flag_next_runtime
1952 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1953 : build_int_cst (NULL_TREE, 0));
1954 fields = TREE_CHAIN (fields);
1955 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1956 initlist);
1957 fields = TREE_CHAIN (fields);
1958 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1959 initlist);
1960 constructor = objc_build_constructor (internal_const_str_type,
1961 nreverse (initlist));
1962 TREE_INVARIANT (constructor) = true;
1964 if (!flag_next_runtime)
1965 constructor
1966 = objc_add_static_instance (constructor, constant_string_type);
1967 else
1969 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1970 DECL_INITIAL (var) = constructor;
1971 TREE_STATIC (var) = 1;
1972 pushdecl_top_level (var);
1973 constructor = var;
1975 desc->constructor = constructor;
1978 addr = convert (build_pointer_type (constant_string_type),
1979 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1981 return addr;
1984 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1986 static GTY(()) int num_static_inst;
1988 static tree
1989 objc_add_static_instance (tree constructor, tree class_decl)
1991 tree *chain, decl;
1992 char buf[256];
1994 /* Find the list of static instances for the CLASS_DECL. Create one if
1995 not found. */
1996 for (chain = &objc_static_instances;
1997 *chain && TREE_VALUE (*chain) != class_decl;
1998 chain = &TREE_CHAIN (*chain));
1999 if (!*chain)
2001 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2002 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2005 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2006 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
2007 DECL_COMMON (decl) = 1;
2008 TREE_STATIC (decl) = 1;
2009 DECL_ARTIFICIAL (decl) = 1;
2010 TREE_USED (decl) = 1;
2011 DECL_INITIAL (decl) = constructor;
2013 /* We may be writing something else just now.
2014 Postpone till end of input. */
2015 DECL_DEFER_OUTPUT (decl) = 1;
2016 pushdecl_top_level (decl);
2017 rest_of_decl_compilation (decl, 1, 0);
2019 /* Add the DECL to the head of this CLASS' list. */
2020 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2022 return decl;
2025 /* Build a static constant CONSTRUCTOR
2026 with type TYPE and elements ELTS. */
2028 static tree
2029 objc_build_constructor (tree type, tree elts)
2031 tree constructor = build_constructor_from_list (type, elts);
2033 TREE_CONSTANT (constructor) = 1;
2034 TREE_STATIC (constructor) = 1;
2035 TREE_READONLY (constructor) = 1;
2037 #ifdef OBJCPLUS
2038 /* Adjust for impedance mismatch. We should figure out how to build
2039 CONSTRUCTORs that consistently please both the C and C++ gods. */
2040 if (!TREE_PURPOSE (elts))
2041 TREE_TYPE (constructor) = NULL_TREE;
2042 TREE_HAS_CONSTRUCTOR (constructor) = 1;
2043 #endif
2045 return constructor;
2048 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2050 /* Predefine the following data type:
2052 struct _objc_symtab
2054 long sel_ref_cnt;
2055 SEL *refs;
2056 short cls_def_cnt;
2057 short cat_def_cnt;
2058 void *defs[cls_def_cnt + cat_def_cnt];
2059 }; */
2061 static void
2062 build_objc_symtab_template (void)
2064 tree field_decl, field_decl_chain;
2066 objc_symtab_template
2067 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2069 /* long sel_ref_cnt; */
2070 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2071 field_decl_chain = field_decl;
2073 /* SEL *refs; */
2074 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2075 "refs");
2076 chainon (field_decl_chain, field_decl);
2078 /* short cls_def_cnt; */
2079 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2080 chainon (field_decl_chain, field_decl);
2082 /* short cat_def_cnt; */
2083 field_decl = create_field_decl (short_integer_type_node,
2084 "cat_def_cnt");
2085 chainon (field_decl_chain, field_decl);
2087 if (imp_count || cat_count || !flag_next_runtime)
2089 /* void *defs[imp_count + cat_count (+ 1)]; */
2090 /* NB: The index is one less than the size of the array. */
2091 int index = imp_count + cat_count
2092 + (flag_next_runtime? -1: 0);
2093 field_decl = create_field_decl
2094 (build_array_type
2095 (ptr_type_node,
2096 build_index_type (build_int_cst (NULL_TREE, index))),
2097 "defs");
2098 chainon (field_decl_chain, field_decl);
2101 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2104 /* Create the initial value for the `defs' field of _objc_symtab.
2105 This is a CONSTRUCTOR. */
2107 static tree
2108 init_def_list (tree type)
2110 tree expr, initlist = NULL_TREE;
2111 struct imp_entry *impent;
2113 if (imp_count)
2114 for (impent = imp_list; impent; impent = impent->next)
2116 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2118 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2119 initlist = tree_cons (NULL_TREE, expr, initlist);
2123 if (cat_count)
2124 for (impent = imp_list; impent; impent = impent->next)
2126 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2128 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2129 initlist = tree_cons (NULL_TREE, expr, initlist);
2133 if (!flag_next_runtime)
2135 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2136 tree expr;
2138 if (static_instances_decl)
2139 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2140 else
2141 expr = build_int_cst (NULL_TREE, 0);
2143 initlist = tree_cons (NULL_TREE, expr, initlist);
2146 return objc_build_constructor (type, nreverse (initlist));
2149 /* Construct the initial value for all of _objc_symtab. */
2151 static tree
2152 init_objc_symtab (tree type)
2154 tree initlist;
2156 /* sel_ref_cnt = { ..., 5, ... } */
2158 initlist = build_tree_list (NULL_TREE,
2159 build_int_cst (long_integer_type_node, 0));
2161 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2163 if (flag_next_runtime || ! sel_ref_chain)
2164 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2165 else
2166 initlist
2167 = tree_cons (NULL_TREE,
2168 convert (build_pointer_type (objc_selector_type),
2169 build_unary_op (ADDR_EXPR,
2170 UOBJC_SELECTOR_TABLE_decl, 1)),
2171 initlist);
2173 /* cls_def_cnt = { ..., 5, ... } */
2175 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2177 /* cat_def_cnt = { ..., 5, ... } */
2179 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2181 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2183 if (imp_count || cat_count || !flag_next_runtime)
2186 tree field = TYPE_FIELDS (type);
2187 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2189 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2190 initlist);
2193 return objc_build_constructor (type, nreverse (initlist));
2196 /* Generate forward declarations for metadata such as
2197 'OBJC_CLASS_...'. */
2199 static tree
2200 build_metadata_decl (const char *name, tree type)
2202 tree decl;
2204 /* struct TYPE NAME_<name>; */
2205 decl = start_var_decl (type, synth_id_with_class_suffix
2206 (name,
2207 objc_implementation_context));
2209 return decl;
2212 /* Push forward-declarations of all the categories so that
2213 init_def_list can use them in a CONSTRUCTOR. */
2215 static void
2216 forward_declare_categories (void)
2218 struct imp_entry *impent;
2219 tree sav = objc_implementation_context;
2221 for (impent = imp_list; impent; impent = impent->next)
2223 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2225 /* Set an invisible arg to synth_id_with_class_suffix. */
2226 objc_implementation_context = impent->imp_context;
2227 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2228 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2229 objc_category_template);
2232 objc_implementation_context = sav;
2235 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2236 and initialized appropriately. */
2238 static void
2239 generate_objc_symtab_decl (void)
2241 /* forward declare categories */
2242 if (cat_count)
2243 forward_declare_categories ();
2245 build_objc_symtab_template ();
2246 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2247 finish_var_decl (UOBJC_SYMBOLS_decl,
2248 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2251 static tree
2252 init_module_descriptor (tree type)
2254 tree initlist, expr;
2256 /* version = { 1, ... } */
2258 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2259 initlist = build_tree_list (NULL_TREE, expr);
2261 /* size = { ..., sizeof (struct _objc_module), ... } */
2263 expr = convert (long_integer_type_node,
2264 size_in_bytes (objc_module_template));
2265 initlist = tree_cons (NULL_TREE, expr, initlist);
2267 /* Don't provide any file name for security reasons. */
2268 /* name = { ..., "", ... } */
2270 expr = add_objc_string (get_identifier (""), class_names);
2271 initlist = tree_cons (NULL_TREE, expr, initlist);
2273 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2275 if (UOBJC_SYMBOLS_decl)
2276 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2277 else
2278 expr = build_int_cst (NULL_TREE, 0);
2279 initlist = tree_cons (NULL_TREE, expr, initlist);
2281 return objc_build_constructor (type, nreverse (initlist));
2284 /* Write out the data structures to describe Objective C classes defined.
2286 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2288 static void
2289 build_module_descriptor (void)
2291 tree field_decl, field_decl_chain;
2293 #ifdef OBJCPLUS
2294 push_lang_context (lang_name_c); /* extern "C" */
2295 #endif
2297 objc_module_template
2298 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2300 /* long version; */
2301 field_decl = create_field_decl (long_integer_type_node, "version");
2302 field_decl_chain = field_decl;
2304 /* long size; */
2305 field_decl = create_field_decl (long_integer_type_node, "size");
2306 chainon (field_decl_chain, field_decl);
2308 /* char *name; */
2309 field_decl = create_field_decl (string_type_node, "name");
2310 chainon (field_decl_chain, field_decl);
2312 /* struct _objc_symtab *symtab; */
2313 field_decl
2314 = create_field_decl (build_pointer_type
2315 (xref_tag (RECORD_TYPE,
2316 get_identifier (UTAG_SYMTAB))),
2317 "symtab");
2318 chainon (field_decl_chain, field_decl);
2320 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2322 /* Create an instance of "_objc_module". */
2323 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2324 finish_var_decl (UOBJC_MODULES_decl,
2325 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2327 #ifdef OBJCPLUS
2328 pop_lang_context ();
2329 #endif
2332 /* The GNU runtime requires us to provide a static initializer function
2333 for each module:
2335 static void __objc_gnu_init (void) {
2336 __objc_exec_class (&L_OBJC_MODULES);
2337 } */
2339 static void
2340 build_module_initializer_routine (void)
2342 tree body;
2344 #ifdef OBJCPLUS
2345 push_lang_context (lang_name_c); /* extern "C" */
2346 #endif
2348 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2349 objc_start_function (get_identifier (TAG_GNUINIT),
2350 build_function_type (void_type_node,
2351 OBJC_VOID_AT_END),
2352 NULL_TREE, objc_get_parm_info (0));
2354 body = c_begin_compound_stmt (true);
2355 add_stmt (build_function_call
2356 (execclass_decl,
2357 build_tree_list
2358 (NULL_TREE,
2359 build_unary_op (ADDR_EXPR,
2360 UOBJC_MODULES_decl, 0))));
2361 add_stmt (c_end_compound_stmt (body, true));
2363 TREE_PUBLIC (current_function_decl) = 0;
2365 #ifndef OBJCPLUS
2366 /* For Objective-C++, we will need to call __objc_gnu_init
2367 from objc_generate_static_init_call() below. */
2368 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2369 #endif
2371 GNU_INIT_decl = current_function_decl;
2372 finish_function ();
2374 #ifdef OBJCPLUS
2375 pop_lang_context ();
2376 #endif
2379 #ifdef OBJCPLUS
2380 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2381 to be called by the module initializer routine. */
2384 objc_static_init_needed_p (void)
2386 return (GNU_INIT_decl != NULL_TREE);
2389 /* Generate a call to the __objc_gnu_init initializer function. */
2391 tree
2392 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2394 add_stmt (build_stmt (EXPR_STMT,
2395 build_function_call (GNU_INIT_decl, NULL_TREE)));
2397 return ctors;
2399 #endif /* OBJCPLUS */
2401 /* Return the DECL of the string IDENT in the SECTION. */
2403 static tree
2404 get_objc_string_decl (tree ident, enum string_section section)
2406 tree chain;
2408 if (section == class_names)
2409 chain = class_names_chain;
2410 else if (section == meth_var_names)
2411 chain = meth_var_names_chain;
2412 else if (section == meth_var_types)
2413 chain = meth_var_types_chain;
2414 else
2415 abort ();
2417 for (; chain != 0; chain = TREE_CHAIN (chain))
2418 if (TREE_VALUE (chain) == ident)
2419 return (TREE_PURPOSE (chain));
2421 abort ();
2422 return NULL_TREE;
2425 /* Output references to all statically allocated objects. Return the DECL
2426 for the array built. */
2428 static void
2429 generate_static_references (void)
2431 tree decls = NULL_TREE, expr = NULL_TREE;
2432 tree class_name, class, decl, initlist;
2433 tree cl_chain, in_chain, type
2434 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2435 int num_inst, num_class;
2436 char buf[256];
2438 if (flag_next_runtime)
2439 abort ();
2441 for (cl_chain = objc_static_instances, num_class = 0;
2442 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2444 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2445 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2447 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2448 decl = start_var_decl (type, buf);
2450 /* Output {class_name, ...}. */
2451 class = TREE_VALUE (cl_chain);
2452 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2453 initlist = build_tree_list (NULL_TREE,
2454 build_unary_op (ADDR_EXPR, class_name, 1));
2456 /* Output {..., instance, ...}. */
2457 for (in_chain = TREE_PURPOSE (cl_chain);
2458 in_chain; in_chain = TREE_CHAIN (in_chain))
2460 expr = build_unary_op (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 (ADDR_EXPR, decl, 1), decls);
2473 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2474 expr = objc_build_constructor (type, nreverse (decls));
2475 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2476 finish_var_decl (static_instances_decl, expr);
2479 static GTY(()) int selector_reference_idx;
2481 static tree
2482 build_selector_reference_decl (void)
2484 tree decl;
2485 char buf[256];
2487 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2488 decl = start_var_decl (objc_selector_type, buf);
2490 return decl;
2493 static void
2494 build_selector_table_decl (void)
2496 tree temp;
2498 if (flag_typed_selectors)
2500 build_selector_template ();
2501 temp = build_array_type (objc_selector_template, NULL_TREE);
2503 else
2504 temp = build_array_type (objc_selector_type, NULL_TREE);
2506 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2509 /* Just a handy wrapper for add_objc_string. */
2511 static tree
2512 build_selector (tree ident)
2514 return convert (objc_selector_type,
2515 add_objc_string (ident, meth_var_names));
2518 static void
2519 build_selector_translation_table (void)
2521 tree chain, initlist = NULL_TREE;
2522 int offset = 0;
2523 tree decl = NULL_TREE;
2525 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2527 tree expr;
2529 if (warn_selector && objc_implementation_context)
2531 tree method_chain;
2532 bool found = false;
2533 for (method_chain = meth_var_names_chain;
2534 method_chain;
2535 method_chain = TREE_CHAIN (method_chain))
2537 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2539 found = true;
2540 break;
2543 if (!found)
2545 location_t *loc;
2546 if (flag_next_runtime && TREE_PURPOSE (chain))
2547 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2548 else
2549 loc = &input_location;
2550 warning (0, "%Hcreating selector for nonexistent method %qE",
2551 loc, TREE_VALUE (chain));
2555 expr = build_selector (TREE_VALUE (chain));
2556 /* add one for the '\0' character */
2557 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2559 if (flag_next_runtime)
2561 decl = TREE_PURPOSE (chain);
2562 finish_var_decl (decl, expr);
2564 else
2566 if (flag_typed_selectors)
2568 tree eltlist = NULL_TREE;
2569 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2570 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2571 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2572 expr = objc_build_constructor (objc_selector_template,
2573 nreverse (eltlist));
2576 initlist = tree_cons (NULL_TREE, expr, initlist);
2580 if (! flag_next_runtime)
2582 /* Cause the selector table (previously forward-declared)
2583 to be actually output. */
2584 initlist = tree_cons (NULL_TREE,
2585 flag_typed_selectors
2586 ? objc_build_constructor
2587 (objc_selector_template,
2588 tree_cons (NULL_TREE,
2589 build_int_cst (NULL_TREE, 0),
2590 tree_cons (NULL_TREE,
2591 build_int_cst (NULL_TREE, 0),
2592 NULL_TREE)))
2593 : build_int_cst (NULL_TREE, 0), initlist);
2594 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2595 nreverse (initlist));
2596 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2600 static tree
2601 get_proto_encoding (tree proto)
2603 tree encoding;
2604 if (proto)
2606 if (! METHOD_ENCODING (proto))
2608 encoding = encode_method_prototype (proto);
2609 METHOD_ENCODING (proto) = encoding;
2611 else
2612 encoding = METHOD_ENCODING (proto);
2614 return add_objc_string (encoding, meth_var_types);
2616 else
2617 return build_int_cst (NULL_TREE, 0);
2620 /* sel_ref_chain is a list whose "value" fields will be instances of
2621 identifier_node that represent the selector. */
2623 static tree
2624 build_typed_selector_reference (tree ident, tree prototype)
2626 tree *chain = &sel_ref_chain;
2627 tree expr;
2628 int index = 0;
2630 while (*chain)
2632 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2633 goto return_at_index;
2635 index++;
2636 chain = &TREE_CHAIN (*chain);
2639 *chain = tree_cons (prototype, ident, NULL_TREE);
2641 return_at_index:
2642 expr = build_unary_op (ADDR_EXPR,
2643 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2644 build_int_cst (NULL_TREE, index)),
2646 return convert (objc_selector_type, expr);
2649 static tree
2650 build_selector_reference (tree ident)
2652 tree *chain = &sel_ref_chain;
2653 tree expr;
2654 int index = 0;
2656 while (*chain)
2658 if (TREE_VALUE (*chain) == ident)
2659 return (flag_next_runtime
2660 ? TREE_PURPOSE (*chain)
2661 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2662 build_int_cst (NULL_TREE, index)));
2664 index++;
2665 chain = &TREE_CHAIN (*chain);
2668 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2670 *chain = tree_cons (expr, ident, NULL_TREE);
2672 return (flag_next_runtime
2673 ? expr
2674 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2675 build_int_cst (NULL_TREE, index)));
2678 static GTY(()) int class_reference_idx;
2680 static tree
2681 build_class_reference_decl (void)
2683 tree decl;
2684 char buf[256];
2686 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2687 decl = start_var_decl (objc_class_type, buf);
2689 return decl;
2692 /* Create a class reference, but don't create a variable to reference
2693 it. */
2695 static void
2696 add_class_reference (tree ident)
2698 tree chain;
2700 if ((chain = cls_ref_chain))
2702 tree tail;
2705 if (ident == TREE_VALUE (chain))
2706 return;
2708 tail = chain;
2709 chain = TREE_CHAIN (chain);
2711 while (chain);
2713 /* Append to the end of the list */
2714 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2716 else
2717 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2720 /* Get a class reference, creating it if necessary. Also create the
2721 reference variable. */
2723 tree
2724 objc_get_class_reference (tree ident)
2726 tree orig_ident = (DECL_P (ident)
2727 ? DECL_NAME (ident)
2728 : TYPE_P (ident)
2729 ? OBJC_TYPE_NAME (ident)
2730 : ident);
2731 bool local_scope = false;
2733 #ifdef OBJCPLUS
2734 if (processing_template_decl)
2735 /* Must wait until template instantiation time. */
2736 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2737 #endif
2739 if (TREE_CODE (ident) == TYPE_DECL)
2740 ident = (DECL_ORIGINAL_TYPE (ident)
2741 ? DECL_ORIGINAL_TYPE (ident)
2742 : TREE_TYPE (ident));
2744 #ifdef OBJCPLUS
2745 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2746 && TYPE_CONTEXT (ident) != global_namespace)
2747 local_scope = true;
2748 #endif
2750 if (local_scope || !(ident = objc_is_class_name (ident)))
2752 error ("%qs is not an Objective-C class name or alias",
2753 IDENTIFIER_POINTER (orig_ident));
2754 return error_mark_node;
2757 if (flag_next_runtime && !flag_zero_link)
2759 tree *chain;
2760 tree decl;
2762 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2763 if (TREE_VALUE (*chain) == ident)
2765 if (! TREE_PURPOSE (*chain))
2766 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2768 return TREE_PURPOSE (*chain);
2771 decl = build_class_reference_decl ();
2772 *chain = tree_cons (decl, ident, NULL_TREE);
2773 return decl;
2775 else
2777 tree params;
2779 add_class_reference (ident);
2781 params = build_tree_list (NULL_TREE,
2782 my_build_string_pointer
2783 (IDENTIFIER_LENGTH (ident) + 1,
2784 IDENTIFIER_POINTER (ident)));
2786 assemble_external (objc_get_class_decl);
2787 return build_function_call (objc_get_class_decl, params);
2791 /* For each string section we have a chain which maps identifier nodes
2792 to decls for the strings. */
2794 static tree
2795 add_objc_string (tree ident, enum string_section section)
2797 tree *chain, decl, type, string_expr;
2799 if (section == class_names)
2800 chain = &class_names_chain;
2801 else if (section == meth_var_names)
2802 chain = &meth_var_names_chain;
2803 else if (section == meth_var_types)
2804 chain = &meth_var_types_chain;
2805 else
2806 abort ();
2808 while (*chain)
2810 if (TREE_VALUE (*chain) == ident)
2811 return convert (string_type_node,
2812 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2814 chain = &TREE_CHAIN (*chain);
2817 decl = build_objc_string_decl (section);
2819 type = build_array_type
2820 (char_type_node,
2821 build_index_type
2822 (build_int_cst (NULL_TREE,
2823 IDENTIFIER_LENGTH (ident))));
2824 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2825 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2826 IDENTIFIER_POINTER (ident));
2827 finish_var_decl (decl, string_expr);
2829 *chain = tree_cons (decl, ident, NULL_TREE);
2831 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2834 static GTY(()) int class_names_idx;
2835 static GTY(()) int meth_var_names_idx;
2836 static GTY(()) int meth_var_types_idx;
2838 static tree
2839 build_objc_string_decl (enum string_section section)
2841 tree decl, ident;
2842 char buf[256];
2844 if (section == class_names)
2845 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2846 else if (section == meth_var_names)
2847 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2848 else if (section == meth_var_types)
2849 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2851 ident = get_identifier (buf);
2853 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2854 DECL_EXTERNAL (decl) = 1;
2855 TREE_PUBLIC (decl) = 0;
2856 TREE_USED (decl) = 1;
2857 TREE_CONSTANT (decl) = 1;
2858 DECL_CONTEXT (decl) = 0;
2859 DECL_ARTIFICIAL (decl) = 1;
2860 #ifdef OBJCPLUS
2861 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2862 #endif
2864 make_decl_rtl (decl);
2865 pushdecl_top_level (decl);
2867 return decl;
2871 void
2872 objc_declare_alias (tree alias_ident, tree class_ident)
2874 tree underlying_class;
2876 #ifdef OBJCPLUS
2877 if (current_namespace != global_namespace) {
2878 error ("Objective-C declarations may only appear in global scope");
2880 #endif /* OBJCPLUS */
2882 if (!(underlying_class = objc_is_class_name (class_ident)))
2883 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2884 else if (objc_is_class_name (alias_ident))
2885 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2886 else
2888 /* Implement @compatibility_alias as a typedef. */
2889 #ifdef OBJCPLUS
2890 push_lang_context (lang_name_c); /* extern "C" */
2891 #endif
2892 lang_hooks.decls.pushdecl (build_decl
2893 (TYPE_DECL,
2894 alias_ident,
2895 xref_tag (RECORD_TYPE, underlying_class)));
2896 #ifdef OBJCPLUS
2897 pop_lang_context ();
2898 #endif
2899 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2903 void
2904 objc_declare_class (tree ident_list)
2906 tree list;
2907 #ifdef OBJCPLUS
2908 if (current_namespace != global_namespace) {
2909 error ("Objective-C declarations may only appear in global scope");
2911 #endif /* OBJCPLUS */
2913 for (list = ident_list; list; list = TREE_CHAIN (list))
2915 tree ident = TREE_VALUE (list);
2917 if (! objc_is_class_name (ident))
2919 tree record = lookup_name (ident), type = record;
2921 if (record)
2923 if (TREE_CODE (record) == TYPE_DECL)
2924 type = DECL_ORIGINAL_TYPE (record);
2926 if (!TYPE_HAS_OBJC_INFO (type)
2927 || !TYPE_OBJC_INTERFACE (type))
2929 error ("%qs redeclared as different kind of symbol",
2930 IDENTIFIER_POINTER (ident));
2931 error ("previous declaration of %q+D",
2932 record);
2936 record = xref_tag (RECORD_TYPE, ident);
2937 INIT_TYPE_OBJC_INFO (record);
2938 TYPE_OBJC_INTERFACE (record) = ident;
2939 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2944 tree
2945 objc_is_class_name (tree ident)
2947 tree chain;
2949 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2950 && identifier_global_value (ident))
2951 ident = identifier_global_value (ident);
2952 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2953 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2955 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2956 ident = OBJC_TYPE_NAME (ident);
2957 #ifdef OBJCPLUS
2958 if (ident && TREE_CODE (ident) == TYPE_DECL)
2959 ident = DECL_NAME (ident);
2960 #endif
2961 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2962 return NULL_TREE;
2964 if (lookup_interface (ident))
2965 return ident;
2967 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2969 if (ident == TREE_VALUE (chain))
2970 return ident;
2973 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2975 if (ident == TREE_VALUE (chain))
2976 return TREE_PURPOSE (chain);
2979 return 0;
2982 /* Check whether TYPE is either 'id' or 'Class'. */
2984 tree
2985 objc_is_id (tree type)
2987 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2988 && identifier_global_value (type))
2989 type = identifier_global_value (type);
2991 if (type && TREE_CODE (type) == TYPE_DECL)
2992 type = TREE_TYPE (type);
2994 /* NB: This function may be called before the ObjC front-end has
2995 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2996 return (objc_object_type && type
2997 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2998 ? type
2999 : NULL_TREE);
3002 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3003 class instance. This is needed by other parts of the compiler to
3004 handle ObjC types gracefully. */
3006 tree
3007 objc_is_object_ptr (tree type)
3009 tree ret;
3011 type = TYPE_MAIN_VARIANT (type);
3012 if (!POINTER_TYPE_P (type))
3013 return 0;
3015 ret = objc_is_id (type);
3016 if (!ret)
3017 ret = objc_is_class_name (TREE_TYPE (type));
3019 return ret;
3022 static int
3023 objc_is_gcable_type (tree type, int or_strong_p)
3025 tree name;
3027 if (!TYPE_P (type))
3028 return 0;
3029 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3030 return 1;
3031 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3032 return 1;
3033 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3034 return 0;
3035 type = TREE_TYPE (type);
3036 if (TREE_CODE (type) != RECORD_TYPE)
3037 return 0;
3038 name = TYPE_NAME (type);
3039 return (objc_is_class_name (name) != NULL_TREE);
3042 static tree
3043 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3045 if (expr == oldexpr)
3046 return newexpr;
3048 switch (TREE_CODE (expr))
3050 case COMPONENT_REF:
3051 return objc_build_component_ref
3052 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3053 oldexpr,
3054 newexpr),
3055 DECL_NAME (TREE_OPERAND (expr, 1)));
3056 case ARRAY_REF:
3057 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3058 oldexpr,
3059 newexpr),
3060 TREE_OPERAND (expr, 1));
3061 case INDIRECT_REF:
3062 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3063 oldexpr,
3064 newexpr), "->");
3065 default:
3066 return expr;
3070 static tree
3071 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3073 tree func_params;
3074 /* The LHS parameter contains the expression 'outervar->memberspec';
3075 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3076 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3078 tree offs
3079 = objc_substitute_decl
3080 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3081 tree func
3082 = (flag_objc_direct_dispatch
3083 ? objc_assign_ivar_fast_decl
3084 : objc_assign_ivar_decl);
3086 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3087 offs = fold (offs);
3088 func_params = tree_cons (NULL_TREE,
3089 convert (objc_object_type, rhs),
3090 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3091 tree_cons (NULL_TREE, offs,
3092 NULL_TREE)));
3094 assemble_external (func);
3095 return build_function_call (func, func_params);
3098 static tree
3099 objc_build_global_assignment (tree lhs, tree rhs)
3101 tree func_params = tree_cons (NULL_TREE,
3102 convert (objc_object_type, rhs),
3103 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3104 build_unary_op (ADDR_EXPR, lhs, 0)),
3105 NULL_TREE));
3107 assemble_external (objc_assign_global_decl);
3108 return build_function_call (objc_assign_global_decl, func_params);
3111 static tree
3112 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3114 tree func_params = tree_cons (NULL_TREE,
3115 convert (objc_object_type, rhs),
3116 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3117 build_unary_op (ADDR_EXPR, lhs, 0)),
3118 NULL_TREE));
3120 assemble_external (objc_assign_strong_cast_decl);
3121 return build_function_call (objc_assign_strong_cast_decl, func_params);
3124 static int
3125 objc_is_gcable_p (tree expr)
3127 return (TREE_CODE (expr) == COMPONENT_REF
3128 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3129 : TREE_CODE (expr) == ARRAY_REF
3130 ? (objc_is_gcable_p (TREE_TYPE (expr))
3131 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3132 : TREE_CODE (expr) == ARRAY_TYPE
3133 ? objc_is_gcable_p (TREE_TYPE (expr))
3134 : TYPE_P (expr)
3135 ? objc_is_gcable_type (expr, 1)
3136 : (objc_is_gcable_p (TREE_TYPE (expr))
3137 || (DECL_P (expr)
3138 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3141 static int
3142 objc_is_ivar_reference_p (tree expr)
3144 return (TREE_CODE (expr) == ARRAY_REF
3145 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3146 : TREE_CODE (expr) == COMPONENT_REF
3147 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3148 : 0);
3151 static int
3152 objc_is_global_reference_p (tree expr)
3154 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3155 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3156 : DECL_P (expr)
3157 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3158 : 0);
3161 tree
3162 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3164 tree result = NULL_TREE, outer;
3165 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3167 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3168 will have been transformed to the form '*(type *)&expr'. */
3169 if (TREE_CODE (lhs) == INDIRECT_REF)
3171 outer = TREE_OPERAND (lhs, 0);
3173 while (!strong_cast_p
3174 && (TREE_CODE (outer) == CONVERT_EXPR
3175 || TREE_CODE (outer) == NOP_EXPR
3176 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3178 tree lhstype = TREE_TYPE (outer);
3180 /* Descend down the cast chain, and record the first objc_gc
3181 attribute found. */
3182 if (POINTER_TYPE_P (lhstype))
3184 tree attr
3185 = lookup_attribute ("objc_gc",
3186 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3188 if (attr)
3189 strong_cast_p = 1;
3192 outer = TREE_OPERAND (outer, 0);
3196 /* If we have a __strong cast, it trumps all else. */
3197 if (strong_cast_p)
3199 if (modifycode != NOP_EXPR)
3200 goto invalid_pointer_arithmetic;
3202 if (warn_assign_intercept)
3203 warning (0, "strong-cast assignment has been intercepted");
3205 result = objc_build_strong_cast_assignment (lhs, rhs);
3207 goto exit_point;
3210 /* the lhs must be of a suitable type, regardless of its underlying
3211 structure. */
3212 if (!objc_is_gcable_p (lhs))
3213 goto exit_point;
3215 outer = lhs;
3217 while (outer
3218 && (TREE_CODE (outer) == COMPONENT_REF
3219 || TREE_CODE (outer) == ARRAY_REF))
3220 outer = TREE_OPERAND (outer, 0);
3222 if (TREE_CODE (outer) == INDIRECT_REF)
3224 outer = TREE_OPERAND (outer, 0);
3225 indirect_p = 1;
3228 outer_gc_p = objc_is_gcable_p (outer);
3230 /* Handle ivar assignments. */
3231 if (objc_is_ivar_reference_p (lhs))
3233 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3234 doesn't cut it here), the best we can do here is suggest a cast. */
3235 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3237 /* We may still be able to use the global write barrier... */
3238 if (!indirect_p && objc_is_global_reference_p (outer))
3239 goto global_reference;
3241 suggest_cast:
3242 if (modifycode == NOP_EXPR)
3244 if (warn_assign_intercept)
3245 warning (0, "strong-cast may possibly be needed");
3248 goto exit_point;
3251 if (modifycode != NOP_EXPR)
3252 goto invalid_pointer_arithmetic;
3254 if (warn_assign_intercept)
3255 warning (0, "instance variable assignment has been intercepted");
3257 result = objc_build_ivar_assignment (outer, lhs, rhs);
3259 goto exit_point;
3262 /* Likewise, intercept assignment to global/static variables if their type is
3263 GC-marked. */
3264 if (objc_is_global_reference_p (outer))
3266 if (indirect_p)
3267 goto suggest_cast;
3269 global_reference:
3270 if (modifycode != NOP_EXPR)
3272 invalid_pointer_arithmetic:
3273 if (outer_gc_p)
3274 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3276 goto exit_point;
3279 if (warn_assign_intercept)
3280 warning (0, "global/static variable assignment has been intercepted");
3282 result = objc_build_global_assignment (lhs, rhs);
3285 /* In all other cases, fall back to the normal mechanism. */
3286 exit_point:
3287 return result;
3290 struct interface_tuple GTY(())
3292 tree id;
3293 tree class_name;
3296 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3298 static hashval_t
3299 hash_interface (const void *p)
3301 const struct interface_tuple *d = p;
3302 return IDENTIFIER_HASH_VALUE (d->id);
3305 static int
3306 eq_interface (const void *p1, const void *p2)
3308 const struct interface_tuple *d = p1;
3309 return d->id == p2;
3312 static tree
3313 lookup_interface (tree ident)
3315 #ifdef OBJCPLUS
3316 if (ident && TREE_CODE (ident) == TYPE_DECL)
3317 ident = DECL_NAME (ident);
3318 #endif
3320 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3321 return NULL_TREE;
3324 struct interface_tuple **slot;
3325 tree i = NULL_TREE;
3327 if (interface_htab)
3329 slot = (struct interface_tuple **)
3330 htab_find_slot_with_hash (interface_htab, ident,
3331 IDENTIFIER_HASH_VALUE (ident),
3332 NO_INSERT);
3333 if (slot && *slot)
3334 i = (*slot)->class_name;
3336 return i;
3340 /* Implement @defs (<classname>) within struct bodies. */
3342 tree
3343 objc_get_class_ivars (tree class_name)
3345 tree interface = lookup_interface (class_name);
3347 if (interface)
3348 return get_class_ivars (interface, true);
3350 error ("cannot find interface declaration for %qs",
3351 IDENTIFIER_POINTER (class_name));
3353 return error_mark_node;
3356 /* Used by: build_private_template, continue_class,
3357 and for @defs constructs. */
3359 static tree
3360 get_class_ivars (tree interface, bool inherited)
3362 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3364 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3365 by the current class (i.e., they do not include super-class ivars).
3366 However, the CLASS_IVARS list will be side-effected by a call to
3367 finish_struct(), which will fill in field offsets. */
3368 if (!CLASS_IVARS (interface))
3369 CLASS_IVARS (interface) = ivar_chain;
3371 if (!inherited)
3372 return ivar_chain;
3374 while (CLASS_SUPER_NAME (interface))
3376 /* Prepend super-class ivars. */
3377 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3378 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3379 ivar_chain);
3382 return ivar_chain;
3385 static tree
3386 objc_create_temporary_var (tree type)
3388 tree decl;
3390 decl = build_decl (VAR_DECL, NULL_TREE, type);
3391 TREE_USED (decl) = 1;
3392 DECL_ARTIFICIAL (decl) = 1;
3393 DECL_IGNORED_P (decl) = 1;
3394 DECL_CONTEXT (decl) = current_function_decl;
3396 return decl;
3399 /* Exception handling constructs. We begin by having the parser do most
3400 of the work and passing us blocks. What we do next depends on whether
3401 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3402 We abstract all of this in a handful of appropriately named routines. */
3404 /* Stack of open try blocks. */
3406 struct objc_try_context
3408 struct objc_try_context *outer;
3410 /* Statements (or statement lists) as processed by the parser. */
3411 tree try_body;
3412 tree finally_body;
3414 /* Some file position locations. */
3415 location_t try_locus;
3416 location_t end_try_locus;
3417 location_t end_catch_locus;
3418 location_t finally_locus;
3419 location_t end_finally_locus;
3421 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3422 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3423 tree catch_list;
3425 /* The CATCH_EXPR of an open @catch clause. */
3426 tree current_catch;
3428 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3429 tree caught_decl;
3430 tree stack_decl;
3431 tree rethrow_decl;
3434 static struct objc_try_context *cur_try_context;
3436 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3437 that represents TYPE. For Objective-C, this is just the class name. */
3438 /* ??? Isn't there a class object or some such? Is it easy to get? */
3440 #ifndef OBJCPLUS
3441 static tree
3442 objc_eh_runtime_type (tree type)
3444 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3446 #endif
3448 /* Initialize exception handling. */
3450 static void
3451 objc_init_exceptions (void)
3453 static bool done = false;
3454 if (done)
3455 return;
3456 done = true;
3458 if (flag_objc_sjlj_exceptions)
3460 /* On Darwin, ObjC exceptions require a sufficiently recent
3461 version of the runtime, so the user must ask for them explicitly. */
3462 if (!flag_objc_exceptions)
3463 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3464 "exception syntax");
3466 #ifndef OBJCPLUS
3467 else
3469 c_eh_initialized_p = true;
3470 eh_personality_libfunc
3471 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3472 ? "__gnu_objc_personality_sj0"
3473 : "__gnu_objc_personality_v0");
3474 default_init_unwind_resume_libfunc ();
3475 using_eh_for_cleanups ();
3476 lang_eh_runtime_type = objc_eh_runtime_type;
3478 #endif
3481 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3482 we'll arrange for it to be initialized (and associated with a binding)
3483 later. */
3485 static tree
3486 objc_build_exc_ptr (void)
3488 if (flag_objc_sjlj_exceptions)
3490 tree var = cur_try_context->caught_decl;
3491 if (!var)
3493 var = objc_create_temporary_var (objc_object_type);
3494 cur_try_context->caught_decl = var;
3496 return var;
3498 else
3499 return build0 (EXC_PTR_EXPR, objc_object_type);
3502 /* Build "objc_exception_try_exit(&_stack)". */
3504 static tree
3505 next_sjlj_build_try_exit (void)
3507 tree t;
3508 t = build_fold_addr_expr (cur_try_context->stack_decl);
3509 t = tree_cons (NULL, t, NULL);
3510 t = build_function_call (objc_exception_try_exit_decl, t);
3511 return t;
3514 /* Build
3515 objc_exception_try_enter (&_stack);
3516 if (_setjmp(&_stack.buf))
3518 else
3520 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3521 empty, ready for the caller to fill them in. */
3523 static tree
3524 next_sjlj_build_enter_and_setjmp (void)
3526 tree t, enter, sj, cond;
3528 t = build_fold_addr_expr (cur_try_context->stack_decl);
3529 t = tree_cons (NULL, t, NULL);
3530 enter = build_function_call (objc_exception_try_enter_decl, t);
3532 t = objc_build_component_ref (cur_try_context->stack_decl,
3533 get_identifier ("buf"));
3534 t = build_fold_addr_expr (t);
3535 #ifdef OBJCPLUS
3536 /* Convert _setjmp argument to type that is expected. */
3537 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3538 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3539 else
3540 t = convert (ptr_type_node, t);
3541 #else
3542 t = convert (ptr_type_node, t);
3543 #endif
3544 t = tree_cons (NULL, t, NULL);
3545 sj = build_function_call (objc_setjmp_decl, t);
3547 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3548 cond = c_common_truthvalue_conversion (cond);
3550 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3553 /* Build:
3555 DECL = objc_exception_extract(&_stack); */
3557 static tree
3558 next_sjlj_build_exc_extract (tree decl)
3560 tree t;
3562 t = build_fold_addr_expr (cur_try_context->stack_decl);
3563 t = tree_cons (NULL, t, NULL);
3564 t = build_function_call (objc_exception_extract_decl, t);
3565 t = convert (TREE_TYPE (decl), t);
3566 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3568 return t;
3571 /* Build
3572 if (objc_exception_match(obj_get_class(TYPE), _caught)
3573 BODY
3574 else if (...)
3576 else
3578 _rethrow = _caught;
3579 objc_exception_try_exit(&_stack);
3581 from the sequence of CATCH_EXPRs in the current try context. */
3583 static tree
3584 next_sjlj_build_catch_list (void)
3586 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3587 tree catch_seq, t;
3588 tree *last = &catch_seq;
3589 bool saw_id = false;
3591 for (; !tsi_end_p (i); tsi_next (&i))
3593 tree stmt = tsi_stmt (i);
3594 tree type = CATCH_TYPES (stmt);
3595 tree body = CATCH_BODY (stmt);
3597 if (type == NULL)
3599 *last = body;
3600 saw_id = true;
3601 break;
3603 else
3605 tree args, cond;
3607 if (type == error_mark_node)
3608 cond = error_mark_node;
3609 else
3611 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3612 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3613 args = tree_cons (NULL, t, args);
3614 t = build_function_call (objc_exception_match_decl, args);
3615 cond = c_common_truthvalue_conversion (t);
3617 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3618 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3620 *last = t;
3621 last = &COND_EXPR_ELSE (t);
3625 if (!saw_id)
3627 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3628 cur_try_context->caught_decl);
3629 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3630 append_to_statement_list (t, last);
3632 t = next_sjlj_build_try_exit ();
3633 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3634 append_to_statement_list (t, last);
3637 return catch_seq;
3640 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3641 exception handling. We aim to build:
3644 struct _objc_exception_data _stack;
3645 id _rethrow = 0;
3648 objc_exception_try_enter (&_stack);
3649 if (_setjmp(&_stack.buf))
3651 id _caught = objc_exception_extract(&_stack);
3652 objc_exception_try_enter (&_stack);
3653 if (_setjmp(&_stack.buf))
3654 _rethrow = objc_exception_extract(&_stack);
3655 else
3656 CATCH-LIST
3658 else
3659 TRY-BLOCK
3661 finally
3663 if (!_rethrow)
3664 objc_exception_try_exit(&_stack);
3665 FINALLY-BLOCK
3666 if (_rethrow)
3667 objc_exception_throw(_rethrow);
3671 If CATCH-LIST is empty, we can omit all of the block containing
3672 "_caught" except for the setting of _rethrow. Note the use of
3673 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3674 but handles goto and other exits from the block. */
3676 static tree
3677 next_sjlj_build_try_catch_finally (void)
3679 tree rethrow_decl, stack_decl, t;
3680 tree catch_seq, try_fin, bind;
3682 /* Create the declarations involved. */
3683 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3684 stack_decl = objc_create_temporary_var (t);
3685 cur_try_context->stack_decl = stack_decl;
3687 rethrow_decl = objc_create_temporary_var (objc_object_type);
3688 cur_try_context->rethrow_decl = rethrow_decl;
3689 TREE_CHAIN (rethrow_decl) = stack_decl;
3691 /* Build the outermost variable binding level. */
3692 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3693 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3694 TREE_SIDE_EFFECTS (bind) = 1;
3696 /* Initialize rethrow_decl. */
3697 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3698 convert (objc_object_type, null_pointer_node));
3699 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3700 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3702 /* Build the outermost TRY_FINALLY_EXPR. */
3703 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3704 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3705 TREE_SIDE_EFFECTS (try_fin) = 1;
3706 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3708 /* Create the complete catch sequence. */
3709 if (cur_try_context->catch_list)
3711 tree caught_decl = objc_build_exc_ptr ();
3712 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3713 TREE_SIDE_EFFECTS (catch_seq) = 1;
3715 t = next_sjlj_build_exc_extract (caught_decl);
3716 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3718 t = next_sjlj_build_enter_and_setjmp ();
3719 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3720 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3721 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3723 else
3724 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3725 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3727 /* Build the main register-and-try if statement. */
3728 t = next_sjlj_build_enter_and_setjmp ();
3729 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3730 COND_EXPR_THEN (t) = catch_seq;
3731 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3732 TREE_OPERAND (try_fin, 0) = t;
3734 /* Build the complete FINALLY statement list. */
3735 t = next_sjlj_build_try_exit ();
3736 t = build_stmt (COND_EXPR,
3737 c_common_truthvalue_conversion (rethrow_decl),
3738 NULL, t);
3739 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3740 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3742 append_to_statement_list (cur_try_context->finally_body,
3743 &TREE_OPERAND (try_fin, 1));
3745 t = tree_cons (NULL, rethrow_decl, NULL);
3746 t = build_function_call (objc_exception_throw_decl, t);
3747 t = build_stmt (COND_EXPR,
3748 c_common_truthvalue_conversion (rethrow_decl),
3749 t, NULL);
3750 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3751 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3753 return bind;
3756 /* Called just after parsing the @try and its associated BODY. We now
3757 must prepare for the tricky bits -- handling the catches and finally. */
3759 void
3760 objc_begin_try_stmt (location_t try_locus, tree body)
3762 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3763 c->outer = cur_try_context;
3764 c->try_body = body;
3765 c->try_locus = try_locus;
3766 c->end_try_locus = input_location;
3767 cur_try_context = c;
3769 objc_init_exceptions ();
3771 if (flag_objc_sjlj_exceptions)
3772 objc_mark_locals_volatile (NULL);
3775 /* Called just after parsing "@catch (parm)". Open a binding level,
3776 enter DECL into the binding level, and initialize it. Leave the
3777 binding level open while the body of the compound statement is parsed. */
3779 void
3780 objc_begin_catch_clause (tree decl)
3782 tree compound, type, t;
3784 /* Begin a new scope that the entire catch clause will live in. */
3785 compound = c_begin_compound_stmt (true);
3787 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3788 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3789 lang_hooks.decls.pushdecl (decl);
3791 /* Since a decl is required here by syntax, don't warn if its unused. */
3792 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3793 be what the previous objc implementation did. */
3794 TREE_USED (decl) = 1;
3796 /* Verify that the type of the catch is valid. It must be a pointer
3797 to an Objective-C class, or "id" (which is catch-all). */
3798 type = TREE_TYPE (decl);
3800 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3801 type = NULL;
3802 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3804 error ("@catch parameter is not a known Objective-C class type");
3805 type = error_mark_node;
3807 else if (cur_try_context->catch_list)
3809 /* Examine previous @catch clauses and see if we've already
3810 caught the type in question. */
3811 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3812 for (; !tsi_end_p (i); tsi_next (&i))
3814 tree stmt = tsi_stmt (i);
3815 t = CATCH_TYPES (stmt);
3816 if (t == error_mark_node)
3817 continue;
3818 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3820 warning (0, "exception of type %<%T%> will be caught",
3821 TREE_TYPE (type));
3822 warning (0, "%H by earlier handler for %<%T%>",
3823 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3824 break;
3829 /* Record the data for the catch in the try context so that we can
3830 finalize it later. */
3831 t = build_stmt (CATCH_EXPR, type, compound);
3832 cur_try_context->current_catch = t;
3834 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3835 t = objc_build_exc_ptr ();
3836 t = convert (TREE_TYPE (decl), t);
3837 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3838 add_stmt (t);
3841 /* Called just after parsing the closing brace of a @catch clause. Close
3842 the open binding level, and record a CATCH_EXPR for it. */
3844 void
3845 objc_finish_catch_clause (void)
3847 tree c = cur_try_context->current_catch;
3848 cur_try_context->current_catch = NULL;
3849 cur_try_context->end_catch_locus = input_location;
3851 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3852 append_to_statement_list (c, &cur_try_context->catch_list);
3855 /* Called after parsing a @finally clause and its associated BODY.
3856 Record the body for later placement. */
3858 void
3859 objc_build_finally_clause (location_t finally_locus, tree body)
3861 cur_try_context->finally_body = body;
3862 cur_try_context->finally_locus = finally_locus;
3863 cur_try_context->end_finally_locus = input_location;
3866 /* Called to finalize a @try construct. */
3868 tree
3869 objc_finish_try_stmt (void)
3871 struct objc_try_context *c = cur_try_context;
3872 tree stmt;
3874 if (c->catch_list == NULL && c->finally_body == NULL)
3875 error ("%<@try%> without %<@catch%> or %<@finally%>");
3877 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3878 if (flag_objc_sjlj_exceptions)
3880 if (!cur_try_context->finally_body)
3882 cur_try_context->finally_locus = input_location;
3883 cur_try_context->end_finally_locus = input_location;
3885 stmt = next_sjlj_build_try_catch_finally ();
3887 else
3889 /* Otherwise, nest the CATCH inside a FINALLY. */
3890 stmt = c->try_body;
3891 if (c->catch_list)
3893 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3894 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3896 if (c->finally_body)
3898 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3899 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3902 add_stmt (stmt);
3904 cur_try_context = c->outer;
3905 free (c);
3906 return stmt;
3909 tree
3910 objc_build_throw_stmt (tree throw_expr)
3912 tree args;
3914 objc_init_exceptions ();
3916 if (throw_expr == NULL)
3918 /* If we're not inside a @catch block, there is no "current
3919 exception" to be rethrown. */
3920 if (cur_try_context == NULL
3921 || cur_try_context->current_catch == NULL)
3923 error ("%<@throw%> (rethrow) used outside of a @catch block");
3924 return NULL_TREE;
3927 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3928 value that we get from the runtime. */
3929 throw_expr = objc_build_exc_ptr ();
3932 /* A throw is just a call to the runtime throw function with the
3933 object as a parameter. */
3934 args = tree_cons (NULL, throw_expr, NULL);
3935 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3938 tree
3939 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3941 tree args, call;
3943 /* First lock the mutex. */
3944 mutex = save_expr (mutex);
3945 args = tree_cons (NULL, mutex, NULL);
3946 call = build_function_call (objc_sync_enter_decl, args);
3947 SET_EXPR_LOCATION (call, start_locus);
3948 add_stmt (call);
3950 /* Build the mutex unlock. */
3951 args = tree_cons (NULL, mutex, NULL);
3952 call = build_function_call (objc_sync_exit_decl, args);
3953 SET_EXPR_LOCATION (call, input_location);
3955 /* Put the that and the body in a TRY_FINALLY. */
3956 objc_begin_try_stmt (start_locus, body);
3957 objc_build_finally_clause (input_location, call);
3958 return objc_finish_try_stmt ();
3962 /* Predefine the following data type:
3964 struct _objc_exception_data
3966 int buf[OBJC_JBLEN];
3967 void *pointers[4];
3968 }; */
3970 /* The following yuckiness should prevent users from having to #include
3971 <setjmp.h> in their code... */
3973 /* Define to a harmless positive value so the below code doesn't die. */
3974 #ifndef OBJC_JBLEN
3975 #define OBJC_JBLEN 18
3976 #endif
3978 static void
3979 build_next_objc_exception_stuff (void)
3981 tree field_decl, field_decl_chain, index, temp_type;
3983 objc_exception_data_template
3984 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3986 /* int buf[OBJC_JBLEN]; */
3988 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3989 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3990 "buf");
3991 field_decl_chain = field_decl;
3993 /* void *pointers[4]; */
3995 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3996 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3997 "pointers");
3998 chainon (field_decl_chain, field_decl);
4000 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
4002 /* int _setjmp(...); */
4003 /* If the user includes <setjmp.h>, this shall be superseded by
4004 'int _setjmp(jmp_buf);' */
4005 temp_type = build_function_type (integer_type_node, NULL_TREE);
4006 objc_setjmp_decl
4007 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4009 /* id objc_exception_extract(struct _objc_exception_data *); */
4010 temp_type
4011 = build_function_type (objc_object_type,
4012 tree_cons (NULL_TREE,
4013 build_pointer_type (objc_exception_data_template),
4014 OBJC_VOID_AT_END));
4015 objc_exception_extract_decl
4016 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4017 NULL_TREE);
4018 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4019 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4020 temp_type
4021 = build_function_type (void_type_node,
4022 tree_cons (NULL_TREE,
4023 build_pointer_type (objc_exception_data_template),
4024 OBJC_VOID_AT_END));
4025 objc_exception_try_enter_decl
4026 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4027 NULL_TREE);
4028 objc_exception_try_exit_decl
4029 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4030 NULL_TREE);
4032 /* int objc_exception_match(id, id); */
4033 temp_type
4034 = build_function_type (integer_type_node,
4035 tree_cons (NULL_TREE, objc_object_type,
4036 tree_cons (NULL_TREE, objc_object_type,
4037 OBJC_VOID_AT_END)));
4038 objc_exception_match_decl
4039 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4040 NULL_TREE);
4042 /* id objc_assign_ivar (id, id, unsigned int); */
4043 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4044 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4045 temp_type
4046 = build_function_type (objc_object_type,
4047 tree_cons
4048 (NULL_TREE, objc_object_type,
4049 tree_cons (NULL_TREE, objc_object_type,
4050 tree_cons (NULL_TREE,
4051 unsigned_type_node,
4052 OBJC_VOID_AT_END))));
4053 objc_assign_ivar_decl
4054 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4055 NULL, NULL_TREE);
4056 #ifdef OFFS_ASSIGNIVAR_FAST
4057 objc_assign_ivar_fast_decl
4058 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4059 NOT_BUILT_IN, NULL, NULL_TREE);
4060 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4061 = tree_cons (get_identifier ("hard_coded_address"),
4062 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4063 NULL_TREE);
4064 #else
4065 /* Default to slower ivar method. */
4066 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4067 #endif
4069 /* id objc_assign_global (id, id *); */
4070 /* id objc_assign_strongCast (id, id *); */
4071 temp_type = build_function_type (objc_object_type,
4072 tree_cons (NULL_TREE, objc_object_type,
4073 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4074 OBJC_VOID_AT_END)));
4075 objc_assign_global_decl
4076 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4077 NULL_TREE);
4078 objc_assign_strong_cast_decl
4079 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4080 NULL_TREE);
4083 static void
4084 build_objc_exception_stuff (void)
4086 tree noreturn_list, nothrow_list, temp_type;
4088 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4089 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4091 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4092 /* void objc_sync_enter(id); */
4093 /* void objc_sync_exit(id); */
4094 temp_type = build_function_type (void_type_node,
4095 tree_cons (NULL_TREE, objc_object_type,
4096 OBJC_VOID_AT_END));
4097 objc_exception_throw_decl
4098 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4099 noreturn_list);
4100 objc_sync_enter_decl
4101 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4102 NULL, nothrow_list);
4103 objc_sync_exit_decl
4104 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4105 NULL, nothrow_list);
4108 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4109 name as the class:
4111 struct <classname> {
4112 struct _objc_class *isa;
4114 }; */
4116 static void
4117 build_private_template (tree class)
4119 if (!CLASS_STATIC_TEMPLATE (class))
4121 tree record = objc_build_struct (class,
4122 get_class_ivars (class, false),
4123 CLASS_SUPER_NAME (class));
4125 /* Set the TREE_USED bit for this struct, so that stab generator
4126 can emit stabs for this struct type. */
4127 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4128 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4132 /* Begin code generation for protocols... */
4134 /* struct _objc_protocol {
4135 struct _objc_class *isa;
4136 char *protocol_name;
4137 struct _objc_protocol **protocol_list;
4138 struct _objc__method_prototype_list *instance_methods;
4139 struct _objc__method_prototype_list *class_methods;
4140 }; */
4142 static void
4143 build_protocol_template (void)
4145 tree field_decl, field_decl_chain;
4147 objc_protocol_template = start_struct (RECORD_TYPE,
4148 get_identifier (UTAG_PROTOCOL));
4150 /* struct _objc_class *isa; */
4151 field_decl = create_field_decl (build_pointer_type
4152 (xref_tag (RECORD_TYPE,
4153 get_identifier (UTAG_CLASS))),
4154 "isa");
4155 field_decl_chain = field_decl;
4157 /* char *protocol_name; */
4158 field_decl = create_field_decl (string_type_node, "protocol_name");
4159 chainon (field_decl_chain, field_decl);
4161 /* struct _objc_protocol **protocol_list; */
4162 field_decl = create_field_decl (build_pointer_type
4163 (build_pointer_type
4164 (objc_protocol_template)),
4165 "protocol_list");
4166 chainon (field_decl_chain, field_decl);
4168 /* struct _objc__method_prototype_list *instance_methods; */
4169 field_decl = create_field_decl (objc_method_proto_list_ptr,
4170 "instance_methods");
4171 chainon (field_decl_chain, field_decl);
4173 /* struct _objc__method_prototype_list *class_methods; */
4174 field_decl = create_field_decl (objc_method_proto_list_ptr,
4175 "class_methods");
4176 chainon (field_decl_chain, field_decl);
4178 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4181 static tree
4182 build_descriptor_table_initializer (tree type, tree entries)
4184 tree initlist = NULL_TREE;
4188 tree eltlist = NULL_TREE;
4190 eltlist
4191 = tree_cons (NULL_TREE,
4192 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4193 eltlist
4194 = tree_cons (NULL_TREE,
4195 add_objc_string (METHOD_ENCODING (entries),
4196 meth_var_types),
4197 eltlist);
4199 initlist
4200 = tree_cons (NULL_TREE,
4201 objc_build_constructor (type, nreverse (eltlist)),
4202 initlist);
4204 entries = TREE_CHAIN (entries);
4206 while (entries);
4208 return objc_build_constructor (build_array_type (type, 0),
4209 nreverse (initlist));
4212 /* struct objc_method_prototype_list {
4213 int count;
4214 struct objc_method_prototype {
4215 SEL name;
4216 char *types;
4217 } list[1];
4218 }; */
4220 static tree
4221 build_method_prototype_list_template (tree list_type, int size)
4223 tree objc_ivar_list_record;
4224 tree field_decl, field_decl_chain;
4226 /* Generate an unnamed struct definition. */
4228 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4230 /* int method_count; */
4231 field_decl = create_field_decl (integer_type_node, "method_count");
4232 field_decl_chain = field_decl;
4234 /* struct objc_method method_list[]; */
4235 field_decl = create_field_decl (build_array_type
4236 (list_type,
4237 build_index_type
4238 (build_int_cst (NULL_TREE, size - 1))),
4239 "method_list");
4240 chainon (field_decl_chain, field_decl);
4242 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4244 return objc_ivar_list_record;
4247 static tree
4248 build_method_prototype_template (void)
4250 tree proto_record;
4251 tree field_decl, field_decl_chain;
4253 proto_record
4254 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4256 /* SEL _cmd; */
4257 field_decl = create_field_decl (objc_selector_type, "_cmd");
4258 field_decl_chain = field_decl;
4260 /* char *method_types; */
4261 field_decl = create_field_decl (string_type_node, "method_types");
4262 chainon (field_decl_chain, field_decl);
4264 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4266 return proto_record;
4269 static tree
4270 objc_method_parm_type (tree type)
4272 type = TREE_VALUE (TREE_TYPE (type));
4273 if (TREE_CODE (type) == TYPE_DECL)
4274 type = TREE_TYPE (type);
4275 return type;
4278 static int
4279 objc_encoded_type_size (tree type)
4281 int sz = int_size_in_bytes (type);
4283 /* Make all integer and enum types at least as large
4284 as an int. */
4285 if (sz > 0 && INTEGRAL_TYPE_P (type))
4286 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4287 /* Treat arrays as pointers, since that's how they're
4288 passed in. */
4289 else if (TREE_CODE (type) == ARRAY_TYPE)
4290 sz = int_size_in_bytes (ptr_type_node);
4291 return sz;
4294 static tree
4295 encode_method_prototype (tree method_decl)
4297 tree parms;
4298 int parm_offset, i;
4299 char buf[40];
4300 tree result;
4302 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4303 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4305 /* Encode return type. */
4306 encode_type (objc_method_parm_type (method_decl),
4307 obstack_object_size (&util_obstack),
4308 OBJC_ENCODE_INLINE_DEFS);
4310 /* Stack size. */
4311 /* The first two arguments (self and _cmd) are pointers; account for
4312 their size. */
4313 i = int_size_in_bytes (ptr_type_node);
4314 parm_offset = 2 * i;
4315 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4316 parms = TREE_CHAIN (parms))
4318 tree type = objc_method_parm_type (parms);
4319 int sz = objc_encoded_type_size (type);
4321 /* If a type size is not known, bail out. */
4322 if (sz < 0)
4324 error ("type %q+D does not have a known size",
4325 type);
4326 /* Pretend that the encoding succeeded; the compilation will
4327 fail nevertheless. */
4328 goto finish_encoding;
4330 parm_offset += sz;
4333 sprintf (buf, "%d@0:%d", parm_offset, i);
4334 obstack_grow (&util_obstack, buf, strlen (buf));
4336 /* Argument types. */
4337 parm_offset = 2 * i;
4338 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4339 parms = TREE_CHAIN (parms))
4341 tree type = objc_method_parm_type (parms);
4343 /* Process argument qualifiers for user supplied arguments. */
4344 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4346 /* Type. */
4347 encode_type (type, obstack_object_size (&util_obstack),
4348 OBJC_ENCODE_INLINE_DEFS);
4350 /* Compute offset. */
4351 sprintf (buf, "%d", parm_offset);
4352 parm_offset += objc_encoded_type_size (type);
4354 obstack_grow (&util_obstack, buf, strlen (buf));
4357 finish_encoding:
4358 obstack_1grow (&util_obstack, '\0');
4359 result = get_identifier (obstack_finish (&util_obstack));
4360 obstack_free (&util_obstack, util_firstobj);
4361 return result;
4364 static tree
4365 generate_descriptor_table (tree type, const char *name, int size, tree list,
4366 tree proto)
4368 tree decl, initlist;
4370 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4372 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4373 initlist = tree_cons (NULL_TREE, list, initlist);
4375 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4377 return decl;
4380 static void
4381 generate_method_descriptors (tree protocol)
4383 tree initlist, chain, method_list_template;
4384 int size;
4386 if (!objc_method_prototype_template)
4387 objc_method_prototype_template = build_method_prototype_template ();
4389 chain = PROTOCOL_CLS_METHODS (protocol);
4390 if (chain)
4392 size = list_length (chain);
4394 method_list_template
4395 = build_method_prototype_list_template (objc_method_prototype_template,
4396 size);
4398 initlist
4399 = build_descriptor_table_initializer (objc_method_prototype_template,
4400 chain);
4402 UOBJC_CLASS_METHODS_decl
4403 = generate_descriptor_table (method_list_template,
4404 "_OBJC_PROTOCOL_CLASS_METHODS",
4405 size, initlist, protocol);
4407 else
4408 UOBJC_CLASS_METHODS_decl = 0;
4410 chain = PROTOCOL_NST_METHODS (protocol);
4411 if (chain)
4413 size = list_length (chain);
4415 method_list_template
4416 = build_method_prototype_list_template (objc_method_prototype_template,
4417 size);
4418 initlist
4419 = build_descriptor_table_initializer (objc_method_prototype_template,
4420 chain);
4422 UOBJC_INSTANCE_METHODS_decl
4423 = generate_descriptor_table (method_list_template,
4424 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4425 size, initlist, protocol);
4427 else
4428 UOBJC_INSTANCE_METHODS_decl = 0;
4431 static void
4432 generate_protocol_references (tree plist)
4434 tree lproto;
4436 /* Forward declare protocols referenced. */
4437 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4439 tree proto = TREE_VALUE (lproto);
4441 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4442 && PROTOCOL_NAME (proto))
4444 if (! PROTOCOL_FORWARD_DECL (proto))
4445 build_protocol_reference (proto);
4447 if (PROTOCOL_LIST (proto))
4448 generate_protocol_references (PROTOCOL_LIST (proto));
4453 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4454 current class. */
4455 #ifdef OBJCPLUS
4456 static void
4457 objc_generate_cxx_ctor_or_dtor (bool dtor)
4459 tree fn, body, compound_stmt, ivar;
4461 /* - (id) .cxx_construct { ... return self; } */
4462 /* - (void) .cxx_construct { ... } */
4464 objc_set_method_type (MINUS_EXPR);
4465 objc_start_method_definition
4466 (objc_build_method_signature (build_tree_list (NULL_TREE,
4467 dtor
4468 ? void_type_node
4469 : objc_object_type),
4470 get_identifier (dtor
4471 ? TAG_CXX_DESTRUCT
4472 : TAG_CXX_CONSTRUCT),
4473 make_node (TREE_LIST),
4474 false));
4475 body = begin_function_body ();
4476 compound_stmt = begin_compound_stmt (0);
4478 ivar = CLASS_IVARS (implementation_template);
4479 /* Destroy ivars in reverse order. */
4480 if (dtor)
4481 ivar = nreverse (copy_list (ivar));
4483 for (; ivar; ivar = TREE_CHAIN (ivar))
4485 if (TREE_CODE (ivar) == FIELD_DECL)
4487 tree type = TREE_TYPE (ivar);
4489 /* Call the ivar's default constructor or destructor. Do not
4490 call the destructor unless a corresponding constructor call
4491 has also been made (or is not needed). */
4492 if (IS_AGGR_TYPE (type)
4493 && (dtor
4494 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4495 && (!TYPE_NEEDS_CONSTRUCTING (type)
4496 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4497 : (TYPE_NEEDS_CONSTRUCTING (type)
4498 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4499 finish_expr_stmt
4500 (build_special_member_call
4501 (build_ivar_reference (DECL_NAME (ivar)),
4502 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4503 NULL_TREE, type, LOOKUP_NORMAL));
4507 /* The constructor returns 'self'. */
4508 if (!dtor)
4509 finish_return_stmt (self_decl);
4511 finish_compound_stmt (compound_stmt);
4512 finish_function_body (body);
4513 fn = current_function_decl;
4514 finish_function ();
4515 objc_finish_method_definition (fn);
4518 /* The following routine will examine the current @interface for any
4519 non-POD C++ ivars requiring non-trivial construction and/or
4520 destruction, and then synthesize special '- .cxx_construct' and/or
4521 '- .cxx_destruct' methods which will run the appropriate
4522 construction or destruction code. Note that ivars inherited from
4523 super-classes are _not_ considered. */
4524 static void
4525 objc_generate_cxx_cdtors (void)
4527 bool need_ctor = false, need_dtor = false;
4528 tree ivar;
4530 /* We do not want to do this for categories, since they do not have
4531 their own ivars. */
4533 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4534 return;
4536 /* First, determine if we even need a constructor and/or destructor. */
4538 for (ivar = CLASS_IVARS (implementation_template); ivar;
4539 ivar = TREE_CHAIN (ivar))
4541 if (TREE_CODE (ivar) == FIELD_DECL)
4543 tree type = TREE_TYPE (ivar);
4545 if (IS_AGGR_TYPE (type))
4547 if (TYPE_NEEDS_CONSTRUCTING (type)
4548 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4549 /* NB: If a default constructor is not available, we will not
4550 be able to initialize this ivar; the add_instance_variable()
4551 routine will already have warned about this. */
4552 need_ctor = true;
4554 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4555 && (!TYPE_NEEDS_CONSTRUCTING (type)
4556 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4557 /* NB: If a default constructor is not available, we will not
4558 call the destructor either, for symmetry. */
4559 need_dtor = true;
4564 /* Generate '- .cxx_construct' if needed. */
4566 if (need_ctor)
4567 objc_generate_cxx_ctor_or_dtor (false);
4569 /* Generate '- .cxx_destruct' if needed. */
4571 if (need_dtor)
4572 objc_generate_cxx_ctor_or_dtor (true);
4574 /* The 'imp_list' variable points at an imp_entry record for the current
4575 @implementation. Record the existence of '- .cxx_construct' and/or
4576 '- .cxx_destruct' methods therein; it will be included in the
4577 metadata for the class. */
4578 if (flag_next_runtime)
4579 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4581 #endif
4583 /* For each protocol which was referenced either from a @protocol()
4584 expression, or because a class/category implements it (then a
4585 pointer to the protocol is stored in the struct describing the
4586 class/category), we create a statically allocated instance of the
4587 Protocol class. The code is written in such a way as to generate
4588 as few Protocol objects as possible; we generate a unique Protocol
4589 instance for each protocol, and we don't generate a Protocol
4590 instance if the protocol is never referenced (either from a
4591 @protocol() or from a class/category implementation). These
4592 statically allocated objects can be referred to via the static
4593 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4595 The statically allocated Protocol objects that we generate here
4596 need to be fixed up at runtime in order to be used: the 'isa'
4597 pointer of the objects need to be set up to point to the 'Protocol'
4598 class, as known at runtime.
4600 The NeXT runtime fixes up all protocols at program startup time,
4601 before main() is entered. It uses a low-level trick to look up all
4602 those symbols, then loops on them and fixes them up.
4604 The GNU runtime as well fixes up all protocols before user code
4605 from the module is executed; it requires pointers to those symbols
4606 to be put in the objc_symtab (which is then passed as argument to
4607 the function __objc_exec_class() which the compiler sets up to be
4608 executed automatically when the module is loaded); setup of those
4609 Protocol objects happen in two ways in the GNU runtime: all
4610 Protocol objects referred to by a class or category implementation
4611 are fixed up when the class/category is loaded; all Protocol
4612 objects referred to by a @protocol() expression are added by the
4613 compiler to the list of statically allocated instances to fixup
4614 (the same list holding the statically allocated constant string
4615 objects). Because, as explained above, the compiler generates as
4616 few Protocol objects as possible, some Protocol object might end up
4617 being referenced multiple times when compiled with the GNU runtime,
4618 and end up being fixed up multiple times at runtime initialization.
4619 But that doesn't hurt, it's just a little inefficient. */
4621 static void
4622 generate_protocols (void)
4624 tree p, encoding;
4625 tree decl;
4626 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4628 /* If a protocol was directly referenced, pull in indirect references. */
4629 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4630 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4631 generate_protocol_references (PROTOCOL_LIST (p));
4633 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4635 tree nst_methods = PROTOCOL_NST_METHODS (p);
4636 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4638 /* If protocol wasn't referenced, don't generate any code. */
4639 decl = PROTOCOL_FORWARD_DECL (p);
4641 if (!decl)
4642 continue;
4644 /* Make sure we link in the Protocol class. */
4645 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4647 while (nst_methods)
4649 if (! METHOD_ENCODING (nst_methods))
4651 encoding = encode_method_prototype (nst_methods);
4652 METHOD_ENCODING (nst_methods) = encoding;
4654 nst_methods = TREE_CHAIN (nst_methods);
4657 while (cls_methods)
4659 if (! METHOD_ENCODING (cls_methods))
4661 encoding = encode_method_prototype (cls_methods);
4662 METHOD_ENCODING (cls_methods) = encoding;
4665 cls_methods = TREE_CHAIN (cls_methods);
4667 generate_method_descriptors (p);
4669 if (PROTOCOL_LIST (p))
4670 refs_decl = generate_protocol_list (p);
4671 else
4672 refs_decl = 0;
4674 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4675 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4677 if (refs_decl)
4678 refs_expr = convert (build_pointer_type (build_pointer_type
4679 (objc_protocol_template)),
4680 build_unary_op (ADDR_EXPR, refs_decl, 0));
4681 else
4682 refs_expr = build_int_cst (NULL_TREE, 0);
4684 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4685 by generate_method_descriptors, which is called above. */
4686 initlist = build_protocol_initializer (TREE_TYPE (decl),
4687 protocol_name_expr, refs_expr,
4688 UOBJC_INSTANCE_METHODS_decl,
4689 UOBJC_CLASS_METHODS_decl);
4690 finish_var_decl (decl, initlist);
4694 static tree
4695 build_protocol_initializer (tree type, tree protocol_name,
4696 tree protocol_list, tree instance_methods,
4697 tree class_methods)
4699 tree initlist = NULL_TREE, expr;
4700 tree cast_type = build_pointer_type
4701 (xref_tag (RECORD_TYPE,
4702 get_identifier (UTAG_CLASS)));
4704 /* Filling the "isa" in with one allows the runtime system to
4705 detect that the version change...should remove before final release. */
4707 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4708 initlist = tree_cons (NULL_TREE, expr, initlist);
4709 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4710 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4712 if (!instance_methods)
4713 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4714 else
4716 expr = convert (objc_method_proto_list_ptr,
4717 build_unary_op (ADDR_EXPR, instance_methods, 0));
4718 initlist = tree_cons (NULL_TREE, expr, initlist);
4721 if (!class_methods)
4722 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4723 else
4725 expr = convert (objc_method_proto_list_ptr,
4726 build_unary_op (ADDR_EXPR, class_methods, 0));
4727 initlist = tree_cons (NULL_TREE, expr, initlist);
4730 return objc_build_constructor (type, nreverse (initlist));
4733 /* struct _objc_category {
4734 char *category_name;
4735 char *class_name;
4736 struct _objc_method_list *instance_methods;
4737 struct _objc_method_list *class_methods;
4738 struct _objc_protocol_list *protocols;
4739 }; */
4741 static void
4742 build_category_template (void)
4744 tree field_decl, field_decl_chain;
4746 objc_category_template = start_struct (RECORD_TYPE,
4747 get_identifier (UTAG_CATEGORY));
4749 /* char *category_name; */
4750 field_decl = create_field_decl (string_type_node, "category_name");
4751 field_decl_chain = field_decl;
4753 /* char *class_name; */
4754 field_decl = create_field_decl (string_type_node, "class_name");
4755 chainon (field_decl_chain, field_decl);
4757 /* struct _objc_method_list *instance_methods; */
4758 field_decl = create_field_decl (objc_method_list_ptr,
4759 "instance_methods");
4760 chainon (field_decl_chain, field_decl);
4762 /* struct _objc_method_list *class_methods; */
4763 field_decl = create_field_decl (objc_method_list_ptr,
4764 "class_methods");
4765 chainon (field_decl_chain, field_decl);
4767 /* struct _objc_protocol **protocol_list; */
4768 field_decl = create_field_decl (build_pointer_type
4769 (build_pointer_type
4770 (objc_protocol_template)),
4771 "protocol_list");
4772 chainon (field_decl_chain, field_decl);
4774 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4777 /* struct _objc_selector {
4778 SEL sel_id;
4779 char *sel_type;
4780 }; */
4782 static void
4783 build_selector_template (void)
4786 tree field_decl, field_decl_chain;
4788 objc_selector_template
4789 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4791 /* SEL sel_id; */
4792 field_decl = create_field_decl (objc_selector_type, "sel_id");
4793 field_decl_chain = field_decl;
4795 /* char *sel_type; */
4796 field_decl = create_field_decl (string_type_node, "sel_type");
4797 chainon (field_decl_chain, field_decl);
4799 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4802 /* struct _objc_class {
4803 struct _objc_class *isa;
4804 struct _objc_class *super_class;
4805 char *name;
4806 long version;
4807 long info;
4808 long instance_size;
4809 struct _objc_ivar_list *ivars;
4810 struct _objc_method_list *methods;
4811 #ifdef __NEXT_RUNTIME__
4812 struct objc_cache *cache;
4813 #else
4814 struct sarray *dtable;
4815 struct _objc_class *subclass_list;
4816 struct _objc_class *sibling_class;
4817 #endif
4818 struct _objc_protocol_list *protocols;
4819 #ifdef __NEXT_RUNTIME__
4820 void *sel_id;
4821 #endif
4822 void *gc_object_type;
4823 }; */
4825 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4826 the NeXT/Apple runtime; still, the compiler must generate them to
4827 maintain backward binary compatibility (and to allow for future
4828 expansion). */
4830 static void
4831 build_class_template (void)
4833 tree field_decl, field_decl_chain;
4835 objc_class_template
4836 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4838 /* struct _objc_class *isa; */
4839 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4840 "isa");
4841 field_decl_chain = field_decl;
4843 /* struct _objc_class *super_class; */
4844 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4845 "super_class");
4846 chainon (field_decl_chain, field_decl);
4848 /* char *name; */
4849 field_decl = create_field_decl (string_type_node, "name");
4850 chainon (field_decl_chain, field_decl);
4852 /* long version; */
4853 field_decl = create_field_decl (long_integer_type_node, "version");
4854 chainon (field_decl_chain, field_decl);
4856 /* long info; */
4857 field_decl = create_field_decl (long_integer_type_node, "info");
4858 chainon (field_decl_chain, field_decl);
4860 /* long instance_size; */
4861 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4862 chainon (field_decl_chain, field_decl);
4864 /* struct _objc_ivar_list *ivars; */
4865 field_decl = create_field_decl (objc_ivar_list_ptr,
4866 "ivars");
4867 chainon (field_decl_chain, field_decl);
4869 /* struct _objc_method_list *methods; */
4870 field_decl = create_field_decl (objc_method_list_ptr,
4871 "methods");
4872 chainon (field_decl_chain, field_decl);
4874 if (flag_next_runtime)
4876 /* struct objc_cache *cache; */
4877 field_decl = create_field_decl (build_pointer_type
4878 (xref_tag (RECORD_TYPE,
4879 get_identifier
4880 ("objc_cache"))),
4881 "cache");
4882 chainon (field_decl_chain, field_decl);
4884 else
4886 /* struct sarray *dtable; */
4887 field_decl = create_field_decl (build_pointer_type
4888 (xref_tag (RECORD_TYPE,
4889 get_identifier
4890 ("sarray"))),
4891 "dtable");
4892 chainon (field_decl_chain, field_decl);
4894 /* struct objc_class *subclass_list; */
4895 field_decl = create_field_decl (build_pointer_type
4896 (objc_class_template),
4897 "subclass_list");
4898 chainon (field_decl_chain, field_decl);
4900 /* struct objc_class *sibling_class; */
4901 field_decl = create_field_decl (build_pointer_type
4902 (objc_class_template),
4903 "sibling_class");
4904 chainon (field_decl_chain, field_decl);
4907 /* struct _objc_protocol **protocol_list; */
4908 field_decl = create_field_decl (build_pointer_type
4909 (build_pointer_type
4910 (xref_tag (RECORD_TYPE,
4911 get_identifier
4912 (UTAG_PROTOCOL)))),
4913 "protocol_list");
4914 chainon (field_decl_chain, field_decl);
4916 if (flag_next_runtime)
4918 /* void *sel_id; */
4919 field_decl = create_field_decl (build_pointer_type (void_type_node),
4920 "sel_id");
4921 chainon (field_decl_chain, field_decl);
4924 /* void *gc_object_type; */
4925 field_decl = create_field_decl (build_pointer_type (void_type_node),
4926 "gc_object_type");
4927 chainon (field_decl_chain, field_decl);
4929 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4932 /* Generate appropriate forward declarations for an implementation. */
4934 static void
4935 synth_forward_declarations (void)
4937 tree an_id;
4939 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4940 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4941 objc_class_template);
4943 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4944 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4945 objc_class_template);
4947 /* Pre-build the following entities - for speed/convenience. */
4949 an_id = get_identifier ("super_class");
4950 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4951 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4954 static void
4955 error_with_ivar (const char *message, tree decl)
4957 error ("%J%s %qs", decl,
4958 message, gen_declaration (decl));
4962 static void
4963 check_ivars (tree inter, tree imp)
4965 tree intdecls = CLASS_RAW_IVARS (inter);
4966 tree impdecls = CLASS_RAW_IVARS (imp);
4968 while (1)
4970 tree t1, t2;
4972 #ifdef OBJCPLUS
4973 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4974 intdecls = TREE_CHAIN (intdecls);
4975 #endif
4976 if (intdecls == 0 && impdecls == 0)
4977 break;
4978 if (intdecls == 0 || impdecls == 0)
4980 error ("inconsistent instance variable specification");
4981 break;
4984 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4986 if (!comptypes (t1, t2)
4987 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4988 DECL_INITIAL (impdecls)))
4990 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4992 error_with_ivar ("conflicting instance variable type",
4993 impdecls);
4994 error_with_ivar ("previous declaration of",
4995 intdecls);
4997 else /* both the type and the name don't match */
4999 error ("inconsistent instance variable specification");
5000 break;
5004 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5006 error_with_ivar ("conflicting instance variable name",
5007 impdecls);
5008 error_with_ivar ("previous declaration of",
5009 intdecls);
5012 intdecls = TREE_CHAIN (intdecls);
5013 impdecls = TREE_CHAIN (impdecls);
5017 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5018 This needs to be done just once per compilation. */
5020 /* struct _objc_super {
5021 struct _objc_object *self;
5022 struct _objc_class *super_class;
5023 }; */
5025 static void
5026 build_super_template (void)
5028 tree field_decl, field_decl_chain;
5030 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5032 /* struct _objc_object *self; */
5033 field_decl = create_field_decl (objc_object_type, "self");
5034 field_decl_chain = field_decl;
5036 /* struct _objc_class *super_class; */
5037 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5038 "super_class");
5039 chainon (field_decl_chain, field_decl);
5041 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5044 /* struct _objc_ivar {
5045 char *ivar_name;
5046 char *ivar_type;
5047 int ivar_offset;
5048 }; */
5050 static tree
5051 build_ivar_template (void)
5053 tree objc_ivar_id, objc_ivar_record;
5054 tree field_decl, field_decl_chain;
5056 objc_ivar_id = get_identifier (UTAG_IVAR);
5057 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5059 /* char *ivar_name; */
5060 field_decl = create_field_decl (string_type_node, "ivar_name");
5061 field_decl_chain = field_decl;
5063 /* char *ivar_type; */
5064 field_decl = create_field_decl (string_type_node, "ivar_type");
5065 chainon (field_decl_chain, field_decl);
5067 /* int ivar_offset; */
5068 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5069 chainon (field_decl_chain, field_decl);
5071 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5073 return objc_ivar_record;
5076 /* struct {
5077 int ivar_count;
5078 struct objc_ivar ivar_list[ivar_count];
5079 }; */
5081 static tree
5082 build_ivar_list_template (tree list_type, int size)
5084 tree objc_ivar_list_record;
5085 tree field_decl, field_decl_chain;
5087 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5089 /* int ivar_count; */
5090 field_decl = create_field_decl (integer_type_node, "ivar_count");
5091 field_decl_chain = field_decl;
5093 /* struct objc_ivar ivar_list[]; */
5094 field_decl = create_field_decl (build_array_type
5095 (list_type,
5096 build_index_type
5097 (build_int_cst (NULL_TREE, size - 1))),
5098 "ivar_list");
5099 chainon (field_decl_chain, field_decl);
5101 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5103 return objc_ivar_list_record;
5106 /* struct {
5107 struct _objc__method_prototype_list *method_next;
5108 int method_count;
5109 struct objc_method method_list[method_count];
5110 }; */
5112 static tree
5113 build_method_list_template (tree list_type, int size)
5115 tree objc_ivar_list_record;
5116 tree field_decl, field_decl_chain;
5118 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5120 /* struct _objc__method_prototype_list *method_next; */
5121 field_decl = create_field_decl (objc_method_proto_list_ptr,
5122 "method_next");
5123 field_decl_chain = field_decl;
5125 /* int method_count; */
5126 field_decl = create_field_decl (integer_type_node, "method_count");
5127 chainon (field_decl_chain, field_decl);
5129 /* struct objc_method method_list[]; */
5130 field_decl = create_field_decl (build_array_type
5131 (list_type,
5132 build_index_type
5133 (build_int_cst (NULL_TREE, size - 1))),
5134 "method_list");
5135 chainon (field_decl_chain, field_decl);
5137 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5139 return objc_ivar_list_record;
5142 static tree
5143 build_ivar_list_initializer (tree type, tree field_decl)
5145 tree initlist = NULL_TREE;
5149 tree ivar = NULL_TREE;
5151 /* Set name. */
5152 if (DECL_NAME (field_decl))
5153 ivar = tree_cons (NULL_TREE,
5154 add_objc_string (DECL_NAME (field_decl),
5155 meth_var_names),
5156 ivar);
5157 else
5158 /* Unnamed bit-field ivar (yuck). */
5159 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5161 /* Set type. */
5162 encode_field_decl (field_decl,
5163 obstack_object_size (&util_obstack),
5164 OBJC_ENCODE_DONT_INLINE_DEFS);
5166 /* Null terminate string. */
5167 obstack_1grow (&util_obstack, 0);
5168 ivar
5169 = tree_cons
5170 (NULL_TREE,
5171 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5172 meth_var_types),
5173 ivar);
5174 obstack_free (&util_obstack, util_firstobj);
5176 /* Set offset. */
5177 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5178 initlist = tree_cons (NULL_TREE,
5179 objc_build_constructor (type, nreverse (ivar)),
5180 initlist);
5182 field_decl = TREE_CHAIN (field_decl);
5183 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5185 while (field_decl);
5187 return objc_build_constructor (build_array_type (type, 0),
5188 nreverse (initlist));
5191 static tree
5192 generate_ivars_list (tree type, const char *name, int size, tree list)
5194 tree decl, initlist;
5196 decl = start_var_decl (type, synth_id_with_class_suffix
5197 (name, objc_implementation_context));
5199 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5200 initlist = tree_cons (NULL_TREE, list, initlist);
5202 finish_var_decl (decl,
5203 objc_build_constructor (TREE_TYPE (decl),
5204 nreverse (initlist)));
5206 return decl;
5209 /* Count only the fields occurring in T. */
5211 static int
5212 ivar_list_length (tree t)
5214 int count = 0;
5216 for (; t; t = TREE_CHAIN (t))
5217 if (TREE_CODE (t) == FIELD_DECL)
5218 ++count;
5220 return count;
5223 static void
5224 generate_ivar_lists (void)
5226 tree initlist, ivar_list_template, chain;
5227 int size;
5229 generating_instance_variables = 1;
5231 if (!objc_ivar_template)
5232 objc_ivar_template = build_ivar_template ();
5234 /* Only generate class variables for the root of the inheritance
5235 hierarchy since these will be the same for every class. */
5237 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5238 && (chain = TYPE_FIELDS (objc_class_template)))
5240 size = ivar_list_length (chain);
5242 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5243 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5245 UOBJC_CLASS_VARIABLES_decl
5246 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5247 size, initlist);
5249 else
5250 UOBJC_CLASS_VARIABLES_decl = 0;
5252 chain = CLASS_IVARS (implementation_template);
5253 if (chain)
5255 size = ivar_list_length (chain);
5256 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5257 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5259 UOBJC_INSTANCE_VARIABLES_decl
5260 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5261 size, initlist);
5263 else
5264 UOBJC_INSTANCE_VARIABLES_decl = 0;
5266 generating_instance_variables = 0;
5269 static tree
5270 build_dispatch_table_initializer (tree type, tree entries)
5272 tree initlist = NULL_TREE;
5276 tree elemlist = NULL_TREE;
5278 elemlist = tree_cons (NULL_TREE,
5279 build_selector (METHOD_SEL_NAME (entries)),
5280 NULL_TREE);
5282 /* Generate the method encoding if we don't have one already. */
5283 if (! METHOD_ENCODING (entries))
5284 METHOD_ENCODING (entries) =
5285 encode_method_prototype (entries);
5287 elemlist = tree_cons (NULL_TREE,
5288 add_objc_string (METHOD_ENCODING (entries),
5289 meth_var_types),
5290 elemlist);
5292 elemlist
5293 = tree_cons (NULL_TREE,
5294 convert (ptr_type_node,
5295 build_unary_op (ADDR_EXPR,
5296 METHOD_DEFINITION (entries), 1)),
5297 elemlist);
5299 initlist = tree_cons (NULL_TREE,
5300 objc_build_constructor (type, nreverse (elemlist)),
5301 initlist);
5303 entries = TREE_CHAIN (entries);
5305 while (entries);
5307 return objc_build_constructor (build_array_type (type, 0),
5308 nreverse (initlist));
5311 /* To accomplish method prototyping without generating all kinds of
5312 inane warnings, the definition of the dispatch table entries were
5313 changed from:
5315 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5317 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5319 static tree
5320 build_method_template (void)
5322 tree _SLT_record;
5323 tree field_decl, field_decl_chain;
5325 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5327 /* SEL _cmd; */
5328 field_decl = create_field_decl (objc_selector_type, "_cmd");
5329 field_decl_chain = field_decl;
5331 /* char *method_types; */
5332 field_decl = create_field_decl (string_type_node, "method_types");
5333 chainon (field_decl_chain, field_decl);
5335 /* void *_imp; */
5336 field_decl = create_field_decl (build_pointer_type (void_type_node),
5337 "_imp");
5338 chainon (field_decl_chain, field_decl);
5340 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5342 return _SLT_record;
5346 static tree
5347 generate_dispatch_table (tree type, const char *name, int size, tree list)
5349 tree decl, initlist;
5351 decl = start_var_decl (type, synth_id_with_class_suffix
5352 (name, objc_implementation_context));
5354 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5355 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5356 initlist = tree_cons (NULL_TREE, list, initlist);
5358 finish_var_decl (decl,
5359 objc_build_constructor (TREE_TYPE (decl),
5360 nreverse (initlist)));
5362 return decl;
5365 static void
5366 mark_referenced_methods (void)
5368 struct imp_entry *impent;
5369 tree chain;
5371 for (impent = imp_list; impent; impent = impent->next)
5373 chain = CLASS_CLS_METHODS (impent->imp_context);
5374 while (chain)
5376 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5377 chain = TREE_CHAIN (chain);
5380 chain = CLASS_NST_METHODS (impent->imp_context);
5381 while (chain)
5383 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5384 chain = TREE_CHAIN (chain);
5389 static void
5390 generate_dispatch_tables (void)
5392 tree initlist, chain, method_list_template;
5393 int size;
5395 if (!objc_method_template)
5396 objc_method_template = build_method_template ();
5398 chain = CLASS_CLS_METHODS (objc_implementation_context);
5399 if (chain)
5401 size = list_length (chain);
5403 method_list_template
5404 = build_method_list_template (objc_method_template, size);
5405 initlist
5406 = build_dispatch_table_initializer (objc_method_template, chain);
5408 UOBJC_CLASS_METHODS_decl
5409 = generate_dispatch_table (method_list_template,
5410 ((TREE_CODE (objc_implementation_context)
5411 == CLASS_IMPLEMENTATION_TYPE)
5412 ? "_OBJC_CLASS_METHODS"
5413 : "_OBJC_CATEGORY_CLASS_METHODS"),
5414 size, initlist);
5416 else
5417 UOBJC_CLASS_METHODS_decl = 0;
5419 chain = CLASS_NST_METHODS (objc_implementation_context);
5420 if (chain)
5422 size = list_length (chain);
5424 method_list_template
5425 = build_method_list_template (objc_method_template, size);
5426 initlist
5427 = build_dispatch_table_initializer (objc_method_template, chain);
5429 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5430 UOBJC_INSTANCE_METHODS_decl
5431 = generate_dispatch_table (method_list_template,
5432 "_OBJC_INSTANCE_METHODS",
5433 size, initlist);
5434 else
5435 /* We have a category. */
5436 UOBJC_INSTANCE_METHODS_decl
5437 = generate_dispatch_table (method_list_template,
5438 "_OBJC_CATEGORY_INSTANCE_METHODS",
5439 size, initlist);
5441 else
5442 UOBJC_INSTANCE_METHODS_decl = 0;
5445 static tree
5446 generate_protocol_list (tree i_or_p)
5448 tree initlist;
5449 tree refs_decl, lproto, e, plist;
5450 int size = 0;
5451 const char *ref_name;
5453 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5454 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5455 plist = CLASS_PROTOCOL_LIST (i_or_p);
5456 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5457 plist = PROTOCOL_LIST (i_or_p);
5458 else
5459 abort ();
5461 /* Compute size. */
5462 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5463 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5464 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5465 size++;
5467 /* Build initializer. */
5468 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5469 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5470 initlist = tree_cons (NULL_TREE, e, initlist);
5472 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5474 tree pval = TREE_VALUE (lproto);
5476 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5477 && PROTOCOL_FORWARD_DECL (pval))
5479 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5480 initlist = tree_cons (NULL_TREE, e, initlist);
5484 /* static struct objc_protocol *refs[n]; */
5486 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5487 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5488 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5489 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5490 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5491 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5492 else
5493 abort ();
5495 refs_decl = start_var_decl
5496 (build_array_type
5497 (build_pointer_type (objc_protocol_template),
5498 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5499 ref_name);
5501 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5502 nreverse (initlist)));
5504 return refs_decl;
5507 static tree
5508 build_category_initializer (tree type, tree cat_name, tree class_name,
5509 tree instance_methods, tree class_methods,
5510 tree protocol_list)
5512 tree initlist = NULL_TREE, expr;
5514 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5515 initlist = tree_cons (NULL_TREE, class_name, initlist);
5517 if (!instance_methods)
5518 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5519 else
5521 expr = convert (objc_method_list_ptr,
5522 build_unary_op (ADDR_EXPR, instance_methods, 0));
5523 initlist = tree_cons (NULL_TREE, expr, initlist);
5525 if (!class_methods)
5526 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5527 else
5529 expr = convert (objc_method_list_ptr,
5530 build_unary_op (ADDR_EXPR, class_methods, 0));
5531 initlist = tree_cons (NULL_TREE, expr, initlist);
5534 /* protocol_list = */
5535 if (!protocol_list)
5536 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5537 else
5539 expr = convert (build_pointer_type
5540 (build_pointer_type
5541 (objc_protocol_template)),
5542 build_unary_op (ADDR_EXPR, protocol_list, 0));
5543 initlist = tree_cons (NULL_TREE, expr, initlist);
5546 return objc_build_constructor (type, nreverse (initlist));
5549 /* struct _objc_class {
5550 struct objc_class *isa;
5551 struct objc_class *super_class;
5552 char *name;
5553 long version;
5554 long info;
5555 long instance_size;
5556 struct objc_ivar_list *ivars;
5557 struct objc_method_list *methods;
5558 if (flag_next_runtime)
5559 struct objc_cache *cache;
5560 else {
5561 struct sarray *dtable;
5562 struct objc_class *subclass_list;
5563 struct objc_class *sibling_class;
5565 struct objc_protocol_list *protocols;
5566 if (flag_next_runtime)
5567 void *sel_id;
5568 void *gc_object_type;
5569 }; */
5571 static tree
5572 build_shared_structure_initializer (tree type, tree isa, tree super,
5573 tree name, tree size, int status,
5574 tree dispatch_table, tree ivar_list,
5575 tree protocol_list)
5577 tree initlist = NULL_TREE, expr;
5579 /* isa = */
5580 initlist = tree_cons (NULL_TREE, isa, initlist);
5582 /* super_class = */
5583 initlist = tree_cons (NULL_TREE, super, initlist);
5585 /* name = */
5586 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5588 /* version = */
5589 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5590 initlist);
5592 /* info = */
5593 initlist = tree_cons (NULL_TREE,
5594 build_int_cst (long_integer_type_node, status),
5595 initlist);
5597 /* instance_size = */
5598 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5599 initlist);
5601 /* objc_ivar_list = */
5602 if (!ivar_list)
5603 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5604 else
5606 expr = convert (objc_ivar_list_ptr,
5607 build_unary_op (ADDR_EXPR, ivar_list, 0));
5608 initlist = tree_cons (NULL_TREE, expr, initlist);
5611 /* objc_method_list = */
5612 if (!dispatch_table)
5613 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5614 else
5616 expr = convert (objc_method_list_ptr,
5617 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5618 initlist = tree_cons (NULL_TREE, expr, initlist);
5621 if (flag_next_runtime)
5622 /* method_cache = */
5623 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5624 else
5626 /* dtable = */
5627 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5629 /* subclass_list = */
5630 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5632 /* sibling_class = */
5633 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5636 /* protocol_list = */
5637 if (! protocol_list)
5638 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5639 else
5641 expr = convert (build_pointer_type
5642 (build_pointer_type
5643 (objc_protocol_template)),
5644 build_unary_op (ADDR_EXPR, protocol_list, 0));
5645 initlist = tree_cons (NULL_TREE, expr, initlist);
5648 if (flag_next_runtime)
5649 /* sel_id = NULL */
5650 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5652 /* gc_object_type = NULL */
5653 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5655 return objc_build_constructor (type, nreverse (initlist));
5658 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5660 static inline tree
5661 lookup_category (tree class, tree cat_name)
5663 tree category = CLASS_CATEGORY_LIST (class);
5665 while (category && CLASS_SUPER_NAME (category) != cat_name)
5666 category = CLASS_CATEGORY_LIST (category);
5667 return category;
5670 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5672 static void
5673 generate_category (tree cat)
5675 tree decl;
5676 tree initlist, cat_name_expr, class_name_expr;
5677 tree protocol_decl, category;
5679 add_class_reference (CLASS_NAME (cat));
5680 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5682 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5684 category = lookup_category (implementation_template,
5685 CLASS_SUPER_NAME (cat));
5687 if (category && CLASS_PROTOCOL_LIST (category))
5689 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5690 protocol_decl = generate_protocol_list (category);
5692 else
5693 protocol_decl = 0;
5695 decl = start_var_decl (objc_category_template,
5696 synth_id_with_class_suffix
5697 ("_OBJC_CATEGORY", objc_implementation_context));
5699 initlist = build_category_initializer (TREE_TYPE (decl),
5700 cat_name_expr, class_name_expr,
5701 UOBJC_INSTANCE_METHODS_decl,
5702 UOBJC_CLASS_METHODS_decl,
5703 protocol_decl);
5705 finish_var_decl (decl, initlist);
5708 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5709 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5711 static void
5712 generate_shared_structures (int cls_flags)
5714 tree sc_spec, decl_specs, decl;
5715 tree name_expr, super_expr, root_expr;
5716 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5717 tree cast_type, initlist, protocol_decl;
5719 my_super_id = CLASS_SUPER_NAME (implementation_template);
5720 if (my_super_id)
5722 add_class_reference (my_super_id);
5724 /* Compute "my_root_id" - this is required for code generation.
5725 the "isa" for all meta class structures points to the root of
5726 the inheritance hierarchy (e.g. "__Object")... */
5727 my_root_id = my_super_id;
5730 tree my_root_int = lookup_interface (my_root_id);
5732 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5733 my_root_id = CLASS_SUPER_NAME (my_root_int);
5734 else
5735 break;
5737 while (1);
5739 else
5740 /* No super class. */
5741 my_root_id = CLASS_NAME (implementation_template);
5743 cast_type = build_pointer_type (objc_class_template);
5744 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5745 class_names);
5747 /* Install class `isa' and `super' pointers at runtime. */
5748 if (my_super_id)
5750 super_expr = add_objc_string (my_super_id, class_names);
5751 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5753 else
5754 super_expr = build_int_cst (NULL_TREE, 0);
5756 root_expr = add_objc_string (my_root_id, class_names);
5757 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5759 if (CLASS_PROTOCOL_LIST (implementation_template))
5761 generate_protocol_references
5762 (CLASS_PROTOCOL_LIST (implementation_template));
5763 protocol_decl = generate_protocol_list (implementation_template);
5765 else
5766 protocol_decl = 0;
5768 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5770 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5771 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5773 decl = start_var_decl (objc_class_template,
5774 IDENTIFIER_POINTER
5775 (DECL_NAME (UOBJC_METACLASS_decl)));
5777 initlist
5778 = build_shared_structure_initializer
5779 (TREE_TYPE (decl),
5780 root_expr, super_expr, name_expr,
5781 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5782 2 /*CLS_META*/,
5783 UOBJC_CLASS_METHODS_decl,
5784 UOBJC_CLASS_VARIABLES_decl,
5785 protocol_decl);
5787 finish_var_decl (decl, initlist);
5789 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5791 decl = start_var_decl (objc_class_template,
5792 IDENTIFIER_POINTER
5793 (DECL_NAME (UOBJC_CLASS_decl)));
5795 initlist
5796 = build_shared_structure_initializer
5797 (TREE_TYPE (decl),
5798 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5799 super_expr, name_expr,
5800 convert (integer_type_node,
5801 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5802 (implementation_template))),
5803 1 /*CLS_FACTORY*/ | cls_flags,
5804 UOBJC_INSTANCE_METHODS_decl,
5805 UOBJC_INSTANCE_VARIABLES_decl,
5806 protocol_decl);
5808 finish_var_decl (decl, initlist);
5812 static const char *
5813 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5815 static char string[BUFSIZE];
5817 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5818 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5820 sprintf (string, "%s_%s", preamble,
5821 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5823 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5824 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5826 /* We have a category. */
5827 const char *const class_name
5828 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5829 const char *const class_super_name
5830 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5831 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5833 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5835 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5836 sprintf (string, "%s_%s", preamble, protocol_name);
5838 else
5839 abort ();
5841 return string;
5844 /* If type is empty or only type qualifiers are present, add default
5845 type of id (otherwise grokdeclarator will default to int). */
5847 static tree
5848 adjust_type_for_id_default (tree type)
5850 if (!type)
5851 type = make_node (TREE_LIST);
5853 if (!TREE_VALUE (type))
5854 TREE_VALUE (type) = objc_object_type;
5855 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5856 && TYPED_OBJECT (TREE_VALUE (type)))
5857 error ("can not use an object as parameter to a method");
5859 return type;
5862 /* Usage:
5863 keyworddecl:
5864 selector ':' '(' typename ')' identifier
5866 Purpose:
5867 Transform an Objective-C keyword argument into
5868 the C equivalent parameter declarator.
5870 In: key_name, an "identifier_node" (optional).
5871 arg_type, a "tree_list" (optional).
5872 arg_name, an "identifier_node".
5874 Note: It would be really nice to strongly type the preceding
5875 arguments in the function prototype; however, then I
5876 could not use the "accessor" macros defined in "tree.h".
5878 Out: an instance of "keyword_decl". */
5880 tree
5881 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5883 tree keyword_decl;
5885 /* If no type is specified, default to "id". */
5886 arg_type = adjust_type_for_id_default (arg_type);
5888 keyword_decl = make_node (KEYWORD_DECL);
5890 TREE_TYPE (keyword_decl) = arg_type;
5891 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5892 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5894 return keyword_decl;
5897 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5899 static tree
5900 build_keyword_selector (tree selector)
5902 int len = 0;
5903 tree key_chain, key_name;
5904 char *buf;
5906 /* Scan the selector to see how much space we'll need. */
5907 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5909 if (TREE_CODE (selector) == KEYWORD_DECL)
5910 key_name = KEYWORD_KEY_NAME (key_chain);
5911 else if (TREE_CODE (selector) == TREE_LIST)
5912 key_name = TREE_PURPOSE (key_chain);
5913 else
5914 abort ();
5916 if (key_name)
5917 len += IDENTIFIER_LENGTH (key_name) + 1;
5918 else
5919 /* Just a ':' arg. */
5920 len++;
5923 buf = (char *) alloca (len + 1);
5924 /* Start the buffer out as an empty string. */
5925 buf[0] = '\0';
5927 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5929 if (TREE_CODE (selector) == KEYWORD_DECL)
5930 key_name = KEYWORD_KEY_NAME (key_chain);
5931 else if (TREE_CODE (selector) == TREE_LIST)
5933 key_name = TREE_PURPOSE (key_chain);
5934 /* The keyword decl chain will later be used as a function argument
5935 chain. Unhook the selector itself so as to not confuse other
5936 parts of the compiler. */
5937 TREE_PURPOSE (key_chain) = NULL_TREE;
5939 else
5940 abort ();
5942 if (key_name)
5943 strcat (buf, IDENTIFIER_POINTER (key_name));
5944 strcat (buf, ":");
5947 return get_identifier (buf);
5950 /* Used for declarations and definitions. */
5952 static tree
5953 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5954 tree add_args, bool ellipsis)
5956 tree method_decl;
5958 /* If no type is specified, default to "id". */
5959 ret_type = adjust_type_for_id_default (ret_type);
5961 method_decl = make_node (code);
5962 TREE_TYPE (method_decl) = ret_type;
5964 /* If we have a keyword selector, create an identifier_node that
5965 represents the full selector name (`:' included)... */
5966 if (TREE_CODE (selector) == KEYWORD_DECL)
5968 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5969 METHOD_SEL_ARGS (method_decl) = selector;
5970 METHOD_ADD_ARGS (method_decl) = add_args;
5971 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5973 else
5975 METHOD_SEL_NAME (method_decl) = selector;
5976 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5977 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5980 return method_decl;
5983 #define METHOD_DEF 0
5984 #define METHOD_REF 1
5986 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5987 an argument list for method METH. CONTEXT is either METHOD_DEF or
5988 METHOD_REF, saying whether we are trying to define a method or call
5989 one. SUPERFLAG says this is for a send to super; this makes a
5990 difference for the NeXT calling sequence in which the lookup and
5991 the method call are done together. If METH is null, user-defined
5992 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5994 static tree
5995 get_arg_type_list (tree meth, int context, int superflag)
5997 tree arglist, akey;
5999 /* Receiver type. */
6000 if (flag_next_runtime && superflag)
6001 arglist = build_tree_list (NULL_TREE, objc_super_type);
6002 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6003 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6004 else
6005 arglist = build_tree_list (NULL_TREE, objc_object_type);
6007 /* Selector type - will eventually change to `int'. */
6008 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6010 /* No actual method prototype given -- assume that remaining arguments
6011 are `...'. */
6012 if (!meth)
6013 return arglist;
6015 /* Build a list of argument types. */
6016 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6018 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6020 /* Decay arrays and functions into pointers. */
6021 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6022 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6023 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6024 arg_type = build_pointer_type (arg_type);
6026 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6029 if (METHOD_ADD_ARGS (meth))
6031 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6032 akey; akey = TREE_CHAIN (akey))
6034 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6036 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6039 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6040 goto lack_of_ellipsis;
6042 else
6044 lack_of_ellipsis:
6045 chainon (arglist, OBJC_VOID_AT_END);
6048 return arglist;
6051 static tree
6052 check_duplicates (hash hsh, int methods, int is_class)
6054 tree meth = NULL_TREE;
6056 if (hsh)
6058 meth = hsh->key;
6060 if (hsh->list)
6062 /* We have two or more methods with the same name but
6063 different types. */
6064 attr loop;
6066 /* But just how different are those types? If
6067 -Wno-strict-selector-match is specified, we shall not
6068 complain if the differences are solely among types with
6069 identical size and alignment. */
6070 if (!warn_strict_selector_match)
6072 for (loop = hsh->list; loop; loop = loop->next)
6073 if (!comp_proto_with_proto (meth, loop->value, 0))
6074 goto issue_warning;
6076 return meth;
6079 issue_warning:
6080 warning (0, "multiple %s named %<%c%s%> found",
6081 methods ? "methods" : "selectors",
6082 (is_class ? '+' : '-'),
6083 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6085 warn_with_method (methods ? "using" : "found",
6086 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6087 ? '-'
6088 : '+'),
6089 meth);
6090 for (loop = hsh->list; loop; loop = loop->next)
6091 warn_with_method ("also found",
6092 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6093 ? '-'
6094 : '+'),
6095 loop->value);
6098 return meth;
6101 /* If RECEIVER is a class reference, return the identifier node for
6102 the referenced class. RECEIVER is created by objc_get_class_reference,
6103 so we check the exact form created depending on which runtimes are
6104 used. */
6106 static tree
6107 receiver_is_class_object (tree receiver, int self, int super)
6109 tree chain, exp, arg;
6111 /* The receiver is 'self' or 'super' in the context of a class method. */
6112 if (objc_method_context
6113 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6114 && (self || super))
6115 return (super
6116 ? CLASS_SUPER_NAME (implementation_template)
6117 : CLASS_NAME (implementation_template));
6119 if (flag_next_runtime)
6121 /* The receiver is a variable created by
6122 build_class_reference_decl. */
6123 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6124 /* Look up the identifier. */
6125 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6126 if (TREE_PURPOSE (chain) == receiver)
6127 return TREE_VALUE (chain);
6130 /* The receiver is a function call that returns an id. Check if
6131 it is a call to objc_getClass, if so, pick up the class name. */
6132 if (TREE_CODE (receiver) == CALL_EXPR
6133 && (exp = CALL_EXPR_FN (receiver))
6134 && TREE_CODE (exp) == ADDR_EXPR
6135 && (exp = TREE_OPERAND (exp, 0))
6136 && TREE_CODE (exp) == FUNCTION_DECL
6137 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6138 prototypes for objc_get_class(). Thankfully, they seem to share the
6139 same function type. */
6140 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6141 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6142 /* We have a call to objc_get_class/objc_getClass! */
6143 && (arg = CALL_EXPR_ARG (receiver, 0)))
6145 STRIP_NOPS (arg);
6146 if (TREE_CODE (arg) == ADDR_EXPR
6147 && (arg = TREE_OPERAND (arg, 0))
6148 && TREE_CODE (arg) == STRING_CST)
6149 /* Finally, we have the class name. */
6150 return get_identifier (TREE_STRING_POINTER (arg));
6152 return 0;
6155 /* If we are currently building a message expr, this holds
6156 the identifier of the selector of the message. This is
6157 used when printing warnings about argument mismatches. */
6159 static tree current_objc_message_selector = 0;
6161 tree
6162 objc_message_selector (void)
6164 return current_objc_message_selector;
6167 /* Construct an expression for sending a message.
6168 MESS has the object to send to in TREE_PURPOSE
6169 and the argument list (including selector) in TREE_VALUE.
6171 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6172 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6174 tree
6175 objc_build_message_expr (tree mess)
6177 tree receiver = TREE_PURPOSE (mess);
6178 tree sel_name;
6179 #ifdef OBJCPLUS
6180 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6181 #else
6182 tree args = TREE_VALUE (mess);
6183 #endif
6184 tree method_params = NULL_TREE;
6186 if (TREE_CODE (receiver) == ERROR_MARK)
6187 return error_mark_node;
6189 /* Obtain the full selector name. */
6190 if (TREE_CODE (args) == IDENTIFIER_NODE)
6191 /* A unary selector. */
6192 sel_name = args;
6193 else if (TREE_CODE (args) == TREE_LIST)
6194 sel_name = build_keyword_selector (args);
6195 else
6196 abort ();
6198 /* Build the parameter list to give to the method. */
6199 if (TREE_CODE (args) == TREE_LIST)
6200 #ifdef OBJCPLUS
6201 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6202 #else
6204 tree chain = args, prev = NULL_TREE;
6206 /* We have a keyword selector--check for comma expressions. */
6207 while (chain)
6209 tree element = TREE_VALUE (chain);
6211 /* We have a comma expression, must collapse... */
6212 if (TREE_CODE (element) == TREE_LIST)
6214 if (prev)
6215 TREE_CHAIN (prev) = element;
6216 else
6217 args = element;
6219 prev = chain;
6220 chain = TREE_CHAIN (chain);
6222 method_params = args;
6224 #endif
6226 #ifdef OBJCPLUS
6227 if (processing_template_decl)
6228 /* Must wait until template instantiation time. */
6229 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6230 method_params);
6231 #endif
6233 return objc_finish_message_expr (receiver, sel_name, method_params);
6236 /* Look up method SEL_NAME that would be suitable for receiver
6237 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6238 nonzero), and report on any duplicates. */
6240 static tree
6241 lookup_method_in_hash_lists (tree sel_name, int is_class)
6243 hash method_prototype = NULL;
6245 if (!is_class)
6246 method_prototype = hash_lookup (nst_method_hash_list,
6247 sel_name);
6249 if (!method_prototype)
6251 method_prototype = hash_lookup (cls_method_hash_list,
6252 sel_name);
6253 is_class = 1;
6256 return check_duplicates (method_prototype, 1, is_class);
6259 /* The 'objc_finish_message_expr' routine is called from within
6260 'objc_build_message_expr' for non-template functions. In the case of
6261 C++ template functions, it is called from 'build_expr_from_tree'
6262 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6264 tree
6265 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6267 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6268 tree selector, retval, class_tree;
6269 int self, super, have_cast;
6271 /* Extract the receiver of the message, as well as its type
6272 (where the latter may take the form of a cast or be inferred
6273 from the implementation context). */
6274 rtype = receiver;
6275 while (TREE_CODE (rtype) == COMPOUND_EXPR
6276 || TREE_CODE (rtype) == MODIFY_EXPR
6277 || TREE_CODE (rtype) == NOP_EXPR
6278 || TREE_CODE (rtype) == CONVERT_EXPR
6279 || TREE_CODE (rtype) == COMPONENT_REF)
6280 rtype = TREE_OPERAND (rtype, 0);
6281 self = (rtype == self_decl);
6282 super = (rtype == UOBJC_SUPER_decl);
6283 rtype = TREE_TYPE (receiver);
6284 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6285 || (TREE_CODE (receiver) == COMPOUND_EXPR
6286 && !IS_SUPER (rtype)));
6288 /* If we are calling [super dealloc], reset our warning flag. */
6289 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6290 should_call_super_dealloc = 0;
6292 /* If the receiver is a class object, retrieve the corresponding
6293 @interface, if one exists. */
6294 class_tree = receiver_is_class_object (receiver, self, super);
6296 /* Now determine the receiver type (if an explicit cast has not been
6297 provided). */
6298 if (!have_cast)
6300 if (class_tree)
6301 rtype = lookup_interface (class_tree);
6302 /* Handle `self' and `super'. */
6303 else if (super)
6305 if (!CLASS_SUPER_NAME (implementation_template))
6307 error ("no super class declared in @interface for %qs",
6308 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6309 return error_mark_node;
6311 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6313 else if (self)
6314 rtype = lookup_interface (CLASS_NAME (implementation_template));
6317 /* If receiver is of type `id' or `Class' (or if the @interface for a
6318 class is not visible), we shall be satisfied with the existence of
6319 any instance or class method. */
6320 if (objc_is_id (rtype))
6322 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6323 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6324 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6325 : NULL_TREE);
6326 rtype = NULL_TREE;
6328 if (rprotos)
6330 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6331 in protocols themselves for the method prototype. */
6332 method_prototype
6333 = lookup_method_in_protocol_list (rprotos, sel_name,
6334 class_tree != NULL_TREE);
6336 /* If messaging 'Class <Proto>' but did not find a class method
6337 prototype, search for an instance method instead, and warn
6338 about having done so. */
6339 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6341 method_prototype
6342 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6344 if (method_prototype)
6345 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6346 IDENTIFIER_POINTER (sel_name),
6347 IDENTIFIER_POINTER (sel_name));
6351 else if (rtype)
6353 tree orig_rtype = rtype, saved_rtype;
6355 if (TREE_CODE (rtype) == POINTER_TYPE)
6356 rtype = TREE_TYPE (rtype);
6357 /* Traverse typedef aliases */
6358 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6359 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6360 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6361 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6362 saved_rtype = rtype;
6363 if (TYPED_OBJECT (rtype))
6365 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6366 rtype = TYPE_OBJC_INTERFACE (rtype);
6368 /* If we could not find an @interface declaration, we must have
6369 only seen a @class declaration; so, we cannot say anything
6370 more intelligent about which methods the receiver will
6371 understand. */
6372 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6373 rtype = NULL_TREE;
6374 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6375 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6377 /* We have a valid ObjC class name. Look up the method name
6378 in the published @interface for the class (and its
6379 superclasses). */
6380 method_prototype
6381 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6383 /* If the method was not found in the @interface, it may still
6384 exist locally as part of the @implementation. */
6385 if (!method_prototype && objc_implementation_context
6386 && CLASS_NAME (objc_implementation_context)
6387 == OBJC_TYPE_NAME (rtype))
6388 method_prototype
6389 = lookup_method
6390 ((class_tree
6391 ? CLASS_CLS_METHODS (objc_implementation_context)
6392 : CLASS_NST_METHODS (objc_implementation_context)),
6393 sel_name);
6395 /* If we haven't found a candidate method by now, try looking for
6396 it in the protocol list. */
6397 if (!method_prototype && rprotos)
6398 method_prototype
6399 = lookup_method_in_protocol_list (rprotos, sel_name,
6400 class_tree != NULL_TREE);
6402 else
6404 warning (0, "invalid receiver type %qs",
6405 gen_type_name (orig_rtype));
6406 /* After issuing the "invalid receiver" warning, perform method
6407 lookup as if we were messaging 'id'. */
6408 rtype = rprotos = NULL_TREE;
6413 /* For 'id' or 'Class' receivers, search in the global hash table
6414 as a last resort. For all receivers, warn if protocol searches
6415 have failed. */
6416 if (!method_prototype)
6418 if (rprotos)
6419 warning (0, "%<%c%s%> not found in protocol(s)",
6420 (class_tree ? '+' : '-'),
6421 IDENTIFIER_POINTER (sel_name));
6423 if (!rtype)
6424 method_prototype
6425 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6428 if (!method_prototype)
6430 static bool warn_missing_methods = false;
6432 if (rtype)
6433 warning (0, "%qs may not respond to %<%c%s%>",
6434 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6435 (class_tree ? '+' : '-'),
6436 IDENTIFIER_POINTER (sel_name));
6437 /* If we are messaging an 'id' or 'Class' object and made it here,
6438 then we have failed to find _any_ instance or class method,
6439 respectively. */
6440 else
6441 warning (0, "no %<%c%s%> method found",
6442 (class_tree ? '+' : '-'),
6443 IDENTIFIER_POINTER (sel_name));
6445 if (!warn_missing_methods)
6447 warning (0, "(Messages without a matching method signature");
6448 warning (0, "will be assumed to return %<id%> and accept");
6449 warning (0, "%<...%> as arguments.)");
6450 warn_missing_methods = true;
6454 /* Save the selector name for printing error messages. */
6455 current_objc_message_selector = sel_name;
6457 /* Build the parameters list for looking up the method.
6458 These are the object itself and the selector. */
6460 if (flag_typed_selectors)
6461 selector = build_typed_selector_reference (sel_name, method_prototype);
6462 else
6463 selector = build_selector_reference (sel_name);
6465 retval = build_objc_method_call (super, method_prototype,
6466 receiver,
6467 selector, method_params);
6469 current_objc_message_selector = 0;
6471 return retval;
6474 /* Build a tree expression to send OBJECT the operation SELECTOR,
6475 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6476 assuming the method has prototype METHOD_PROTOTYPE.
6477 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6478 Use METHOD_PARAMS as list of args to pass to the method.
6479 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6481 static tree
6482 build_objc_method_call (int super_flag, tree method_prototype,
6483 tree lookup_object, tree selector,
6484 tree method_params)
6486 tree sender = (super_flag ? umsg_super_decl :
6487 (!flag_next_runtime || flag_nil_receivers
6488 ? (flag_objc_direct_dispatch
6489 ? umsg_fast_decl
6490 : umsg_decl)
6491 : umsg_nonnil_decl));
6492 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6494 /* If a prototype for the method to be called exists, then cast
6495 the sender's return type and arguments to match that of the method.
6496 Otherwise, leave sender as is. */
6497 tree ret_type
6498 = (method_prototype
6499 ? TREE_VALUE (TREE_TYPE (method_prototype))
6500 : objc_object_type);
6501 tree sender_cast
6502 = build_pointer_type
6503 (build_function_type
6504 (ret_type,
6505 get_arg_type_list
6506 (method_prototype, METHOD_REF, super_flag)));
6507 tree method, t;
6509 lookup_object = build_c_cast (rcv_p, lookup_object);
6511 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6512 lookup_object = save_expr (lookup_object);
6514 if (flag_next_runtime)
6516 /* If we are returning a struct in memory, and the address
6517 of that memory location is passed as a hidden first
6518 argument, then change which messenger entry point this
6519 expr will call. NB: Note that sender_cast remains
6520 unchanged (it already has a struct return type). */
6521 if (!targetm.calls.struct_value_rtx (0, 0)
6522 && (TREE_CODE (ret_type) == RECORD_TYPE
6523 || TREE_CODE (ret_type) == UNION_TYPE)
6524 && targetm.calls.return_in_memory (ret_type, 0))
6525 sender = (super_flag ? umsg_super_stret_decl :
6526 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6528 method_params = tree_cons (NULL_TREE, lookup_object,
6529 tree_cons (NULL_TREE, selector,
6530 method_params));
6531 method = build_fold_addr_expr (sender);
6533 else
6535 /* This is the portable (GNU) way. */
6536 tree object;
6538 /* First, call the lookup function to get a pointer to the method,
6539 then cast the pointer, then call it with the method arguments. */
6541 object = (super_flag ? self_decl : lookup_object);
6543 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6544 t = tree_cons (NULL_TREE, lookup_object, t);
6545 method = build_function_call (sender, t);
6547 /* Pass the object to the method. */
6548 method_params = tree_cons (NULL_TREE, object,
6549 tree_cons (NULL_TREE, selector,
6550 method_params));
6553 /* ??? Selector is not at this point something we can use inside
6554 the compiler itself. Set it to garbage for the nonce. */
6555 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6556 return build_function_call (t, method_params);
6559 static void
6560 build_protocol_reference (tree p)
6562 tree decl;
6563 const char *proto_name;
6565 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6567 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6568 decl = start_var_decl (objc_protocol_template, proto_name);
6570 PROTOCOL_FORWARD_DECL (p) = decl;
6573 /* This function is called by the parser when (and only when) a
6574 @protocol() expression is found, in order to compile it. */
6575 tree
6576 objc_build_protocol_expr (tree protoname)
6578 tree expr;
6579 tree p = lookup_protocol (protoname);
6581 if (!p)
6583 error ("cannot find protocol declaration for %qs",
6584 IDENTIFIER_POINTER (protoname));
6585 return error_mark_node;
6588 if (!PROTOCOL_FORWARD_DECL (p))
6589 build_protocol_reference (p);
6591 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6593 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6594 if we have it, rather than converting it here. */
6595 expr = convert (objc_protocol_type, expr);
6597 /* The @protocol() expression is being compiled into a pointer to a
6598 statically allocated instance of the Protocol class. To become
6599 usable at runtime, the 'isa' pointer of the instance need to be
6600 fixed up at runtime by the runtime library, to point to the
6601 actual 'Protocol' class. */
6603 /* For the GNU runtime, put the static Protocol instance in the list
6604 of statically allocated instances, so that we make sure that its
6605 'isa' pointer is fixed up at runtime by the GNU runtime library
6606 to point to the Protocol class (at runtime, when loading the
6607 module, the GNU runtime library loops on the statically allocated
6608 instances (as found in the defs field in objc_symtab) and fixups
6609 all the 'isa' pointers of those objects). */
6610 if (! flag_next_runtime)
6612 /* This type is a struct containing the fields of a Protocol
6613 object. (Cfr. objc_protocol_type instead is the type of a pointer
6614 to such a struct). */
6615 tree protocol_struct_type = xref_tag
6616 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6617 tree *chain;
6619 /* Look for the list of Protocol statically allocated instances
6620 to fixup at runtime. Create a new list to hold Protocol
6621 statically allocated instances, if the list is not found. At
6622 present there is only another list, holding NSConstantString
6623 static instances to be fixed up at runtime. */
6624 for (chain = &objc_static_instances;
6625 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6626 chain = &TREE_CHAIN (*chain));
6627 if (!*chain)
6629 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6630 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6631 class_names);
6634 /* Add this statically allocated instance to the Protocol list. */
6635 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6636 PROTOCOL_FORWARD_DECL (p),
6637 TREE_PURPOSE (*chain));
6641 return expr;
6644 /* This function is called by the parser when a @selector() expression
6645 is found, in order to compile it. It is only called by the parser
6646 and only to compile a @selector(). */
6647 tree
6648 objc_build_selector_expr (tree selnamelist)
6650 tree selname;
6652 /* Obtain the full selector name. */
6653 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6654 /* A unary selector. */
6655 selname = selnamelist;
6656 else if (TREE_CODE (selnamelist) == TREE_LIST)
6657 selname = build_keyword_selector (selnamelist);
6658 else
6659 abort ();
6661 /* If we are required to check @selector() expressions as they
6662 are found, check that the selector has been declared. */
6663 if (warn_undeclared_selector)
6665 /* Look the selector up in the list of all known class and
6666 instance methods (up to this line) to check that the selector
6667 exists. */
6668 hash hsh;
6670 /* First try with instance methods. */
6671 hsh = hash_lookup (nst_method_hash_list, selname);
6673 /* If not found, try with class methods. */
6674 if (!hsh)
6676 hsh = hash_lookup (cls_method_hash_list, selname);
6679 /* If still not found, print out a warning. */
6680 if (!hsh)
6682 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6687 if (flag_typed_selectors)
6688 return build_typed_selector_reference (selname, 0);
6689 else
6690 return build_selector_reference (selname);
6693 tree
6694 objc_build_encode_expr (tree type)
6696 tree result;
6697 const char *string;
6699 encode_type (type, obstack_object_size (&util_obstack),
6700 OBJC_ENCODE_INLINE_DEFS);
6701 obstack_1grow (&util_obstack, 0); /* null terminate string */
6702 string = obstack_finish (&util_obstack);
6704 /* Synthesize a string that represents the encoded struct/union. */
6705 result = my_build_string (strlen (string) + 1, string);
6706 obstack_free (&util_obstack, util_firstobj);
6707 return result;
6710 static tree
6711 build_ivar_reference (tree id)
6713 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6715 /* Historically, a class method that produced objects (factory
6716 method) would assign `self' to the instance that it
6717 allocated. This would effectively turn the class method into
6718 an instance method. Following this assignment, the instance
6719 variables could be accessed. That practice, while safe,
6720 violates the simple rule that a class method should not refer
6721 to an instance variable. It's better to catch the cases
6722 where this is done unknowingly than to support the above
6723 paradigm. */
6724 warning (0, "instance variable %qs accessed in class method",
6725 IDENTIFIER_POINTER (id));
6726 self_decl = convert (objc_instance_type, self_decl); /* cast */
6729 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6732 /* Compute a hash value for a given method SEL_NAME. */
6734 static size_t
6735 hash_func (tree sel_name)
6737 const unsigned char *s
6738 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6739 size_t h = 0;
6741 while (*s)
6742 h = h * 67 + *s++ - 113;
6743 return h;
6746 static void
6747 hash_init (void)
6749 nst_method_hash_list
6750 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6751 cls_method_hash_list
6752 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6754 /* Initialize the hash table used to hold the constant string objects. */
6755 string_htab = htab_create_ggc (31, string_hash,
6756 string_eq, NULL);
6758 /* Initialize the hash table used to hold EH-volatilized types. */
6759 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6760 volatilized_eq, NULL);
6763 /* WARNING!!!! hash_enter is called with a method, and will peek
6764 inside to find its selector! But hash_lookup is given a selector
6765 directly, and looks for the selector that's inside the found
6766 entry's key (method) for comparison. */
6768 static void
6769 hash_enter (hash *hashlist, tree method)
6771 hash obj;
6772 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6774 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6775 obj->list = 0;
6776 obj->next = hashlist[slot];
6777 obj->key = method;
6779 hashlist[slot] = obj; /* append to front */
6782 static hash
6783 hash_lookup (hash *hashlist, tree sel_name)
6785 hash target;
6787 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6789 while (target)
6791 if (sel_name == METHOD_SEL_NAME (target->key))
6792 return target;
6794 target = target->next;
6796 return 0;
6799 static void
6800 hash_add_attr (hash entry, tree value)
6802 attr obj;
6804 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6805 obj->next = entry->list;
6806 obj->value = value;
6808 entry->list = obj; /* append to front */
6811 static tree
6812 lookup_method (tree mchain, tree method)
6814 tree key;
6816 if (TREE_CODE (method) == IDENTIFIER_NODE)
6817 key = method;
6818 else
6819 key = METHOD_SEL_NAME (method);
6821 while (mchain)
6823 if (METHOD_SEL_NAME (mchain) == key)
6824 return mchain;
6826 mchain = TREE_CHAIN (mchain);
6828 return NULL_TREE;
6831 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6832 in INTERFACE, along with any categories and protocols attached thereto.
6833 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6834 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6835 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6836 be found in INTERFACE or any of its superclasses, look for an _instance_
6837 method of the same name in the root class as a last resort.
6839 If a suitable method cannot be found, return NULL_TREE. */
6841 static tree
6842 lookup_method_static (tree interface, tree ident, int flags)
6844 tree meth = NULL_TREE, root_inter = NULL_TREE;
6845 tree inter = interface;
6846 int is_class = (flags & OBJC_LOOKUP_CLASS);
6847 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6849 while (inter)
6851 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6852 tree category = inter;
6854 /* First, look up the method in the class itself. */
6855 if ((meth = lookup_method (chain, ident)))
6856 return meth;
6858 /* Failing that, look for the method in each category of the class. */
6859 while ((category = CLASS_CATEGORY_LIST (category)))
6861 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6863 /* Check directly in each category. */
6864 if ((meth = lookup_method (chain, ident)))
6865 return meth;
6867 /* Failing that, check in each category's protocols. */
6868 if (CLASS_PROTOCOL_LIST (category))
6870 if ((meth = (lookup_method_in_protocol_list
6871 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6872 return meth;
6876 /* If not found in categories, check in protocols of the main class. */
6877 if (CLASS_PROTOCOL_LIST (inter))
6879 if ((meth = (lookup_method_in_protocol_list
6880 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6881 return meth;
6884 /* If we were instructed not to look in superclasses, don't. */
6885 if (no_superclasses)
6886 return NULL_TREE;
6888 /* Failing that, climb up the inheritance hierarchy. */
6889 root_inter = inter;
6890 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6892 while (inter);
6894 /* If no class (factory) method was found, check if an _instance_
6895 method of the same name exists in the root class. This is what
6896 the Objective-C runtime will do. If an instance method was not
6897 found, return 0. */
6898 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6901 /* Add the method to the hash list if it doesn't contain an identical
6902 method already. */
6904 static void
6905 add_method_to_hash_list (hash *hash_list, tree method)
6907 hash hsh;
6909 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6911 /* Install on a global chain. */
6912 hash_enter (hash_list, method);
6914 else
6916 /* Check types against those; if different, add to a list. */
6917 attr loop;
6918 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6919 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6920 already_there |= comp_proto_with_proto (method, loop->value, 1);
6921 if (!already_there)
6922 hash_add_attr (hsh, method);
6926 static tree
6927 objc_add_method (tree class, tree method, int is_class)
6929 tree mth;
6931 if (!(mth = lookup_method (is_class
6932 ? CLASS_CLS_METHODS (class)
6933 : CLASS_NST_METHODS (class), method)))
6935 /* put method on list in reverse order */
6936 if (is_class)
6938 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6939 CLASS_CLS_METHODS (class) = method;
6941 else
6943 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6944 CLASS_NST_METHODS (class) = method;
6947 else
6949 /* When processing an @interface for a class or category, give hard
6950 errors on methods with identical selectors but differing argument
6951 and/or return types. We do not do this for @implementations, because
6952 C/C++ will do it for us (i.e., there will be duplicate function
6953 definition errors). */
6954 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6955 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6956 && !comp_proto_with_proto (method, mth, 1))
6957 error ("duplicate declaration of method %<%c%s%>",
6958 is_class ? '+' : '-',
6959 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6962 if (is_class)
6963 add_method_to_hash_list (cls_method_hash_list, method);
6964 else
6966 add_method_to_hash_list (nst_method_hash_list, method);
6968 /* Instance methods in root classes (and categories thereof)
6969 may act as class methods as a last resort. We also add
6970 instance methods listed in @protocol declarations to
6971 the class hash table, on the assumption that @protocols
6972 may be adopted by root classes or categories. */
6973 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6974 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6975 class = lookup_interface (CLASS_NAME (class));
6977 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6978 || !CLASS_SUPER_NAME (class))
6979 add_method_to_hash_list (cls_method_hash_list, method);
6982 return method;
6985 static tree
6986 add_class (tree class_name, tree name)
6988 struct interface_tuple **slot;
6990 /* Put interfaces on list in reverse order. */
6991 TREE_CHAIN (class_name) = interface_chain;
6992 interface_chain = class_name;
6994 if (interface_htab == NULL)
6995 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6996 slot = (struct interface_tuple **)
6997 htab_find_slot_with_hash (interface_htab, name,
6998 IDENTIFIER_HASH_VALUE (name),
6999 INSERT);
7000 if (!*slot)
7002 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7003 (*slot)->id = name;
7005 (*slot)->class_name = class_name;
7007 return interface_chain;
7010 static void
7011 add_category (tree class, tree category)
7013 /* Put categories on list in reverse order. */
7014 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7016 if (cat)
7018 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7019 IDENTIFIER_POINTER (CLASS_NAME (class)),
7020 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7022 else
7024 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7025 CLASS_CATEGORY_LIST (class) = category;
7029 /* Called after parsing each instance variable declaration. Necessary to
7030 preserve typedefs and implement public/private...
7032 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7034 static tree
7035 add_instance_variable (tree class, int public, tree field_decl)
7037 tree field_type = TREE_TYPE (field_decl);
7038 const char *ivar_name = DECL_NAME (field_decl)
7039 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7040 : "<unnamed>";
7042 #ifdef OBJCPLUS
7043 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7045 error ("illegal reference type specified for instance variable %qs",
7046 ivar_name);
7047 /* Return class as is without adding this ivar. */
7048 return class;
7050 #endif
7052 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7053 || TYPE_SIZE (field_type) == error_mark_node)
7054 /* 'type[0]' is allowed, but 'type[]' is not! */
7056 error ("instance variable %qs has unknown size", ivar_name);
7057 /* Return class as is without adding this ivar. */
7058 return class;
7061 #ifdef OBJCPLUS
7062 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7063 need to either (1) warn the user about it or (2) generate suitable
7064 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7065 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7066 if (IS_AGGR_TYPE (field_type)
7067 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7068 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7069 || TYPE_POLYMORPHIC_P (field_type)))
7071 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7073 if (flag_objc_call_cxx_cdtors)
7075 /* Since the ObjC runtime will be calling the constructors and
7076 destructors for us, the only thing we can't handle is the lack
7077 of a default constructor. */
7078 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7079 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7081 warning (0, "type %qs has no default constructor to call",
7082 type_name);
7084 /* If we cannot call a constructor, we should also avoid
7085 calling the destructor, for symmetry. */
7086 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7087 warning (0, "destructor for %qs shall not be run either",
7088 type_name);
7091 else
7093 static bool warn_cxx_ivars = false;
7095 if (TYPE_POLYMORPHIC_P (field_type))
7097 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7098 initialize them. */
7099 error ("type %qs has virtual member functions", type_name);
7100 error ("illegal aggregate type %qs specified "
7101 "for instance variable %qs",
7102 type_name, ivar_name);
7103 /* Return class as is without adding this ivar. */
7104 return class;
7107 /* User-defined constructors and destructors are not known to Obj-C
7108 and hence will not be called. This may or may not be a problem. */
7109 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7110 warning (0, "type %qs has a user-defined constructor", type_name);
7111 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7112 warning (0, "type %qs has a user-defined destructor", type_name);
7114 if (!warn_cxx_ivars)
7116 warning (0, "C++ constructors and destructors will not "
7117 "be invoked for Objective-C fields");
7118 warn_cxx_ivars = true;
7122 #endif
7124 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7125 switch (public)
7127 case 0:
7128 TREE_PUBLIC (field_decl) = 0;
7129 TREE_PRIVATE (field_decl) = 0;
7130 TREE_PROTECTED (field_decl) = 1;
7131 break;
7133 case 1:
7134 TREE_PUBLIC (field_decl) = 1;
7135 TREE_PRIVATE (field_decl) = 0;
7136 TREE_PROTECTED (field_decl) = 0;
7137 break;
7139 case 2:
7140 TREE_PUBLIC (field_decl) = 0;
7141 TREE_PRIVATE (field_decl) = 1;
7142 TREE_PROTECTED (field_decl) = 0;
7143 break;
7147 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7149 return class;
7152 static tree
7153 is_ivar (tree decl_chain, tree ident)
7155 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7156 if (DECL_NAME (decl_chain) == ident)
7157 return decl_chain;
7158 return NULL_TREE;
7161 /* True if the ivar is private and we are not in its implementation. */
7163 static int
7164 is_private (tree decl)
7166 return (TREE_PRIVATE (decl)
7167 && ! is_ivar (CLASS_IVARS (implementation_template),
7168 DECL_NAME (decl)));
7171 /* We have an instance variable reference;, check to see if it is public. */
7174 objc_is_public (tree expr, tree identifier)
7176 tree basetype, decl;
7178 #ifdef OBJCPLUS
7179 if (processing_template_decl)
7180 return 1;
7181 #endif
7183 if (TREE_TYPE (expr) == error_mark_node)
7184 return 1;
7186 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7188 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7190 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7192 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7194 if (!class)
7196 error ("cannot find interface declaration for %qs",
7197 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7198 return 0;
7201 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7203 if (TREE_PUBLIC (decl))
7204 return 1;
7206 /* Important difference between the Stepstone translator:
7207 all instance variables should be public within the context
7208 of the implementation. */
7209 if (objc_implementation_context
7210 && ((TREE_CODE (objc_implementation_context)
7211 == CLASS_IMPLEMENTATION_TYPE)
7212 || (TREE_CODE (objc_implementation_context)
7213 == CATEGORY_IMPLEMENTATION_TYPE)))
7215 tree curtype = TYPE_MAIN_VARIANT
7216 (CLASS_STATIC_TEMPLATE
7217 (implementation_template));
7219 if (basetype == curtype
7220 || DERIVED_FROM_P (basetype, curtype))
7222 int private = is_private (decl);
7224 if (private)
7225 error ("instance variable %qs is declared private",
7226 IDENTIFIER_POINTER (DECL_NAME (decl)));
7228 return !private;
7232 /* The 2.95.2 compiler sometimes allowed C functions to access
7233 non-@public ivars. We will let this slide for now... */
7234 if (!objc_method_context)
7236 warning (0, "instance variable %qs is %s; "
7237 "this will be a hard error in the future",
7238 IDENTIFIER_POINTER (identifier),
7239 TREE_PRIVATE (decl) ? "@private" : "@protected");
7240 return 1;
7243 error ("instance variable %qs is declared %s",
7244 IDENTIFIER_POINTER (identifier),
7245 TREE_PRIVATE (decl) ? "private" : "protected");
7246 return 0;
7251 return 1;
7254 /* Make sure all entries in CHAIN are also in LIST. */
7256 static int
7257 check_methods (tree chain, tree list, int mtype)
7259 int first = 1;
7261 while (chain)
7263 if (!lookup_method (list, chain))
7265 if (first)
7267 if (TREE_CODE (objc_implementation_context)
7268 == CLASS_IMPLEMENTATION_TYPE)
7269 warning (0, "incomplete implementation of class %qs",
7270 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7271 else if (TREE_CODE (objc_implementation_context)
7272 == CATEGORY_IMPLEMENTATION_TYPE)
7273 warning (0, "incomplete implementation of category %qs",
7274 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7275 first = 0;
7278 warning (0, "method definition for %<%c%s%> not found",
7279 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7282 chain = TREE_CHAIN (chain);
7285 return first;
7288 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7290 static int
7291 conforms_to_protocol (tree class, tree protocol)
7293 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7295 tree p = CLASS_PROTOCOL_LIST (class);
7296 while (p && TREE_VALUE (p) != protocol)
7297 p = TREE_CHAIN (p);
7299 if (!p)
7301 tree super = (CLASS_SUPER_NAME (class)
7302 ? lookup_interface (CLASS_SUPER_NAME (class))
7303 : NULL_TREE);
7304 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7305 if (!tmp)
7306 return 0;
7310 return 1;
7313 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7314 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7316 static int
7317 check_methods_accessible (tree chain, tree context, int mtype)
7319 int first = 1;
7320 tree list;
7321 tree base_context = context;
7323 while (chain)
7325 context = base_context;
7326 while (context)
7328 if (mtype == '+')
7329 list = CLASS_CLS_METHODS (context);
7330 else
7331 list = CLASS_NST_METHODS (context);
7333 if (lookup_method (list, chain))
7334 break;
7336 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7337 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7338 context = (CLASS_SUPER_NAME (context)
7339 ? lookup_interface (CLASS_SUPER_NAME (context))
7340 : NULL_TREE);
7342 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7343 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7344 context = (CLASS_NAME (context)
7345 ? lookup_interface (CLASS_NAME (context))
7346 : NULL_TREE);
7347 else
7348 abort ();
7351 if (context == NULL_TREE)
7353 if (first)
7355 if (TREE_CODE (objc_implementation_context)
7356 == CLASS_IMPLEMENTATION_TYPE)
7357 warning (0, "incomplete implementation of class %qs",
7358 IDENTIFIER_POINTER
7359 (CLASS_NAME (objc_implementation_context)));
7360 else if (TREE_CODE (objc_implementation_context)
7361 == CATEGORY_IMPLEMENTATION_TYPE)
7362 warning (0, "incomplete implementation of category %qs",
7363 IDENTIFIER_POINTER
7364 (CLASS_SUPER_NAME (objc_implementation_context)));
7365 first = 0;
7367 warning (0, "method definition for %<%c%s%> not found",
7368 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7371 chain = TREE_CHAIN (chain); /* next method... */
7373 return first;
7376 /* Check whether the current interface (accessible via
7377 'objc_implementation_context') actually implements protocol P, along
7378 with any protocols that P inherits. */
7380 static void
7381 check_protocol (tree p, const char *type, const char *name)
7383 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7385 int f1, f2;
7387 /* Ensure that all protocols have bodies! */
7388 if (warn_protocol)
7390 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7391 CLASS_CLS_METHODS (objc_implementation_context),
7392 '+');
7393 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7394 CLASS_NST_METHODS (objc_implementation_context),
7395 '-');
7397 else
7399 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7400 objc_implementation_context,
7401 '+');
7402 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7403 objc_implementation_context,
7404 '-');
7407 if (!f1 || !f2)
7408 warning (0, "%s %qs does not fully implement the %qs protocol",
7409 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7412 /* Check protocols recursively. */
7413 if (PROTOCOL_LIST (p))
7415 tree subs = PROTOCOL_LIST (p);
7416 tree super_class =
7417 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7419 while (subs)
7421 tree sub = TREE_VALUE (subs);
7423 /* If the superclass does not conform to the protocols
7424 inherited by P, then we must! */
7425 if (!super_class || !conforms_to_protocol (super_class, sub))
7426 check_protocol (sub, type, name);
7427 subs = TREE_CHAIN (subs);
7432 /* Check whether the current interface (accessible via
7433 'objc_implementation_context') actually implements the protocols listed
7434 in PROTO_LIST. */
7436 static void
7437 check_protocols (tree proto_list, const char *type, const char *name)
7439 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7441 tree p = TREE_VALUE (proto_list);
7443 check_protocol (p, type, name);
7447 /* Make sure that the class CLASS_NAME is defined
7448 CODE says which kind of thing CLASS_NAME ought to be.
7449 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7450 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7452 static tree
7453 start_class (enum tree_code code, tree class_name, tree super_name,
7454 tree protocol_list)
7456 tree class, decl;
7458 #ifdef OBJCPLUS
7459 if (current_namespace != global_namespace) {
7460 error ("Objective-C declarations may only appear in global scope");
7462 #endif /* OBJCPLUS */
7464 if (objc_implementation_context)
7466 warning (0, "%<@end%> missing in implementation context");
7467 finish_class (objc_implementation_context);
7468 objc_ivar_chain = NULL_TREE;
7469 objc_implementation_context = NULL_TREE;
7472 class = make_node (code);
7473 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7475 /* Check for existence of the super class, if one was specified. Note
7476 that we must have seen an @interface, not just a @class. If we
7477 are looking at a @compatibility_alias, traverse it first. */
7478 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7479 && super_name)
7481 tree super = objc_is_class_name (super_name);
7483 if (!super || !lookup_interface (super))
7485 error ("cannot find interface declaration for %qs, superclass of %qs",
7486 IDENTIFIER_POINTER (super ? super : super_name),
7487 IDENTIFIER_POINTER (class_name));
7488 super_name = NULL_TREE;
7490 else
7491 super_name = super;
7494 CLASS_NAME (class) = class_name;
7495 CLASS_SUPER_NAME (class) = super_name;
7496 CLASS_CLS_METHODS (class) = NULL_TREE;
7498 if (! objc_is_class_name (class_name)
7499 && (decl = lookup_name (class_name)))
7501 error ("%qs redeclared as different kind of symbol",
7502 IDENTIFIER_POINTER (class_name));
7503 error ("previous declaration of %q+D",
7504 decl);
7507 if (code == CLASS_IMPLEMENTATION_TYPE)
7510 tree chain;
7512 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7513 if (TREE_VALUE (chain) == class_name)
7515 error ("reimplementation of class %qs",
7516 IDENTIFIER_POINTER (class_name));
7517 return error_mark_node;
7519 implemented_classes = tree_cons (NULL_TREE, class_name,
7520 implemented_classes);
7523 /* Reset for multiple classes per file. */
7524 method_slot = 0;
7526 objc_implementation_context = class;
7528 /* Lookup the interface for this implementation. */
7530 if (!(implementation_template = lookup_interface (class_name)))
7532 warning (0, "cannot find interface declaration for %qs",
7533 IDENTIFIER_POINTER (class_name));
7534 add_class (implementation_template = objc_implementation_context,
7535 class_name);
7538 /* If a super class has been specified in the implementation,
7539 insure it conforms to the one specified in the interface. */
7541 if (super_name
7542 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7544 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7545 const char *const name =
7546 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7547 error ("conflicting super class name %qs",
7548 IDENTIFIER_POINTER (super_name));
7549 error ("previous declaration of %qs", name);
7552 else if (! super_name)
7554 CLASS_SUPER_NAME (objc_implementation_context)
7555 = CLASS_SUPER_NAME (implementation_template);
7559 else if (code == CLASS_INTERFACE_TYPE)
7561 if (lookup_interface (class_name))
7562 #ifdef OBJCPLUS
7563 error ("duplicate interface declaration for class %qs",
7564 #else
7565 warning (0, "duplicate interface declaration for class %qs",
7566 #endif
7567 IDENTIFIER_POINTER (class_name));
7568 else
7569 add_class (class, class_name);
7571 if (protocol_list)
7572 CLASS_PROTOCOL_LIST (class)
7573 = lookup_and_install_protocols (protocol_list);
7576 else if (code == CATEGORY_INTERFACE_TYPE)
7578 tree class_category_is_assoc_with;
7580 /* For a category, class_name is really the name of the class that
7581 the following set of methods will be associated with. We must
7582 find the interface so that can derive the objects template. */
7584 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7586 error ("cannot find interface declaration for %qs",
7587 IDENTIFIER_POINTER (class_name));
7588 exit (FATAL_EXIT_CODE);
7590 else
7591 add_category (class_category_is_assoc_with, class);
7593 if (protocol_list)
7594 CLASS_PROTOCOL_LIST (class)
7595 = lookup_and_install_protocols (protocol_list);
7598 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7600 /* Reset for multiple classes per file. */
7601 method_slot = 0;
7603 objc_implementation_context = class;
7605 /* For a category, class_name is really the name of the class that
7606 the following set of methods will be associated with. We must
7607 find the interface so that can derive the objects template. */
7609 if (!(implementation_template = lookup_interface (class_name)))
7611 error ("cannot find interface declaration for %qs",
7612 IDENTIFIER_POINTER (class_name));
7613 exit (FATAL_EXIT_CODE);
7616 return class;
7619 static tree
7620 continue_class (tree class)
7622 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7623 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7625 struct imp_entry *imp_entry;
7627 /* Check consistency of the instance variables. */
7629 if (CLASS_RAW_IVARS (class))
7630 check_ivars (implementation_template, class);
7632 /* code generation */
7634 #ifdef OBJCPLUS
7635 push_lang_context (lang_name_c);
7636 #endif
7638 build_private_template (implementation_template);
7639 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7640 objc_instance_type = build_pointer_type (uprivate_record);
7642 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7644 imp_entry->next = imp_list;
7645 imp_entry->imp_context = class;
7646 imp_entry->imp_template = implementation_template;
7648 synth_forward_declarations ();
7649 imp_entry->class_decl = UOBJC_CLASS_decl;
7650 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7651 imp_entry->has_cxx_cdtors = 0;
7653 /* Append to front and increment count. */
7654 imp_list = imp_entry;
7655 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7656 imp_count++;
7657 else
7658 cat_count++;
7660 #ifdef OBJCPLUS
7661 pop_lang_context ();
7662 #endif /* OBJCPLUS */
7664 return get_class_ivars (implementation_template, true);
7667 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7669 #ifdef OBJCPLUS
7670 push_lang_context (lang_name_c);
7671 #endif /* OBJCPLUS */
7673 build_private_template (class);
7675 #ifdef OBJCPLUS
7676 pop_lang_context ();
7677 #endif /* OBJCPLUS */
7679 return NULL_TREE;
7682 else
7683 return error_mark_node;
7686 /* This is called once we see the "@end" in an interface/implementation. */
7688 static void
7689 finish_class (tree class)
7691 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7693 /* All code generation is done in finish_objc. */
7695 if (implementation_template != objc_implementation_context)
7697 /* Ensure that all method listed in the interface contain bodies. */
7698 check_methods (CLASS_CLS_METHODS (implementation_template),
7699 CLASS_CLS_METHODS (objc_implementation_context), '+');
7700 check_methods (CLASS_NST_METHODS (implementation_template),
7701 CLASS_NST_METHODS (objc_implementation_context), '-');
7703 if (CLASS_PROTOCOL_LIST (implementation_template))
7704 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7705 "class",
7706 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7710 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7712 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7714 if (category)
7716 /* Ensure all method listed in the interface contain bodies. */
7717 check_methods (CLASS_CLS_METHODS (category),
7718 CLASS_CLS_METHODS (objc_implementation_context), '+');
7719 check_methods (CLASS_NST_METHODS (category),
7720 CLASS_NST_METHODS (objc_implementation_context), '-');
7722 if (CLASS_PROTOCOL_LIST (category))
7723 check_protocols (CLASS_PROTOCOL_LIST (category),
7724 "category",
7725 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7730 static tree
7731 add_protocol (tree protocol)
7733 /* Put protocol on list in reverse order. */
7734 TREE_CHAIN (protocol) = protocol_chain;
7735 protocol_chain = protocol;
7736 return protocol_chain;
7739 static tree
7740 lookup_protocol (tree ident)
7742 tree chain;
7744 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7745 if (ident == PROTOCOL_NAME (chain))
7746 return chain;
7748 return NULL_TREE;
7751 /* This function forward declares the protocols named by NAMES. If
7752 they are already declared or defined, the function has no effect. */
7754 void
7755 objc_declare_protocols (tree names)
7757 tree list;
7759 #ifdef OBJCPLUS
7760 if (current_namespace != global_namespace) {
7761 error ("Objective-C declarations may only appear in global scope");
7763 #endif /* OBJCPLUS */
7765 for (list = names; list; list = TREE_CHAIN (list))
7767 tree name = TREE_VALUE (list);
7769 if (lookup_protocol (name) == NULL_TREE)
7771 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7773 TYPE_LANG_SLOT_1 (protocol)
7774 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7775 PROTOCOL_NAME (protocol) = name;
7776 PROTOCOL_LIST (protocol) = NULL_TREE;
7777 add_protocol (protocol);
7778 PROTOCOL_DEFINED (protocol) = 0;
7779 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7784 static tree
7785 start_protocol (enum tree_code code, tree name, tree list)
7787 tree protocol;
7789 #ifdef OBJCPLUS
7790 if (current_namespace != global_namespace) {
7791 error ("Objective-C declarations may only appear in global scope");
7793 #endif /* OBJCPLUS */
7795 protocol = lookup_protocol (name);
7797 if (!protocol)
7799 protocol = make_node (code);
7800 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7802 PROTOCOL_NAME (protocol) = name;
7803 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7804 add_protocol (protocol);
7805 PROTOCOL_DEFINED (protocol) = 1;
7806 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7808 check_protocol_recursively (protocol, list);
7810 else if (! PROTOCOL_DEFINED (protocol))
7812 PROTOCOL_DEFINED (protocol) = 1;
7813 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7815 check_protocol_recursively (protocol, list);
7817 else
7819 warning (0, "duplicate declaration for protocol %qs",
7820 IDENTIFIER_POINTER (name));
7822 return protocol;
7826 /* "Encode" a data type into a string, which grows in util_obstack.
7827 ??? What is the FORMAT? Someone please document this! */
7829 static void
7830 encode_type_qualifiers (tree declspecs)
7832 tree spec;
7834 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7836 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7837 obstack_1grow (&util_obstack, 'n');
7838 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7839 obstack_1grow (&util_obstack, 'N');
7840 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7841 obstack_1grow (&util_obstack, 'o');
7842 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7843 obstack_1grow (&util_obstack, 'O');
7844 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7845 obstack_1grow (&util_obstack, 'R');
7846 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7847 obstack_1grow (&util_obstack, 'V');
7851 /* Encode a pointer type. */
7853 static void
7854 encode_pointer (tree type, int curtype, int format)
7856 tree pointer_to = TREE_TYPE (type);
7858 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7860 if (OBJC_TYPE_NAME (pointer_to)
7861 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7863 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7865 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7867 obstack_1grow (&util_obstack, '@');
7868 return;
7870 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7871 && TYPE_OBJC_INTERFACE (pointer_to))
7873 if (generating_instance_variables)
7875 obstack_1grow (&util_obstack, '@');
7876 obstack_1grow (&util_obstack, '"');
7877 obstack_grow (&util_obstack, name, strlen (name));
7878 obstack_1grow (&util_obstack, '"');
7879 return;
7881 else
7883 obstack_1grow (&util_obstack, '@');
7884 return;
7887 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7889 obstack_1grow (&util_obstack, '#');
7890 return;
7892 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7894 obstack_1grow (&util_obstack, ':');
7895 return;
7899 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7900 && TYPE_MODE (pointer_to) == QImode)
7902 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7903 ? OBJC_TYPE_NAME (pointer_to)
7904 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7906 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7908 /* It appears that "r*" means "const char *" rather than
7909 "char *const". */
7910 if (TYPE_READONLY (pointer_to))
7911 obstack_1grow (&util_obstack, 'r');
7913 obstack_1grow (&util_obstack, '*');
7914 return;
7918 /* We have a type that does not get special treatment. */
7920 /* NeXT extension */
7921 obstack_1grow (&util_obstack, '^');
7922 encode_type (pointer_to, curtype, format);
7925 static void
7926 encode_array (tree type, int curtype, int format)
7928 tree an_int_cst = TYPE_SIZE (type);
7929 tree array_of = TREE_TYPE (type);
7930 char buffer[40];
7932 /* An incomplete array is treated like a pointer. */
7933 if (an_int_cst == NULL)
7935 encode_pointer (type, curtype, format);
7936 return;
7939 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7940 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7941 else
7942 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7943 TREE_INT_CST_LOW (an_int_cst)
7944 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7946 obstack_grow (&util_obstack, buffer, strlen (buffer));
7947 encode_type (array_of, curtype, format);
7948 obstack_1grow (&util_obstack, ']');
7949 return;
7952 static void
7953 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7955 tree field = TYPE_FIELDS (type);
7957 for (; field; field = TREE_CHAIN (field))
7959 #ifdef OBJCPLUS
7960 /* C++ static members, and things that are not field at all,
7961 should not appear in the encoding. */
7962 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7963 continue;
7964 #endif
7966 /* Recursively encode fields of embedded base classes. */
7967 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7968 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7970 encode_aggregate_fields (TREE_TYPE (field),
7971 pointed_to, curtype, format);
7972 continue;
7975 if (generating_instance_variables && !pointed_to)
7977 tree fname = DECL_NAME (field);
7979 obstack_1grow (&util_obstack, '"');
7981 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7982 obstack_grow (&util_obstack,
7983 IDENTIFIER_POINTER (fname),
7984 strlen (IDENTIFIER_POINTER (fname)));
7986 obstack_1grow (&util_obstack, '"');
7989 encode_field_decl (field, curtype, format);
7993 static void
7994 encode_aggregate_within (tree type, int curtype, int format, int left,
7995 int right)
7997 tree name;
7998 /* NB: aggregates that are pointed to have slightly different encoding
7999 rules in that you never encode the names of instance variables. */
8000 int ob_size = obstack_object_size (&util_obstack);
8001 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8002 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8003 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8004 int inline_contents
8005 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8006 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8008 /* Traverse struct aliases; it is important to get the
8009 original struct and its tag name (if any). */
8010 type = TYPE_MAIN_VARIANT (type);
8011 name = OBJC_TYPE_NAME (type);
8012 /* Open parenth/bracket. */
8013 obstack_1grow (&util_obstack, left);
8015 /* Encode the struct/union tag name, or '?' if a tag was
8016 not provided. Typedef aliases do not qualify. */
8017 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8018 #ifdef OBJCPLUS
8019 /* Did this struct have a tag? */
8020 && !TYPE_WAS_ANONYMOUS (type)
8021 #endif
8023 obstack_grow (&util_obstack,
8024 IDENTIFIER_POINTER (name),
8025 strlen (IDENTIFIER_POINTER (name)));
8026 else
8027 obstack_1grow (&util_obstack, '?');
8029 /* Encode the types (and possibly names) of the inner fields,
8030 if required. */
8031 if (inline_contents)
8033 obstack_1grow (&util_obstack, '=');
8034 encode_aggregate_fields (type, pointed_to, curtype, format);
8036 /* Close parenth/bracket. */
8037 obstack_1grow (&util_obstack, right);
8040 static void
8041 encode_aggregate (tree type, int curtype, int format)
8043 enum tree_code code = TREE_CODE (type);
8045 switch (code)
8047 case RECORD_TYPE:
8049 encode_aggregate_within (type, curtype, format, '{', '}');
8050 break;
8052 case UNION_TYPE:
8054 encode_aggregate_within (type, curtype, format, '(', ')');
8055 break;
8058 case ENUMERAL_TYPE:
8059 obstack_1grow (&util_obstack, 'i');
8060 break;
8062 default:
8063 break;
8067 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8068 field type. */
8070 static void
8071 encode_next_bitfield (int width)
8073 char buffer[40];
8074 sprintf (buffer, "b%d", width);
8075 obstack_grow (&util_obstack, buffer, strlen (buffer));
8078 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8079 static void
8080 encode_type (tree type, int curtype, int format)
8082 enum tree_code code = TREE_CODE (type);
8083 char c;
8085 if (TYPE_READONLY (type))
8086 obstack_1grow (&util_obstack, 'r');
8088 if (code == INTEGER_TYPE)
8090 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8092 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8093 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8094 case 32:
8095 if (type == long_unsigned_type_node
8096 || type == long_integer_type_node)
8097 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8098 else
8099 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8100 break;
8101 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8102 default: abort ();
8104 obstack_1grow (&util_obstack, c);
8107 else if (code == REAL_TYPE)
8109 /* Floating point types. */
8110 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8112 case 32: c = 'f'; break;
8113 case 64:
8114 case 96:
8115 case 128: c = 'd'; break;
8116 default: abort ();
8118 obstack_1grow (&util_obstack, c);
8121 else if (code == VOID_TYPE)
8122 obstack_1grow (&util_obstack, 'v');
8124 else if (code == BOOLEAN_TYPE)
8125 obstack_1grow (&util_obstack, 'B');
8127 else if (code == ARRAY_TYPE)
8128 encode_array (type, curtype, format);
8130 else if (code == POINTER_TYPE)
8131 encode_pointer (type, curtype, format);
8133 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8134 encode_aggregate (type, curtype, format);
8136 else if (code == FUNCTION_TYPE) /* '?' */
8137 obstack_1grow (&util_obstack, '?');
8139 else if (code == COMPLEX_TYPE)
8141 obstack_1grow (&util_obstack, 'j');
8142 encode_type (TREE_TYPE (type), curtype, format);
8146 static void
8147 encode_gnu_bitfield (int position, tree type, int size)
8149 enum tree_code code = TREE_CODE (type);
8150 char buffer[40];
8151 char charType = '?';
8153 if (code == INTEGER_TYPE)
8155 if (integer_zerop (TYPE_MIN_VALUE (type)))
8157 /* Unsigned integer types. */
8159 if (TYPE_MODE (type) == QImode)
8160 charType = 'C';
8161 else if (TYPE_MODE (type) == HImode)
8162 charType = 'S';
8163 else if (TYPE_MODE (type) == SImode)
8165 if (type == long_unsigned_type_node)
8166 charType = 'L';
8167 else
8168 charType = 'I';
8170 else if (TYPE_MODE (type) == DImode)
8171 charType = 'Q';
8174 else
8175 /* Signed integer types. */
8177 if (TYPE_MODE (type) == QImode)
8178 charType = 'c';
8179 else if (TYPE_MODE (type) == HImode)
8180 charType = 's';
8181 else if (TYPE_MODE (type) == SImode)
8183 if (type == long_integer_type_node)
8184 charType = 'l';
8185 else
8186 charType = 'i';
8189 else if (TYPE_MODE (type) == DImode)
8190 charType = 'q';
8193 else if (code == ENUMERAL_TYPE)
8194 charType = 'i';
8195 else
8196 abort ();
8198 sprintf (buffer, "b%d%c%d", position, charType, size);
8199 obstack_grow (&util_obstack, buffer, strlen (buffer));
8202 static void
8203 encode_field_decl (tree field_decl, int curtype, int format)
8205 tree type;
8207 #ifdef OBJCPLUS
8208 /* C++ static members, and things that are not fields at all,
8209 should not appear in the encoding. */
8210 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8211 return;
8212 #endif
8214 type = TREE_TYPE (field_decl);
8216 /* Generate the bitfield typing information, if needed. Note the difference
8217 between GNU and NeXT runtimes. */
8218 if (DECL_BIT_FIELD_TYPE (field_decl))
8220 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8222 if (flag_next_runtime)
8223 encode_next_bitfield (size);
8224 else
8225 encode_gnu_bitfield (int_bit_position (field_decl),
8226 DECL_BIT_FIELD_TYPE (field_decl), size);
8228 else
8229 encode_type (TREE_TYPE (field_decl), curtype, format);
8232 static GTY(()) tree objc_parmlist = NULL_TREE;
8234 /* Append PARM to a list of formal parameters of a method, making a necessary
8235 array-to-pointer adjustment along the way. */
8237 static void
8238 objc_push_parm (tree parm)
8240 bool relayout_needed = false;
8241 /* Decay arrays and functions into pointers. */
8242 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8244 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8245 relayout_needed = true;
8247 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8249 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8250 relayout_needed = true;
8253 if (relayout_needed)
8254 relayout_decl (parm);
8257 DECL_ARG_TYPE (parm)
8258 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8260 /* Record constancy and volatility. */
8261 c_apply_type_quals_to_decl
8262 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8263 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8264 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8266 objc_parmlist = chainon (objc_parmlist, parm);
8269 /* Retrieve the formal parameter list constructed via preceding calls to
8270 objc_push_parm(). */
8272 #ifdef OBJCPLUS
8273 static tree
8274 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8275 #else
8276 static struct c_arg_info *
8277 objc_get_parm_info (int have_ellipsis)
8278 #endif
8280 #ifdef OBJCPLUS
8281 tree parm_info = objc_parmlist;
8282 objc_parmlist = NULL_TREE;
8284 return parm_info;
8285 #else
8286 tree parm_info = objc_parmlist;
8287 struct c_arg_info *arg_info;
8288 /* The C front-end requires an elaborate song and dance at
8289 this point. */
8290 push_scope ();
8291 declare_parm_level ();
8292 while (parm_info)
8294 tree next = TREE_CHAIN (parm_info);
8296 TREE_CHAIN (parm_info) = NULL_TREE;
8297 parm_info = pushdecl (parm_info);
8298 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8299 parm_info = next;
8301 arg_info = get_parm_info (have_ellipsis);
8302 pop_scope ();
8303 objc_parmlist = NULL_TREE;
8304 return arg_info;
8305 #endif
8308 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8309 method definitions. In the case of instance methods, we can be more
8310 specific as to the type of 'self'. */
8312 static void
8313 synth_self_and_ucmd_args (void)
8315 tree self_type;
8317 if (objc_method_context
8318 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8319 self_type = objc_instance_type;
8320 else
8321 /* Really a `struct objc_class *'. However, we allow people to
8322 assign to self, which changes its type midstream. */
8323 self_type = objc_object_type;
8325 /* id self; */
8326 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8328 /* SEL _cmd; */
8329 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8332 /* Transform an Objective-C method definition into a static C function
8333 definition, synthesizing the first two arguments, "self" and "_cmd",
8334 in the process. */
8336 static void
8337 start_method_def (tree method)
8339 tree parmlist;
8340 #ifdef OBJCPLUS
8341 tree parm_info;
8342 #else
8343 struct c_arg_info *parm_info;
8344 #endif
8345 int have_ellipsis = 0;
8347 /* If we are defining a "dealloc" method in a non-root class, we
8348 will need to check if a [super dealloc] is missing, and warn if
8349 it is. */
8350 if(CLASS_SUPER_NAME (objc_implementation_context)
8351 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8352 should_call_super_dealloc = 1;
8353 else
8354 should_call_super_dealloc = 0;
8356 /* Required to implement _msgSuper. */
8357 objc_method_context = method;
8358 UOBJC_SUPER_decl = NULL_TREE;
8360 /* Generate prototype declarations for arguments..."new-style". */
8361 synth_self_and_ucmd_args ();
8363 /* Generate argument declarations if a keyword_decl. */
8364 parmlist = METHOD_SEL_ARGS (method);
8365 while (parmlist)
8367 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8369 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8370 objc_push_parm (parm);
8371 parmlist = TREE_CHAIN (parmlist);
8374 if (METHOD_ADD_ARGS (method))
8376 tree akey;
8378 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8379 akey; akey = TREE_CHAIN (akey))
8381 objc_push_parm (TREE_VALUE (akey));
8384 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8385 have_ellipsis = 1;
8388 parm_info = objc_get_parm_info (have_ellipsis);
8390 really_start_method (objc_method_context, parm_info);
8393 static void
8394 warn_with_method (const char *message, int mtype, tree method)
8396 /* Add a readable method name to the warning. */
8397 warning (0, "%J%s %<%c%s%>", method,
8398 message, mtype, gen_method_decl (method));
8401 /* Return 1 if TYPE1 is equivalent to TYPE2
8402 for purposes of method overloading. */
8404 static int
8405 objc_types_are_equivalent (tree type1, tree type2)
8407 if (type1 == type2)
8408 return 1;
8410 /* Strip away indirections. */
8411 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8412 && (TREE_CODE (type1) == TREE_CODE (type2)))
8413 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8414 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8415 return 0;
8417 type1 = (TYPE_HAS_OBJC_INFO (type1)
8418 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8419 : NULL_TREE);
8420 type2 = (TYPE_HAS_OBJC_INFO (type2)
8421 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8422 : NULL_TREE);
8424 if (list_length (type1) == list_length (type2))
8426 for (; type2; type2 = TREE_CHAIN (type2))
8427 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8428 return 0;
8429 return 1;
8431 return 0;
8434 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8436 static int
8437 objc_types_share_size_and_alignment (tree type1, tree type2)
8439 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8440 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8443 /* Return 1 if PROTO1 is equivalent to PROTO2
8444 for purposes of method overloading. Ordinarily, the type signatures
8445 should match up exactly, unless STRICT is zero, in which case we
8446 shall allow differences in which the size and alignment of a type
8447 is the same. */
8449 static int
8450 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8452 tree type1, type2;
8454 /* The following test is needed in case there are hashing
8455 collisions. */
8456 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8457 return 0;
8459 /* Compare return types. */
8460 type1 = TREE_VALUE (TREE_TYPE (proto1));
8461 type2 = TREE_VALUE (TREE_TYPE (proto2));
8463 if (!objc_types_are_equivalent (type1, type2)
8464 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8465 return 0;
8467 /* Compare argument types. */
8468 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8469 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8470 type1 && type2;
8471 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8473 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8474 && (strict
8475 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8476 TREE_VALUE (type2))))
8477 return 0;
8480 return (!type1 && !type2);
8483 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8484 this occurs. ObjC method dispatches are _not_ like C++ virtual
8485 member function dispatches, and we account for the difference here. */
8486 tree
8487 #ifdef OBJCPLUS
8488 objc_fold_obj_type_ref (tree ref, tree known_type)
8489 #else
8490 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8491 tree known_type ATTRIBUTE_UNUSED)
8492 #endif
8494 #ifdef OBJCPLUS
8495 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8497 /* If the receiver does not have virtual member functions, there
8498 is nothing we can (or need to) do here. */
8499 if (!v)
8500 return NULL_TREE;
8502 /* Let C++ handle C++ virtual functions. */
8503 return cp_fold_obj_type_ref (ref, known_type);
8504 #else
8505 /* For plain ObjC, we currently do not need to do anything. */
8506 return NULL_TREE;
8507 #endif
8510 static void
8511 objc_start_function (tree name, tree type, tree attrs,
8512 #ifdef OBJCPLUS
8513 tree params
8514 #else
8515 struct c_arg_info *params
8516 #endif
8519 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8521 #ifdef OBJCPLUS
8522 DECL_ARGUMENTS (fndecl) = params;
8523 DECL_INITIAL (fndecl) = error_mark_node;
8524 DECL_EXTERNAL (fndecl) = 0;
8525 TREE_STATIC (fndecl) = 1;
8526 retrofit_lang_decl (fndecl);
8527 cplus_decl_attributes (&fndecl, attrs, 0);
8528 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8529 #else
8530 struct c_label_context_se *nstack_se;
8531 struct c_label_context_vm *nstack_vm;
8532 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8533 nstack_se->labels_def = NULL;
8534 nstack_se->labels_used = NULL;
8535 nstack_se->next = label_context_stack_se;
8536 label_context_stack_se = nstack_se;
8537 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8538 nstack_vm->labels_def = NULL;
8539 nstack_vm->labels_used = NULL;
8540 nstack_vm->scope = 0;
8541 nstack_vm->next = label_context_stack_vm;
8542 label_context_stack_vm = nstack_vm;
8543 current_function_returns_value = 0; /* Assume, until we see it does. */
8544 current_function_returns_null = 0;
8546 decl_attributes (&fndecl, attrs, 0);
8547 announce_function (fndecl);
8548 DECL_INITIAL (fndecl) = error_mark_node;
8549 DECL_EXTERNAL (fndecl) = 0;
8550 TREE_STATIC (fndecl) = 1;
8551 current_function_decl = pushdecl (fndecl);
8552 push_scope ();
8553 declare_parm_level ();
8554 DECL_RESULT (current_function_decl)
8555 = build_decl (RESULT_DECL, NULL_TREE,
8556 TREE_TYPE (TREE_TYPE (current_function_decl)));
8557 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8558 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8559 start_fname_decls ();
8560 store_parm_decls_from (params);
8561 #endif
8563 TREE_USED (current_function_decl) = 1;
8566 /* - Generate an identifier for the function. the format is "_n_cls",
8567 where 1 <= n <= nMethods, and cls is the name the implementation we
8568 are processing.
8569 - Install the return type from the method declaration.
8570 - If we have a prototype, check for type consistency. */
8572 static void
8573 really_start_method (tree method,
8574 #ifdef OBJCPLUS
8575 tree parmlist
8576 #else
8577 struct c_arg_info *parmlist
8578 #endif
8581 tree ret_type, meth_type;
8582 tree method_id;
8583 const char *sel_name, *class_name, *cat_name;
8584 char *buf;
8586 /* Synth the storage class & assemble the return type. */
8587 ret_type = TREE_VALUE (TREE_TYPE (method));
8589 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8590 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8591 cat_name = ((TREE_CODE (objc_implementation_context)
8592 == CLASS_IMPLEMENTATION_TYPE)
8593 ? NULL
8594 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8595 method_slot++;
8597 /* Make sure this is big enough for any plausible method label. */
8598 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8599 + (cat_name ? strlen (cat_name) : 0));
8601 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8602 class_name, cat_name, sel_name, method_slot);
8604 method_id = get_identifier (buf);
8606 #ifdef OBJCPLUS
8607 /* Objective-C methods cannot be overloaded, so we don't need
8608 the type encoding appended. It looks bad anyway... */
8609 push_lang_context (lang_name_c);
8610 #endif
8612 meth_type
8613 = build_function_type (ret_type,
8614 get_arg_type_list (method, METHOD_DEF, 0));
8615 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8617 /* Set self_decl from the first argument. */
8618 self_decl = DECL_ARGUMENTS (current_function_decl);
8620 /* Suppress unused warnings. */
8621 TREE_USED (self_decl) = 1;
8622 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8623 #ifdef OBJCPLUS
8624 pop_lang_context ();
8625 #endif
8627 METHOD_DEFINITION (method) = current_function_decl;
8629 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8631 if (implementation_template != objc_implementation_context)
8633 tree proto
8634 = lookup_method_static (implementation_template,
8635 METHOD_SEL_NAME (method),
8636 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8637 | OBJC_LOOKUP_NO_SUPER));
8639 if (proto)
8641 if (!comp_proto_with_proto (method, proto, 1))
8643 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8645 warn_with_method ("conflicting types for", type, method);
8646 warn_with_method ("previous declaration of", type, proto);
8649 else
8651 /* We have a method @implementation even though we did not
8652 see a corresponding @interface declaration (which is allowed
8653 by Objective-C rules). Go ahead and place the method in
8654 the @interface anyway, so that message dispatch lookups
8655 will see it. */
8656 tree interface = implementation_template;
8658 if (TREE_CODE (objc_implementation_context)
8659 == CATEGORY_IMPLEMENTATION_TYPE)
8660 interface = lookup_category
8661 (interface,
8662 CLASS_SUPER_NAME (objc_implementation_context));
8664 if (interface)
8665 objc_add_method (interface, copy_node (method),
8666 TREE_CODE (method) == CLASS_METHOD_DECL);
8671 static void *UOBJC_SUPER_scope = 0;
8673 /* _n_Method (id self, SEL sel, ...)
8675 struct objc_super _S;
8676 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8677 } */
8679 static tree
8680 get_super_receiver (void)
8682 if (objc_method_context)
8684 tree super_expr, super_expr_list;
8686 if (!UOBJC_SUPER_decl)
8688 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8689 objc_super_template);
8690 /* This prevents `unused variable' warnings when compiling with -Wall. */
8691 TREE_USED (UOBJC_SUPER_decl) = 1;
8692 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8693 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8694 UOBJC_SUPER_scope = objc_get_current_scope ();
8697 /* Set receiver to self. */
8698 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8699 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8700 super_expr_list = super_expr;
8702 /* Set class to begin searching. */
8703 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8704 get_identifier ("super_class"));
8706 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8708 /* [_cls, __cls]Super are "pre-built" in
8709 synth_forward_declarations. */
8711 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8712 ((TREE_CODE (objc_method_context)
8713 == INSTANCE_METHOD_DECL)
8714 ? ucls_super_ref
8715 : uucls_super_ref));
8718 else
8719 /* We have a category. */
8721 tree super_name = CLASS_SUPER_NAME (implementation_template);
8722 tree super_class;
8724 /* Barf if super used in a category of Object. */
8725 if (!super_name)
8727 error ("no super class declared in interface for %qs",
8728 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8729 return error_mark_node;
8732 if (flag_next_runtime && !flag_zero_link)
8734 super_class = objc_get_class_reference (super_name);
8735 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8736 /* If we are in a class method, we must retrieve the
8737 _metaclass_ for the current class, pointed at by
8738 the class's "isa" pointer. The following assumes that
8739 "isa" is the first ivar in a class (which it must be). */
8740 super_class
8741 = build_indirect_ref
8742 (build_c_cast (build_pointer_type (objc_class_type),
8743 super_class), "unary *");
8745 else
8747 add_class_reference (super_name);
8748 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8749 ? objc_get_class_decl : objc_get_meta_class_decl);
8750 assemble_external (super_class);
8751 super_class
8752 = build_function_call
8753 (super_class,
8754 build_tree_list
8755 (NULL_TREE,
8756 my_build_string_pointer
8757 (IDENTIFIER_LENGTH (super_name) + 1,
8758 IDENTIFIER_POINTER (super_name))));
8761 super_expr
8762 = build_modify_expr (super_expr, NOP_EXPR,
8763 build_c_cast (TREE_TYPE (super_expr),
8764 super_class));
8767 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8769 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8770 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8772 return super_expr_list;
8774 else
8776 error ("[super ...] must appear in a method context");
8777 return error_mark_node;
8781 /* When exiting a scope, sever links to a 'super' declaration (if any)
8782 therein contained. */
8784 void
8785 objc_clear_super_receiver (void)
8787 if (objc_method_context
8788 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8789 UOBJC_SUPER_decl = 0;
8790 UOBJC_SUPER_scope = 0;
8794 void
8795 objc_finish_method_definition (tree fndecl)
8797 /* We cannot validly inline ObjC methods, at least not without a language
8798 extension to declare that a method need not be dynamically
8799 dispatched, so suppress all thoughts of doing so. */
8800 DECL_INLINE (fndecl) = 0;
8801 DECL_UNINLINABLE (fndecl) = 1;
8803 #ifndef OBJCPLUS
8804 /* The C++ front-end will have called finish_function() for us. */
8805 finish_function ();
8806 #endif
8808 METHOD_ENCODING (objc_method_context)
8809 = encode_method_prototype (objc_method_context);
8811 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8812 since the optimizer may find "may be used before set" errors. */
8813 objc_method_context = NULL_TREE;
8815 if (should_call_super_dealloc)
8816 warning (0, "method possibly missing a [super dealloc] call");
8819 #if 0
8821 lang_report_error_function (tree decl)
8823 if (objc_method_context)
8825 fprintf (stderr, "In method %qs\n",
8826 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8827 return 1;
8830 else
8831 return 0;
8833 #endif
8835 /* Given a tree DECL node, produce a printable description of it in the given
8836 buffer, overwriting the buffer. */
8838 static char *
8839 gen_declaration (tree decl)
8841 errbuf[0] = '\0';
8843 if (DECL_P (decl))
8845 gen_type_name_0 (TREE_TYPE (decl));
8847 if (DECL_NAME (decl))
8849 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8850 strcat (errbuf, " ");
8852 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8855 if (DECL_INITIAL (decl)
8856 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8857 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8858 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8861 return errbuf;
8864 /* Given a tree TYPE node, produce a printable description of it in the given
8865 buffer, overwriting the buffer. */
8867 static char *
8868 gen_type_name_0 (tree type)
8870 tree orig = type, proto;
8872 if (TYPE_P (type) && TYPE_NAME (type))
8873 type = TYPE_NAME (type);
8874 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8876 tree inner = TREE_TYPE (type);
8878 while (TREE_CODE (inner) == ARRAY_TYPE)
8879 inner = TREE_TYPE (inner);
8881 gen_type_name_0 (inner);
8883 if (!POINTER_TYPE_P (inner))
8884 strcat (errbuf, " ");
8886 if (POINTER_TYPE_P (type))
8887 strcat (errbuf, "*");
8888 else
8889 while (type != inner)
8891 strcat (errbuf, "[");
8893 if (TYPE_DOMAIN (type))
8895 char sz[20];
8897 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8898 (TREE_INT_CST_LOW
8899 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8900 strcat (errbuf, sz);
8903 strcat (errbuf, "]");
8904 type = TREE_TYPE (type);
8907 goto exit_function;
8910 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8911 type = DECL_NAME (type);
8913 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8914 ? IDENTIFIER_POINTER (type)
8915 : "");
8917 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8918 if (objc_is_id (orig))
8919 orig = TREE_TYPE (orig);
8921 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8923 if (proto)
8925 strcat (errbuf, " <");
8927 while (proto) {
8928 strcat (errbuf,
8929 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8930 proto = TREE_CHAIN (proto);
8931 strcat (errbuf, proto ? ", " : ">");
8935 exit_function:
8936 return errbuf;
8939 static char *
8940 gen_type_name (tree type)
8942 errbuf[0] = '\0';
8944 return gen_type_name_0 (type);
8947 /* Given a method tree, put a printable description into the given
8948 buffer (overwriting) and return a pointer to the buffer. */
8950 static char *
8951 gen_method_decl (tree method)
8953 tree chain;
8955 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8956 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8957 strcat (errbuf, ")");
8958 chain = METHOD_SEL_ARGS (method);
8960 if (chain)
8962 /* We have a chain of keyword_decls. */
8965 if (KEYWORD_KEY_NAME (chain))
8966 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8968 strcat (errbuf, ":(");
8969 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8970 strcat (errbuf, ")");
8972 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8973 if ((chain = TREE_CHAIN (chain)))
8974 strcat (errbuf, " ");
8976 while (chain);
8978 if (METHOD_ADD_ARGS (method))
8980 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8982 /* Know we have a chain of parm_decls. */
8983 while (chain)
8985 strcat (errbuf, ", ");
8986 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8987 chain = TREE_CHAIN (chain);
8990 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8991 strcat (errbuf, ", ...");
8995 else
8996 /* We have a unary selector. */
8997 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8999 return errbuf;
9002 /* Debug info. */
9005 /* Dump an @interface declaration of the supplied class CHAIN to the
9006 supplied file FP. Used to implement the -gen-decls option (which
9007 prints out an @interface declaration of all classes compiled in
9008 this run); potentially useful for debugging the compiler too. */
9009 static void
9010 dump_interface (FILE *fp, tree chain)
9012 /* FIXME: A heap overflow here whenever a method (or ivar)
9013 declaration is so long that it doesn't fit in the buffer. The
9014 code and all the related functions should be rewritten to avoid
9015 using fixed size buffers. */
9016 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9017 tree ivar_decls = CLASS_RAW_IVARS (chain);
9018 tree nst_methods = CLASS_NST_METHODS (chain);
9019 tree cls_methods = CLASS_CLS_METHODS (chain);
9021 fprintf (fp, "\n@interface %s", my_name);
9023 /* CLASS_SUPER_NAME is used to store the superclass name for
9024 classes, and the category name for categories. */
9025 if (CLASS_SUPER_NAME (chain))
9027 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9029 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9030 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9032 fprintf (fp, " (%s)\n", name);
9034 else
9036 fprintf (fp, " : %s\n", name);
9039 else
9040 fprintf (fp, "\n");
9042 /* FIXME - the following doesn't seem to work at the moment. */
9043 if (ivar_decls)
9045 fprintf (fp, "{\n");
9048 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9049 ivar_decls = TREE_CHAIN (ivar_decls);
9051 while (ivar_decls);
9052 fprintf (fp, "}\n");
9055 while (nst_methods)
9057 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9058 nst_methods = TREE_CHAIN (nst_methods);
9061 while (cls_methods)
9063 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9064 cls_methods = TREE_CHAIN (cls_methods);
9067 fprintf (fp, "@end\n");
9070 /* Demangle function for Objective-C */
9071 static const char *
9072 objc_demangle (const char *mangled)
9074 char *demangled, *cp;
9076 if (mangled[0] == '_' &&
9077 (mangled[1] == 'i' || mangled[1] == 'c') &&
9078 mangled[2] == '_')
9080 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9081 if (mangled[1] == 'i')
9082 *cp++ = '-'; /* for instance method */
9083 else
9084 *cp++ = '+'; /* for class method */
9085 *cp++ = '['; /* opening left brace */
9086 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9087 while (*cp && *cp == '_')
9088 cp++; /* skip any initial underbars in class name */
9089 cp = strchr(cp, '_'); /* find first non-initial underbar */
9090 if (cp == NULL)
9092 free(demangled); /* not mangled name */
9093 return mangled;
9095 if (cp[1] == '_') /* easy case: no category name */
9097 *cp++ = ' '; /* replace two '_' with one ' ' */
9098 strcpy(cp, mangled + (cp - demangled) + 2);
9100 else
9102 *cp++ = '('; /* less easy case: category name */
9103 cp = strchr(cp, '_');
9104 if (cp == 0)
9106 free(demangled); /* not mangled name */
9107 return mangled;
9109 *cp++ = ')';
9110 *cp++ = ' '; /* overwriting 1st char of method name... */
9111 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9113 while (*cp && *cp == '_')
9114 cp++; /* skip any initial underbars in method name */
9115 for (; *cp; cp++)
9116 if (*cp == '_')
9117 *cp = ':'; /* replace remaining '_' with ':' */
9118 *cp++ = ']'; /* closing right brace */
9119 *cp++ = 0; /* string terminator */
9120 return demangled;
9122 else
9123 return mangled; /* not an objc mangled name */
9126 const char *
9127 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9129 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9132 static void
9133 init_objc (void)
9135 gcc_obstack_init (&util_obstack);
9136 util_firstobj = (char *) obstack_finish (&util_obstack);
9138 errbuf = XNEWVEC (char, 1024 * 10);
9139 hash_init ();
9140 synth_module_prologue ();
9143 static void
9144 finish_objc (void)
9146 struct imp_entry *impent;
9147 tree chain;
9148 /* The internally generated initializers appear to have missing braces.
9149 Don't warn about this. */
9150 int save_warn_missing_braces = warn_missing_braces;
9151 warn_missing_braces = 0;
9153 /* A missing @end may not be detected by the parser. */
9154 if (objc_implementation_context)
9156 warning (0, "%<@end%> missing in implementation context");
9157 finish_class (objc_implementation_context);
9158 objc_ivar_chain = NULL_TREE;
9159 objc_implementation_context = NULL_TREE;
9162 /* Process the static instances here because initialization of objc_symtab
9163 depends on them. */
9164 if (objc_static_instances)
9165 generate_static_references ();
9167 if (imp_list || class_names_chain
9168 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9169 generate_objc_symtab_decl ();
9171 for (impent = imp_list; impent; impent = impent->next)
9173 objc_implementation_context = impent->imp_context;
9174 implementation_template = impent->imp_template;
9176 UOBJC_CLASS_decl = impent->class_decl;
9177 UOBJC_METACLASS_decl = impent->meta_decl;
9179 /* Dump the @interface of each class as we compile it, if the
9180 -gen-decls option is in use. TODO: Dump the classes in the
9181 order they were found, rather than in reverse order as we
9182 are doing now. */
9183 if (flag_gen_declaration)
9185 dump_interface (gen_declaration_file, objc_implementation_context);
9188 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9190 /* all of the following reference the string pool... */
9191 generate_ivar_lists ();
9192 generate_dispatch_tables ();
9193 generate_shared_structures (impent->has_cxx_cdtors
9194 ? CLS_HAS_CXX_STRUCTORS
9195 : 0);
9197 else
9199 generate_dispatch_tables ();
9200 generate_category (objc_implementation_context);
9204 /* If we are using an array of selectors, we must always
9205 finish up the array decl even if no selectors were used. */
9206 if (! flag_next_runtime || sel_ref_chain)
9207 build_selector_translation_table ();
9209 if (protocol_chain)
9210 generate_protocols ();
9212 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9213 generate_objc_image_info ();
9215 /* Arrange for ObjC data structures to be initialized at run time. */
9216 if (objc_implementation_context || class_names_chain || objc_static_instances
9217 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9219 build_module_descriptor ();
9221 if (!flag_next_runtime)
9222 build_module_initializer_routine ();
9225 /* Dump the class references. This forces the appropriate classes
9226 to be linked into the executable image, preserving unix archive
9227 semantics. This can be removed when we move to a more dynamically
9228 linked environment. */
9230 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9232 handle_class_ref (chain);
9233 if (TREE_PURPOSE (chain))
9234 generate_classref_translation_entry (chain);
9237 for (impent = imp_list; impent; impent = impent->next)
9238 handle_impent (impent);
9240 if (warn_selector)
9242 int slot;
9243 hash hsh;
9245 /* Run through the selector hash tables and print a warning for any
9246 selector which has multiple methods. */
9248 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9250 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9251 check_duplicates (hsh, 0, 1);
9252 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9253 check_duplicates (hsh, 0, 1);
9257 warn_missing_braces = save_warn_missing_braces;
9260 /* Subroutines of finish_objc. */
9262 static void
9263 generate_classref_translation_entry (tree chain)
9265 tree expr, decl, type;
9267 decl = TREE_PURPOSE (chain);
9268 type = TREE_TYPE (decl);
9270 expr = add_objc_string (TREE_VALUE (chain), class_names);
9271 expr = convert (type, expr); /* cast! */
9273 /* The decl that is the one that we
9274 forward declared in build_class_reference. */
9275 finish_var_decl (decl, expr);
9276 return;
9279 static void
9280 handle_class_ref (tree chain)
9282 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9283 char *string = (char *) alloca (strlen (name) + 30);
9284 tree decl;
9285 tree exp;
9287 sprintf (string, "%sobjc_class_name_%s",
9288 (flag_next_runtime ? "." : "__"), name);
9290 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9291 if (flag_next_runtime)
9293 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9294 return;
9296 #endif
9298 /* Make a decl for this name, so we can use its address in a tree. */
9299 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9300 DECL_EXTERNAL (decl) = 1;
9301 TREE_PUBLIC (decl) = 1;
9303 pushdecl (decl);
9304 rest_of_decl_compilation (decl, 0, 0);
9306 /* Make a decl for the address. */
9307 sprintf (string, "%sobjc_class_ref_%s",
9308 (flag_next_runtime ? "." : "__"), name);
9309 exp = build1 (ADDR_EXPR, string_type_node, decl);
9310 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9311 DECL_INITIAL (decl) = exp;
9312 TREE_STATIC (decl) = 1;
9313 TREE_USED (decl) = 1;
9314 /* Force the output of the decl as this forces the reference of the class. */
9315 mark_decl_referenced (decl);
9317 pushdecl (decl);
9318 rest_of_decl_compilation (decl, 0, 0);
9321 static void
9322 handle_impent (struct imp_entry *impent)
9324 char *string;
9326 objc_implementation_context = impent->imp_context;
9327 implementation_template = impent->imp_template;
9329 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9331 const char *const class_name =
9332 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9334 string = (char *) alloca (strlen (class_name) + 30);
9336 sprintf (string, "%sobjc_class_name_%s",
9337 (flag_next_runtime ? "." : "__"), class_name);
9339 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9341 const char *const class_name =
9342 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9343 const char *const class_super_name =
9344 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9346 string = (char *) alloca (strlen (class_name)
9347 + strlen (class_super_name) + 30);
9349 /* Do the same for categories. Even though no references to
9350 these symbols are generated automatically by the compiler, it
9351 gives you a handle to pull them into an archive by hand. */
9352 sprintf (string, "*%sobjc_category_name_%s_%s",
9353 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9355 else
9356 return;
9358 #ifdef ASM_DECLARE_CLASS_REFERENCE
9359 if (flag_next_runtime)
9361 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9362 return;
9364 else
9365 #endif
9367 tree decl, init;
9369 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9370 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9371 TREE_PUBLIC (decl) = 1;
9372 TREE_READONLY (decl) = 1;
9373 TREE_USED (decl) = 1;
9374 TREE_CONSTANT (decl) = 1;
9375 DECL_CONTEXT (decl) = 0;
9376 DECL_ARTIFICIAL (decl) = 1;
9377 DECL_INITIAL (decl) = init;
9378 assemble_variable (decl, 1, 0, 0);
9382 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9383 later requires that ObjC translation units participating in F&C be
9384 specially marked. The following routine accomplishes this. */
9386 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9388 static void
9389 generate_objc_image_info (void)
9391 tree decl, initlist;
9392 int flags
9393 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9394 | (flag_objc_gc ? 2 : 0));
9396 decl = start_var_decl (build_array_type
9397 (integer_type_node,
9398 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9399 "_OBJC_IMAGE_INFO");
9401 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9402 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9403 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9405 finish_var_decl (decl, initlist);
9408 /* Look up ID as an instance variable. OTHER contains the result of
9409 the C or C++ lookup, which we may want to use instead. */
9411 tree
9412 objc_lookup_ivar (tree other, tree id)
9414 tree ivar;
9416 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9417 if (!objc_method_context)
9418 return other;
9420 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9421 /* We have a message to super. */
9422 return get_super_receiver ();
9424 /* In a class method, look up an instance variable only as a last
9425 resort. */
9426 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9427 && other && other != error_mark_node)
9428 return other;
9430 /* Look up the ivar, but do not use it if it is not accessible. */
9431 ivar = is_ivar (objc_ivar_chain, id);
9433 if (!ivar || is_private (ivar))
9434 return other;
9436 /* In an instance method, a local variable (or parameter) may hide the
9437 instance variable. */
9438 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9439 && other && other != error_mark_node
9440 #ifdef OBJCPLUS
9441 && CP_DECL_CONTEXT (other) != global_namespace)
9442 #else
9443 && !DECL_FILE_SCOPE_P (other))
9444 #endif
9446 warning (0, "local declaration of %qs hides instance variable",
9447 IDENTIFIER_POINTER (id));
9449 return other;
9452 /* At this point, we are either in an instance method with no obscuring
9453 local definitions, or in a class method with no alternate definitions
9454 at all. */
9455 return build_ivar_reference (id);
9458 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9459 needs to be done if we are calling a function through a cast. */
9461 tree
9462 objc_rewrite_function_call (tree function, tree params)
9464 if (TREE_CODE (function) == NOP_EXPR
9465 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9466 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9467 == FUNCTION_DECL)
9469 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9470 TREE_OPERAND (function, 0),
9471 TREE_VALUE (params), size_zero_node);
9474 return function;
9477 /* Look for the special case of OBJC_TYPE_REF with the address of
9478 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9479 of its cousins). */
9481 enum gimplify_status
9482 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9484 enum gimplify_status r0, r1;
9485 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9486 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9487 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9488 == FUNCTION_DECL)
9490 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9491 value of the OBJ_TYPE_REF, so force them to be emitted
9492 during subexpression evaluation rather than after the
9493 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9494 C to use direct rather than indirect calls when the
9495 object expression has a postincrement. */
9496 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9497 is_gimple_val, fb_rvalue);
9498 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9499 is_gimple_val, fb_rvalue);
9501 return MIN (r0, r1);
9504 #ifdef OBJCPLUS
9505 return cp_gimplify_expr (expr_p, pre_p, post_p);
9506 #else
9507 return c_gimplify_expr (expr_p, pre_p, post_p);
9508 #endif
9511 /* Given a CALL expression, find the function being called. The ObjC
9512 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9514 tree
9515 objc_get_callee_fndecl (tree call_expr)
9517 tree addr = CALL_EXPR_FN (call_expr);
9518 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9519 return 0;
9521 addr = OBJ_TYPE_REF_EXPR (addr);
9523 /* If the address is just `&f' for some function `f', then we know
9524 that `f' is being called. */
9525 if (TREE_CODE (addr) == ADDR_EXPR
9526 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9527 return TREE_OPERAND (addr, 0);
9529 return 0;
9532 #include "gt-objc-objc-act.h"