* objc/objc-act.c: Fix comment typos.
[official-gcc.git] / gcc / objc / objc-act.c
blob0cbd759e9d4dc05b9ae8423407bfe298f6b54227
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 volatile _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_THIS_VOLATILE (rethrow_decl) = 1;
3690 TREE_CHAIN (rethrow_decl) = stack_decl;
3692 /* Build the outermost variable binding level. */
3693 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3694 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3695 TREE_SIDE_EFFECTS (bind) = 1;
3697 /* Initialize rethrow_decl. */
3698 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3699 convert (objc_object_type, null_pointer_node));
3700 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3701 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3703 /* Build the outermost TRY_FINALLY_EXPR. */
3704 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3705 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3706 TREE_SIDE_EFFECTS (try_fin) = 1;
3707 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3709 /* Create the complete catch sequence. */
3710 if (cur_try_context->catch_list)
3712 tree caught_decl = objc_build_exc_ptr ();
3713 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3714 TREE_SIDE_EFFECTS (catch_seq) = 1;
3716 t = next_sjlj_build_exc_extract (caught_decl);
3717 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3719 t = next_sjlj_build_enter_and_setjmp ();
3720 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3721 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3722 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3724 else
3725 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3726 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3728 /* Build the main register-and-try if statement. */
3729 t = next_sjlj_build_enter_and_setjmp ();
3730 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3731 COND_EXPR_THEN (t) = catch_seq;
3732 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3733 TREE_OPERAND (try_fin, 0) = t;
3735 /* Build the complete FINALLY statement list. */
3736 t = next_sjlj_build_try_exit ();
3737 t = build_stmt (COND_EXPR,
3738 c_common_truthvalue_conversion (rethrow_decl),
3739 NULL, t);
3740 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3741 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3743 append_to_statement_list (cur_try_context->finally_body,
3744 &TREE_OPERAND (try_fin, 1));
3746 t = tree_cons (NULL, rethrow_decl, NULL);
3747 t = build_function_call (objc_exception_throw_decl, t);
3748 t = build_stmt (COND_EXPR,
3749 c_common_truthvalue_conversion (rethrow_decl),
3750 t, NULL);
3751 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3752 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3754 return bind;
3757 /* Called just after parsing the @try and its associated BODY. We now
3758 must prepare for the tricky bits -- handling the catches and finally. */
3760 void
3761 objc_begin_try_stmt (location_t try_locus, tree body)
3763 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3764 c->outer = cur_try_context;
3765 c->try_body = body;
3766 c->try_locus = try_locus;
3767 c->end_try_locus = input_location;
3768 cur_try_context = c;
3770 objc_init_exceptions ();
3772 if (flag_objc_sjlj_exceptions)
3773 objc_mark_locals_volatile (NULL);
3776 /* Called just after parsing "@catch (parm)". Open a binding level,
3777 enter DECL into the binding level, and initialize it. Leave the
3778 binding level open while the body of the compound statement is parsed. */
3780 void
3781 objc_begin_catch_clause (tree decl)
3783 tree compound, type, t;
3785 /* Begin a new scope that the entire catch clause will live in. */
3786 compound = c_begin_compound_stmt (true);
3788 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3789 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3790 lang_hooks.decls.pushdecl (decl);
3792 /* Since a decl is required here by syntax, don't warn if its unused. */
3793 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3794 be what the previous objc implementation did. */
3795 TREE_USED (decl) = 1;
3797 /* Verify that the type of the catch is valid. It must be a pointer
3798 to an Objective-C class, or "id" (which is catch-all). */
3799 type = TREE_TYPE (decl);
3801 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3802 type = NULL;
3803 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3805 error ("@catch parameter is not a known Objective-C class type");
3806 type = error_mark_node;
3808 else if (cur_try_context->catch_list)
3810 /* Examine previous @catch clauses and see if we've already
3811 caught the type in question. */
3812 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3813 for (; !tsi_end_p (i); tsi_next (&i))
3815 tree stmt = tsi_stmt (i);
3816 t = CATCH_TYPES (stmt);
3817 if (t == error_mark_node)
3818 continue;
3819 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3821 warning (0, "exception of type %<%T%> will be caught",
3822 TREE_TYPE (type));
3823 warning (0, "%H by earlier handler for %<%T%>",
3824 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3825 break;
3830 /* Record the data for the catch in the try context so that we can
3831 finalize it later. */
3832 t = build_stmt (CATCH_EXPR, type, compound);
3833 cur_try_context->current_catch = t;
3835 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3836 t = objc_build_exc_ptr ();
3837 t = convert (TREE_TYPE (decl), t);
3838 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3839 add_stmt (t);
3842 /* Called just after parsing the closing brace of a @catch clause. Close
3843 the open binding level, and record a CATCH_EXPR for it. */
3845 void
3846 objc_finish_catch_clause (void)
3848 tree c = cur_try_context->current_catch;
3849 cur_try_context->current_catch = NULL;
3850 cur_try_context->end_catch_locus = input_location;
3852 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3853 append_to_statement_list (c, &cur_try_context->catch_list);
3856 /* Called after parsing a @finally clause and its associated BODY.
3857 Record the body for later placement. */
3859 void
3860 objc_build_finally_clause (location_t finally_locus, tree body)
3862 cur_try_context->finally_body = body;
3863 cur_try_context->finally_locus = finally_locus;
3864 cur_try_context->end_finally_locus = input_location;
3867 /* Called to finalize a @try construct. */
3869 tree
3870 objc_finish_try_stmt (void)
3872 struct objc_try_context *c = cur_try_context;
3873 tree stmt;
3875 if (c->catch_list == NULL && c->finally_body == NULL)
3876 error ("%<@try%> without %<@catch%> or %<@finally%>");
3878 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3879 if (flag_objc_sjlj_exceptions)
3881 if (!cur_try_context->finally_body)
3883 cur_try_context->finally_locus = input_location;
3884 cur_try_context->end_finally_locus = input_location;
3886 stmt = next_sjlj_build_try_catch_finally ();
3888 else
3890 /* Otherwise, nest the CATCH inside a FINALLY. */
3891 stmt = c->try_body;
3892 if (c->catch_list)
3894 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3895 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3897 if (c->finally_body)
3899 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3900 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3903 add_stmt (stmt);
3905 cur_try_context = c->outer;
3906 free (c);
3907 return stmt;
3910 tree
3911 objc_build_throw_stmt (tree throw_expr)
3913 tree args;
3915 objc_init_exceptions ();
3917 if (throw_expr == NULL)
3919 /* If we're not inside a @catch block, there is no "current
3920 exception" to be rethrown. */
3921 if (cur_try_context == NULL
3922 || cur_try_context->current_catch == NULL)
3924 error ("%<@throw%> (rethrow) used outside of a @catch block");
3925 return NULL_TREE;
3928 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3929 value that we get from the runtime. */
3930 throw_expr = objc_build_exc_ptr ();
3933 /* A throw is just a call to the runtime throw function with the
3934 object as a parameter. */
3935 args = tree_cons (NULL, throw_expr, NULL);
3936 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3939 tree
3940 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3942 tree args, call;
3944 /* First lock the mutex. */
3945 mutex = save_expr (mutex);
3946 args = tree_cons (NULL, mutex, NULL);
3947 call = build_function_call (objc_sync_enter_decl, args);
3948 SET_EXPR_LOCATION (call, start_locus);
3949 add_stmt (call);
3951 /* Build the mutex unlock. */
3952 args = tree_cons (NULL, mutex, NULL);
3953 call = build_function_call (objc_sync_exit_decl, args);
3954 SET_EXPR_LOCATION (call, input_location);
3956 /* Put the that and the body in a TRY_FINALLY. */
3957 objc_begin_try_stmt (start_locus, body);
3958 objc_build_finally_clause (input_location, call);
3959 return objc_finish_try_stmt ();
3963 /* Predefine the following data type:
3965 struct _objc_exception_data
3967 int buf[OBJC_JBLEN];
3968 void *pointers[4];
3969 }; */
3971 /* The following yuckiness should prevent users from having to #include
3972 <setjmp.h> in their code... */
3974 /* Define to a harmless positive value so the below code doesn't die. */
3975 #ifndef OBJC_JBLEN
3976 #define OBJC_JBLEN 18
3977 #endif
3979 static void
3980 build_next_objc_exception_stuff (void)
3982 tree field_decl, field_decl_chain, index, temp_type;
3984 objc_exception_data_template
3985 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3987 /* int buf[OBJC_JBLEN]; */
3989 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3990 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3991 "buf");
3992 field_decl_chain = field_decl;
3994 /* void *pointers[4]; */
3996 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3997 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3998 "pointers");
3999 chainon (field_decl_chain, field_decl);
4001 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
4003 /* int _setjmp(...); */
4004 /* If the user includes <setjmp.h>, this shall be superseded by
4005 'int _setjmp(jmp_buf);' */
4006 temp_type = build_function_type (integer_type_node, NULL_TREE);
4007 objc_setjmp_decl
4008 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4010 /* id objc_exception_extract(struct _objc_exception_data *); */
4011 temp_type
4012 = build_function_type (objc_object_type,
4013 tree_cons (NULL_TREE,
4014 build_pointer_type (objc_exception_data_template),
4015 OBJC_VOID_AT_END));
4016 objc_exception_extract_decl
4017 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4018 NULL_TREE);
4019 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4020 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4021 temp_type
4022 = build_function_type (void_type_node,
4023 tree_cons (NULL_TREE,
4024 build_pointer_type (objc_exception_data_template),
4025 OBJC_VOID_AT_END));
4026 objc_exception_try_enter_decl
4027 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4028 NULL_TREE);
4029 objc_exception_try_exit_decl
4030 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4031 NULL_TREE);
4033 /* int objc_exception_match(id, id); */
4034 temp_type
4035 = build_function_type (integer_type_node,
4036 tree_cons (NULL_TREE, objc_object_type,
4037 tree_cons (NULL_TREE, objc_object_type,
4038 OBJC_VOID_AT_END)));
4039 objc_exception_match_decl
4040 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4041 NULL_TREE);
4043 /* id objc_assign_ivar (id, id, unsigned int); */
4044 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4045 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4046 temp_type
4047 = build_function_type (objc_object_type,
4048 tree_cons
4049 (NULL_TREE, objc_object_type,
4050 tree_cons (NULL_TREE, objc_object_type,
4051 tree_cons (NULL_TREE,
4052 unsigned_type_node,
4053 OBJC_VOID_AT_END))));
4054 objc_assign_ivar_decl
4055 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4056 NULL, NULL_TREE);
4057 #ifdef OFFS_ASSIGNIVAR_FAST
4058 objc_assign_ivar_fast_decl
4059 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4060 NOT_BUILT_IN, NULL, NULL_TREE);
4061 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4062 = tree_cons (get_identifier ("hard_coded_address"),
4063 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4064 NULL_TREE);
4065 #else
4066 /* Default to slower ivar method. */
4067 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4068 #endif
4070 /* id objc_assign_global (id, id *); */
4071 /* id objc_assign_strongCast (id, id *); */
4072 temp_type = build_function_type (objc_object_type,
4073 tree_cons (NULL_TREE, objc_object_type,
4074 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4075 OBJC_VOID_AT_END)));
4076 objc_assign_global_decl
4077 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4078 NULL_TREE);
4079 objc_assign_strong_cast_decl
4080 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4081 NULL_TREE);
4084 static void
4085 build_objc_exception_stuff (void)
4087 tree noreturn_list, nothrow_list, temp_type;
4089 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4090 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4092 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4093 /* void objc_sync_enter(id); */
4094 /* void objc_sync_exit(id); */
4095 temp_type = build_function_type (void_type_node,
4096 tree_cons (NULL_TREE, objc_object_type,
4097 OBJC_VOID_AT_END));
4098 objc_exception_throw_decl
4099 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4100 noreturn_list);
4101 objc_sync_enter_decl
4102 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4103 NULL, nothrow_list);
4104 objc_sync_exit_decl
4105 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4106 NULL, nothrow_list);
4109 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4110 name as the class:
4112 struct <classname> {
4113 struct _objc_class *isa;
4115 }; */
4117 static void
4118 build_private_template (tree class)
4120 if (!CLASS_STATIC_TEMPLATE (class))
4122 tree record = objc_build_struct (class,
4123 get_class_ivars (class, false),
4124 CLASS_SUPER_NAME (class));
4126 /* Set the TREE_USED bit for this struct, so that stab generator
4127 can emit stabs for this struct type. */
4128 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4129 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4133 /* Begin code generation for protocols... */
4135 /* struct _objc_protocol {
4136 struct _objc_class *isa;
4137 char *protocol_name;
4138 struct _objc_protocol **protocol_list;
4139 struct _objc__method_prototype_list *instance_methods;
4140 struct _objc__method_prototype_list *class_methods;
4141 }; */
4143 static void
4144 build_protocol_template (void)
4146 tree field_decl, field_decl_chain;
4148 objc_protocol_template = start_struct (RECORD_TYPE,
4149 get_identifier (UTAG_PROTOCOL));
4151 /* struct _objc_class *isa; */
4152 field_decl = create_field_decl (build_pointer_type
4153 (xref_tag (RECORD_TYPE,
4154 get_identifier (UTAG_CLASS))),
4155 "isa");
4156 field_decl_chain = field_decl;
4158 /* char *protocol_name; */
4159 field_decl = create_field_decl (string_type_node, "protocol_name");
4160 chainon (field_decl_chain, field_decl);
4162 /* struct _objc_protocol **protocol_list; */
4163 field_decl = create_field_decl (build_pointer_type
4164 (build_pointer_type
4165 (objc_protocol_template)),
4166 "protocol_list");
4167 chainon (field_decl_chain, field_decl);
4169 /* struct _objc__method_prototype_list *instance_methods; */
4170 field_decl = create_field_decl (objc_method_proto_list_ptr,
4171 "instance_methods");
4172 chainon (field_decl_chain, field_decl);
4174 /* struct _objc__method_prototype_list *class_methods; */
4175 field_decl = create_field_decl (objc_method_proto_list_ptr,
4176 "class_methods");
4177 chainon (field_decl_chain, field_decl);
4179 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4182 static tree
4183 build_descriptor_table_initializer (tree type, tree entries)
4185 tree initlist = NULL_TREE;
4189 tree eltlist = NULL_TREE;
4191 eltlist
4192 = tree_cons (NULL_TREE,
4193 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4194 eltlist
4195 = tree_cons (NULL_TREE,
4196 add_objc_string (METHOD_ENCODING (entries),
4197 meth_var_types),
4198 eltlist);
4200 initlist
4201 = tree_cons (NULL_TREE,
4202 objc_build_constructor (type, nreverse (eltlist)),
4203 initlist);
4205 entries = TREE_CHAIN (entries);
4207 while (entries);
4209 return objc_build_constructor (build_array_type (type, 0),
4210 nreverse (initlist));
4213 /* struct objc_method_prototype_list {
4214 int count;
4215 struct objc_method_prototype {
4216 SEL name;
4217 char *types;
4218 } list[1];
4219 }; */
4221 static tree
4222 build_method_prototype_list_template (tree list_type, int size)
4224 tree objc_ivar_list_record;
4225 tree field_decl, field_decl_chain;
4227 /* Generate an unnamed struct definition. */
4229 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4231 /* int method_count; */
4232 field_decl = create_field_decl (integer_type_node, "method_count");
4233 field_decl_chain = field_decl;
4235 /* struct objc_method method_list[]; */
4236 field_decl = create_field_decl (build_array_type
4237 (list_type,
4238 build_index_type
4239 (build_int_cst (NULL_TREE, size - 1))),
4240 "method_list");
4241 chainon (field_decl_chain, field_decl);
4243 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4245 return objc_ivar_list_record;
4248 static tree
4249 build_method_prototype_template (void)
4251 tree proto_record;
4252 tree field_decl, field_decl_chain;
4254 proto_record
4255 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4257 /* SEL _cmd; */
4258 field_decl = create_field_decl (objc_selector_type, "_cmd");
4259 field_decl_chain = field_decl;
4261 /* char *method_types; */
4262 field_decl = create_field_decl (string_type_node, "method_types");
4263 chainon (field_decl_chain, field_decl);
4265 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4267 return proto_record;
4270 static tree
4271 objc_method_parm_type (tree type)
4273 type = TREE_VALUE (TREE_TYPE (type));
4274 if (TREE_CODE (type) == TYPE_DECL)
4275 type = TREE_TYPE (type);
4276 return type;
4279 static int
4280 objc_encoded_type_size (tree type)
4282 int sz = int_size_in_bytes (type);
4284 /* Make all integer and enum types at least as large
4285 as an int. */
4286 if (sz > 0 && INTEGRAL_TYPE_P (type))
4287 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4288 /* Treat arrays as pointers, since that's how they're
4289 passed in. */
4290 else if (TREE_CODE (type) == ARRAY_TYPE)
4291 sz = int_size_in_bytes (ptr_type_node);
4292 return sz;
4295 static tree
4296 encode_method_prototype (tree method_decl)
4298 tree parms;
4299 int parm_offset, i;
4300 char buf[40];
4301 tree result;
4303 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4304 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4306 /* Encode return type. */
4307 encode_type (objc_method_parm_type (method_decl),
4308 obstack_object_size (&util_obstack),
4309 OBJC_ENCODE_INLINE_DEFS);
4311 /* Stack size. */
4312 /* The first two arguments (self and _cmd) are pointers; account for
4313 their size. */
4314 i = int_size_in_bytes (ptr_type_node);
4315 parm_offset = 2 * i;
4316 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4317 parms = TREE_CHAIN (parms))
4319 tree type = objc_method_parm_type (parms);
4320 int sz = objc_encoded_type_size (type);
4322 /* If a type size is not known, bail out. */
4323 if (sz < 0)
4325 error ("type %q+D does not have a known size",
4326 type);
4327 /* Pretend that the encoding succeeded; the compilation will
4328 fail nevertheless. */
4329 goto finish_encoding;
4331 parm_offset += sz;
4334 sprintf (buf, "%d@0:%d", parm_offset, i);
4335 obstack_grow (&util_obstack, buf, strlen (buf));
4337 /* Argument types. */
4338 parm_offset = 2 * i;
4339 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4340 parms = TREE_CHAIN (parms))
4342 tree type = objc_method_parm_type (parms);
4344 /* Process argument qualifiers for user supplied arguments. */
4345 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4347 /* Type. */
4348 encode_type (type, obstack_object_size (&util_obstack),
4349 OBJC_ENCODE_INLINE_DEFS);
4351 /* Compute offset. */
4352 sprintf (buf, "%d", parm_offset);
4353 parm_offset += objc_encoded_type_size (type);
4355 obstack_grow (&util_obstack, buf, strlen (buf));
4358 finish_encoding:
4359 obstack_1grow (&util_obstack, '\0');
4360 result = get_identifier (obstack_finish (&util_obstack));
4361 obstack_free (&util_obstack, util_firstobj);
4362 return result;
4365 static tree
4366 generate_descriptor_table (tree type, const char *name, int size, tree list,
4367 tree proto)
4369 tree decl, initlist;
4371 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4373 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4374 initlist = tree_cons (NULL_TREE, list, initlist);
4376 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4378 return decl;
4381 static void
4382 generate_method_descriptors (tree protocol)
4384 tree initlist, chain, method_list_template;
4385 int size;
4387 if (!objc_method_prototype_template)
4388 objc_method_prototype_template = build_method_prototype_template ();
4390 chain = PROTOCOL_CLS_METHODS (protocol);
4391 if (chain)
4393 size = list_length (chain);
4395 method_list_template
4396 = build_method_prototype_list_template (objc_method_prototype_template,
4397 size);
4399 initlist
4400 = build_descriptor_table_initializer (objc_method_prototype_template,
4401 chain);
4403 UOBJC_CLASS_METHODS_decl
4404 = generate_descriptor_table (method_list_template,
4405 "_OBJC_PROTOCOL_CLASS_METHODS",
4406 size, initlist, protocol);
4408 else
4409 UOBJC_CLASS_METHODS_decl = 0;
4411 chain = PROTOCOL_NST_METHODS (protocol);
4412 if (chain)
4414 size = list_length (chain);
4416 method_list_template
4417 = build_method_prototype_list_template (objc_method_prototype_template,
4418 size);
4419 initlist
4420 = build_descriptor_table_initializer (objc_method_prototype_template,
4421 chain);
4423 UOBJC_INSTANCE_METHODS_decl
4424 = generate_descriptor_table (method_list_template,
4425 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4426 size, initlist, protocol);
4428 else
4429 UOBJC_INSTANCE_METHODS_decl = 0;
4432 static void
4433 generate_protocol_references (tree plist)
4435 tree lproto;
4437 /* Forward declare protocols referenced. */
4438 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4440 tree proto = TREE_VALUE (lproto);
4442 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4443 && PROTOCOL_NAME (proto))
4445 if (! PROTOCOL_FORWARD_DECL (proto))
4446 build_protocol_reference (proto);
4448 if (PROTOCOL_LIST (proto))
4449 generate_protocol_references (PROTOCOL_LIST (proto));
4454 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4455 current class. */
4456 #ifdef OBJCPLUS
4457 static void
4458 objc_generate_cxx_ctor_or_dtor (bool dtor)
4460 tree fn, body, compound_stmt, ivar;
4462 /* - (id) .cxx_construct { ... return self; } */
4463 /* - (void) .cxx_construct { ... } */
4465 objc_set_method_type (MINUS_EXPR);
4466 objc_start_method_definition
4467 (objc_build_method_signature (build_tree_list (NULL_TREE,
4468 dtor
4469 ? void_type_node
4470 : objc_object_type),
4471 get_identifier (dtor
4472 ? TAG_CXX_DESTRUCT
4473 : TAG_CXX_CONSTRUCT),
4474 make_node (TREE_LIST),
4475 false));
4476 body = begin_function_body ();
4477 compound_stmt = begin_compound_stmt (0);
4479 ivar = CLASS_IVARS (implementation_template);
4480 /* Destroy ivars in reverse order. */
4481 if (dtor)
4482 ivar = nreverse (copy_list (ivar));
4484 for (; ivar; ivar = TREE_CHAIN (ivar))
4486 if (TREE_CODE (ivar) == FIELD_DECL)
4488 tree type = TREE_TYPE (ivar);
4490 /* Call the ivar's default constructor or destructor. Do not
4491 call the destructor unless a corresponding constructor call
4492 has also been made (or is not needed). */
4493 if (IS_AGGR_TYPE (type)
4494 && (dtor
4495 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4496 && (!TYPE_NEEDS_CONSTRUCTING (type)
4497 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4498 : (TYPE_NEEDS_CONSTRUCTING (type)
4499 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4500 finish_expr_stmt
4501 (build_special_member_call
4502 (build_ivar_reference (DECL_NAME (ivar)),
4503 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4504 NULL_TREE, type, LOOKUP_NORMAL));
4508 /* The constructor returns 'self'. */
4509 if (!dtor)
4510 finish_return_stmt (self_decl);
4512 finish_compound_stmt (compound_stmt);
4513 finish_function_body (body);
4514 fn = current_function_decl;
4515 finish_function ();
4516 objc_finish_method_definition (fn);
4519 /* The following routine will examine the current @interface for any
4520 non-POD C++ ivars requiring non-trivial construction and/or
4521 destruction, and then synthesize special '- .cxx_construct' and/or
4522 '- .cxx_destruct' methods which will run the appropriate
4523 construction or destruction code. Note that ivars inherited from
4524 super-classes are _not_ considered. */
4525 static void
4526 objc_generate_cxx_cdtors (void)
4528 bool need_ctor = false, need_dtor = false;
4529 tree ivar;
4531 /* We do not want to do this for categories, since they do not have
4532 their own ivars. */
4534 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4535 return;
4537 /* First, determine if we even need a constructor and/or destructor. */
4539 for (ivar = CLASS_IVARS (implementation_template); ivar;
4540 ivar = TREE_CHAIN (ivar))
4542 if (TREE_CODE (ivar) == FIELD_DECL)
4544 tree type = TREE_TYPE (ivar);
4546 if (IS_AGGR_TYPE (type))
4548 if (TYPE_NEEDS_CONSTRUCTING (type)
4549 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4550 /* NB: If a default constructor is not available, we will not
4551 be able to initialize this ivar; the add_instance_variable()
4552 routine will already have warned about this. */
4553 need_ctor = true;
4555 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4556 && (!TYPE_NEEDS_CONSTRUCTING (type)
4557 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4558 /* NB: If a default constructor is not available, we will not
4559 call the destructor either, for symmetry. */
4560 need_dtor = true;
4565 /* Generate '- .cxx_construct' if needed. */
4567 if (need_ctor)
4568 objc_generate_cxx_ctor_or_dtor (false);
4570 /* Generate '- .cxx_destruct' if needed. */
4572 if (need_dtor)
4573 objc_generate_cxx_ctor_or_dtor (true);
4575 /* The 'imp_list' variable points at an imp_entry record for the current
4576 @implementation. Record the existence of '- .cxx_construct' and/or
4577 '- .cxx_destruct' methods therein; it will be included in the
4578 metadata for the class. */
4579 if (flag_next_runtime)
4580 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4582 #endif
4584 /* For each protocol which was referenced either from a @protocol()
4585 expression, or because a class/category implements it (then a
4586 pointer to the protocol is stored in the struct describing the
4587 class/category), we create a statically allocated instance of the
4588 Protocol class. The code is written in such a way as to generate
4589 as few Protocol objects as possible; we generate a unique Protocol
4590 instance for each protocol, and we don't generate a Protocol
4591 instance if the protocol is never referenced (either from a
4592 @protocol() or from a class/category implementation). These
4593 statically allocated objects can be referred to via the static
4594 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4596 The statically allocated Protocol objects that we generate here
4597 need to be fixed up at runtime in order to be used: the 'isa'
4598 pointer of the objects need to be set up to point to the 'Protocol'
4599 class, as known at runtime.
4601 The NeXT runtime fixes up all protocols at program startup time,
4602 before main() is entered. It uses a low-level trick to look up all
4603 those symbols, then loops on them and fixes them up.
4605 The GNU runtime as well fixes up all protocols before user code
4606 from the module is executed; it requires pointers to those symbols
4607 to be put in the objc_symtab (which is then passed as argument to
4608 the function __objc_exec_class() which the compiler sets up to be
4609 executed automatically when the module is loaded); setup of those
4610 Protocol objects happen in two ways in the GNU runtime: all
4611 Protocol objects referred to by a class or category implementation
4612 are fixed up when the class/category is loaded; all Protocol
4613 objects referred to by a @protocol() expression are added by the
4614 compiler to the list of statically allocated instances to fixup
4615 (the same list holding the statically allocated constant string
4616 objects). Because, as explained above, the compiler generates as
4617 few Protocol objects as possible, some Protocol object might end up
4618 being referenced multiple times when compiled with the GNU runtime,
4619 and end up being fixed up multiple times at runtime initialization.
4620 But that doesn't hurt, it's just a little inefficient. */
4622 static void
4623 generate_protocols (void)
4625 tree p, encoding;
4626 tree decl;
4627 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4629 /* If a protocol was directly referenced, pull in indirect references. */
4630 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4631 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4632 generate_protocol_references (PROTOCOL_LIST (p));
4634 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4636 tree nst_methods = PROTOCOL_NST_METHODS (p);
4637 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4639 /* If protocol wasn't referenced, don't generate any code. */
4640 decl = PROTOCOL_FORWARD_DECL (p);
4642 if (!decl)
4643 continue;
4645 /* Make sure we link in the Protocol class. */
4646 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4648 while (nst_methods)
4650 if (! METHOD_ENCODING (nst_methods))
4652 encoding = encode_method_prototype (nst_methods);
4653 METHOD_ENCODING (nst_methods) = encoding;
4655 nst_methods = TREE_CHAIN (nst_methods);
4658 while (cls_methods)
4660 if (! METHOD_ENCODING (cls_methods))
4662 encoding = encode_method_prototype (cls_methods);
4663 METHOD_ENCODING (cls_methods) = encoding;
4666 cls_methods = TREE_CHAIN (cls_methods);
4668 generate_method_descriptors (p);
4670 if (PROTOCOL_LIST (p))
4671 refs_decl = generate_protocol_list (p);
4672 else
4673 refs_decl = 0;
4675 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4676 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4678 if (refs_decl)
4679 refs_expr = convert (build_pointer_type (build_pointer_type
4680 (objc_protocol_template)),
4681 build_unary_op (ADDR_EXPR, refs_decl, 0));
4682 else
4683 refs_expr = build_int_cst (NULL_TREE, 0);
4685 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4686 by generate_method_descriptors, which is called above. */
4687 initlist = build_protocol_initializer (TREE_TYPE (decl),
4688 protocol_name_expr, refs_expr,
4689 UOBJC_INSTANCE_METHODS_decl,
4690 UOBJC_CLASS_METHODS_decl);
4691 finish_var_decl (decl, initlist);
4695 static tree
4696 build_protocol_initializer (tree type, tree protocol_name,
4697 tree protocol_list, tree instance_methods,
4698 tree class_methods)
4700 tree initlist = NULL_TREE, expr;
4701 tree cast_type = build_pointer_type
4702 (xref_tag (RECORD_TYPE,
4703 get_identifier (UTAG_CLASS)));
4705 /* Filling the "isa" in with one allows the runtime system to
4706 detect that the version change...should remove before final release. */
4708 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4709 initlist = tree_cons (NULL_TREE, expr, initlist);
4710 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4711 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4713 if (!instance_methods)
4714 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4715 else
4717 expr = convert (objc_method_proto_list_ptr,
4718 build_unary_op (ADDR_EXPR, instance_methods, 0));
4719 initlist = tree_cons (NULL_TREE, expr, initlist);
4722 if (!class_methods)
4723 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4724 else
4726 expr = convert (objc_method_proto_list_ptr,
4727 build_unary_op (ADDR_EXPR, class_methods, 0));
4728 initlist = tree_cons (NULL_TREE, expr, initlist);
4731 return objc_build_constructor (type, nreverse (initlist));
4734 /* struct _objc_category {
4735 char *category_name;
4736 char *class_name;
4737 struct _objc_method_list *instance_methods;
4738 struct _objc_method_list *class_methods;
4739 struct _objc_protocol_list *protocols;
4740 }; */
4742 static void
4743 build_category_template (void)
4745 tree field_decl, field_decl_chain;
4747 objc_category_template = start_struct (RECORD_TYPE,
4748 get_identifier (UTAG_CATEGORY));
4750 /* char *category_name; */
4751 field_decl = create_field_decl (string_type_node, "category_name");
4752 field_decl_chain = field_decl;
4754 /* char *class_name; */
4755 field_decl = create_field_decl (string_type_node, "class_name");
4756 chainon (field_decl_chain, field_decl);
4758 /* struct _objc_method_list *instance_methods; */
4759 field_decl = create_field_decl (objc_method_list_ptr,
4760 "instance_methods");
4761 chainon (field_decl_chain, field_decl);
4763 /* struct _objc_method_list *class_methods; */
4764 field_decl = create_field_decl (objc_method_list_ptr,
4765 "class_methods");
4766 chainon (field_decl_chain, field_decl);
4768 /* struct _objc_protocol **protocol_list; */
4769 field_decl = create_field_decl (build_pointer_type
4770 (build_pointer_type
4771 (objc_protocol_template)),
4772 "protocol_list");
4773 chainon (field_decl_chain, field_decl);
4775 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4778 /* struct _objc_selector {
4779 SEL sel_id;
4780 char *sel_type;
4781 }; */
4783 static void
4784 build_selector_template (void)
4787 tree field_decl, field_decl_chain;
4789 objc_selector_template
4790 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4792 /* SEL sel_id; */
4793 field_decl = create_field_decl (objc_selector_type, "sel_id");
4794 field_decl_chain = field_decl;
4796 /* char *sel_type; */
4797 field_decl = create_field_decl (string_type_node, "sel_type");
4798 chainon (field_decl_chain, field_decl);
4800 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4803 /* struct _objc_class {
4804 struct _objc_class *isa;
4805 struct _objc_class *super_class;
4806 char *name;
4807 long version;
4808 long info;
4809 long instance_size;
4810 struct _objc_ivar_list *ivars;
4811 struct _objc_method_list *methods;
4812 #ifdef __NEXT_RUNTIME__
4813 struct objc_cache *cache;
4814 #else
4815 struct sarray *dtable;
4816 struct _objc_class *subclass_list;
4817 struct _objc_class *sibling_class;
4818 #endif
4819 struct _objc_protocol_list *protocols;
4820 #ifdef __NEXT_RUNTIME__
4821 void *sel_id;
4822 #endif
4823 void *gc_object_type;
4824 }; */
4826 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4827 the NeXT/Apple runtime; still, the compiler must generate them to
4828 maintain backward binary compatibility (and to allow for future
4829 expansion). */
4831 static void
4832 build_class_template (void)
4834 tree field_decl, field_decl_chain;
4836 objc_class_template
4837 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4839 /* struct _objc_class *isa; */
4840 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4841 "isa");
4842 field_decl_chain = field_decl;
4844 /* struct _objc_class *super_class; */
4845 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4846 "super_class");
4847 chainon (field_decl_chain, field_decl);
4849 /* char *name; */
4850 field_decl = create_field_decl (string_type_node, "name");
4851 chainon (field_decl_chain, field_decl);
4853 /* long version; */
4854 field_decl = create_field_decl (long_integer_type_node, "version");
4855 chainon (field_decl_chain, field_decl);
4857 /* long info; */
4858 field_decl = create_field_decl (long_integer_type_node, "info");
4859 chainon (field_decl_chain, field_decl);
4861 /* long instance_size; */
4862 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4863 chainon (field_decl_chain, field_decl);
4865 /* struct _objc_ivar_list *ivars; */
4866 field_decl = create_field_decl (objc_ivar_list_ptr,
4867 "ivars");
4868 chainon (field_decl_chain, field_decl);
4870 /* struct _objc_method_list *methods; */
4871 field_decl = create_field_decl (objc_method_list_ptr,
4872 "methods");
4873 chainon (field_decl_chain, field_decl);
4875 if (flag_next_runtime)
4877 /* struct objc_cache *cache; */
4878 field_decl = create_field_decl (build_pointer_type
4879 (xref_tag (RECORD_TYPE,
4880 get_identifier
4881 ("objc_cache"))),
4882 "cache");
4883 chainon (field_decl_chain, field_decl);
4885 else
4887 /* struct sarray *dtable; */
4888 field_decl = create_field_decl (build_pointer_type
4889 (xref_tag (RECORD_TYPE,
4890 get_identifier
4891 ("sarray"))),
4892 "dtable");
4893 chainon (field_decl_chain, field_decl);
4895 /* struct objc_class *subclass_list; */
4896 field_decl = create_field_decl (build_pointer_type
4897 (objc_class_template),
4898 "subclass_list");
4899 chainon (field_decl_chain, field_decl);
4901 /* struct objc_class *sibling_class; */
4902 field_decl = create_field_decl (build_pointer_type
4903 (objc_class_template),
4904 "sibling_class");
4905 chainon (field_decl_chain, field_decl);
4908 /* struct _objc_protocol **protocol_list; */
4909 field_decl = create_field_decl (build_pointer_type
4910 (build_pointer_type
4911 (xref_tag (RECORD_TYPE,
4912 get_identifier
4913 (UTAG_PROTOCOL)))),
4914 "protocol_list");
4915 chainon (field_decl_chain, field_decl);
4917 if (flag_next_runtime)
4919 /* void *sel_id; */
4920 field_decl = create_field_decl (build_pointer_type (void_type_node),
4921 "sel_id");
4922 chainon (field_decl_chain, field_decl);
4925 /* void *gc_object_type; */
4926 field_decl = create_field_decl (build_pointer_type (void_type_node),
4927 "gc_object_type");
4928 chainon (field_decl_chain, field_decl);
4930 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4933 /* Generate appropriate forward declarations for an implementation. */
4935 static void
4936 synth_forward_declarations (void)
4938 tree an_id;
4940 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4941 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4942 objc_class_template);
4944 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4945 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4946 objc_class_template);
4948 /* Pre-build the following entities - for speed/convenience. */
4950 an_id = get_identifier ("super_class");
4951 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4952 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4955 static void
4956 error_with_ivar (const char *message, tree decl)
4958 error ("%J%s %qs", decl,
4959 message, gen_declaration (decl));
4963 static void
4964 check_ivars (tree inter, tree imp)
4966 tree intdecls = CLASS_RAW_IVARS (inter);
4967 tree impdecls = CLASS_RAW_IVARS (imp);
4969 while (1)
4971 tree t1, t2;
4973 #ifdef OBJCPLUS
4974 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4975 intdecls = TREE_CHAIN (intdecls);
4976 #endif
4977 if (intdecls == 0 && impdecls == 0)
4978 break;
4979 if (intdecls == 0 || impdecls == 0)
4981 error ("inconsistent instance variable specification");
4982 break;
4985 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4987 if (!comptypes (t1, t2)
4988 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4989 DECL_INITIAL (impdecls)))
4991 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4993 error_with_ivar ("conflicting instance variable type",
4994 impdecls);
4995 error_with_ivar ("previous declaration of",
4996 intdecls);
4998 else /* both the type and the name don't match */
5000 error ("inconsistent instance variable specification");
5001 break;
5005 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5007 error_with_ivar ("conflicting instance variable name",
5008 impdecls);
5009 error_with_ivar ("previous declaration of",
5010 intdecls);
5013 intdecls = TREE_CHAIN (intdecls);
5014 impdecls = TREE_CHAIN (impdecls);
5018 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5019 This needs to be done just once per compilation. */
5021 /* struct _objc_super {
5022 struct _objc_object *self;
5023 struct _objc_class *super_class;
5024 }; */
5026 static void
5027 build_super_template (void)
5029 tree field_decl, field_decl_chain;
5031 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5033 /* struct _objc_object *self; */
5034 field_decl = create_field_decl (objc_object_type, "self");
5035 field_decl_chain = field_decl;
5037 /* struct _objc_class *super_class; */
5038 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5039 "super_class");
5040 chainon (field_decl_chain, field_decl);
5042 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5045 /* struct _objc_ivar {
5046 char *ivar_name;
5047 char *ivar_type;
5048 int ivar_offset;
5049 }; */
5051 static tree
5052 build_ivar_template (void)
5054 tree objc_ivar_id, objc_ivar_record;
5055 tree field_decl, field_decl_chain;
5057 objc_ivar_id = get_identifier (UTAG_IVAR);
5058 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5060 /* char *ivar_name; */
5061 field_decl = create_field_decl (string_type_node, "ivar_name");
5062 field_decl_chain = field_decl;
5064 /* char *ivar_type; */
5065 field_decl = create_field_decl (string_type_node, "ivar_type");
5066 chainon (field_decl_chain, field_decl);
5068 /* int ivar_offset; */
5069 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5070 chainon (field_decl_chain, field_decl);
5072 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5074 return objc_ivar_record;
5077 /* struct {
5078 int ivar_count;
5079 struct objc_ivar ivar_list[ivar_count];
5080 }; */
5082 static tree
5083 build_ivar_list_template (tree list_type, int size)
5085 tree objc_ivar_list_record;
5086 tree field_decl, field_decl_chain;
5088 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5090 /* int ivar_count; */
5091 field_decl = create_field_decl (integer_type_node, "ivar_count");
5092 field_decl_chain = field_decl;
5094 /* struct objc_ivar ivar_list[]; */
5095 field_decl = create_field_decl (build_array_type
5096 (list_type,
5097 build_index_type
5098 (build_int_cst (NULL_TREE, size - 1))),
5099 "ivar_list");
5100 chainon (field_decl_chain, field_decl);
5102 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5104 return objc_ivar_list_record;
5107 /* struct {
5108 struct _objc__method_prototype_list *method_next;
5109 int method_count;
5110 struct objc_method method_list[method_count];
5111 }; */
5113 static tree
5114 build_method_list_template (tree list_type, int size)
5116 tree objc_ivar_list_record;
5117 tree field_decl, field_decl_chain;
5119 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5121 /* struct _objc__method_prototype_list *method_next; */
5122 field_decl = create_field_decl (objc_method_proto_list_ptr,
5123 "method_next");
5124 field_decl_chain = field_decl;
5126 /* int method_count; */
5127 field_decl = create_field_decl (integer_type_node, "method_count");
5128 chainon (field_decl_chain, field_decl);
5130 /* struct objc_method method_list[]; */
5131 field_decl = create_field_decl (build_array_type
5132 (list_type,
5133 build_index_type
5134 (build_int_cst (NULL_TREE, size - 1))),
5135 "method_list");
5136 chainon (field_decl_chain, field_decl);
5138 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5140 return objc_ivar_list_record;
5143 static tree
5144 build_ivar_list_initializer (tree type, tree field_decl)
5146 tree initlist = NULL_TREE;
5150 tree ivar = NULL_TREE;
5152 /* Set name. */
5153 if (DECL_NAME (field_decl))
5154 ivar = tree_cons (NULL_TREE,
5155 add_objc_string (DECL_NAME (field_decl),
5156 meth_var_names),
5157 ivar);
5158 else
5159 /* Unnamed bit-field ivar (yuck). */
5160 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5162 /* Set type. */
5163 encode_field_decl (field_decl,
5164 obstack_object_size (&util_obstack),
5165 OBJC_ENCODE_DONT_INLINE_DEFS);
5167 /* Null terminate string. */
5168 obstack_1grow (&util_obstack, 0);
5169 ivar
5170 = tree_cons
5171 (NULL_TREE,
5172 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5173 meth_var_types),
5174 ivar);
5175 obstack_free (&util_obstack, util_firstobj);
5177 /* Set offset. */
5178 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5179 initlist = tree_cons (NULL_TREE,
5180 objc_build_constructor (type, nreverse (ivar)),
5181 initlist);
5183 field_decl = TREE_CHAIN (field_decl);
5184 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5186 while (field_decl);
5188 return objc_build_constructor (build_array_type (type, 0),
5189 nreverse (initlist));
5192 static tree
5193 generate_ivars_list (tree type, const char *name, int size, tree list)
5195 tree decl, initlist;
5197 decl = start_var_decl (type, synth_id_with_class_suffix
5198 (name, objc_implementation_context));
5200 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5201 initlist = tree_cons (NULL_TREE, list, initlist);
5203 finish_var_decl (decl,
5204 objc_build_constructor (TREE_TYPE (decl),
5205 nreverse (initlist)));
5207 return decl;
5210 /* Count only the fields occurring in T. */
5212 static int
5213 ivar_list_length (tree t)
5215 int count = 0;
5217 for (; t; t = TREE_CHAIN (t))
5218 if (TREE_CODE (t) == FIELD_DECL)
5219 ++count;
5221 return count;
5224 static void
5225 generate_ivar_lists (void)
5227 tree initlist, ivar_list_template, chain;
5228 int size;
5230 generating_instance_variables = 1;
5232 if (!objc_ivar_template)
5233 objc_ivar_template = build_ivar_template ();
5235 /* Only generate class variables for the root of the inheritance
5236 hierarchy since these will be the same for every class. */
5238 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5239 && (chain = TYPE_FIELDS (objc_class_template)))
5241 size = ivar_list_length (chain);
5243 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5244 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5246 UOBJC_CLASS_VARIABLES_decl
5247 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5248 size, initlist);
5250 else
5251 UOBJC_CLASS_VARIABLES_decl = 0;
5253 chain = CLASS_IVARS (implementation_template);
5254 if (chain)
5256 size = ivar_list_length (chain);
5257 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5258 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5260 UOBJC_INSTANCE_VARIABLES_decl
5261 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5262 size, initlist);
5264 else
5265 UOBJC_INSTANCE_VARIABLES_decl = 0;
5267 generating_instance_variables = 0;
5270 static tree
5271 build_dispatch_table_initializer (tree type, tree entries)
5273 tree initlist = NULL_TREE;
5277 tree elemlist = NULL_TREE;
5279 elemlist = tree_cons (NULL_TREE,
5280 build_selector (METHOD_SEL_NAME (entries)),
5281 NULL_TREE);
5283 /* Generate the method encoding if we don't have one already. */
5284 if (! METHOD_ENCODING (entries))
5285 METHOD_ENCODING (entries) =
5286 encode_method_prototype (entries);
5288 elemlist = tree_cons (NULL_TREE,
5289 add_objc_string (METHOD_ENCODING (entries),
5290 meth_var_types),
5291 elemlist);
5293 elemlist
5294 = tree_cons (NULL_TREE,
5295 convert (ptr_type_node,
5296 build_unary_op (ADDR_EXPR,
5297 METHOD_DEFINITION (entries), 1)),
5298 elemlist);
5300 initlist = tree_cons (NULL_TREE,
5301 objc_build_constructor (type, nreverse (elemlist)),
5302 initlist);
5304 entries = TREE_CHAIN (entries);
5306 while (entries);
5308 return objc_build_constructor (build_array_type (type, 0),
5309 nreverse (initlist));
5312 /* To accomplish method prototyping without generating all kinds of
5313 inane warnings, the definition of the dispatch table entries were
5314 changed from:
5316 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5318 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5320 static tree
5321 build_method_template (void)
5323 tree _SLT_record;
5324 tree field_decl, field_decl_chain;
5326 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5328 /* SEL _cmd; */
5329 field_decl = create_field_decl (objc_selector_type, "_cmd");
5330 field_decl_chain = field_decl;
5332 /* char *method_types; */
5333 field_decl = create_field_decl (string_type_node, "method_types");
5334 chainon (field_decl_chain, field_decl);
5336 /* void *_imp; */
5337 field_decl = create_field_decl (build_pointer_type (void_type_node),
5338 "_imp");
5339 chainon (field_decl_chain, field_decl);
5341 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5343 return _SLT_record;
5347 static tree
5348 generate_dispatch_table (tree type, const char *name, int size, tree list)
5350 tree decl, initlist;
5352 decl = start_var_decl (type, synth_id_with_class_suffix
5353 (name, objc_implementation_context));
5355 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5356 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5357 initlist = tree_cons (NULL_TREE, list, initlist);
5359 finish_var_decl (decl,
5360 objc_build_constructor (TREE_TYPE (decl),
5361 nreverse (initlist)));
5363 return decl;
5366 static void
5367 mark_referenced_methods (void)
5369 struct imp_entry *impent;
5370 tree chain;
5372 for (impent = imp_list; impent; impent = impent->next)
5374 chain = CLASS_CLS_METHODS (impent->imp_context);
5375 while (chain)
5377 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5378 chain = TREE_CHAIN (chain);
5381 chain = CLASS_NST_METHODS (impent->imp_context);
5382 while (chain)
5384 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5385 chain = TREE_CHAIN (chain);
5390 static void
5391 generate_dispatch_tables (void)
5393 tree initlist, chain, method_list_template;
5394 int size;
5396 if (!objc_method_template)
5397 objc_method_template = build_method_template ();
5399 chain = CLASS_CLS_METHODS (objc_implementation_context);
5400 if (chain)
5402 size = list_length (chain);
5404 method_list_template
5405 = build_method_list_template (objc_method_template, size);
5406 initlist
5407 = build_dispatch_table_initializer (objc_method_template, chain);
5409 UOBJC_CLASS_METHODS_decl
5410 = generate_dispatch_table (method_list_template,
5411 ((TREE_CODE (objc_implementation_context)
5412 == CLASS_IMPLEMENTATION_TYPE)
5413 ? "_OBJC_CLASS_METHODS"
5414 : "_OBJC_CATEGORY_CLASS_METHODS"),
5415 size, initlist);
5417 else
5418 UOBJC_CLASS_METHODS_decl = 0;
5420 chain = CLASS_NST_METHODS (objc_implementation_context);
5421 if (chain)
5423 size = list_length (chain);
5425 method_list_template
5426 = build_method_list_template (objc_method_template, size);
5427 initlist
5428 = build_dispatch_table_initializer (objc_method_template, chain);
5430 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5431 UOBJC_INSTANCE_METHODS_decl
5432 = generate_dispatch_table (method_list_template,
5433 "_OBJC_INSTANCE_METHODS",
5434 size, initlist);
5435 else
5436 /* We have a category. */
5437 UOBJC_INSTANCE_METHODS_decl
5438 = generate_dispatch_table (method_list_template,
5439 "_OBJC_CATEGORY_INSTANCE_METHODS",
5440 size, initlist);
5442 else
5443 UOBJC_INSTANCE_METHODS_decl = 0;
5446 static tree
5447 generate_protocol_list (tree i_or_p)
5449 tree initlist;
5450 tree refs_decl, lproto, e, plist;
5451 int size = 0;
5452 const char *ref_name;
5454 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5455 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5456 plist = CLASS_PROTOCOL_LIST (i_or_p);
5457 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5458 plist = PROTOCOL_LIST (i_or_p);
5459 else
5460 abort ();
5462 /* Compute size. */
5463 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5464 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5465 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5466 size++;
5468 /* Build initializer. */
5469 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5470 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5471 initlist = tree_cons (NULL_TREE, e, initlist);
5473 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5475 tree pval = TREE_VALUE (lproto);
5477 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5478 && PROTOCOL_FORWARD_DECL (pval))
5480 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5481 initlist = tree_cons (NULL_TREE, e, initlist);
5485 /* static struct objc_protocol *refs[n]; */
5487 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5488 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5489 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5490 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5491 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5492 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5493 else
5494 abort ();
5496 refs_decl = start_var_decl
5497 (build_array_type
5498 (build_pointer_type (objc_protocol_template),
5499 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5500 ref_name);
5502 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5503 nreverse (initlist)));
5505 return refs_decl;
5508 static tree
5509 build_category_initializer (tree type, tree cat_name, tree class_name,
5510 tree instance_methods, tree class_methods,
5511 tree protocol_list)
5513 tree initlist = NULL_TREE, expr;
5515 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5516 initlist = tree_cons (NULL_TREE, class_name, initlist);
5518 if (!instance_methods)
5519 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5520 else
5522 expr = convert (objc_method_list_ptr,
5523 build_unary_op (ADDR_EXPR, instance_methods, 0));
5524 initlist = tree_cons (NULL_TREE, expr, initlist);
5526 if (!class_methods)
5527 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5528 else
5530 expr = convert (objc_method_list_ptr,
5531 build_unary_op (ADDR_EXPR, class_methods, 0));
5532 initlist = tree_cons (NULL_TREE, expr, initlist);
5535 /* protocol_list = */
5536 if (!protocol_list)
5537 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5538 else
5540 expr = convert (build_pointer_type
5541 (build_pointer_type
5542 (objc_protocol_template)),
5543 build_unary_op (ADDR_EXPR, protocol_list, 0));
5544 initlist = tree_cons (NULL_TREE, expr, initlist);
5547 return objc_build_constructor (type, nreverse (initlist));
5550 /* struct _objc_class {
5551 struct objc_class *isa;
5552 struct objc_class *super_class;
5553 char *name;
5554 long version;
5555 long info;
5556 long instance_size;
5557 struct objc_ivar_list *ivars;
5558 struct objc_method_list *methods;
5559 if (flag_next_runtime)
5560 struct objc_cache *cache;
5561 else {
5562 struct sarray *dtable;
5563 struct objc_class *subclass_list;
5564 struct objc_class *sibling_class;
5566 struct objc_protocol_list *protocols;
5567 if (flag_next_runtime)
5568 void *sel_id;
5569 void *gc_object_type;
5570 }; */
5572 static tree
5573 build_shared_structure_initializer (tree type, tree isa, tree super,
5574 tree name, tree size, int status,
5575 tree dispatch_table, tree ivar_list,
5576 tree protocol_list)
5578 tree initlist = NULL_TREE, expr;
5580 /* isa = */
5581 initlist = tree_cons (NULL_TREE, isa, initlist);
5583 /* super_class = */
5584 initlist = tree_cons (NULL_TREE, super, initlist);
5586 /* name = */
5587 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5589 /* version = */
5590 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5591 initlist);
5593 /* info = */
5594 initlist = tree_cons (NULL_TREE,
5595 build_int_cst (long_integer_type_node, status),
5596 initlist);
5598 /* instance_size = */
5599 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5600 initlist);
5602 /* objc_ivar_list = */
5603 if (!ivar_list)
5604 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5605 else
5607 expr = convert (objc_ivar_list_ptr,
5608 build_unary_op (ADDR_EXPR, ivar_list, 0));
5609 initlist = tree_cons (NULL_TREE, expr, initlist);
5612 /* objc_method_list = */
5613 if (!dispatch_table)
5614 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5615 else
5617 expr = convert (objc_method_list_ptr,
5618 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5619 initlist = tree_cons (NULL_TREE, expr, initlist);
5622 if (flag_next_runtime)
5623 /* method_cache = */
5624 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5625 else
5627 /* dtable = */
5628 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5630 /* subclass_list = */
5631 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5633 /* sibling_class = */
5634 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5637 /* protocol_list = */
5638 if (! protocol_list)
5639 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5640 else
5642 expr = convert (build_pointer_type
5643 (build_pointer_type
5644 (objc_protocol_template)),
5645 build_unary_op (ADDR_EXPR, protocol_list, 0));
5646 initlist = tree_cons (NULL_TREE, expr, initlist);
5649 if (flag_next_runtime)
5650 /* sel_id = NULL */
5651 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5653 /* gc_object_type = NULL */
5654 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5656 return objc_build_constructor (type, nreverse (initlist));
5659 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5661 static inline tree
5662 lookup_category (tree class, tree cat_name)
5664 tree category = CLASS_CATEGORY_LIST (class);
5666 while (category && CLASS_SUPER_NAME (category) != cat_name)
5667 category = CLASS_CATEGORY_LIST (category);
5668 return category;
5671 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5673 static void
5674 generate_category (tree cat)
5676 tree decl;
5677 tree initlist, cat_name_expr, class_name_expr;
5678 tree protocol_decl, category;
5680 add_class_reference (CLASS_NAME (cat));
5681 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5683 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5685 category = lookup_category (implementation_template,
5686 CLASS_SUPER_NAME (cat));
5688 if (category && CLASS_PROTOCOL_LIST (category))
5690 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5691 protocol_decl = generate_protocol_list (category);
5693 else
5694 protocol_decl = 0;
5696 decl = start_var_decl (objc_category_template,
5697 synth_id_with_class_suffix
5698 ("_OBJC_CATEGORY", objc_implementation_context));
5700 initlist = build_category_initializer (TREE_TYPE (decl),
5701 cat_name_expr, class_name_expr,
5702 UOBJC_INSTANCE_METHODS_decl,
5703 UOBJC_CLASS_METHODS_decl,
5704 protocol_decl);
5706 finish_var_decl (decl, initlist);
5709 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5710 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5712 static void
5713 generate_shared_structures (int cls_flags)
5715 tree sc_spec, decl_specs, decl;
5716 tree name_expr, super_expr, root_expr;
5717 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5718 tree cast_type, initlist, protocol_decl;
5720 my_super_id = CLASS_SUPER_NAME (implementation_template);
5721 if (my_super_id)
5723 add_class_reference (my_super_id);
5725 /* Compute "my_root_id" - this is required for code generation.
5726 the "isa" for all meta class structures points to the root of
5727 the inheritance hierarchy (e.g. "__Object")... */
5728 my_root_id = my_super_id;
5731 tree my_root_int = lookup_interface (my_root_id);
5733 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5734 my_root_id = CLASS_SUPER_NAME (my_root_int);
5735 else
5736 break;
5738 while (1);
5740 else
5741 /* No super class. */
5742 my_root_id = CLASS_NAME (implementation_template);
5744 cast_type = build_pointer_type (objc_class_template);
5745 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5746 class_names);
5748 /* Install class `isa' and `super' pointers at runtime. */
5749 if (my_super_id)
5751 super_expr = add_objc_string (my_super_id, class_names);
5752 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5754 else
5755 super_expr = build_int_cst (NULL_TREE, 0);
5757 root_expr = add_objc_string (my_root_id, class_names);
5758 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5760 if (CLASS_PROTOCOL_LIST (implementation_template))
5762 generate_protocol_references
5763 (CLASS_PROTOCOL_LIST (implementation_template));
5764 protocol_decl = generate_protocol_list (implementation_template);
5766 else
5767 protocol_decl = 0;
5769 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5771 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5772 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5774 decl = start_var_decl (objc_class_template,
5775 IDENTIFIER_POINTER
5776 (DECL_NAME (UOBJC_METACLASS_decl)));
5778 initlist
5779 = build_shared_structure_initializer
5780 (TREE_TYPE (decl),
5781 root_expr, super_expr, name_expr,
5782 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5783 2 /*CLS_META*/,
5784 UOBJC_CLASS_METHODS_decl,
5785 UOBJC_CLASS_VARIABLES_decl,
5786 protocol_decl);
5788 finish_var_decl (decl, initlist);
5790 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5792 decl = start_var_decl (objc_class_template,
5793 IDENTIFIER_POINTER
5794 (DECL_NAME (UOBJC_CLASS_decl)));
5796 initlist
5797 = build_shared_structure_initializer
5798 (TREE_TYPE (decl),
5799 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5800 super_expr, name_expr,
5801 convert (integer_type_node,
5802 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5803 (implementation_template))),
5804 1 /*CLS_FACTORY*/ | cls_flags,
5805 UOBJC_INSTANCE_METHODS_decl,
5806 UOBJC_INSTANCE_VARIABLES_decl,
5807 protocol_decl);
5809 finish_var_decl (decl, initlist);
5813 static const char *
5814 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5816 static char string[BUFSIZE];
5818 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5819 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5821 sprintf (string, "%s_%s", preamble,
5822 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5824 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5825 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5827 /* We have a category. */
5828 const char *const class_name
5829 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5830 const char *const class_super_name
5831 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5832 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5834 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5836 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5837 sprintf (string, "%s_%s", preamble, protocol_name);
5839 else
5840 abort ();
5842 return string;
5845 /* If type is empty or only type qualifiers are present, add default
5846 type of id (otherwise grokdeclarator will default to int). */
5848 static tree
5849 adjust_type_for_id_default (tree type)
5851 if (!type)
5852 type = make_node (TREE_LIST);
5854 if (!TREE_VALUE (type))
5855 TREE_VALUE (type) = objc_object_type;
5856 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5857 && TYPED_OBJECT (TREE_VALUE (type)))
5858 error ("can not use an object as parameter to a method");
5860 return type;
5863 /* Usage:
5864 keyworddecl:
5865 selector ':' '(' typename ')' identifier
5867 Purpose:
5868 Transform an Objective-C keyword argument into
5869 the C equivalent parameter declarator.
5871 In: key_name, an "identifier_node" (optional).
5872 arg_type, a "tree_list" (optional).
5873 arg_name, an "identifier_node".
5875 Note: It would be really nice to strongly type the preceding
5876 arguments in the function prototype; however, then I
5877 could not use the "accessor" macros defined in "tree.h".
5879 Out: an instance of "keyword_decl". */
5881 tree
5882 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5884 tree keyword_decl;
5886 /* If no type is specified, default to "id". */
5887 arg_type = adjust_type_for_id_default (arg_type);
5889 keyword_decl = make_node (KEYWORD_DECL);
5891 TREE_TYPE (keyword_decl) = arg_type;
5892 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5893 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5895 return keyword_decl;
5898 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5900 static tree
5901 build_keyword_selector (tree selector)
5903 int len = 0;
5904 tree key_chain, key_name;
5905 char *buf;
5907 /* Scan the selector to see how much space we'll need. */
5908 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5910 if (TREE_CODE (selector) == KEYWORD_DECL)
5911 key_name = KEYWORD_KEY_NAME (key_chain);
5912 else if (TREE_CODE (selector) == TREE_LIST)
5913 key_name = TREE_PURPOSE (key_chain);
5914 else
5915 abort ();
5917 if (key_name)
5918 len += IDENTIFIER_LENGTH (key_name) + 1;
5919 else
5920 /* Just a ':' arg. */
5921 len++;
5924 buf = (char *) alloca (len + 1);
5925 /* Start the buffer out as an empty string. */
5926 buf[0] = '\0';
5928 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5930 if (TREE_CODE (selector) == KEYWORD_DECL)
5931 key_name = KEYWORD_KEY_NAME (key_chain);
5932 else if (TREE_CODE (selector) == TREE_LIST)
5934 key_name = TREE_PURPOSE (key_chain);
5935 /* The keyword decl chain will later be used as a function argument
5936 chain. Unhook the selector itself so as to not confuse other
5937 parts of the compiler. */
5938 TREE_PURPOSE (key_chain) = NULL_TREE;
5940 else
5941 abort ();
5943 if (key_name)
5944 strcat (buf, IDENTIFIER_POINTER (key_name));
5945 strcat (buf, ":");
5948 return get_identifier (buf);
5951 /* Used for declarations and definitions. */
5953 static tree
5954 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5955 tree add_args, bool ellipsis)
5957 tree method_decl;
5959 /* If no type is specified, default to "id". */
5960 ret_type = adjust_type_for_id_default (ret_type);
5962 method_decl = make_node (code);
5963 TREE_TYPE (method_decl) = ret_type;
5965 /* If we have a keyword selector, create an identifier_node that
5966 represents the full selector name (`:' included)... */
5967 if (TREE_CODE (selector) == KEYWORD_DECL)
5969 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5970 METHOD_SEL_ARGS (method_decl) = selector;
5971 METHOD_ADD_ARGS (method_decl) = add_args;
5972 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5974 else
5976 METHOD_SEL_NAME (method_decl) = selector;
5977 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5978 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5981 return method_decl;
5984 #define METHOD_DEF 0
5985 #define METHOD_REF 1
5987 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5988 an argument list for method METH. CONTEXT is either METHOD_DEF or
5989 METHOD_REF, saying whether we are trying to define a method or call
5990 one. SUPERFLAG says this is for a send to super; this makes a
5991 difference for the NeXT calling sequence in which the lookup and
5992 the method call are done together. If METH is null, user-defined
5993 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5995 static tree
5996 get_arg_type_list (tree meth, int context, int superflag)
5998 tree arglist, akey;
6000 /* Receiver type. */
6001 if (flag_next_runtime && superflag)
6002 arglist = build_tree_list (NULL_TREE, objc_super_type);
6003 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6004 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6005 else
6006 arglist = build_tree_list (NULL_TREE, objc_object_type);
6008 /* Selector type - will eventually change to `int'. */
6009 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6011 /* No actual method prototype given -- assume that remaining arguments
6012 are `...'. */
6013 if (!meth)
6014 return arglist;
6016 /* Build a list of argument types. */
6017 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6019 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6021 /* Decay arrays and functions into pointers. */
6022 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6023 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6024 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6025 arg_type = build_pointer_type (arg_type);
6027 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6030 if (METHOD_ADD_ARGS (meth))
6032 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6033 akey; akey = TREE_CHAIN (akey))
6035 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6037 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6040 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6041 goto lack_of_ellipsis;
6043 else
6045 lack_of_ellipsis:
6046 chainon (arglist, OBJC_VOID_AT_END);
6049 return arglist;
6052 static tree
6053 check_duplicates (hash hsh, int methods, int is_class)
6055 tree meth = NULL_TREE;
6057 if (hsh)
6059 meth = hsh->key;
6061 if (hsh->list)
6063 /* We have two or more methods with the same name but
6064 different types. */
6065 attr loop;
6067 /* But just how different are those types? If
6068 -Wno-strict-selector-match is specified, we shall not
6069 complain if the differences are solely among types with
6070 identical size and alignment. */
6071 if (!warn_strict_selector_match)
6073 for (loop = hsh->list; loop; loop = loop->next)
6074 if (!comp_proto_with_proto (meth, loop->value, 0))
6075 goto issue_warning;
6077 return meth;
6080 issue_warning:
6081 warning (0, "multiple %s named %<%c%s%> found",
6082 methods ? "methods" : "selectors",
6083 (is_class ? '+' : '-'),
6084 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6086 warn_with_method (methods ? "using" : "found",
6087 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6088 ? '-'
6089 : '+'),
6090 meth);
6091 for (loop = hsh->list; loop; loop = loop->next)
6092 warn_with_method ("also found",
6093 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6094 ? '-'
6095 : '+'),
6096 loop->value);
6099 return meth;
6102 /* If RECEIVER is a class reference, return the identifier node for
6103 the referenced class. RECEIVER is created by objc_get_class_reference,
6104 so we check the exact form created depending on which runtimes are
6105 used. */
6107 static tree
6108 receiver_is_class_object (tree receiver, int self, int super)
6110 tree chain, exp, arg;
6112 /* The receiver is 'self' or 'super' in the context of a class method. */
6113 if (objc_method_context
6114 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6115 && (self || super))
6116 return (super
6117 ? CLASS_SUPER_NAME (implementation_template)
6118 : CLASS_NAME (implementation_template));
6120 if (flag_next_runtime)
6122 /* The receiver is a variable created by
6123 build_class_reference_decl. */
6124 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6125 /* Look up the identifier. */
6126 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6127 if (TREE_PURPOSE (chain) == receiver)
6128 return TREE_VALUE (chain);
6131 /* The receiver is a function call that returns an id. Check if
6132 it is a call to objc_getClass, if so, pick up the class name. */
6133 if (TREE_CODE (receiver) == CALL_EXPR
6134 && (exp = CALL_EXPR_FN (receiver))
6135 && TREE_CODE (exp) == ADDR_EXPR
6136 && (exp = TREE_OPERAND (exp, 0))
6137 && TREE_CODE (exp) == FUNCTION_DECL
6138 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6139 prototypes for objc_get_class(). Thankfully, they seem to share the
6140 same function type. */
6141 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6142 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6143 /* We have a call to objc_get_class/objc_getClass! */
6144 && (arg = CALL_EXPR_ARG (receiver, 0)))
6146 STRIP_NOPS (arg);
6147 if (TREE_CODE (arg) == ADDR_EXPR
6148 && (arg = TREE_OPERAND (arg, 0))
6149 && TREE_CODE (arg) == STRING_CST)
6150 /* Finally, we have the class name. */
6151 return get_identifier (TREE_STRING_POINTER (arg));
6153 return 0;
6156 /* If we are currently building a message expr, this holds
6157 the identifier of the selector of the message. This is
6158 used when printing warnings about argument mismatches. */
6160 static tree current_objc_message_selector = 0;
6162 tree
6163 objc_message_selector (void)
6165 return current_objc_message_selector;
6168 /* Construct an expression for sending a message.
6169 MESS has the object to send to in TREE_PURPOSE
6170 and the argument list (including selector) in TREE_VALUE.
6172 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6173 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6175 tree
6176 objc_build_message_expr (tree mess)
6178 tree receiver = TREE_PURPOSE (mess);
6179 tree sel_name;
6180 #ifdef OBJCPLUS
6181 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6182 #else
6183 tree args = TREE_VALUE (mess);
6184 #endif
6185 tree method_params = NULL_TREE;
6187 if (TREE_CODE (receiver) == ERROR_MARK)
6188 return error_mark_node;
6190 /* Obtain the full selector name. */
6191 if (TREE_CODE (args) == IDENTIFIER_NODE)
6192 /* A unary selector. */
6193 sel_name = args;
6194 else if (TREE_CODE (args) == TREE_LIST)
6195 sel_name = build_keyword_selector (args);
6196 else
6197 abort ();
6199 /* Build the parameter list to give to the method. */
6200 if (TREE_CODE (args) == TREE_LIST)
6201 #ifdef OBJCPLUS
6202 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6203 #else
6205 tree chain = args, prev = NULL_TREE;
6207 /* We have a keyword selector--check for comma expressions. */
6208 while (chain)
6210 tree element = TREE_VALUE (chain);
6212 /* We have a comma expression, must collapse... */
6213 if (TREE_CODE (element) == TREE_LIST)
6215 if (prev)
6216 TREE_CHAIN (prev) = element;
6217 else
6218 args = element;
6220 prev = chain;
6221 chain = TREE_CHAIN (chain);
6223 method_params = args;
6225 #endif
6227 #ifdef OBJCPLUS
6228 if (processing_template_decl)
6229 /* Must wait until template instantiation time. */
6230 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6231 method_params);
6232 #endif
6234 return objc_finish_message_expr (receiver, sel_name, method_params);
6237 /* Look up method SEL_NAME that would be suitable for receiver
6238 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6239 nonzero), and report on any duplicates. */
6241 static tree
6242 lookup_method_in_hash_lists (tree sel_name, int is_class)
6244 hash method_prototype = NULL;
6246 if (!is_class)
6247 method_prototype = hash_lookup (nst_method_hash_list,
6248 sel_name);
6250 if (!method_prototype)
6252 method_prototype = hash_lookup (cls_method_hash_list,
6253 sel_name);
6254 is_class = 1;
6257 return check_duplicates (method_prototype, 1, is_class);
6260 /* The 'objc_finish_message_expr' routine is called from within
6261 'objc_build_message_expr' for non-template functions. In the case of
6262 C++ template functions, it is called from 'build_expr_from_tree'
6263 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6265 tree
6266 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6268 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6269 tree selector, retval, class_tree;
6270 int self, super, have_cast;
6272 /* Extract the receiver of the message, as well as its type
6273 (where the latter may take the form of a cast or be inferred
6274 from the implementation context). */
6275 rtype = receiver;
6276 while (TREE_CODE (rtype) == COMPOUND_EXPR
6277 || TREE_CODE (rtype) == MODIFY_EXPR
6278 || TREE_CODE (rtype) == NOP_EXPR
6279 || TREE_CODE (rtype) == CONVERT_EXPR
6280 || TREE_CODE (rtype) == COMPONENT_REF)
6281 rtype = TREE_OPERAND (rtype, 0);
6282 self = (rtype == self_decl);
6283 super = (rtype == UOBJC_SUPER_decl);
6284 rtype = TREE_TYPE (receiver);
6285 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6286 || (TREE_CODE (receiver) == COMPOUND_EXPR
6287 && !IS_SUPER (rtype)));
6289 /* If we are calling [super dealloc], reset our warning flag. */
6290 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6291 should_call_super_dealloc = 0;
6293 /* If the receiver is a class object, retrieve the corresponding
6294 @interface, if one exists. */
6295 class_tree = receiver_is_class_object (receiver, self, super);
6297 /* Now determine the receiver type (if an explicit cast has not been
6298 provided). */
6299 if (!have_cast)
6301 if (class_tree)
6302 rtype = lookup_interface (class_tree);
6303 /* Handle `self' and `super'. */
6304 else if (super)
6306 if (!CLASS_SUPER_NAME (implementation_template))
6308 error ("no super class declared in @interface for %qs",
6309 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6310 return error_mark_node;
6312 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6314 else if (self)
6315 rtype = lookup_interface (CLASS_NAME (implementation_template));
6318 /* If receiver is of type `id' or `Class' (or if the @interface for a
6319 class is not visible), we shall be satisfied with the existence of
6320 any instance or class method. */
6321 if (objc_is_id (rtype))
6323 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6324 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6325 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6326 : NULL_TREE);
6327 rtype = NULL_TREE;
6329 if (rprotos)
6331 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6332 in protocols themselves for the method prototype. */
6333 method_prototype
6334 = lookup_method_in_protocol_list (rprotos, sel_name,
6335 class_tree != NULL_TREE);
6337 /* If messaging 'Class <Proto>' but did not find a class method
6338 prototype, search for an instance method instead, and warn
6339 about having done so. */
6340 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6342 method_prototype
6343 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6345 if (method_prototype)
6346 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6347 IDENTIFIER_POINTER (sel_name),
6348 IDENTIFIER_POINTER (sel_name));
6352 else if (rtype)
6354 tree orig_rtype = rtype, saved_rtype;
6356 if (TREE_CODE (rtype) == POINTER_TYPE)
6357 rtype = TREE_TYPE (rtype);
6358 /* Traverse typedef aliases */
6359 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6360 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6361 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6362 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6363 saved_rtype = rtype;
6364 if (TYPED_OBJECT (rtype))
6366 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6367 rtype = TYPE_OBJC_INTERFACE (rtype);
6369 /* If we could not find an @interface declaration, we must have
6370 only seen a @class declaration; so, we cannot say anything
6371 more intelligent about which methods the receiver will
6372 understand. */
6373 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6374 rtype = NULL_TREE;
6375 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6376 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6378 /* We have a valid ObjC class name. Look up the method name
6379 in the published @interface for the class (and its
6380 superclasses). */
6381 method_prototype
6382 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6384 /* If the method was not found in the @interface, it may still
6385 exist locally as part of the @implementation. */
6386 if (!method_prototype && objc_implementation_context
6387 && CLASS_NAME (objc_implementation_context)
6388 == OBJC_TYPE_NAME (rtype))
6389 method_prototype
6390 = lookup_method
6391 ((class_tree
6392 ? CLASS_CLS_METHODS (objc_implementation_context)
6393 : CLASS_NST_METHODS (objc_implementation_context)),
6394 sel_name);
6396 /* If we haven't found a candidate method by now, try looking for
6397 it in the protocol list. */
6398 if (!method_prototype && rprotos)
6399 method_prototype
6400 = lookup_method_in_protocol_list (rprotos, sel_name,
6401 class_tree != NULL_TREE);
6403 else
6405 warning (0, "invalid receiver type %qs",
6406 gen_type_name (orig_rtype));
6407 /* After issuing the "invalid receiver" warning, perform method
6408 lookup as if we were messaging 'id'. */
6409 rtype = rprotos = NULL_TREE;
6414 /* For 'id' or 'Class' receivers, search in the global hash table
6415 as a last resort. For all receivers, warn if protocol searches
6416 have failed. */
6417 if (!method_prototype)
6419 if (rprotos)
6420 warning (0, "%<%c%s%> not found in protocol(s)",
6421 (class_tree ? '+' : '-'),
6422 IDENTIFIER_POINTER (sel_name));
6424 if (!rtype)
6425 method_prototype
6426 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6429 if (!method_prototype)
6431 static bool warn_missing_methods = false;
6433 if (rtype)
6434 warning (0, "%qs may not respond to %<%c%s%>",
6435 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6436 (class_tree ? '+' : '-'),
6437 IDENTIFIER_POINTER (sel_name));
6438 /* If we are messaging an 'id' or 'Class' object and made it here,
6439 then we have failed to find _any_ instance or class method,
6440 respectively. */
6441 else
6442 warning (0, "no %<%c%s%> method found",
6443 (class_tree ? '+' : '-'),
6444 IDENTIFIER_POINTER (sel_name));
6446 if (!warn_missing_methods)
6448 warning (0, "(Messages without a matching method signature");
6449 warning (0, "will be assumed to return %<id%> and accept");
6450 warning (0, "%<...%> as arguments.)");
6451 warn_missing_methods = true;
6455 /* Save the selector name for printing error messages. */
6456 current_objc_message_selector = sel_name;
6458 /* Build the parameters list for looking up the method.
6459 These are the object itself and the selector. */
6461 if (flag_typed_selectors)
6462 selector = build_typed_selector_reference (sel_name, method_prototype);
6463 else
6464 selector = build_selector_reference (sel_name);
6466 retval = build_objc_method_call (super, method_prototype,
6467 receiver,
6468 selector, method_params);
6470 current_objc_message_selector = 0;
6472 return retval;
6475 /* Build a tree expression to send OBJECT the operation SELECTOR,
6476 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6477 assuming the method has prototype METHOD_PROTOTYPE.
6478 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6479 Use METHOD_PARAMS as list of args to pass to the method.
6480 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6482 static tree
6483 build_objc_method_call (int super_flag, tree method_prototype,
6484 tree lookup_object, tree selector,
6485 tree method_params)
6487 tree sender = (super_flag ? umsg_super_decl :
6488 (!flag_next_runtime || flag_nil_receivers
6489 ? (flag_objc_direct_dispatch
6490 ? umsg_fast_decl
6491 : umsg_decl)
6492 : umsg_nonnil_decl));
6493 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6495 /* If a prototype for the method to be called exists, then cast
6496 the sender's return type and arguments to match that of the method.
6497 Otherwise, leave sender as is. */
6498 tree ret_type
6499 = (method_prototype
6500 ? TREE_VALUE (TREE_TYPE (method_prototype))
6501 : objc_object_type);
6502 tree sender_cast
6503 = build_pointer_type
6504 (build_function_type
6505 (ret_type,
6506 get_arg_type_list
6507 (method_prototype, METHOD_REF, super_flag)));
6508 tree method, t;
6510 lookup_object = build_c_cast (rcv_p, lookup_object);
6512 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6513 lookup_object = save_expr (lookup_object);
6515 if (flag_next_runtime)
6517 /* If we are returning a struct in memory, and the address
6518 of that memory location is passed as a hidden first
6519 argument, then change which messenger entry point this
6520 expr will call. NB: Note that sender_cast remains
6521 unchanged (it already has a struct return type). */
6522 if (!targetm.calls.struct_value_rtx (0, 0)
6523 && (TREE_CODE (ret_type) == RECORD_TYPE
6524 || TREE_CODE (ret_type) == UNION_TYPE)
6525 && targetm.calls.return_in_memory (ret_type, 0))
6526 sender = (super_flag ? umsg_super_stret_decl :
6527 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6529 method_params = tree_cons (NULL_TREE, lookup_object,
6530 tree_cons (NULL_TREE, selector,
6531 method_params));
6532 method = build_fold_addr_expr (sender);
6534 else
6536 /* This is the portable (GNU) way. */
6537 tree object;
6539 /* First, call the lookup function to get a pointer to the method,
6540 then cast the pointer, then call it with the method arguments. */
6542 object = (super_flag ? self_decl : lookup_object);
6544 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6545 t = tree_cons (NULL_TREE, lookup_object, t);
6546 method = build_function_call (sender, t);
6548 /* Pass the object to the method. */
6549 method_params = tree_cons (NULL_TREE, object,
6550 tree_cons (NULL_TREE, selector,
6551 method_params));
6554 /* ??? Selector is not at this point something we can use inside
6555 the compiler itself. Set it to garbage for the nonce. */
6556 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6557 return build_function_call (t, method_params);
6560 static void
6561 build_protocol_reference (tree p)
6563 tree decl;
6564 const char *proto_name;
6566 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6568 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6569 decl = start_var_decl (objc_protocol_template, proto_name);
6571 PROTOCOL_FORWARD_DECL (p) = decl;
6574 /* This function is called by the parser when (and only when) a
6575 @protocol() expression is found, in order to compile it. */
6576 tree
6577 objc_build_protocol_expr (tree protoname)
6579 tree expr;
6580 tree p = lookup_protocol (protoname);
6582 if (!p)
6584 error ("cannot find protocol declaration for %qs",
6585 IDENTIFIER_POINTER (protoname));
6586 return error_mark_node;
6589 if (!PROTOCOL_FORWARD_DECL (p))
6590 build_protocol_reference (p);
6592 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6594 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6595 if we have it, rather than converting it here. */
6596 expr = convert (objc_protocol_type, expr);
6598 /* The @protocol() expression is being compiled into a pointer to a
6599 statically allocated instance of the Protocol class. To become
6600 usable at runtime, the 'isa' pointer of the instance need to be
6601 fixed up at runtime by the runtime library, to point to the
6602 actual 'Protocol' class. */
6604 /* For the GNU runtime, put the static Protocol instance in the list
6605 of statically allocated instances, so that we make sure that its
6606 'isa' pointer is fixed up at runtime by the GNU runtime library
6607 to point to the Protocol class (at runtime, when loading the
6608 module, the GNU runtime library loops on the statically allocated
6609 instances (as found in the defs field in objc_symtab) and fixups
6610 all the 'isa' pointers of those objects). */
6611 if (! flag_next_runtime)
6613 /* This type is a struct containing the fields of a Protocol
6614 object. (Cfr. objc_protocol_type instead is the type of a pointer
6615 to such a struct). */
6616 tree protocol_struct_type = xref_tag
6617 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6618 tree *chain;
6620 /* Look for the list of Protocol statically allocated instances
6621 to fixup at runtime. Create a new list to hold Protocol
6622 statically allocated instances, if the list is not found. At
6623 present there is only another list, holding NSConstantString
6624 static instances to be fixed up at runtime. */
6625 for (chain = &objc_static_instances;
6626 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6627 chain = &TREE_CHAIN (*chain));
6628 if (!*chain)
6630 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6631 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6632 class_names);
6635 /* Add this statically allocated instance to the Protocol list. */
6636 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6637 PROTOCOL_FORWARD_DECL (p),
6638 TREE_PURPOSE (*chain));
6642 return expr;
6645 /* This function is called by the parser when a @selector() expression
6646 is found, in order to compile it. It is only called by the parser
6647 and only to compile a @selector(). */
6648 tree
6649 objc_build_selector_expr (tree selnamelist)
6651 tree selname;
6653 /* Obtain the full selector name. */
6654 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6655 /* A unary selector. */
6656 selname = selnamelist;
6657 else if (TREE_CODE (selnamelist) == TREE_LIST)
6658 selname = build_keyword_selector (selnamelist);
6659 else
6660 abort ();
6662 /* If we are required to check @selector() expressions as they
6663 are found, check that the selector has been declared. */
6664 if (warn_undeclared_selector)
6666 /* Look the selector up in the list of all known class and
6667 instance methods (up to this line) to check that the selector
6668 exists. */
6669 hash hsh;
6671 /* First try with instance methods. */
6672 hsh = hash_lookup (nst_method_hash_list, selname);
6674 /* If not found, try with class methods. */
6675 if (!hsh)
6677 hsh = hash_lookup (cls_method_hash_list, selname);
6680 /* If still not found, print out a warning. */
6681 if (!hsh)
6683 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6688 if (flag_typed_selectors)
6689 return build_typed_selector_reference (selname, 0);
6690 else
6691 return build_selector_reference (selname);
6694 tree
6695 objc_build_encode_expr (tree type)
6697 tree result;
6698 const char *string;
6700 encode_type (type, obstack_object_size (&util_obstack),
6701 OBJC_ENCODE_INLINE_DEFS);
6702 obstack_1grow (&util_obstack, 0); /* null terminate string */
6703 string = obstack_finish (&util_obstack);
6705 /* Synthesize a string that represents the encoded struct/union. */
6706 result = my_build_string (strlen (string) + 1, string);
6707 obstack_free (&util_obstack, util_firstobj);
6708 return result;
6711 static tree
6712 build_ivar_reference (tree id)
6714 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6716 /* Historically, a class method that produced objects (factory
6717 method) would assign `self' to the instance that it
6718 allocated. This would effectively turn the class method into
6719 an instance method. Following this assignment, the instance
6720 variables could be accessed. That practice, while safe,
6721 violates the simple rule that a class method should not refer
6722 to an instance variable. It's better to catch the cases
6723 where this is done unknowingly than to support the above
6724 paradigm. */
6725 warning (0, "instance variable %qs accessed in class method",
6726 IDENTIFIER_POINTER (id));
6727 self_decl = convert (objc_instance_type, self_decl); /* cast */
6730 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6733 /* Compute a hash value for a given method SEL_NAME. */
6735 static size_t
6736 hash_func (tree sel_name)
6738 const unsigned char *s
6739 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6740 size_t h = 0;
6742 while (*s)
6743 h = h * 67 + *s++ - 113;
6744 return h;
6747 static void
6748 hash_init (void)
6750 nst_method_hash_list
6751 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6752 cls_method_hash_list
6753 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6755 /* Initialize the hash table used to hold the constant string objects. */
6756 string_htab = htab_create_ggc (31, string_hash,
6757 string_eq, NULL);
6759 /* Initialize the hash table used to hold EH-volatilized types. */
6760 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6761 volatilized_eq, NULL);
6764 /* WARNING!!!! hash_enter is called with a method, and will peek
6765 inside to find its selector! But hash_lookup is given a selector
6766 directly, and looks for the selector that's inside the found
6767 entry's key (method) for comparison. */
6769 static void
6770 hash_enter (hash *hashlist, tree method)
6772 hash obj;
6773 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6775 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6776 obj->list = 0;
6777 obj->next = hashlist[slot];
6778 obj->key = method;
6780 hashlist[slot] = obj; /* append to front */
6783 static hash
6784 hash_lookup (hash *hashlist, tree sel_name)
6786 hash target;
6788 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6790 while (target)
6792 if (sel_name == METHOD_SEL_NAME (target->key))
6793 return target;
6795 target = target->next;
6797 return 0;
6800 static void
6801 hash_add_attr (hash entry, tree value)
6803 attr obj;
6805 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6806 obj->next = entry->list;
6807 obj->value = value;
6809 entry->list = obj; /* append to front */
6812 static tree
6813 lookup_method (tree mchain, tree method)
6815 tree key;
6817 if (TREE_CODE (method) == IDENTIFIER_NODE)
6818 key = method;
6819 else
6820 key = METHOD_SEL_NAME (method);
6822 while (mchain)
6824 if (METHOD_SEL_NAME (mchain) == key)
6825 return mchain;
6827 mchain = TREE_CHAIN (mchain);
6829 return NULL_TREE;
6832 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6833 in INTERFACE, along with any categories and protocols attached thereto.
6834 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6835 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6836 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6837 be found in INTERFACE or any of its superclasses, look for an _instance_
6838 method of the same name in the root class as a last resort.
6840 If a suitable method cannot be found, return NULL_TREE. */
6842 static tree
6843 lookup_method_static (tree interface, tree ident, int flags)
6845 tree meth = NULL_TREE, root_inter = NULL_TREE;
6846 tree inter = interface;
6847 int is_class = (flags & OBJC_LOOKUP_CLASS);
6848 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6850 while (inter)
6852 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6853 tree category = inter;
6855 /* First, look up the method in the class itself. */
6856 if ((meth = lookup_method (chain, ident)))
6857 return meth;
6859 /* Failing that, look for the method in each category of the class. */
6860 while ((category = CLASS_CATEGORY_LIST (category)))
6862 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6864 /* Check directly in each category. */
6865 if ((meth = lookup_method (chain, ident)))
6866 return meth;
6868 /* Failing that, check in each category's protocols. */
6869 if (CLASS_PROTOCOL_LIST (category))
6871 if ((meth = (lookup_method_in_protocol_list
6872 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6873 return meth;
6877 /* If not found in categories, check in protocols of the main class. */
6878 if (CLASS_PROTOCOL_LIST (inter))
6880 if ((meth = (lookup_method_in_protocol_list
6881 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6882 return meth;
6885 /* If we were instructed not to look in superclasses, don't. */
6886 if (no_superclasses)
6887 return NULL_TREE;
6889 /* Failing that, climb up the inheritance hierarchy. */
6890 root_inter = inter;
6891 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6893 while (inter);
6895 /* If no class (factory) method was found, check if an _instance_
6896 method of the same name exists in the root class. This is what
6897 the Objective-C runtime will do. If an instance method was not
6898 found, return 0. */
6899 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6902 /* Add the method to the hash list if it doesn't contain an identical
6903 method already. */
6905 static void
6906 add_method_to_hash_list (hash *hash_list, tree method)
6908 hash hsh;
6910 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6912 /* Install on a global chain. */
6913 hash_enter (hash_list, method);
6915 else
6917 /* Check types against those; if different, add to a list. */
6918 attr loop;
6919 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6920 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6921 already_there |= comp_proto_with_proto (method, loop->value, 1);
6922 if (!already_there)
6923 hash_add_attr (hsh, method);
6927 static tree
6928 objc_add_method (tree class, tree method, int is_class)
6930 tree mth;
6932 if (!(mth = lookup_method (is_class
6933 ? CLASS_CLS_METHODS (class)
6934 : CLASS_NST_METHODS (class), method)))
6936 /* put method on list in reverse order */
6937 if (is_class)
6939 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6940 CLASS_CLS_METHODS (class) = method;
6942 else
6944 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6945 CLASS_NST_METHODS (class) = method;
6948 else
6950 /* When processing an @interface for a class or category, give hard
6951 errors on methods with identical selectors but differing argument
6952 and/or return types. We do not do this for @implementations, because
6953 C/C++ will do it for us (i.e., there will be duplicate function
6954 definition errors). */
6955 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6956 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6957 && !comp_proto_with_proto (method, mth, 1))
6958 error ("duplicate declaration of method %<%c%s%>",
6959 is_class ? '+' : '-',
6960 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6963 if (is_class)
6964 add_method_to_hash_list (cls_method_hash_list, method);
6965 else
6967 add_method_to_hash_list (nst_method_hash_list, method);
6969 /* Instance methods in root classes (and categories thereof)
6970 may act as class methods as a last resort. We also add
6971 instance methods listed in @protocol declarations to
6972 the class hash table, on the assumption that @protocols
6973 may be adopted by root classes or categories. */
6974 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6975 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6976 class = lookup_interface (CLASS_NAME (class));
6978 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6979 || !CLASS_SUPER_NAME (class))
6980 add_method_to_hash_list (cls_method_hash_list, method);
6983 return method;
6986 static tree
6987 add_class (tree class_name, tree name)
6989 struct interface_tuple **slot;
6991 /* Put interfaces on list in reverse order. */
6992 TREE_CHAIN (class_name) = interface_chain;
6993 interface_chain = class_name;
6995 if (interface_htab == NULL)
6996 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6997 slot = (struct interface_tuple **)
6998 htab_find_slot_with_hash (interface_htab, name,
6999 IDENTIFIER_HASH_VALUE (name),
7000 INSERT);
7001 if (!*slot)
7003 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7004 (*slot)->id = name;
7006 (*slot)->class_name = class_name;
7008 return interface_chain;
7011 static void
7012 add_category (tree class, tree category)
7014 /* Put categories on list in reverse order. */
7015 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7017 if (cat)
7019 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7020 IDENTIFIER_POINTER (CLASS_NAME (class)),
7021 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7023 else
7025 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7026 CLASS_CATEGORY_LIST (class) = category;
7030 /* Called after parsing each instance variable declaration. Necessary to
7031 preserve typedefs and implement public/private...
7033 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7035 static tree
7036 add_instance_variable (tree class, int public, tree field_decl)
7038 tree field_type = TREE_TYPE (field_decl);
7039 const char *ivar_name = DECL_NAME (field_decl)
7040 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7041 : "<unnamed>";
7043 #ifdef OBJCPLUS
7044 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7046 error ("illegal reference type specified for instance variable %qs",
7047 ivar_name);
7048 /* Return class as is without adding this ivar. */
7049 return class;
7051 #endif
7053 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7054 || TYPE_SIZE (field_type) == error_mark_node)
7055 /* 'type[0]' is allowed, but 'type[]' is not! */
7057 error ("instance variable %qs has unknown size", ivar_name);
7058 /* Return class as is without adding this ivar. */
7059 return class;
7062 #ifdef OBJCPLUS
7063 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7064 need to either (1) warn the user about it or (2) generate suitable
7065 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7066 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7067 if (IS_AGGR_TYPE (field_type)
7068 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7069 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7070 || TYPE_POLYMORPHIC_P (field_type)))
7072 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7074 if (flag_objc_call_cxx_cdtors)
7076 /* Since the ObjC runtime will be calling the constructors and
7077 destructors for us, the only thing we can't handle is the lack
7078 of a default constructor. */
7079 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7080 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7082 warning (0, "type %qs has no default constructor to call",
7083 type_name);
7085 /* If we cannot call a constructor, we should also avoid
7086 calling the destructor, for symmetry. */
7087 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7088 warning (0, "destructor for %qs shall not be run either",
7089 type_name);
7092 else
7094 static bool warn_cxx_ivars = false;
7096 if (TYPE_POLYMORPHIC_P (field_type))
7098 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7099 initialize them. */
7100 error ("type %qs has virtual member functions", type_name);
7101 error ("illegal aggregate type %qs specified "
7102 "for instance variable %qs",
7103 type_name, ivar_name);
7104 /* Return class as is without adding this ivar. */
7105 return class;
7108 /* User-defined constructors and destructors are not known to Obj-C
7109 and hence will not be called. This may or may not be a problem. */
7110 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7111 warning (0, "type %qs has a user-defined constructor", type_name);
7112 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7113 warning (0, "type %qs has a user-defined destructor", type_name);
7115 if (!warn_cxx_ivars)
7117 warning (0, "C++ constructors and destructors will not "
7118 "be invoked for Objective-C fields");
7119 warn_cxx_ivars = true;
7123 #endif
7125 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7126 switch (public)
7128 case 0:
7129 TREE_PUBLIC (field_decl) = 0;
7130 TREE_PRIVATE (field_decl) = 0;
7131 TREE_PROTECTED (field_decl) = 1;
7132 break;
7134 case 1:
7135 TREE_PUBLIC (field_decl) = 1;
7136 TREE_PRIVATE (field_decl) = 0;
7137 TREE_PROTECTED (field_decl) = 0;
7138 break;
7140 case 2:
7141 TREE_PUBLIC (field_decl) = 0;
7142 TREE_PRIVATE (field_decl) = 1;
7143 TREE_PROTECTED (field_decl) = 0;
7144 break;
7148 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7150 return class;
7153 static tree
7154 is_ivar (tree decl_chain, tree ident)
7156 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7157 if (DECL_NAME (decl_chain) == ident)
7158 return decl_chain;
7159 return NULL_TREE;
7162 /* True if the ivar is private and we are not in its implementation. */
7164 static int
7165 is_private (tree decl)
7167 return (TREE_PRIVATE (decl)
7168 && ! is_ivar (CLASS_IVARS (implementation_template),
7169 DECL_NAME (decl)));
7172 /* We have an instance variable reference;, check to see if it is public. */
7175 objc_is_public (tree expr, tree identifier)
7177 tree basetype, decl;
7179 #ifdef OBJCPLUS
7180 if (processing_template_decl)
7181 return 1;
7182 #endif
7184 if (TREE_TYPE (expr) == error_mark_node)
7185 return 1;
7187 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7189 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7191 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7193 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7195 if (!class)
7197 error ("cannot find interface declaration for %qs",
7198 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7199 return 0;
7202 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7204 if (TREE_PUBLIC (decl))
7205 return 1;
7207 /* Important difference between the Stepstone translator:
7208 all instance variables should be public within the context
7209 of the implementation. */
7210 if (objc_implementation_context
7211 && ((TREE_CODE (objc_implementation_context)
7212 == CLASS_IMPLEMENTATION_TYPE)
7213 || (TREE_CODE (objc_implementation_context)
7214 == CATEGORY_IMPLEMENTATION_TYPE)))
7216 tree curtype = TYPE_MAIN_VARIANT
7217 (CLASS_STATIC_TEMPLATE
7218 (implementation_template));
7220 if (basetype == curtype
7221 || DERIVED_FROM_P (basetype, curtype))
7223 int private = is_private (decl);
7225 if (private)
7226 error ("instance variable %qs is declared private",
7227 IDENTIFIER_POINTER (DECL_NAME (decl)));
7229 return !private;
7233 /* The 2.95.2 compiler sometimes allowed C functions to access
7234 non-@public ivars. We will let this slide for now... */
7235 if (!objc_method_context)
7237 warning (0, "instance variable %qs is %s; "
7238 "this will be a hard error in the future",
7239 IDENTIFIER_POINTER (identifier),
7240 TREE_PRIVATE (decl) ? "@private" : "@protected");
7241 return 1;
7244 error ("instance variable %qs is declared %s",
7245 IDENTIFIER_POINTER (identifier),
7246 TREE_PRIVATE (decl) ? "private" : "protected");
7247 return 0;
7252 return 1;
7255 /* Make sure all entries in CHAIN are also in LIST. */
7257 static int
7258 check_methods (tree chain, tree list, int mtype)
7260 int first = 1;
7262 while (chain)
7264 if (!lookup_method (list, chain))
7266 if (first)
7268 if (TREE_CODE (objc_implementation_context)
7269 == CLASS_IMPLEMENTATION_TYPE)
7270 warning (0, "incomplete implementation of class %qs",
7271 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7272 else if (TREE_CODE (objc_implementation_context)
7273 == CATEGORY_IMPLEMENTATION_TYPE)
7274 warning (0, "incomplete implementation of category %qs",
7275 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7276 first = 0;
7279 warning (0, "method definition for %<%c%s%> not found",
7280 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7283 chain = TREE_CHAIN (chain);
7286 return first;
7289 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7291 static int
7292 conforms_to_protocol (tree class, tree protocol)
7294 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7296 tree p = CLASS_PROTOCOL_LIST (class);
7297 while (p && TREE_VALUE (p) != protocol)
7298 p = TREE_CHAIN (p);
7300 if (!p)
7302 tree super = (CLASS_SUPER_NAME (class)
7303 ? lookup_interface (CLASS_SUPER_NAME (class))
7304 : NULL_TREE);
7305 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7306 if (!tmp)
7307 return 0;
7311 return 1;
7314 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7315 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7317 static int
7318 check_methods_accessible (tree chain, tree context, int mtype)
7320 int first = 1;
7321 tree list;
7322 tree base_context = context;
7324 while (chain)
7326 context = base_context;
7327 while (context)
7329 if (mtype == '+')
7330 list = CLASS_CLS_METHODS (context);
7331 else
7332 list = CLASS_NST_METHODS (context);
7334 if (lookup_method (list, chain))
7335 break;
7337 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7338 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7339 context = (CLASS_SUPER_NAME (context)
7340 ? lookup_interface (CLASS_SUPER_NAME (context))
7341 : NULL_TREE);
7343 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7344 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7345 context = (CLASS_NAME (context)
7346 ? lookup_interface (CLASS_NAME (context))
7347 : NULL_TREE);
7348 else
7349 abort ();
7352 if (context == NULL_TREE)
7354 if (first)
7356 if (TREE_CODE (objc_implementation_context)
7357 == CLASS_IMPLEMENTATION_TYPE)
7358 warning (0, "incomplete implementation of class %qs",
7359 IDENTIFIER_POINTER
7360 (CLASS_NAME (objc_implementation_context)));
7361 else if (TREE_CODE (objc_implementation_context)
7362 == CATEGORY_IMPLEMENTATION_TYPE)
7363 warning (0, "incomplete implementation of category %qs",
7364 IDENTIFIER_POINTER
7365 (CLASS_SUPER_NAME (objc_implementation_context)));
7366 first = 0;
7368 warning (0, "method definition for %<%c%s%> not found",
7369 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7372 chain = TREE_CHAIN (chain); /* next method... */
7374 return first;
7377 /* Check whether the current interface (accessible via
7378 'objc_implementation_context') actually implements protocol P, along
7379 with any protocols that P inherits. */
7381 static void
7382 check_protocol (tree p, const char *type, const char *name)
7384 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7386 int f1, f2;
7388 /* Ensure that all protocols have bodies! */
7389 if (warn_protocol)
7391 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7392 CLASS_CLS_METHODS (objc_implementation_context),
7393 '+');
7394 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7395 CLASS_NST_METHODS (objc_implementation_context),
7396 '-');
7398 else
7400 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7401 objc_implementation_context,
7402 '+');
7403 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7404 objc_implementation_context,
7405 '-');
7408 if (!f1 || !f2)
7409 warning (0, "%s %qs does not fully implement the %qs protocol",
7410 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7413 /* Check protocols recursively. */
7414 if (PROTOCOL_LIST (p))
7416 tree subs = PROTOCOL_LIST (p);
7417 tree super_class =
7418 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7420 while (subs)
7422 tree sub = TREE_VALUE (subs);
7424 /* If the superclass does not conform to the protocols
7425 inherited by P, then we must! */
7426 if (!super_class || !conforms_to_protocol (super_class, sub))
7427 check_protocol (sub, type, name);
7428 subs = TREE_CHAIN (subs);
7433 /* Check whether the current interface (accessible via
7434 'objc_implementation_context') actually implements the protocols listed
7435 in PROTO_LIST. */
7437 static void
7438 check_protocols (tree proto_list, const char *type, const char *name)
7440 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7442 tree p = TREE_VALUE (proto_list);
7444 check_protocol (p, type, name);
7448 /* Make sure that the class CLASS_NAME is defined
7449 CODE says which kind of thing CLASS_NAME ought to be.
7450 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7451 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7453 static tree
7454 start_class (enum tree_code code, tree class_name, tree super_name,
7455 tree protocol_list)
7457 tree class, decl;
7459 #ifdef OBJCPLUS
7460 if (current_namespace != global_namespace) {
7461 error ("Objective-C declarations may only appear in global scope");
7463 #endif /* OBJCPLUS */
7465 if (objc_implementation_context)
7467 warning (0, "%<@end%> missing in implementation context");
7468 finish_class (objc_implementation_context);
7469 objc_ivar_chain = NULL_TREE;
7470 objc_implementation_context = NULL_TREE;
7473 class = make_node (code);
7474 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7476 /* Check for existence of the super class, if one was specified. Note
7477 that we must have seen an @interface, not just a @class. If we
7478 are looking at a @compatibility_alias, traverse it first. */
7479 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7480 && super_name)
7482 tree super = objc_is_class_name (super_name);
7484 if (!super || !lookup_interface (super))
7486 error ("cannot find interface declaration for %qs, superclass of %qs",
7487 IDENTIFIER_POINTER (super ? super : super_name),
7488 IDENTIFIER_POINTER (class_name));
7489 super_name = NULL_TREE;
7491 else
7492 super_name = super;
7495 CLASS_NAME (class) = class_name;
7496 CLASS_SUPER_NAME (class) = super_name;
7497 CLASS_CLS_METHODS (class) = NULL_TREE;
7499 if (! objc_is_class_name (class_name)
7500 && (decl = lookup_name (class_name)))
7502 error ("%qs redeclared as different kind of symbol",
7503 IDENTIFIER_POINTER (class_name));
7504 error ("previous declaration of %q+D",
7505 decl);
7508 if (code == CLASS_IMPLEMENTATION_TYPE)
7511 tree chain;
7513 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7514 if (TREE_VALUE (chain) == class_name)
7516 error ("reimplementation of class %qs",
7517 IDENTIFIER_POINTER (class_name));
7518 return error_mark_node;
7520 implemented_classes = tree_cons (NULL_TREE, class_name,
7521 implemented_classes);
7524 /* Reset for multiple classes per file. */
7525 method_slot = 0;
7527 objc_implementation_context = class;
7529 /* Lookup the interface for this implementation. */
7531 if (!(implementation_template = lookup_interface (class_name)))
7533 warning (0, "cannot find interface declaration for %qs",
7534 IDENTIFIER_POINTER (class_name));
7535 add_class (implementation_template = objc_implementation_context,
7536 class_name);
7539 /* If a super class has been specified in the implementation,
7540 insure it conforms to the one specified in the interface. */
7542 if (super_name
7543 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7545 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7546 const char *const name =
7547 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7548 error ("conflicting super class name %qs",
7549 IDENTIFIER_POINTER (super_name));
7550 error ("previous declaration of %qs", name);
7553 else if (! super_name)
7555 CLASS_SUPER_NAME (objc_implementation_context)
7556 = CLASS_SUPER_NAME (implementation_template);
7560 else if (code == CLASS_INTERFACE_TYPE)
7562 if (lookup_interface (class_name))
7563 #ifdef OBJCPLUS
7564 error ("duplicate interface declaration for class %qs",
7565 #else
7566 warning (0, "duplicate interface declaration for class %qs",
7567 #endif
7568 IDENTIFIER_POINTER (class_name));
7569 else
7570 add_class (class, class_name);
7572 if (protocol_list)
7573 CLASS_PROTOCOL_LIST (class)
7574 = lookup_and_install_protocols (protocol_list);
7577 else if (code == CATEGORY_INTERFACE_TYPE)
7579 tree class_category_is_assoc_with;
7581 /* For a category, class_name is really the name of the class that
7582 the following set of methods will be associated with. We must
7583 find the interface so that can derive the objects template. */
7585 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7587 error ("cannot find interface declaration for %qs",
7588 IDENTIFIER_POINTER (class_name));
7589 exit (FATAL_EXIT_CODE);
7591 else
7592 add_category (class_category_is_assoc_with, class);
7594 if (protocol_list)
7595 CLASS_PROTOCOL_LIST (class)
7596 = lookup_and_install_protocols (protocol_list);
7599 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7601 /* Reset for multiple classes per file. */
7602 method_slot = 0;
7604 objc_implementation_context = class;
7606 /* For a category, class_name is really the name of the class that
7607 the following set of methods will be associated with. We must
7608 find the interface so that can derive the objects template. */
7610 if (!(implementation_template = lookup_interface (class_name)))
7612 error ("cannot find interface declaration for %qs",
7613 IDENTIFIER_POINTER (class_name));
7614 exit (FATAL_EXIT_CODE);
7617 return class;
7620 static tree
7621 continue_class (tree class)
7623 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7624 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7626 struct imp_entry *imp_entry;
7628 /* Check consistency of the instance variables. */
7630 if (CLASS_RAW_IVARS (class))
7631 check_ivars (implementation_template, class);
7633 /* code generation */
7635 #ifdef OBJCPLUS
7636 push_lang_context (lang_name_c);
7637 #endif
7639 build_private_template (implementation_template);
7640 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7641 objc_instance_type = build_pointer_type (uprivate_record);
7643 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7645 imp_entry->next = imp_list;
7646 imp_entry->imp_context = class;
7647 imp_entry->imp_template = implementation_template;
7649 synth_forward_declarations ();
7650 imp_entry->class_decl = UOBJC_CLASS_decl;
7651 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7652 imp_entry->has_cxx_cdtors = 0;
7654 /* Append to front and increment count. */
7655 imp_list = imp_entry;
7656 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7657 imp_count++;
7658 else
7659 cat_count++;
7661 #ifdef OBJCPLUS
7662 pop_lang_context ();
7663 #endif /* OBJCPLUS */
7665 return get_class_ivars (implementation_template, true);
7668 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7670 #ifdef OBJCPLUS
7671 push_lang_context (lang_name_c);
7672 #endif /* OBJCPLUS */
7674 build_private_template (class);
7676 #ifdef OBJCPLUS
7677 pop_lang_context ();
7678 #endif /* OBJCPLUS */
7680 return NULL_TREE;
7683 else
7684 return error_mark_node;
7687 /* This is called once we see the "@end" in an interface/implementation. */
7689 static void
7690 finish_class (tree class)
7692 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7694 /* All code generation is done in finish_objc. */
7696 if (implementation_template != objc_implementation_context)
7698 /* Ensure that all method listed in the interface contain bodies. */
7699 check_methods (CLASS_CLS_METHODS (implementation_template),
7700 CLASS_CLS_METHODS (objc_implementation_context), '+');
7701 check_methods (CLASS_NST_METHODS (implementation_template),
7702 CLASS_NST_METHODS (objc_implementation_context), '-');
7704 if (CLASS_PROTOCOL_LIST (implementation_template))
7705 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7706 "class",
7707 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7711 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7713 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7715 if (category)
7717 /* Ensure all method listed in the interface contain bodies. */
7718 check_methods (CLASS_CLS_METHODS (category),
7719 CLASS_CLS_METHODS (objc_implementation_context), '+');
7720 check_methods (CLASS_NST_METHODS (category),
7721 CLASS_NST_METHODS (objc_implementation_context), '-');
7723 if (CLASS_PROTOCOL_LIST (category))
7724 check_protocols (CLASS_PROTOCOL_LIST (category),
7725 "category",
7726 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7731 static tree
7732 add_protocol (tree protocol)
7734 /* Put protocol on list in reverse order. */
7735 TREE_CHAIN (protocol) = protocol_chain;
7736 protocol_chain = protocol;
7737 return protocol_chain;
7740 static tree
7741 lookup_protocol (tree ident)
7743 tree chain;
7745 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7746 if (ident == PROTOCOL_NAME (chain))
7747 return chain;
7749 return NULL_TREE;
7752 /* This function forward declares the protocols named by NAMES. If
7753 they are already declared or defined, the function has no effect. */
7755 void
7756 objc_declare_protocols (tree names)
7758 tree list;
7760 #ifdef OBJCPLUS
7761 if (current_namespace != global_namespace) {
7762 error ("Objective-C declarations may only appear in global scope");
7764 #endif /* OBJCPLUS */
7766 for (list = names; list; list = TREE_CHAIN (list))
7768 tree name = TREE_VALUE (list);
7770 if (lookup_protocol (name) == NULL_TREE)
7772 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7774 TYPE_LANG_SLOT_1 (protocol)
7775 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7776 PROTOCOL_NAME (protocol) = name;
7777 PROTOCOL_LIST (protocol) = NULL_TREE;
7778 add_protocol (protocol);
7779 PROTOCOL_DEFINED (protocol) = 0;
7780 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7785 static tree
7786 start_protocol (enum tree_code code, tree name, tree list)
7788 tree protocol;
7790 #ifdef OBJCPLUS
7791 if (current_namespace != global_namespace) {
7792 error ("Objective-C declarations may only appear in global scope");
7794 #endif /* OBJCPLUS */
7796 protocol = lookup_protocol (name);
7798 if (!protocol)
7800 protocol = make_node (code);
7801 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7803 PROTOCOL_NAME (protocol) = name;
7804 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7805 add_protocol (protocol);
7806 PROTOCOL_DEFINED (protocol) = 1;
7807 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7809 check_protocol_recursively (protocol, list);
7811 else if (! PROTOCOL_DEFINED (protocol))
7813 PROTOCOL_DEFINED (protocol) = 1;
7814 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7816 check_protocol_recursively (protocol, list);
7818 else
7820 warning (0, "duplicate declaration for protocol %qs",
7821 IDENTIFIER_POINTER (name));
7823 return protocol;
7827 /* "Encode" a data type into a string, which grows in util_obstack.
7828 ??? What is the FORMAT? Someone please document this! */
7830 static void
7831 encode_type_qualifiers (tree declspecs)
7833 tree spec;
7835 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7837 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7838 obstack_1grow (&util_obstack, 'n');
7839 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7840 obstack_1grow (&util_obstack, 'N');
7841 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7842 obstack_1grow (&util_obstack, 'o');
7843 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7844 obstack_1grow (&util_obstack, 'O');
7845 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7846 obstack_1grow (&util_obstack, 'R');
7847 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7848 obstack_1grow (&util_obstack, 'V');
7852 /* Encode a pointer type. */
7854 static void
7855 encode_pointer (tree type, int curtype, int format)
7857 tree pointer_to = TREE_TYPE (type);
7859 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7861 if (OBJC_TYPE_NAME (pointer_to)
7862 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7864 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7866 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7868 obstack_1grow (&util_obstack, '@');
7869 return;
7871 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7872 && TYPE_OBJC_INTERFACE (pointer_to))
7874 if (generating_instance_variables)
7876 obstack_1grow (&util_obstack, '@');
7877 obstack_1grow (&util_obstack, '"');
7878 obstack_grow (&util_obstack, name, strlen (name));
7879 obstack_1grow (&util_obstack, '"');
7880 return;
7882 else
7884 obstack_1grow (&util_obstack, '@');
7885 return;
7888 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7890 obstack_1grow (&util_obstack, '#');
7891 return;
7893 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7895 obstack_1grow (&util_obstack, ':');
7896 return;
7900 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7901 && TYPE_MODE (pointer_to) == QImode)
7903 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7904 ? OBJC_TYPE_NAME (pointer_to)
7905 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7907 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7909 /* It appears that "r*" means "const char *" rather than
7910 "char *const". */
7911 if (TYPE_READONLY (pointer_to))
7912 obstack_1grow (&util_obstack, 'r');
7914 obstack_1grow (&util_obstack, '*');
7915 return;
7919 /* We have a type that does not get special treatment. */
7921 /* NeXT extension */
7922 obstack_1grow (&util_obstack, '^');
7923 encode_type (pointer_to, curtype, format);
7926 static void
7927 encode_array (tree type, int curtype, int format)
7929 tree an_int_cst = TYPE_SIZE (type);
7930 tree array_of = TREE_TYPE (type);
7931 char buffer[40];
7933 /* An incomplete array is treated like a pointer. */
7934 if (an_int_cst == NULL)
7936 encode_pointer (type, curtype, format);
7937 return;
7940 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7941 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7942 else
7943 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7944 TREE_INT_CST_LOW (an_int_cst)
7945 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7947 obstack_grow (&util_obstack, buffer, strlen (buffer));
7948 encode_type (array_of, curtype, format);
7949 obstack_1grow (&util_obstack, ']');
7950 return;
7953 static void
7954 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7956 tree field = TYPE_FIELDS (type);
7958 for (; field; field = TREE_CHAIN (field))
7960 #ifdef OBJCPLUS
7961 /* C++ static members, and things that are not field at all,
7962 should not appear in the encoding. */
7963 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7964 continue;
7965 #endif
7967 /* Recursively encode fields of embedded base classes. */
7968 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7969 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7971 encode_aggregate_fields (TREE_TYPE (field),
7972 pointed_to, curtype, format);
7973 continue;
7976 if (generating_instance_variables && !pointed_to)
7978 tree fname = DECL_NAME (field);
7980 obstack_1grow (&util_obstack, '"');
7982 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7983 obstack_grow (&util_obstack,
7984 IDENTIFIER_POINTER (fname),
7985 strlen (IDENTIFIER_POINTER (fname)));
7987 obstack_1grow (&util_obstack, '"');
7990 encode_field_decl (field, curtype, format);
7994 static void
7995 encode_aggregate_within (tree type, int curtype, int format, int left,
7996 int right)
7998 tree name;
7999 /* NB: aggregates that are pointed to have slightly different encoding
8000 rules in that you never encode the names of instance variables. */
8001 int ob_size = obstack_object_size (&util_obstack);
8002 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8003 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8004 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8005 int inline_contents
8006 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8007 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8009 /* Traverse struct aliases; it is important to get the
8010 original struct and its tag name (if any). */
8011 type = TYPE_MAIN_VARIANT (type);
8012 name = OBJC_TYPE_NAME (type);
8013 /* Open parenth/bracket. */
8014 obstack_1grow (&util_obstack, left);
8016 /* Encode the struct/union tag name, or '?' if a tag was
8017 not provided. Typedef aliases do not qualify. */
8018 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8019 #ifdef OBJCPLUS
8020 /* Did this struct have a tag? */
8021 && !TYPE_WAS_ANONYMOUS (type)
8022 #endif
8024 obstack_grow (&util_obstack,
8025 IDENTIFIER_POINTER (name),
8026 strlen (IDENTIFIER_POINTER (name)));
8027 else
8028 obstack_1grow (&util_obstack, '?');
8030 /* Encode the types (and possibly names) of the inner fields,
8031 if required. */
8032 if (inline_contents)
8034 obstack_1grow (&util_obstack, '=');
8035 encode_aggregate_fields (type, pointed_to, curtype, format);
8037 /* Close parenth/bracket. */
8038 obstack_1grow (&util_obstack, right);
8041 static void
8042 encode_aggregate (tree type, int curtype, int format)
8044 enum tree_code code = TREE_CODE (type);
8046 switch (code)
8048 case RECORD_TYPE:
8050 encode_aggregate_within (type, curtype, format, '{', '}');
8051 break;
8053 case UNION_TYPE:
8055 encode_aggregate_within (type, curtype, format, '(', ')');
8056 break;
8059 case ENUMERAL_TYPE:
8060 obstack_1grow (&util_obstack, 'i');
8061 break;
8063 default:
8064 break;
8068 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8069 field type. */
8071 static void
8072 encode_next_bitfield (int width)
8074 char buffer[40];
8075 sprintf (buffer, "b%d", width);
8076 obstack_grow (&util_obstack, buffer, strlen (buffer));
8079 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8080 static void
8081 encode_type (tree type, int curtype, int format)
8083 enum tree_code code = TREE_CODE (type);
8084 char c;
8086 if (TYPE_READONLY (type))
8087 obstack_1grow (&util_obstack, 'r');
8089 if (code == INTEGER_TYPE)
8091 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8093 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8094 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8095 case 32:
8096 if (type == long_unsigned_type_node
8097 || type == long_integer_type_node)
8098 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8099 else
8100 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8101 break;
8102 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8103 default: abort ();
8105 obstack_1grow (&util_obstack, c);
8108 else if (code == REAL_TYPE)
8110 /* Floating point types. */
8111 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8113 case 32: c = 'f'; break;
8114 case 64:
8115 case 96:
8116 case 128: c = 'd'; break;
8117 default: abort ();
8119 obstack_1grow (&util_obstack, c);
8122 else if (code == VOID_TYPE)
8123 obstack_1grow (&util_obstack, 'v');
8125 else if (code == BOOLEAN_TYPE)
8126 obstack_1grow (&util_obstack, 'B');
8128 else if (code == ARRAY_TYPE)
8129 encode_array (type, curtype, format);
8131 else if (code == POINTER_TYPE)
8132 encode_pointer (type, curtype, format);
8134 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8135 encode_aggregate (type, curtype, format);
8137 else if (code == FUNCTION_TYPE) /* '?' */
8138 obstack_1grow (&util_obstack, '?');
8140 else if (code == COMPLEX_TYPE)
8142 obstack_1grow (&util_obstack, 'j');
8143 encode_type (TREE_TYPE (type), curtype, format);
8147 static void
8148 encode_gnu_bitfield (int position, tree type, int size)
8150 enum tree_code code = TREE_CODE (type);
8151 char buffer[40];
8152 char charType = '?';
8154 if (code == INTEGER_TYPE)
8156 if (integer_zerop (TYPE_MIN_VALUE (type)))
8158 /* Unsigned integer types. */
8160 if (TYPE_MODE (type) == QImode)
8161 charType = 'C';
8162 else if (TYPE_MODE (type) == HImode)
8163 charType = 'S';
8164 else if (TYPE_MODE (type) == SImode)
8166 if (type == long_unsigned_type_node)
8167 charType = 'L';
8168 else
8169 charType = 'I';
8171 else if (TYPE_MODE (type) == DImode)
8172 charType = 'Q';
8175 else
8176 /* Signed integer types. */
8178 if (TYPE_MODE (type) == QImode)
8179 charType = 'c';
8180 else if (TYPE_MODE (type) == HImode)
8181 charType = 's';
8182 else if (TYPE_MODE (type) == SImode)
8184 if (type == long_integer_type_node)
8185 charType = 'l';
8186 else
8187 charType = 'i';
8190 else if (TYPE_MODE (type) == DImode)
8191 charType = 'q';
8194 else if (code == ENUMERAL_TYPE)
8195 charType = 'i';
8196 else
8197 abort ();
8199 sprintf (buffer, "b%d%c%d", position, charType, size);
8200 obstack_grow (&util_obstack, buffer, strlen (buffer));
8203 static void
8204 encode_field_decl (tree field_decl, int curtype, int format)
8206 tree type;
8208 #ifdef OBJCPLUS
8209 /* C++ static members, and things that are not fields at all,
8210 should not appear in the encoding. */
8211 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8212 return;
8213 #endif
8215 type = TREE_TYPE (field_decl);
8217 /* Generate the bitfield typing information, if needed. Note the difference
8218 between GNU and NeXT runtimes. */
8219 if (DECL_BIT_FIELD_TYPE (field_decl))
8221 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8223 if (flag_next_runtime)
8224 encode_next_bitfield (size);
8225 else
8226 encode_gnu_bitfield (int_bit_position (field_decl),
8227 DECL_BIT_FIELD_TYPE (field_decl), size);
8229 else
8230 encode_type (TREE_TYPE (field_decl), curtype, format);
8233 static GTY(()) tree objc_parmlist = NULL_TREE;
8235 /* Append PARM to a list of formal parameters of a method, making a necessary
8236 array-to-pointer adjustment along the way. */
8238 static void
8239 objc_push_parm (tree parm)
8241 bool relayout_needed = false;
8242 /* Decay arrays and functions into pointers. */
8243 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8245 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8246 relayout_needed = true;
8248 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8250 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8251 relayout_needed = true;
8254 if (relayout_needed)
8255 relayout_decl (parm);
8258 DECL_ARG_TYPE (parm)
8259 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8261 /* Record constancy and volatility. */
8262 c_apply_type_quals_to_decl
8263 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8264 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8265 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8267 objc_parmlist = chainon (objc_parmlist, parm);
8270 /* Retrieve the formal parameter list constructed via preceding calls to
8271 objc_push_parm(). */
8273 #ifdef OBJCPLUS
8274 static tree
8275 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8276 #else
8277 static struct c_arg_info *
8278 objc_get_parm_info (int have_ellipsis)
8279 #endif
8281 #ifdef OBJCPLUS
8282 tree parm_info = objc_parmlist;
8283 objc_parmlist = NULL_TREE;
8285 return parm_info;
8286 #else
8287 tree parm_info = objc_parmlist;
8288 struct c_arg_info *arg_info;
8289 /* The C front-end requires an elaborate song and dance at
8290 this point. */
8291 push_scope ();
8292 declare_parm_level ();
8293 while (parm_info)
8295 tree next = TREE_CHAIN (parm_info);
8297 TREE_CHAIN (parm_info) = NULL_TREE;
8298 parm_info = pushdecl (parm_info);
8299 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8300 parm_info = next;
8302 arg_info = get_parm_info (have_ellipsis);
8303 pop_scope ();
8304 objc_parmlist = NULL_TREE;
8305 return arg_info;
8306 #endif
8309 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8310 method definitions. In the case of instance methods, we can be more
8311 specific as to the type of 'self'. */
8313 static void
8314 synth_self_and_ucmd_args (void)
8316 tree self_type;
8318 if (objc_method_context
8319 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8320 self_type = objc_instance_type;
8321 else
8322 /* Really a `struct objc_class *'. However, we allow people to
8323 assign to self, which changes its type midstream. */
8324 self_type = objc_object_type;
8326 /* id self; */
8327 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8329 /* SEL _cmd; */
8330 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8333 /* Transform an Objective-C method definition into a static C function
8334 definition, synthesizing the first two arguments, "self" and "_cmd",
8335 in the process. */
8337 static void
8338 start_method_def (tree method)
8340 tree parmlist;
8341 #ifdef OBJCPLUS
8342 tree parm_info;
8343 #else
8344 struct c_arg_info *parm_info;
8345 #endif
8346 int have_ellipsis = 0;
8348 /* If we are defining a "dealloc" method in a non-root class, we
8349 will need to check if a [super dealloc] is missing, and warn if
8350 it is. */
8351 if(CLASS_SUPER_NAME (objc_implementation_context)
8352 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8353 should_call_super_dealloc = 1;
8354 else
8355 should_call_super_dealloc = 0;
8357 /* Required to implement _msgSuper. */
8358 objc_method_context = method;
8359 UOBJC_SUPER_decl = NULL_TREE;
8361 /* Generate prototype declarations for arguments..."new-style". */
8362 synth_self_and_ucmd_args ();
8364 /* Generate argument declarations if a keyword_decl. */
8365 parmlist = METHOD_SEL_ARGS (method);
8366 while (parmlist)
8368 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8370 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8371 objc_push_parm (parm);
8372 parmlist = TREE_CHAIN (parmlist);
8375 if (METHOD_ADD_ARGS (method))
8377 tree akey;
8379 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8380 akey; akey = TREE_CHAIN (akey))
8382 objc_push_parm (TREE_VALUE (akey));
8385 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8386 have_ellipsis = 1;
8389 parm_info = objc_get_parm_info (have_ellipsis);
8391 really_start_method (objc_method_context, parm_info);
8394 static void
8395 warn_with_method (const char *message, int mtype, tree method)
8397 /* Add a readable method name to the warning. */
8398 warning (0, "%J%s %<%c%s%>", method,
8399 message, mtype, gen_method_decl (method));
8402 /* Return 1 if TYPE1 is equivalent to TYPE2
8403 for purposes of method overloading. */
8405 static int
8406 objc_types_are_equivalent (tree type1, tree type2)
8408 if (type1 == type2)
8409 return 1;
8411 /* Strip away indirections. */
8412 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8413 && (TREE_CODE (type1) == TREE_CODE (type2)))
8414 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8415 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8416 return 0;
8418 type1 = (TYPE_HAS_OBJC_INFO (type1)
8419 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8420 : NULL_TREE);
8421 type2 = (TYPE_HAS_OBJC_INFO (type2)
8422 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8423 : NULL_TREE);
8425 if (list_length (type1) == list_length (type2))
8427 for (; type2; type2 = TREE_CHAIN (type2))
8428 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8429 return 0;
8430 return 1;
8432 return 0;
8435 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8437 static int
8438 objc_types_share_size_and_alignment (tree type1, tree type2)
8440 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8441 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8444 /* Return 1 if PROTO1 is equivalent to PROTO2
8445 for purposes of method overloading. Ordinarily, the type signatures
8446 should match up exactly, unless STRICT is zero, in which case we
8447 shall allow differences in which the size and alignment of a type
8448 is the same. */
8450 static int
8451 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8453 tree type1, type2;
8455 /* The following test is needed in case there are hashing
8456 collisions. */
8457 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8458 return 0;
8460 /* Compare return types. */
8461 type1 = TREE_VALUE (TREE_TYPE (proto1));
8462 type2 = TREE_VALUE (TREE_TYPE (proto2));
8464 if (!objc_types_are_equivalent (type1, type2)
8465 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8466 return 0;
8468 /* Compare argument types. */
8469 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8470 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8471 type1 && type2;
8472 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8474 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8475 && (strict
8476 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8477 TREE_VALUE (type2))))
8478 return 0;
8481 return (!type1 && !type2);
8484 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8485 this occurs. ObjC method dispatches are _not_ like C++ virtual
8486 member function dispatches, and we account for the difference here. */
8487 tree
8488 #ifdef OBJCPLUS
8489 objc_fold_obj_type_ref (tree ref, tree known_type)
8490 #else
8491 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8492 tree known_type ATTRIBUTE_UNUSED)
8493 #endif
8495 #ifdef OBJCPLUS
8496 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8498 /* If the receiver does not have virtual member functions, there
8499 is nothing we can (or need to) do here. */
8500 if (!v)
8501 return NULL_TREE;
8503 /* Let C++ handle C++ virtual functions. */
8504 return cp_fold_obj_type_ref (ref, known_type);
8505 #else
8506 /* For plain ObjC, we currently do not need to do anything. */
8507 return NULL_TREE;
8508 #endif
8511 static void
8512 objc_start_function (tree name, tree type, tree attrs,
8513 #ifdef OBJCPLUS
8514 tree params
8515 #else
8516 struct c_arg_info *params
8517 #endif
8520 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8522 #ifdef OBJCPLUS
8523 DECL_ARGUMENTS (fndecl) = params;
8524 DECL_INITIAL (fndecl) = error_mark_node;
8525 DECL_EXTERNAL (fndecl) = 0;
8526 TREE_STATIC (fndecl) = 1;
8527 retrofit_lang_decl (fndecl);
8528 cplus_decl_attributes (&fndecl, attrs, 0);
8529 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8530 #else
8531 struct c_label_context_se *nstack_se;
8532 struct c_label_context_vm *nstack_vm;
8533 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8534 nstack_se->labels_def = NULL;
8535 nstack_se->labels_used = NULL;
8536 nstack_se->next = label_context_stack_se;
8537 label_context_stack_se = nstack_se;
8538 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8539 nstack_vm->labels_def = NULL;
8540 nstack_vm->labels_used = NULL;
8541 nstack_vm->scope = 0;
8542 nstack_vm->next = label_context_stack_vm;
8543 label_context_stack_vm = nstack_vm;
8544 current_function_returns_value = 0; /* Assume, until we see it does. */
8545 current_function_returns_null = 0;
8547 decl_attributes (&fndecl, attrs, 0);
8548 announce_function (fndecl);
8549 DECL_INITIAL (fndecl) = error_mark_node;
8550 DECL_EXTERNAL (fndecl) = 0;
8551 TREE_STATIC (fndecl) = 1;
8552 current_function_decl = pushdecl (fndecl);
8553 push_scope ();
8554 declare_parm_level ();
8555 DECL_RESULT (current_function_decl)
8556 = build_decl (RESULT_DECL, NULL_TREE,
8557 TREE_TYPE (TREE_TYPE (current_function_decl)));
8558 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8559 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8560 start_fname_decls ();
8561 store_parm_decls_from (params);
8562 #endif
8564 TREE_USED (current_function_decl) = 1;
8567 /* - Generate an identifier for the function. the format is "_n_cls",
8568 where 1 <= n <= nMethods, and cls is the name the implementation we
8569 are processing.
8570 - Install the return type from the method declaration.
8571 - If we have a prototype, check for type consistency. */
8573 static void
8574 really_start_method (tree method,
8575 #ifdef OBJCPLUS
8576 tree parmlist
8577 #else
8578 struct c_arg_info *parmlist
8579 #endif
8582 tree ret_type, meth_type;
8583 tree method_id;
8584 const char *sel_name, *class_name, *cat_name;
8585 char *buf;
8587 /* Synth the storage class & assemble the return type. */
8588 ret_type = TREE_VALUE (TREE_TYPE (method));
8590 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8591 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8592 cat_name = ((TREE_CODE (objc_implementation_context)
8593 == CLASS_IMPLEMENTATION_TYPE)
8594 ? NULL
8595 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8596 method_slot++;
8598 /* Make sure this is big enough for any plausible method label. */
8599 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8600 + (cat_name ? strlen (cat_name) : 0));
8602 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8603 class_name, cat_name, sel_name, method_slot);
8605 method_id = get_identifier (buf);
8607 #ifdef OBJCPLUS
8608 /* Objective-C methods cannot be overloaded, so we don't need
8609 the type encoding appended. It looks bad anyway... */
8610 push_lang_context (lang_name_c);
8611 #endif
8613 meth_type
8614 = build_function_type (ret_type,
8615 get_arg_type_list (method, METHOD_DEF, 0));
8616 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8618 /* Set self_decl from the first argument. */
8619 self_decl = DECL_ARGUMENTS (current_function_decl);
8621 /* Suppress unused warnings. */
8622 TREE_USED (self_decl) = 1;
8623 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8624 #ifdef OBJCPLUS
8625 pop_lang_context ();
8626 #endif
8628 METHOD_DEFINITION (method) = current_function_decl;
8630 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8632 if (implementation_template != objc_implementation_context)
8634 tree proto
8635 = lookup_method_static (implementation_template,
8636 METHOD_SEL_NAME (method),
8637 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8638 | OBJC_LOOKUP_NO_SUPER));
8640 if (proto)
8642 if (!comp_proto_with_proto (method, proto, 1))
8644 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8646 warn_with_method ("conflicting types for", type, method);
8647 warn_with_method ("previous declaration of", type, proto);
8650 else
8652 /* We have a method @implementation even though we did not
8653 see a corresponding @interface declaration (which is allowed
8654 by Objective-C rules). Go ahead and place the method in
8655 the @interface anyway, so that message dispatch lookups
8656 will see it. */
8657 tree interface = implementation_template;
8659 if (TREE_CODE (objc_implementation_context)
8660 == CATEGORY_IMPLEMENTATION_TYPE)
8661 interface = lookup_category
8662 (interface,
8663 CLASS_SUPER_NAME (objc_implementation_context));
8665 if (interface)
8666 objc_add_method (interface, copy_node (method),
8667 TREE_CODE (method) == CLASS_METHOD_DECL);
8672 static void *UOBJC_SUPER_scope = 0;
8674 /* _n_Method (id self, SEL sel, ...)
8676 struct objc_super _S;
8677 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8678 } */
8680 static tree
8681 get_super_receiver (void)
8683 if (objc_method_context)
8685 tree super_expr, super_expr_list;
8687 if (!UOBJC_SUPER_decl)
8689 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8690 objc_super_template);
8691 /* This prevents `unused variable' warnings when compiling with -Wall. */
8692 TREE_USED (UOBJC_SUPER_decl) = 1;
8693 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8694 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8695 UOBJC_SUPER_scope = objc_get_current_scope ();
8698 /* Set receiver to self. */
8699 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8700 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8701 super_expr_list = super_expr;
8703 /* Set class to begin searching. */
8704 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8705 get_identifier ("super_class"));
8707 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8709 /* [_cls, __cls]Super are "pre-built" in
8710 synth_forward_declarations. */
8712 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8713 ((TREE_CODE (objc_method_context)
8714 == INSTANCE_METHOD_DECL)
8715 ? ucls_super_ref
8716 : uucls_super_ref));
8719 else
8720 /* We have a category. */
8722 tree super_name = CLASS_SUPER_NAME (implementation_template);
8723 tree super_class;
8725 /* Barf if super used in a category of Object. */
8726 if (!super_name)
8728 error ("no super class declared in interface for %qs",
8729 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8730 return error_mark_node;
8733 if (flag_next_runtime && !flag_zero_link)
8735 super_class = objc_get_class_reference (super_name);
8736 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8737 /* If we are in a class method, we must retrieve the
8738 _metaclass_ for the current class, pointed at by
8739 the class's "isa" pointer. The following assumes that
8740 "isa" is the first ivar in a class (which it must be). */
8741 super_class
8742 = build_indirect_ref
8743 (build_c_cast (build_pointer_type (objc_class_type),
8744 super_class), "unary *");
8746 else
8748 add_class_reference (super_name);
8749 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8750 ? objc_get_class_decl : objc_get_meta_class_decl);
8751 assemble_external (super_class);
8752 super_class
8753 = build_function_call
8754 (super_class,
8755 build_tree_list
8756 (NULL_TREE,
8757 my_build_string_pointer
8758 (IDENTIFIER_LENGTH (super_name) + 1,
8759 IDENTIFIER_POINTER (super_name))));
8762 super_expr
8763 = build_modify_expr (super_expr, NOP_EXPR,
8764 build_c_cast (TREE_TYPE (super_expr),
8765 super_class));
8768 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8770 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8771 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8773 return super_expr_list;
8775 else
8777 error ("[super ...] must appear in a method context");
8778 return error_mark_node;
8782 /* When exiting a scope, sever links to a 'super' declaration (if any)
8783 therein contained. */
8785 void
8786 objc_clear_super_receiver (void)
8788 if (objc_method_context
8789 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8790 UOBJC_SUPER_decl = 0;
8791 UOBJC_SUPER_scope = 0;
8795 void
8796 objc_finish_method_definition (tree fndecl)
8798 /* We cannot validly inline ObjC methods, at least not without a language
8799 extension to declare that a method need not be dynamically
8800 dispatched, so suppress all thoughts of doing so. */
8801 DECL_INLINE (fndecl) = 0;
8802 DECL_UNINLINABLE (fndecl) = 1;
8804 #ifndef OBJCPLUS
8805 /* The C++ front-end will have called finish_function() for us. */
8806 finish_function ();
8807 #endif
8809 METHOD_ENCODING (objc_method_context)
8810 = encode_method_prototype (objc_method_context);
8812 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8813 since the optimizer may find "may be used before set" errors. */
8814 objc_method_context = NULL_TREE;
8816 if (should_call_super_dealloc)
8817 warning (0, "method possibly missing a [super dealloc] call");
8820 #if 0
8822 lang_report_error_function (tree decl)
8824 if (objc_method_context)
8826 fprintf (stderr, "In method %qs\n",
8827 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8828 return 1;
8831 else
8832 return 0;
8834 #endif
8836 /* Given a tree DECL node, produce a printable description of it in the given
8837 buffer, overwriting the buffer. */
8839 static char *
8840 gen_declaration (tree decl)
8842 errbuf[0] = '\0';
8844 if (DECL_P (decl))
8846 gen_type_name_0 (TREE_TYPE (decl));
8848 if (DECL_NAME (decl))
8850 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8851 strcat (errbuf, " ");
8853 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8856 if (DECL_INITIAL (decl)
8857 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8858 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8859 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8862 return errbuf;
8865 /* Given a tree TYPE node, produce a printable description of it in the given
8866 buffer, overwriting the buffer. */
8868 static char *
8869 gen_type_name_0 (tree type)
8871 tree orig = type, proto;
8873 if (TYPE_P (type) && TYPE_NAME (type))
8874 type = TYPE_NAME (type);
8875 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8877 tree inner = TREE_TYPE (type);
8879 while (TREE_CODE (inner) == ARRAY_TYPE)
8880 inner = TREE_TYPE (inner);
8882 gen_type_name_0 (inner);
8884 if (!POINTER_TYPE_P (inner))
8885 strcat (errbuf, " ");
8887 if (POINTER_TYPE_P (type))
8888 strcat (errbuf, "*");
8889 else
8890 while (type != inner)
8892 strcat (errbuf, "[");
8894 if (TYPE_DOMAIN (type))
8896 char sz[20];
8898 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8899 (TREE_INT_CST_LOW
8900 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8901 strcat (errbuf, sz);
8904 strcat (errbuf, "]");
8905 type = TREE_TYPE (type);
8908 goto exit_function;
8911 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8912 type = DECL_NAME (type);
8914 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8915 ? IDENTIFIER_POINTER (type)
8916 : "");
8918 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8919 if (objc_is_id (orig))
8920 orig = TREE_TYPE (orig);
8922 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8924 if (proto)
8926 strcat (errbuf, " <");
8928 while (proto) {
8929 strcat (errbuf,
8930 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8931 proto = TREE_CHAIN (proto);
8932 strcat (errbuf, proto ? ", " : ">");
8936 exit_function:
8937 return errbuf;
8940 static char *
8941 gen_type_name (tree type)
8943 errbuf[0] = '\0';
8945 return gen_type_name_0 (type);
8948 /* Given a method tree, put a printable description into the given
8949 buffer (overwriting) and return a pointer to the buffer. */
8951 static char *
8952 gen_method_decl (tree method)
8954 tree chain;
8956 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8957 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8958 strcat (errbuf, ")");
8959 chain = METHOD_SEL_ARGS (method);
8961 if (chain)
8963 /* We have a chain of keyword_decls. */
8966 if (KEYWORD_KEY_NAME (chain))
8967 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8969 strcat (errbuf, ":(");
8970 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8971 strcat (errbuf, ")");
8973 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8974 if ((chain = TREE_CHAIN (chain)))
8975 strcat (errbuf, " ");
8977 while (chain);
8979 if (METHOD_ADD_ARGS (method))
8981 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8983 /* Know we have a chain of parm_decls. */
8984 while (chain)
8986 strcat (errbuf, ", ");
8987 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8988 chain = TREE_CHAIN (chain);
8991 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8992 strcat (errbuf, ", ...");
8996 else
8997 /* We have a unary selector. */
8998 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9000 return errbuf;
9003 /* Debug info. */
9006 /* Dump an @interface declaration of the supplied class CHAIN to the
9007 supplied file FP. Used to implement the -gen-decls option (which
9008 prints out an @interface declaration of all classes compiled in
9009 this run); potentially useful for debugging the compiler too. */
9010 static void
9011 dump_interface (FILE *fp, tree chain)
9013 /* FIXME: A heap overflow here whenever a method (or ivar)
9014 declaration is so long that it doesn't fit in the buffer. The
9015 code and all the related functions should be rewritten to avoid
9016 using fixed size buffers. */
9017 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9018 tree ivar_decls = CLASS_RAW_IVARS (chain);
9019 tree nst_methods = CLASS_NST_METHODS (chain);
9020 tree cls_methods = CLASS_CLS_METHODS (chain);
9022 fprintf (fp, "\n@interface %s", my_name);
9024 /* CLASS_SUPER_NAME is used to store the superclass name for
9025 classes, and the category name for categories. */
9026 if (CLASS_SUPER_NAME (chain))
9028 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9030 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9031 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9033 fprintf (fp, " (%s)\n", name);
9035 else
9037 fprintf (fp, " : %s\n", name);
9040 else
9041 fprintf (fp, "\n");
9043 /* FIXME - the following doesn't seem to work at the moment. */
9044 if (ivar_decls)
9046 fprintf (fp, "{\n");
9049 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9050 ivar_decls = TREE_CHAIN (ivar_decls);
9052 while (ivar_decls);
9053 fprintf (fp, "}\n");
9056 while (nst_methods)
9058 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9059 nst_methods = TREE_CHAIN (nst_methods);
9062 while (cls_methods)
9064 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9065 cls_methods = TREE_CHAIN (cls_methods);
9068 fprintf (fp, "@end\n");
9071 /* Demangle function for Objective-C */
9072 static const char *
9073 objc_demangle (const char *mangled)
9075 char *demangled, *cp;
9077 if (mangled[0] == '_' &&
9078 (mangled[1] == 'i' || mangled[1] == 'c') &&
9079 mangled[2] == '_')
9081 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9082 if (mangled[1] == 'i')
9083 *cp++ = '-'; /* for instance method */
9084 else
9085 *cp++ = '+'; /* for class method */
9086 *cp++ = '['; /* opening left brace */
9087 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9088 while (*cp && *cp == '_')
9089 cp++; /* skip any initial underbars in class name */
9090 cp = strchr(cp, '_'); /* find first non-initial underbar */
9091 if (cp == NULL)
9093 free(demangled); /* not mangled name */
9094 return mangled;
9096 if (cp[1] == '_') /* easy case: no category name */
9098 *cp++ = ' '; /* replace two '_' with one ' ' */
9099 strcpy(cp, mangled + (cp - demangled) + 2);
9101 else
9103 *cp++ = '('; /* less easy case: category name */
9104 cp = strchr(cp, '_');
9105 if (cp == 0)
9107 free(demangled); /* not mangled name */
9108 return mangled;
9110 *cp++ = ')';
9111 *cp++ = ' '; /* overwriting 1st char of method name... */
9112 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9114 while (*cp && *cp == '_')
9115 cp++; /* skip any initial underbars in method name */
9116 for (; *cp; cp++)
9117 if (*cp == '_')
9118 *cp = ':'; /* replace remaining '_' with ':' */
9119 *cp++ = ']'; /* closing right brace */
9120 *cp++ = 0; /* string terminator */
9121 return demangled;
9123 else
9124 return mangled; /* not an objc mangled name */
9127 const char *
9128 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9130 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9133 static void
9134 init_objc (void)
9136 gcc_obstack_init (&util_obstack);
9137 util_firstobj = (char *) obstack_finish (&util_obstack);
9139 errbuf = XNEWVEC (char, 1024 * 10);
9140 hash_init ();
9141 synth_module_prologue ();
9144 static void
9145 finish_objc (void)
9147 struct imp_entry *impent;
9148 tree chain;
9149 /* The internally generated initializers appear to have missing braces.
9150 Don't warn about this. */
9151 int save_warn_missing_braces = warn_missing_braces;
9152 warn_missing_braces = 0;
9154 /* A missing @end may not be detected by the parser. */
9155 if (objc_implementation_context)
9157 warning (0, "%<@end%> missing in implementation context");
9158 finish_class (objc_implementation_context);
9159 objc_ivar_chain = NULL_TREE;
9160 objc_implementation_context = NULL_TREE;
9163 /* Process the static instances here because initialization of objc_symtab
9164 depends on them. */
9165 if (objc_static_instances)
9166 generate_static_references ();
9168 if (imp_list || class_names_chain
9169 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9170 generate_objc_symtab_decl ();
9172 for (impent = imp_list; impent; impent = impent->next)
9174 objc_implementation_context = impent->imp_context;
9175 implementation_template = impent->imp_template;
9177 UOBJC_CLASS_decl = impent->class_decl;
9178 UOBJC_METACLASS_decl = impent->meta_decl;
9180 /* Dump the @interface of each class as we compile it, if the
9181 -gen-decls option is in use. TODO: Dump the classes in the
9182 order they were found, rather than in reverse order as we
9183 are doing now. */
9184 if (flag_gen_declaration)
9186 dump_interface (gen_declaration_file, objc_implementation_context);
9189 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9191 /* all of the following reference the string pool... */
9192 generate_ivar_lists ();
9193 generate_dispatch_tables ();
9194 generate_shared_structures (impent->has_cxx_cdtors
9195 ? CLS_HAS_CXX_STRUCTORS
9196 : 0);
9198 else
9200 generate_dispatch_tables ();
9201 generate_category (objc_implementation_context);
9205 /* If we are using an array of selectors, we must always
9206 finish up the array decl even if no selectors were used. */
9207 if (! flag_next_runtime || sel_ref_chain)
9208 build_selector_translation_table ();
9210 if (protocol_chain)
9211 generate_protocols ();
9213 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9214 generate_objc_image_info ();
9216 /* Arrange for ObjC data structures to be initialized at run time. */
9217 if (objc_implementation_context || class_names_chain || objc_static_instances
9218 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9220 build_module_descriptor ();
9222 if (!flag_next_runtime)
9223 build_module_initializer_routine ();
9226 /* Dump the class references. This forces the appropriate classes
9227 to be linked into the executable image, preserving unix archive
9228 semantics. This can be removed when we move to a more dynamically
9229 linked environment. */
9231 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9233 handle_class_ref (chain);
9234 if (TREE_PURPOSE (chain))
9235 generate_classref_translation_entry (chain);
9238 for (impent = imp_list; impent; impent = impent->next)
9239 handle_impent (impent);
9241 if (warn_selector)
9243 int slot;
9244 hash hsh;
9246 /* Run through the selector hash tables and print a warning for any
9247 selector which has multiple methods. */
9249 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9251 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9252 check_duplicates (hsh, 0, 1);
9253 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9254 check_duplicates (hsh, 0, 1);
9258 warn_missing_braces = save_warn_missing_braces;
9261 /* Subroutines of finish_objc. */
9263 static void
9264 generate_classref_translation_entry (tree chain)
9266 tree expr, decl, type;
9268 decl = TREE_PURPOSE (chain);
9269 type = TREE_TYPE (decl);
9271 expr = add_objc_string (TREE_VALUE (chain), class_names);
9272 expr = convert (type, expr); /* cast! */
9274 /* The decl that is the one that we
9275 forward declared in build_class_reference. */
9276 finish_var_decl (decl, expr);
9277 return;
9280 static void
9281 handle_class_ref (tree chain)
9283 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9284 char *string = (char *) alloca (strlen (name) + 30);
9285 tree decl;
9286 tree exp;
9288 sprintf (string, "%sobjc_class_name_%s",
9289 (flag_next_runtime ? "." : "__"), name);
9291 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9292 if (flag_next_runtime)
9294 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9295 return;
9297 #endif
9299 /* Make a decl for this name, so we can use its address in a tree. */
9300 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9301 DECL_EXTERNAL (decl) = 1;
9302 TREE_PUBLIC (decl) = 1;
9304 pushdecl (decl);
9305 rest_of_decl_compilation (decl, 0, 0);
9307 /* Make a decl for the address. */
9308 sprintf (string, "%sobjc_class_ref_%s",
9309 (flag_next_runtime ? "." : "__"), name);
9310 exp = build1 (ADDR_EXPR, string_type_node, decl);
9311 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9312 DECL_INITIAL (decl) = exp;
9313 TREE_STATIC (decl) = 1;
9314 TREE_USED (decl) = 1;
9315 /* Force the output of the decl as this forces the reference of the class. */
9316 mark_decl_referenced (decl);
9318 pushdecl (decl);
9319 rest_of_decl_compilation (decl, 0, 0);
9322 static void
9323 handle_impent (struct imp_entry *impent)
9325 char *string;
9327 objc_implementation_context = impent->imp_context;
9328 implementation_template = impent->imp_template;
9330 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9332 const char *const class_name =
9333 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9335 string = (char *) alloca (strlen (class_name) + 30);
9337 sprintf (string, "%sobjc_class_name_%s",
9338 (flag_next_runtime ? "." : "__"), class_name);
9340 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9342 const char *const class_name =
9343 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9344 const char *const class_super_name =
9345 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9347 string = (char *) alloca (strlen (class_name)
9348 + strlen (class_super_name) + 30);
9350 /* Do the same for categories. Even though no references to
9351 these symbols are generated automatically by the compiler, it
9352 gives you a handle to pull them into an archive by hand. */
9353 sprintf (string, "*%sobjc_category_name_%s_%s",
9354 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9356 else
9357 return;
9359 #ifdef ASM_DECLARE_CLASS_REFERENCE
9360 if (flag_next_runtime)
9362 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9363 return;
9365 else
9366 #endif
9368 tree decl, init;
9370 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9371 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9372 TREE_PUBLIC (decl) = 1;
9373 TREE_READONLY (decl) = 1;
9374 TREE_USED (decl) = 1;
9375 TREE_CONSTANT (decl) = 1;
9376 DECL_CONTEXT (decl) = 0;
9377 DECL_ARTIFICIAL (decl) = 1;
9378 DECL_INITIAL (decl) = init;
9379 assemble_variable (decl, 1, 0, 0);
9383 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9384 later requires that ObjC translation units participating in F&C be
9385 specially marked. The following routine accomplishes this. */
9387 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9389 static void
9390 generate_objc_image_info (void)
9392 tree decl, initlist;
9393 int flags
9394 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9395 | (flag_objc_gc ? 2 : 0));
9397 decl = start_var_decl (build_array_type
9398 (integer_type_node,
9399 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9400 "_OBJC_IMAGE_INFO");
9402 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9403 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9404 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9406 finish_var_decl (decl, initlist);
9409 /* Look up ID as an instance variable. OTHER contains the result of
9410 the C or C++ lookup, which we may want to use instead. */
9412 tree
9413 objc_lookup_ivar (tree other, tree id)
9415 tree ivar;
9417 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9418 if (!objc_method_context)
9419 return other;
9421 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9422 /* We have a message to super. */
9423 return get_super_receiver ();
9425 /* In a class method, look up an instance variable only as a last
9426 resort. */
9427 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9428 && other && other != error_mark_node)
9429 return other;
9431 /* Look up the ivar, but do not use it if it is not accessible. */
9432 ivar = is_ivar (objc_ivar_chain, id);
9434 if (!ivar || is_private (ivar))
9435 return other;
9437 /* In an instance method, a local variable (or parameter) may hide the
9438 instance variable. */
9439 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9440 && other && other != error_mark_node
9441 #ifdef OBJCPLUS
9442 && CP_DECL_CONTEXT (other) != global_namespace)
9443 #else
9444 && !DECL_FILE_SCOPE_P (other))
9445 #endif
9447 warning (0, "local declaration of %qs hides instance variable",
9448 IDENTIFIER_POINTER (id));
9450 return other;
9453 /* At this point, we are either in an instance method with no obscuring
9454 local definitions, or in a class method with no alternate definitions
9455 at all. */
9456 return build_ivar_reference (id);
9459 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9460 needs to be done if we are calling a function through a cast. */
9462 tree
9463 objc_rewrite_function_call (tree function, tree params)
9465 if (TREE_CODE (function) == NOP_EXPR
9466 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9467 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9468 == FUNCTION_DECL)
9470 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9471 TREE_OPERAND (function, 0),
9472 TREE_VALUE (params), size_zero_node);
9475 return function;
9478 /* Look for the special case of OBJC_TYPE_REF with the address of
9479 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9480 of its cousins). */
9482 enum gimplify_status
9483 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9485 enum gimplify_status r0, r1;
9486 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9487 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9488 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9489 == FUNCTION_DECL)
9491 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9492 value of the OBJ_TYPE_REF, so force them to be emitted
9493 during subexpression evaluation rather than after the
9494 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9495 C to use direct rather than indirect calls when the
9496 object expression has a postincrement. */
9497 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9498 is_gimple_val, fb_rvalue);
9499 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9500 is_gimple_val, fb_rvalue);
9502 return MIN (r0, r1);
9505 #ifdef OBJCPLUS
9506 return cp_gimplify_expr (expr_p, pre_p, post_p);
9507 #else
9508 return c_gimplify_expr (expr_p, pre_p, post_p);
9509 #endif
9512 /* Given a CALL expression, find the function being called. The ObjC
9513 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9515 tree
9516 objc_get_callee_fndecl (tree call_expr)
9518 tree addr = CALL_EXPR_FN (call_expr);
9519 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9520 return 0;
9522 addr = OBJ_TYPE_REF_EXPR (addr);
9524 /* If the address is just `&f' for some function `f', then we know
9525 that `f' is being called. */
9526 if (TREE_CODE (addr) == ADDR_EXPR
9527 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9528 return TREE_OPERAND (addr, 0);
9530 return 0;
9533 #include "gt-objc-objc-act.h"