Update concepts branch to revision 131834
[official-gcc.git] / gcc / objc / objc-act.c
blobb19821cf4ee78c392a21dc421a78574a656447ca
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
57 #include "c-common.h"
58 #include "c-pragma.h"
59 #include "flags.h"
60 #include "langhooks.h"
61 #include "objc-act.h"
62 #include "input.h"
63 #include "except.h"
64 #include "function.h"
65 #include "output.h"
66 #include "toplev.h"
67 #include "ggc.h"
68 #include "varray.h"
69 #include "debug.h"
70 #include "target.h"
71 #include "diagnostic.h"
72 #include "cgraph.h"
73 #include "tree-iterator.h"
74 #include "libfuncs.h"
75 #include "hashtab.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
84 #ifdef OBJCPLUS
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
87 #endif /* OBJCPLUS */
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
95 do { \
96 char *temp; \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
99 (CLASS_NAME), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
101 (SEL_NAME)); \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
104 } while (0)
105 #endif
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
110 #endif
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
114 #endif
116 /* Set up for use of obstacks. */
118 #include "obstack.h"
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
125 char *util_firstobj;
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
157 #ifdef OBJCPLUS
158 static void objc_start_function (tree, tree, tree, tree);
159 #else
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
161 #endif
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
174 #ifndef OBJCPLUS
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
177 #endif
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
189 #ifdef OBJCPLUS
190 static void objc_generate_cxx_cdtors (void);
191 #endif
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
204 enum string_section
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
220 /* Type encoding. */
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
226 #ifdef OBJCPLUS
227 static void really_start_method (tree, tree);
228 #else
229 static void really_start_method (tree, struct c_arg_info *);
230 #endif
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
233 #ifdef OBJCPLUS
234 static tree objc_get_parm_info (int);
235 #else
236 static struct c_arg_info *objc_get_parm_info (int);
237 #endif
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
256 ATTRIBUTE_NORETURN;
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
288 NeXT runtime. */
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
371 #define BUFSIZE 1024
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
391 tree literal;
393 /* The resulting constant string. */
394 tree constructor;
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
402 tree type;
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
420 static void
421 generate_struct_by_value_array (void)
423 tree type;
424 tree field_decl, field_decl_chain;
425 int i, j;
426 int aggregate_in_mem[32];
427 int found = 0;
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
432 char buffer[5];
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
439 buffer);
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
446 buffer);
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
453 found = 1;
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
458 if (found)
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
462 break;
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
471 printf ("\n};\n");
474 exit (0);
477 bool
478 objc_init (void)
480 #ifdef OBJCPLUS
481 if (cxx_init () == false)
482 #else
483 if (c_objc_common_init () == false)
484 #endif
485 return false;
487 /* If gen_declaration desired, open the output file. */
488 if (flag_gen_declaration)
490 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
491 gen_declaration_file = fopen (dumpname, "w");
492 if (gen_declaration_file == 0)
493 fatal_error ("can't open %s: %m", dumpname);
494 free (dumpname);
497 if (flag_next_runtime)
499 TAG_GETCLASS = "objc_getClass";
500 TAG_GETMETACLASS = "objc_getMetaClass";
501 TAG_MSGSEND = "objc_msgSend";
502 TAG_MSGSENDSUPER = "objc_msgSendSuper";
503 TAG_MSGSEND_STRET = "objc_msgSend_stret";
504 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
505 default_constant_string_class_name = "NSConstantString";
507 else
509 TAG_GETCLASS = "objc_get_class";
510 TAG_GETMETACLASS = "objc_get_meta_class";
511 TAG_MSGSEND = "objc_msg_lookup";
512 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
513 /* GNU runtime does not provide special functions to support
514 structure-returning methods. */
515 default_constant_string_class_name = "NXConstantString";
516 flag_typed_selectors = 1;
519 init_objc ();
521 if (print_struct_values)
522 generate_struct_by_value_array ();
524 return true;
527 void
528 objc_finish_file (void)
530 mark_referenced_methods ();
532 #ifdef OBJCPLUS
533 /* We need to instantiate templates _before_ we emit ObjC metadata;
534 if we do not, some metadata (such as selectors) may go missing. */
535 at_eof = 1;
536 instantiate_pending_templates (0);
537 #endif
539 /* Finalize Objective-C runtime data. No need to generate tables
540 and code if only checking syntax, or if generating a PCH file. */
541 if (!flag_syntax_only && !pch_file)
542 finish_objc ();
544 if (gen_declaration_file)
545 fclose (gen_declaration_file);
548 /* Return the first occurrence of a method declaration corresponding
549 to sel_name in rproto_list. Search rproto_list recursively.
550 If is_class is 0, search for instance methods, otherwise for class
551 methods. */
552 static tree
553 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
554 int is_class)
556 tree rproto, p;
557 tree fnd = 0;
559 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
561 p = TREE_VALUE (rproto);
563 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
565 if ((fnd = lookup_method (is_class
566 ? PROTOCOL_CLS_METHODS (p)
567 : PROTOCOL_NST_METHODS (p), sel_name)))
569 else if (PROTOCOL_LIST (p))
570 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
571 sel_name, is_class);
573 else
575 ; /* An identifier...if we could not find a protocol. */
578 if (fnd)
579 return fnd;
582 return 0;
585 static tree
586 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
588 tree rproto, p;
590 /* Make sure the protocol is supported by the object on the rhs. */
591 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
593 tree fnd = 0;
594 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
596 p = TREE_VALUE (rproto);
598 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
600 if (lproto == p)
601 fnd = lproto;
603 else if (PROTOCOL_LIST (p))
604 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
607 if (fnd)
608 return fnd;
611 else
613 ; /* An identifier...if we could not find a protocol. */
616 return 0;
619 void
620 objc_start_class_interface (tree class, tree super_class, tree protos)
622 objc_interface_context
623 = objc_ivar_context
624 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
625 objc_public_flag = 0;
628 void
629 objc_start_category_interface (tree class, tree categ, tree protos)
631 objc_interface_context
632 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
633 objc_ivar_chain
634 = continue_class (objc_interface_context);
637 void
638 objc_start_protocol (tree name, tree protos)
640 objc_interface_context
641 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
644 void
645 objc_continue_interface (void)
647 objc_ivar_chain
648 = continue_class (objc_interface_context);
651 void
652 objc_finish_interface (void)
654 finish_class (objc_interface_context);
655 objc_interface_context = NULL_TREE;
658 void
659 objc_start_class_implementation (tree class, tree super_class)
661 objc_implementation_context
662 = objc_ivar_context
663 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
664 objc_public_flag = 0;
667 void
668 objc_start_category_implementation (tree class, tree categ)
670 objc_implementation_context
671 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
672 objc_ivar_chain
673 = continue_class (objc_implementation_context);
676 void
677 objc_continue_implementation (void)
679 objc_ivar_chain
680 = continue_class (objc_implementation_context);
683 void
684 objc_finish_implementation (void)
686 #ifdef OBJCPLUS
687 if (flag_objc_call_cxx_cdtors)
688 objc_generate_cxx_cdtors ();
689 #endif
691 if (objc_implementation_context)
693 finish_class (objc_implementation_context);
694 objc_ivar_chain = NULL_TREE;
695 objc_implementation_context = NULL_TREE;
697 else
698 warning (0, "%<@end%> must appear in an @implementation context");
701 void
702 objc_set_visibility (int visibility)
704 objc_public_flag = visibility;
707 void
708 objc_set_method_type (enum tree_code type)
710 objc_inherit_code = (type == PLUS_EXPR
711 ? CLASS_METHOD_DECL
712 : INSTANCE_METHOD_DECL);
715 tree
716 objc_build_method_signature (tree rettype, tree selector,
717 tree optparms, bool ellipsis)
719 return build_method_decl (objc_inherit_code, rettype, selector,
720 optparms, ellipsis);
723 void
724 objc_add_method_declaration (tree decl)
726 if (!objc_interface_context)
727 fatal_error ("method declaration not in @interface context");
729 objc_add_method (objc_interface_context,
730 decl,
731 objc_inherit_code == CLASS_METHOD_DECL);
734 void
735 objc_start_method_definition (tree decl)
737 if (!objc_implementation_context)
738 fatal_error ("method definition not in @implementation context");
740 objc_add_method (objc_implementation_context,
741 decl,
742 objc_inherit_code == CLASS_METHOD_DECL);
743 start_method_def (decl);
746 void
747 objc_add_instance_variable (tree decl)
749 (void) add_instance_variable (objc_ivar_context,
750 objc_public_flag,
751 decl);
754 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
755 an '@'. */
758 objc_is_reserved_word (tree ident)
760 unsigned char code = C_RID_CODE (ident);
762 return (OBJC_IS_AT_KEYWORD (code)
763 #ifdef OBJCPLUS
764 || code == RID_CLASS || code == RID_PUBLIC
765 || code == RID_PROTECTED || code == RID_PRIVATE
766 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
767 #endif
771 /* Return true if TYPE is 'id'. */
773 static bool
774 objc_is_object_id (tree type)
776 return OBJC_TYPE_NAME (type) == objc_object_id;
779 static bool
780 objc_is_class_id (tree type)
782 return OBJC_TYPE_NAME (type) == objc_class_id;
785 /* Construct a C struct with same name as CLASS, a base struct with tag
786 SUPER_NAME (if any), and FIELDS indicated. */
788 static tree
789 objc_build_struct (tree class, tree fields, tree super_name)
791 tree name = CLASS_NAME (class);
792 tree s = start_struct (RECORD_TYPE, name);
793 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
794 tree t, objc_info = NULL_TREE;
796 if (super)
798 /* Prepend a packed variant of the base class into the layout. This
799 is necessary to preserve ObjC ABI compatibility. */
800 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
801 tree field = TYPE_FIELDS (super);
803 while (field && TREE_CHAIN (field)
804 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
805 field = TREE_CHAIN (field);
807 /* For ObjC ABI purposes, the "packed" size of a base class is the
808 the sum of the offset and the size (in bits) of the last field
809 in the class. */
810 DECL_SIZE (base)
811 = (field && TREE_CODE (field) == FIELD_DECL
812 ? size_binop (PLUS_EXPR,
813 size_binop (PLUS_EXPR,
814 size_binop
815 (MULT_EXPR,
816 convert (bitsizetype,
817 DECL_FIELD_OFFSET (field)),
818 bitsize_int (BITS_PER_UNIT)),
819 DECL_FIELD_BIT_OFFSET (field)),
820 DECL_SIZE (field))
821 : bitsize_zero_node);
822 DECL_SIZE_UNIT (base)
823 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
824 size_int (BITS_PER_UNIT));
825 DECL_ARTIFICIAL (base) = 1;
826 DECL_ALIGN (base) = 1;
827 DECL_FIELD_CONTEXT (base) = s;
828 #ifdef OBJCPLUS
829 DECL_FIELD_IS_BASE (base) = 1;
831 if (fields)
832 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
833 #endif /* are following the ObjC ABI here. */
834 TREE_CHAIN (base) = fields;
835 fields = base;
838 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
839 in all variants of this RECORD_TYPE to be clobbered, but it is therein
840 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
841 Hence, we must squirrel away the ObjC-specific information before calling
842 finish_struct(), and then reinstate it afterwards. */
844 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
845 objc_info
846 = chainon (objc_info,
847 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
849 /* Point the struct at its related Objective-C class. */
850 INIT_TYPE_OBJC_INFO (s);
851 TYPE_OBJC_INTERFACE (s) = class;
853 s = finish_struct (s, fields, NULL_TREE);
855 for (t = TYPE_NEXT_VARIANT (s); t;
856 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
858 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
859 /* Replace the IDENTIFIER_NODE with an actual @interface. */
860 TYPE_OBJC_INTERFACE (t) = class;
863 /* Use TYPE_BINFO structures to point at the super class, if any. */
864 objc_xref_basetypes (s, super);
866 /* Mark this struct as a class template. */
867 CLASS_STATIC_TEMPLATE (class) = s;
869 return s;
872 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
873 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
874 process. */
875 static tree
876 objc_build_volatilized_type (tree type)
878 tree t;
880 /* Check if we have not constructed the desired variant already. */
881 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
883 /* The type qualifiers must (obviously) match up. */
884 if (!TYPE_VOLATILE (t)
885 || (TYPE_READONLY (t) != TYPE_READONLY (type))
886 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
887 continue;
889 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
890 info, if any) must match up. */
891 if (POINTER_TYPE_P (t)
892 && (TREE_TYPE (t) != TREE_TYPE (type)))
893 continue;
895 /* Everything matches up! */
896 return t;
899 /* Ok, we could not re-use any of the pre-existing variants. Create
900 a new one. */
901 t = build_variant_type_copy (type);
902 TYPE_VOLATILE (t) = 1;
904 /* Set up the canonical type information. */
905 if (TYPE_STRUCTURAL_EQUALITY_P (type))
906 SET_TYPE_STRUCTURAL_EQUALITY (t);
907 else if (TYPE_CANONICAL (type) != type)
908 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
909 else
910 TYPE_CANONICAL (t) = t;
912 return t;
915 /* Mark DECL as being 'volatile' for purposes of Darwin
916 _setjmp()/_longjmp() exception handling. Called from
917 objc_mark_locals_volatile(). */
918 void
919 objc_volatilize_decl (tree decl)
921 /* Do not mess with variables that are 'static' or (already)
922 'volatile'. */
923 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
924 && (TREE_CODE (decl) == VAR_DECL
925 || TREE_CODE (decl) == PARM_DECL))
927 tree t = TREE_TYPE (decl);
928 struct volatilized_type key;
929 void **loc;
931 t = objc_build_volatilized_type (t);
932 key.type = t;
933 loc = htab_find_slot (volatilized_htab, &key, INSERT);
935 if (!*loc)
937 *loc = ggc_alloc (sizeof (key));
938 ((struct volatilized_type *) *loc)->type = t;
941 TREE_TYPE (decl) = t;
942 TREE_THIS_VOLATILE (decl) = 1;
943 TREE_SIDE_EFFECTS (decl) = 1;
944 DECL_REGISTER (decl) = 0;
945 #ifndef OBJCPLUS
946 C_DECL_REGISTER (decl) = 0;
947 #endif
951 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
952 (including its categories and superclasses) or by object type TYP.
953 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
955 static bool
956 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
958 bool class_type = (cls != NULL_TREE);
960 while (cls)
962 tree c;
964 /* Check protocols adopted by the class and its categories. */
965 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
967 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
968 return true;
971 /* Repeat for superclasses. */
972 cls = lookup_interface (CLASS_SUPER_NAME (cls));
975 /* Check for any protocols attached directly to the object type. */
976 if (TYPE_HAS_OBJC_INFO (typ))
978 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
979 return true;
982 if (warn)
984 strcpy (errbuf, class_type ? "class \'" : "type \'");
985 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
986 strcat (errbuf, "\' does not ");
987 /* NB: Types 'id' and 'Class' cannot reasonably be described as
988 "implementing" a given protocol, since they do not have an
989 implementation. */
990 strcat (errbuf, class_type ? "implement" : "conform to");
991 strcat (errbuf, " the \'");
992 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
993 strcat (errbuf, "\' protocol");
994 warning (0, errbuf);
997 return false;
1000 /* Check if class RCLS and instance struct type RTYP conform to at least the
1001 same protocols that LCLS and LTYP conform to. */
1003 static bool
1004 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1006 tree p;
1007 bool have_lproto = false;
1009 while (lcls)
1011 /* NB: We do _not_ look at categories defined for LCLS; these may or
1012 may not get loaded in, and therefore it is unreasonable to require
1013 that RCLS/RTYP must implement any of their protocols. */
1014 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1016 have_lproto = true;
1018 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1019 return warn;
1022 /* Repeat for superclasses. */
1023 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1026 /* Check for any protocols attached directly to the object type. */
1027 if (TYPE_HAS_OBJC_INFO (ltyp))
1029 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1031 have_lproto = true;
1033 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1034 return warn;
1038 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1039 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1040 away with simply checking for 'id' or 'Class' (!RCLS), since this
1041 routine will not get called in other cases. */
1042 return have_lproto || (rcls != NULL_TREE);
1045 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1046 an instance of RTYP to an instance of LTYP or to compare the two
1047 (if ARGNO is equal to -3), per ObjC type system rules. Before
1048 returning 'true', this routine may issue warnings related to, e.g.,
1049 protocol conformance. When returning 'false', the routine must
1050 produce absolutely no warnings; the C or C++ front-end will do so
1051 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1052 the routine must return 'false'.
1054 The ARGNO parameter is encoded as follows:
1055 >= 1 Parameter number (CALLEE contains function being called);
1056 0 Return value;
1057 -1 Assignment;
1058 -2 Initialization;
1059 -3 Comparison (LTYP and RTYP may match in either direction). */
1061 bool
1062 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1064 tree lcls, rcls, lproto, rproto;
1065 bool pointers_compatible;
1067 /* We must be dealing with pointer types */
1068 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1069 return false;
1073 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1074 rtyp = TREE_TYPE (rtyp);
1076 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1078 /* Past this point, we are only interested in ObjC class instances,
1079 or 'id' or 'Class'. */
1080 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1081 return false;
1083 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1084 && !TYPE_HAS_OBJC_INFO (ltyp))
1085 return false;
1087 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1088 && !TYPE_HAS_OBJC_INFO (rtyp))
1089 return false;
1091 /* Past this point, we are committed to returning 'true' to the caller.
1092 However, we can still warn about type and/or protocol mismatches. */
1094 if (TYPE_HAS_OBJC_INFO (ltyp))
1096 lcls = TYPE_OBJC_INTERFACE (ltyp);
1097 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1099 else
1100 lcls = lproto = NULL_TREE;
1102 if (TYPE_HAS_OBJC_INFO (rtyp))
1104 rcls = TYPE_OBJC_INTERFACE (rtyp);
1105 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1107 else
1108 rcls = rproto = NULL_TREE;
1110 /* If we could not find an @interface declaration, we must have
1111 only seen a @class declaration; for purposes of type comparison,
1112 treat it as a stand-alone (root) class. */
1114 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1115 lcls = NULL_TREE;
1117 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1118 rcls = NULL_TREE;
1120 /* If either type is an unqualified 'id', we're done. */
1121 if ((!lproto && objc_is_object_id (ltyp))
1122 || (!rproto && objc_is_object_id (rtyp)))
1123 return true;
1125 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1127 /* If the underlying types are the same, and at most one of them has
1128 a protocol list, we do not need to issue any diagnostics. */
1129 if (pointers_compatible && (!lproto || !rproto))
1130 return true;
1132 /* If exactly one of the types is 'Class', issue a diagnostic; any
1133 exceptions of this rule have already been handled. */
1134 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1135 pointers_compatible = false;
1136 /* Otherwise, check for inheritance relations. */
1137 else
1139 if (!pointers_compatible)
1140 pointers_compatible
1141 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1143 if (!pointers_compatible)
1144 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1146 if (!pointers_compatible && argno == -3)
1147 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1150 /* If the pointers match modulo protocols, check for protocol conformance
1151 mismatches. */
1152 if (pointers_compatible)
1154 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1155 argno != -3);
1157 if (!pointers_compatible && argno == -3)
1158 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1159 argno != -3);
1162 if (!pointers_compatible)
1164 /* NB: For the time being, we shall make our warnings look like their
1165 C counterparts. In the future, we may wish to make them more
1166 ObjC-specific. */
1167 switch (argno)
1169 case -3:
1170 warning (0, "comparison of distinct Objective-C types lacks a cast");
1171 break;
1173 case -2:
1174 warning (0, "initialization from distinct Objective-C type");
1175 break;
1177 case -1:
1178 warning (0, "assignment from distinct Objective-C type");
1179 break;
1181 case 0:
1182 warning (0, "distinct Objective-C type in return");
1183 break;
1185 default:
1186 warning (0, "passing argument %d of %qE from distinct "
1187 "Objective-C type", argno, callee);
1188 break;
1192 return true;
1195 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1196 lives in the volatilized hash table, ignore the 'volatile' bit when
1197 making the comparison. */
1199 bool
1200 objc_type_quals_match (tree ltyp, tree rtyp)
1202 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1203 struct volatilized_type key;
1205 key.type = ltyp;
1207 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1208 lquals &= ~TYPE_QUAL_VOLATILE;
1210 key.type = rtyp;
1212 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1213 rquals &= ~TYPE_QUAL_VOLATILE;
1215 return (lquals == rquals);
1218 #ifndef OBJCPLUS
1219 /* Determine if CHILD is derived from PARENT. The routine assumes that
1220 both parameters are RECORD_TYPEs, and is non-reflexive. */
1222 static bool
1223 objc_derived_from_p (tree parent, tree child)
1225 parent = TYPE_MAIN_VARIANT (parent);
1227 for (child = TYPE_MAIN_VARIANT (child);
1228 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1230 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1231 (TYPE_BINFO (child),
1232 0)));
1234 if (child == parent)
1235 return true;
1238 return false;
1240 #endif
1242 static tree
1243 objc_build_component_ref (tree datum, tree component)
1245 /* If COMPONENT is NULL, the caller is referring to the anonymous
1246 base class field. */
1247 if (!component)
1249 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1251 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1254 /* The 'build_component_ref' routine has been removed from the C++
1255 front-end, but 'finish_class_member_access_expr' seems to be
1256 a worthy substitute. */
1257 #ifdef OBJCPLUS
1258 return finish_class_member_access_expr (datum, component, false,
1259 tf_warning_or_error);
1260 #else
1261 return build_component_ref (datum, component);
1262 #endif
1265 /* Recursively copy inheritance information rooted at BINFO. To do this,
1266 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1268 static tree
1269 objc_copy_binfo (tree binfo)
1271 tree btype = BINFO_TYPE (binfo);
1272 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1273 tree base_binfo;
1274 int ix;
1276 BINFO_TYPE (binfo2) = btype;
1277 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1278 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1280 /* Recursively copy base binfos of BINFO. */
1281 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1283 tree base_binfo2 = objc_copy_binfo (base_binfo);
1285 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1286 BINFO_BASE_APPEND (binfo2, base_binfo2);
1289 return binfo2;
1292 /* Record superclass information provided in BASETYPE for ObjC class REF.
1293 This is loosely based on cp/decl.c:xref_basetypes(). */
1295 static void
1296 objc_xref_basetypes (tree ref, tree basetype)
1298 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1300 TYPE_BINFO (ref) = binfo;
1301 BINFO_OFFSET (binfo) = size_zero_node;
1302 BINFO_TYPE (binfo) = ref;
1304 if (basetype)
1306 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1308 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1309 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1310 BINFO_BASE_APPEND (binfo, base_binfo);
1311 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1315 static hashval_t
1316 volatilized_hash (const void *ptr)
1318 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1320 return htab_hash_pointer(typ);
1323 static int
1324 volatilized_eq (const void *ptr1, const void *ptr2)
1326 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1327 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1329 return typ1 == typ2;
1332 /* Called from finish_decl. */
1334 void
1335 objc_check_decl (tree decl)
1337 tree type = TREE_TYPE (decl);
1339 if (TREE_CODE (type) != RECORD_TYPE)
1340 return;
1341 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1342 error ("statically allocated instance of Objective-C class %qs",
1343 IDENTIFIER_POINTER (type));
1346 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1347 either name an Objective-C class, or refer to the special 'id' or 'Class'
1348 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1350 tree
1351 objc_get_protocol_qualified_type (tree interface, tree protocols)
1353 /* If INTERFACE is not provided, default to 'id'. */
1354 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1355 bool is_ptr = (type != NULL_TREE);
1357 if (!is_ptr)
1359 type = objc_is_class_name (interface);
1361 if (type)
1362 type = xref_tag (RECORD_TYPE, type);
1363 else
1364 return interface;
1367 if (protocols)
1369 type = build_variant_type_copy (type);
1371 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1372 to the pointee. */
1373 if (is_ptr)
1375 tree orig_pointee_type = TREE_TYPE (type);
1376 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1378 /* Set up the canonical type information. */
1379 TYPE_CANONICAL (type)
1380 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1382 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1383 type = TREE_TYPE (type);
1386 /* Look up protocols and install in lang specific list. */
1387 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1388 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1390 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1391 return the pointer to the new pointee variant. */
1392 if (is_ptr)
1393 type = TYPE_POINTER_TO (type);
1394 else
1395 TYPE_OBJC_INTERFACE (type)
1396 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1399 return type;
1402 /* Check for circular dependencies in protocols. The arguments are
1403 PROTO, the protocol to check, and LIST, a list of protocol it
1404 conforms to. */
1406 static void
1407 check_protocol_recursively (tree proto, tree list)
1409 tree p;
1411 for (p = list; p; p = TREE_CHAIN (p))
1413 tree pp = TREE_VALUE (p);
1415 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1416 pp = lookup_protocol (pp);
1418 if (pp == proto)
1419 fatal_error ("protocol %qs has circular dependency",
1420 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1421 if (pp)
1422 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1426 /* Look up PROTOCOLS, and return a list of those that are found.
1427 If none are found, return NULL. */
1429 static tree
1430 lookup_and_install_protocols (tree protocols)
1432 tree proto;
1433 tree return_value = NULL_TREE;
1435 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1437 tree ident = TREE_VALUE (proto);
1438 tree p = lookup_protocol (ident);
1440 if (p)
1441 return_value = chainon (return_value,
1442 build_tree_list (NULL_TREE, p));
1443 else if (ident != error_mark_node)
1444 error ("cannot find protocol declaration for %qs",
1445 IDENTIFIER_POINTER (ident));
1448 return return_value;
1451 /* Create a declaration for field NAME of a given TYPE. */
1453 static tree
1454 create_field_decl (tree type, const char *name)
1456 return build_decl (FIELD_DECL, get_identifier (name), type);
1459 /* Create a global, static declaration for variable NAME of a given TYPE. The
1460 finish_var_decl() routine will need to be called on it afterwards. */
1462 static tree
1463 start_var_decl (tree type, const char *name)
1465 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1467 TREE_STATIC (var) = 1;
1468 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1469 DECL_IGNORED_P (var) = 1;
1470 DECL_ARTIFICIAL (var) = 1;
1471 DECL_CONTEXT (var) = NULL_TREE;
1472 #ifdef OBJCPLUS
1473 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1474 #endif
1476 return var;
1479 /* Finish off the variable declaration created by start_var_decl(). */
1481 static void
1482 finish_var_decl (tree var, tree initializer)
1484 finish_decl (var, initializer, NULL_TREE);
1485 /* Ensure that the variable actually gets output. */
1486 mark_decl_referenced (var);
1487 /* Mark the decl to avoid "defined but not used" warning. */
1488 TREE_USED (var) = 1;
1491 /* Find the decl for the constant string class reference. This is only
1492 used for the NeXT runtime. */
1494 static tree
1495 setup_string_decl (void)
1497 char *name;
1498 size_t length;
1500 /* %s in format will provide room for terminating null */
1501 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1502 + strlen (constant_string_class_name);
1503 name = xmalloc (length);
1504 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1505 constant_string_class_name);
1506 constant_string_global_id = get_identifier (name);
1507 string_class_decl = lookup_name (constant_string_global_id);
1509 return string_class_decl;
1512 /* Purpose: "play" parser, creating/installing representations
1513 of the declarations that are required by Objective-C.
1515 Model:
1517 type_spec--------->sc_spec
1518 (tree_list) (tree_list)
1521 identifier_node identifier_node */
1523 static void
1524 synth_module_prologue (void)
1526 tree type;
1527 enum debug_info_type save_write_symbols = write_symbols;
1528 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1530 /* Suppress outputting debug symbols, because
1531 dbxout_init hasn'r been called yet. */
1532 write_symbols = NO_DEBUG;
1533 debug_hooks = &do_nothing_debug_hooks;
1535 #ifdef OBJCPLUS
1536 push_lang_context (lang_name_c); /* extern "C" */
1537 #endif
1539 /* The following are also defined in <objc/objc.h> and friends. */
1541 objc_object_id = get_identifier (TAG_OBJECT);
1542 objc_class_id = get_identifier (TAG_CLASS);
1544 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1545 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1547 objc_object_type = build_pointer_type (objc_object_reference);
1548 objc_class_type = build_pointer_type (objc_class_reference);
1550 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1551 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1553 /* Declare the 'id' and 'Class' typedefs. */
1555 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1556 objc_object_name,
1557 objc_object_type));
1558 DECL_IN_SYSTEM_HEADER (type) = 1;
1559 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1560 objc_class_name,
1561 objc_class_type));
1562 DECL_IN_SYSTEM_HEADER (type) = 1;
1564 /* Forward-declare '@interface Protocol'. */
1566 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1567 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1568 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1569 type));
1571 /* Declare type of selector-objects that represent an operation name. */
1573 if (flag_next_runtime)
1574 /* `struct objc_selector *' */
1575 objc_selector_type
1576 = build_pointer_type (xref_tag (RECORD_TYPE,
1577 get_identifier (TAG_SELECTOR)));
1578 else
1579 /* `const struct objc_selector *' */
1580 objc_selector_type
1581 = build_pointer_type
1582 (build_qualified_type (xref_tag (RECORD_TYPE,
1583 get_identifier (TAG_SELECTOR)),
1584 TYPE_QUAL_CONST));
1586 /* Declare receiver type used for dispatching messages to 'super'. */
1588 /* `struct objc_super *' */
1589 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1590 get_identifier (TAG_SUPER)));
1592 /* Declare pointers to method and ivar lists. */
1593 objc_method_list_ptr = build_pointer_type
1594 (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_LIST)));
1596 objc_method_proto_list_ptr
1597 = build_pointer_type (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1599 objc_ivar_list_ptr = build_pointer_type
1600 (xref_tag (RECORD_TYPE,
1601 get_identifier (UTAG_IVAR_LIST)));
1603 /* TREE_NOTHROW is cleared for the message-sending functions,
1604 because the function that gets called can throw in Obj-C++, or
1605 could itself call something that can throw even in Obj-C. */
1607 if (flag_next_runtime)
1609 /* NB: In order to call one of the ..._stret (struct-returning)
1610 functions, the function *MUST* first be cast to a signature that
1611 corresponds to the actual ObjC method being invoked. This is
1612 what is done by the build_objc_method_call() routine below. */
1614 /* id objc_msgSend (id, SEL, ...); */
1615 /* id objc_msgSendNonNil (id, SEL, ...); */
1616 /* id objc_msgSend_stret (id, SEL, ...); */
1617 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1618 type
1619 = build_function_type (objc_object_type,
1620 tree_cons (NULL_TREE, objc_object_type,
1621 tree_cons (NULL_TREE, objc_selector_type,
1622 NULL_TREE)));
1623 umsg_decl = add_builtin_function (TAG_MSGSEND,
1624 type, 0, NOT_BUILT_IN,
1625 NULL, NULL_TREE);
1626 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1627 type, 0, NOT_BUILT_IN,
1628 NULL, NULL_TREE);
1629 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1630 type, 0, NOT_BUILT_IN,
1631 NULL, NULL_TREE);
1632 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1633 type, 0, NOT_BUILT_IN,
1634 NULL, NULL_TREE);
1636 /* These can throw, because the function that gets called can throw
1637 in Obj-C++, or could itself call something that can throw even
1638 in Obj-C. */
1639 TREE_NOTHROW (umsg_decl) = 0;
1640 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1641 TREE_NOTHROW (umsg_stret_decl) = 0;
1642 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1644 /* id objc_msgSend_Fast (id, SEL, ...)
1645 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1646 #ifdef OFFS_MSGSEND_FAST
1647 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1648 type, 0, NOT_BUILT_IN,
1649 NULL, NULL_TREE);
1650 TREE_NOTHROW (umsg_fast_decl) = 0;
1651 DECL_ATTRIBUTES (umsg_fast_decl)
1652 = tree_cons (get_identifier ("hard_coded_address"),
1653 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1654 NULL_TREE);
1655 #else
1656 /* No direct dispatch available. */
1657 umsg_fast_decl = umsg_decl;
1658 #endif
1660 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1661 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1662 type
1663 = build_function_type (objc_object_type,
1664 tree_cons (NULL_TREE, objc_super_type,
1665 tree_cons (NULL_TREE, objc_selector_type,
1666 NULL_TREE)));
1667 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1668 type, 0, NOT_BUILT_IN,
1669 NULL, NULL_TREE);
1670 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1671 type, 0, NOT_BUILT_IN, 0,
1672 NULL_TREE);
1673 TREE_NOTHROW (umsg_super_decl) = 0;
1674 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1676 else
1678 /* GNU runtime messenger entry points. */
1680 /* typedef id (*IMP)(id, SEL, ...); */
1681 tree IMP_type
1682 = build_pointer_type
1683 (build_function_type (objc_object_type,
1684 tree_cons (NULL_TREE, objc_object_type,
1685 tree_cons (NULL_TREE, objc_selector_type,
1686 NULL_TREE))));
1688 /* IMP objc_msg_lookup (id, SEL); */
1689 type
1690 = build_function_type (IMP_type,
1691 tree_cons (NULL_TREE, objc_object_type,
1692 tree_cons (NULL_TREE, objc_selector_type,
1693 OBJC_VOID_AT_END)));
1694 umsg_decl = add_builtin_function (TAG_MSGSEND,
1695 type, 0, NOT_BUILT_IN,
1696 NULL, NULL_TREE);
1697 TREE_NOTHROW (umsg_decl) = 0;
1699 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1700 type
1701 = build_function_type (IMP_type,
1702 tree_cons (NULL_TREE, objc_super_type,
1703 tree_cons (NULL_TREE, objc_selector_type,
1704 OBJC_VOID_AT_END)));
1705 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1706 type, 0, NOT_BUILT_IN,
1707 NULL, NULL_TREE);
1708 TREE_NOTHROW (umsg_super_decl) = 0;
1710 /* The following GNU runtime entry point is called to initialize
1711 each module:
1713 __objc_exec_class (void *); */
1714 type
1715 = build_function_type (void_type_node,
1716 tree_cons (NULL_TREE, ptr_type_node,
1717 OBJC_VOID_AT_END));
1718 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1719 type, 0, NOT_BUILT_IN,
1720 NULL, NULL_TREE);
1723 /* id objc_getClass (const char *); */
1725 type = build_function_type (objc_object_type,
1726 tree_cons (NULL_TREE,
1727 const_string_type_node,
1728 OBJC_VOID_AT_END));
1730 objc_get_class_decl
1731 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1732 NULL, NULL_TREE);
1734 /* id objc_getMetaClass (const char *); */
1736 objc_get_meta_class_decl
1737 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1739 build_class_template ();
1740 build_super_template ();
1741 build_protocol_template ();
1742 build_category_template ();
1743 build_objc_exception_stuff ();
1745 if (flag_next_runtime)
1746 build_next_objc_exception_stuff ();
1748 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1750 if (! flag_next_runtime)
1751 build_selector_table_decl ();
1753 /* Forward declare constant_string_id and constant_string_type. */
1754 if (!constant_string_class_name)
1755 constant_string_class_name = default_constant_string_class_name;
1757 constant_string_id = get_identifier (constant_string_class_name);
1758 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1760 /* Pre-build the following entities - for speed/convenience. */
1761 self_id = get_identifier ("self");
1762 ucmd_id = get_identifier ("_cmd");
1764 #ifdef OBJCPLUS
1765 pop_lang_context ();
1766 #endif
1768 write_symbols = save_write_symbols;
1769 debug_hooks = save_hooks;
1772 /* Ensure that the ivar list for NSConstantString/NXConstantString
1773 (or whatever was specified via `-fconstant-string-class')
1774 contains fields at least as large as the following three, so that
1775 the runtime can stomp on them with confidence:
1777 struct STRING_OBJECT_CLASS_NAME
1779 Object isa;
1780 char *cString;
1781 unsigned int length;
1782 }; */
1784 static int
1785 check_string_class_template (void)
1787 tree field_decl = objc_get_class_ivars (constant_string_id);
1789 #define AT_LEAST_AS_LARGE_AS(F, T) \
1790 (F && TREE_CODE (F) == FIELD_DECL \
1791 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1792 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1794 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1795 return 0;
1797 field_decl = TREE_CHAIN (field_decl);
1798 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1799 return 0;
1801 field_decl = TREE_CHAIN (field_decl);
1802 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1804 #undef AT_LEAST_AS_LARGE_AS
1807 /* Avoid calling `check_string_class_template ()' more than once. */
1808 static GTY(()) int string_layout_checked;
1810 /* Construct an internal string layout to be used as a template for
1811 creating NSConstantString/NXConstantString instances. */
1813 static tree
1814 objc_build_internal_const_str_type (void)
1816 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1817 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1818 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1820 TREE_CHAIN (field) = fields; fields = field;
1821 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1822 TREE_CHAIN (field) = fields; fields = field;
1823 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1824 reverse order! */
1825 finish_builtin_struct (type, "__builtin_ObjCString",
1826 fields, NULL_TREE);
1828 return type;
1831 /* Custom build_string which sets TREE_TYPE! */
1833 static tree
1834 my_build_string (int len, const char *str)
1836 return fix_string_type (build_string (len, str));
1839 /* Build a string with contents STR and length LEN and convert it to a
1840 pointer. */
1842 static tree
1843 my_build_string_pointer (int len, const char *str)
1845 tree string = my_build_string (len, str);
1846 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1847 return build1 (ADDR_EXPR, ptrtype, string);
1850 static hashval_t
1851 string_hash (const void *ptr)
1853 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1854 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1855 int i, len = TREE_STRING_LENGTH (str);
1856 hashval_t h = len;
1858 for (i = 0; i < len; i++)
1859 h = ((h * 613) + p[i]);
1861 return h;
1864 static int
1865 string_eq (const void *ptr1, const void *ptr2)
1867 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1868 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1869 int len1 = TREE_STRING_LENGTH (str1);
1871 return (len1 == TREE_STRING_LENGTH (str2)
1872 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1873 len1));
1876 /* Given a chain of STRING_CST's, build a static instance of
1877 NXConstantString which points at the concatenation of those
1878 strings. We place the string object in the __string_objects
1879 section of the __OBJC segment. The Objective-C runtime will
1880 initialize the isa pointers of the string objects to point at the
1881 NXConstantString class object. */
1883 tree
1884 objc_build_string_object (tree string)
1886 tree initlist, constructor, constant_string_class;
1887 int length;
1888 tree fields, addr;
1889 struct string_descriptor *desc, key;
1890 void **loc;
1892 /* Prep the string argument. */
1893 string = fix_string_type (string);
1894 TREE_SET_CODE (string, STRING_CST);
1895 length = TREE_STRING_LENGTH (string) - 1;
1897 /* Check whether the string class being used actually exists and has the
1898 correct ivar layout. */
1899 if (!string_layout_checked)
1901 string_layout_checked = -1;
1902 constant_string_class = lookup_interface (constant_string_id);
1903 internal_const_str_type = objc_build_internal_const_str_type ();
1905 if (!constant_string_class
1906 || !(constant_string_type
1907 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1908 error ("cannot find interface declaration for %qs",
1909 IDENTIFIER_POINTER (constant_string_id));
1910 /* The NSConstantString/NXConstantString ivar layout is now known. */
1911 else if (!check_string_class_template ())
1912 error ("interface %qs does not have valid constant string layout",
1913 IDENTIFIER_POINTER (constant_string_id));
1914 /* For the NeXT runtime, we can generate a literal reference
1915 to the string class, don't need to run a constructor. */
1916 else if (flag_next_runtime && !setup_string_decl ())
1917 error ("cannot find reference tag for class %qs",
1918 IDENTIFIER_POINTER (constant_string_id));
1919 else
1921 string_layout_checked = 1; /* Success! */
1922 add_class_reference (constant_string_id);
1926 if (string_layout_checked == -1)
1927 return error_mark_node;
1929 /* Perhaps we already constructed a constant string just like this one? */
1930 key.literal = string;
1931 loc = htab_find_slot (string_htab, &key, INSERT);
1932 desc = *loc;
1934 if (!desc)
1936 tree var;
1937 *loc = desc = ggc_alloc (sizeof (*desc));
1938 desc->literal = string;
1940 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1941 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1942 fields = TYPE_FIELDS (internal_const_str_type);
1943 initlist
1944 = build_tree_list (fields,
1945 flag_next_runtime
1946 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1947 : build_int_cst (NULL_TREE, 0));
1948 fields = TREE_CHAIN (fields);
1949 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1950 initlist);
1951 fields = TREE_CHAIN (fields);
1952 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1953 initlist);
1954 constructor = objc_build_constructor (internal_const_str_type,
1955 nreverse (initlist));
1957 if (!flag_next_runtime)
1958 constructor
1959 = objc_add_static_instance (constructor, constant_string_type);
1960 else
1962 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1963 DECL_INITIAL (var) = constructor;
1964 TREE_STATIC (var) = 1;
1965 pushdecl_top_level (var);
1966 constructor = var;
1968 desc->constructor = constructor;
1971 addr = convert (build_pointer_type (constant_string_type),
1972 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1974 return addr;
1977 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1979 static GTY(()) int num_static_inst;
1981 static tree
1982 objc_add_static_instance (tree constructor, tree class_decl)
1984 tree *chain, decl;
1985 char buf[256];
1987 /* Find the list of static instances for the CLASS_DECL. Create one if
1988 not found. */
1989 for (chain = &objc_static_instances;
1990 *chain && TREE_VALUE (*chain) != class_decl;
1991 chain = &TREE_CHAIN (*chain));
1992 if (!*chain)
1994 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1995 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1998 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1999 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
2000 DECL_COMMON (decl) = 1;
2001 TREE_STATIC (decl) = 1;
2002 DECL_ARTIFICIAL (decl) = 1;
2003 TREE_USED (decl) = 1;
2004 DECL_INITIAL (decl) = constructor;
2006 /* We may be writing something else just now.
2007 Postpone till end of input. */
2008 DECL_DEFER_OUTPUT (decl) = 1;
2009 pushdecl_top_level (decl);
2010 rest_of_decl_compilation (decl, 1, 0);
2012 /* Add the DECL to the head of this CLASS' list. */
2013 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2015 return decl;
2018 /* Build a static constant CONSTRUCTOR
2019 with type TYPE and elements ELTS. */
2021 static tree
2022 objc_build_constructor (tree type, tree elts)
2024 tree constructor = build_constructor_from_list (type, elts);
2026 TREE_CONSTANT (constructor) = 1;
2027 TREE_STATIC (constructor) = 1;
2028 TREE_READONLY (constructor) = 1;
2030 #ifdef OBJCPLUS
2031 /* Adjust for impedance mismatch. We should figure out how to build
2032 CONSTRUCTORs that consistently please both the C and C++ gods. */
2033 if (!TREE_PURPOSE (elts))
2034 TREE_TYPE (constructor) = NULL_TREE;
2035 TREE_HAS_CONSTRUCTOR (constructor) = 1;
2036 #endif
2038 return constructor;
2041 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2043 /* Predefine the following data type:
2045 struct _objc_symtab
2047 long sel_ref_cnt;
2048 SEL *refs;
2049 short cls_def_cnt;
2050 short cat_def_cnt;
2051 void *defs[cls_def_cnt + cat_def_cnt];
2052 }; */
2054 static void
2055 build_objc_symtab_template (void)
2057 tree field_decl, field_decl_chain;
2059 objc_symtab_template
2060 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2062 /* long sel_ref_cnt; */
2063 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2064 field_decl_chain = field_decl;
2066 /* SEL *refs; */
2067 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2068 "refs");
2069 chainon (field_decl_chain, field_decl);
2071 /* short cls_def_cnt; */
2072 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2073 chainon (field_decl_chain, field_decl);
2075 /* short cat_def_cnt; */
2076 field_decl = create_field_decl (short_integer_type_node,
2077 "cat_def_cnt");
2078 chainon (field_decl_chain, field_decl);
2080 if (imp_count || cat_count || !flag_next_runtime)
2082 /* void *defs[imp_count + cat_count (+ 1)]; */
2083 /* NB: The index is one less than the size of the array. */
2084 int index = imp_count + cat_count
2085 + (flag_next_runtime? -1: 0);
2086 field_decl = create_field_decl
2087 (build_array_type
2088 (ptr_type_node,
2089 build_index_type (build_int_cst (NULL_TREE, index))),
2090 "defs");
2091 chainon (field_decl_chain, field_decl);
2094 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2097 /* Create the initial value for the `defs' field of _objc_symtab.
2098 This is a CONSTRUCTOR. */
2100 static tree
2101 init_def_list (tree type)
2103 tree expr, initlist = NULL_TREE;
2104 struct imp_entry *impent;
2106 if (imp_count)
2107 for (impent = imp_list; impent; impent = impent->next)
2109 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2111 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2112 initlist = tree_cons (NULL_TREE, expr, initlist);
2116 if (cat_count)
2117 for (impent = imp_list; impent; impent = impent->next)
2119 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2121 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2122 initlist = tree_cons (NULL_TREE, expr, initlist);
2126 if (!flag_next_runtime)
2128 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2129 tree expr;
2131 if (static_instances_decl)
2132 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2133 else
2134 expr = build_int_cst (NULL_TREE, 0);
2136 initlist = tree_cons (NULL_TREE, expr, initlist);
2139 return objc_build_constructor (type, nreverse (initlist));
2142 /* Construct the initial value for all of _objc_symtab. */
2144 static tree
2145 init_objc_symtab (tree type)
2147 tree initlist;
2149 /* sel_ref_cnt = { ..., 5, ... } */
2151 initlist = build_tree_list (NULL_TREE,
2152 build_int_cst (long_integer_type_node, 0));
2154 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2156 if (flag_next_runtime || ! sel_ref_chain)
2157 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2158 else
2159 initlist
2160 = tree_cons (NULL_TREE,
2161 convert (build_pointer_type (objc_selector_type),
2162 build_unary_op (ADDR_EXPR,
2163 UOBJC_SELECTOR_TABLE_decl, 1)),
2164 initlist);
2166 /* cls_def_cnt = { ..., 5, ... } */
2168 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2170 /* cat_def_cnt = { ..., 5, ... } */
2172 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2174 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2176 if (imp_count || cat_count || !flag_next_runtime)
2179 tree field = TYPE_FIELDS (type);
2180 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2182 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2183 initlist);
2186 return objc_build_constructor (type, nreverse (initlist));
2189 /* Generate forward declarations for metadata such as
2190 'OBJC_CLASS_...'. */
2192 static tree
2193 build_metadata_decl (const char *name, tree type)
2195 tree decl;
2197 /* struct TYPE NAME_<name>; */
2198 decl = start_var_decl (type, synth_id_with_class_suffix
2199 (name,
2200 objc_implementation_context));
2202 return decl;
2205 /* Push forward-declarations of all the categories so that
2206 init_def_list can use them in a CONSTRUCTOR. */
2208 static void
2209 forward_declare_categories (void)
2211 struct imp_entry *impent;
2212 tree sav = objc_implementation_context;
2214 for (impent = imp_list; impent; impent = impent->next)
2216 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2218 /* Set an invisible arg to synth_id_with_class_suffix. */
2219 objc_implementation_context = impent->imp_context;
2220 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2221 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2222 objc_category_template);
2225 objc_implementation_context = sav;
2228 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2229 and initialized appropriately. */
2231 static void
2232 generate_objc_symtab_decl (void)
2234 /* forward declare categories */
2235 if (cat_count)
2236 forward_declare_categories ();
2238 build_objc_symtab_template ();
2239 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2240 finish_var_decl (UOBJC_SYMBOLS_decl,
2241 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2244 static tree
2245 init_module_descriptor (tree type)
2247 tree initlist, expr;
2249 /* version = { 1, ... } */
2251 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2252 initlist = build_tree_list (NULL_TREE, expr);
2254 /* size = { ..., sizeof (struct _objc_module), ... } */
2256 expr = convert (long_integer_type_node,
2257 size_in_bytes (objc_module_template));
2258 initlist = tree_cons (NULL_TREE, expr, initlist);
2260 /* Don't provide any file name for security reasons. */
2261 /* name = { ..., "", ... } */
2263 expr = add_objc_string (get_identifier (""), class_names);
2264 initlist = tree_cons (NULL_TREE, expr, initlist);
2266 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2268 if (UOBJC_SYMBOLS_decl)
2269 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2270 else
2271 expr = build_int_cst (NULL_TREE, 0);
2272 initlist = tree_cons (NULL_TREE, expr, initlist);
2274 return objc_build_constructor (type, nreverse (initlist));
2277 /* Write out the data structures to describe Objective C classes defined.
2279 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2281 static void
2282 build_module_descriptor (void)
2284 tree field_decl, field_decl_chain;
2286 #ifdef OBJCPLUS
2287 push_lang_context (lang_name_c); /* extern "C" */
2288 #endif
2290 objc_module_template
2291 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2293 /* long version; */
2294 field_decl = create_field_decl (long_integer_type_node, "version");
2295 field_decl_chain = field_decl;
2297 /* long size; */
2298 field_decl = create_field_decl (long_integer_type_node, "size");
2299 chainon (field_decl_chain, field_decl);
2301 /* char *name; */
2302 field_decl = create_field_decl (string_type_node, "name");
2303 chainon (field_decl_chain, field_decl);
2305 /* struct _objc_symtab *symtab; */
2306 field_decl
2307 = create_field_decl (build_pointer_type
2308 (xref_tag (RECORD_TYPE,
2309 get_identifier (UTAG_SYMTAB))),
2310 "symtab");
2311 chainon (field_decl_chain, field_decl);
2313 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2315 /* Create an instance of "_objc_module". */
2316 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2317 finish_var_decl (UOBJC_MODULES_decl,
2318 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2320 #ifdef OBJCPLUS
2321 pop_lang_context ();
2322 #endif
2325 /* The GNU runtime requires us to provide a static initializer function
2326 for each module:
2328 static void __objc_gnu_init (void) {
2329 __objc_exec_class (&L_OBJC_MODULES);
2330 } */
2332 static void
2333 build_module_initializer_routine (void)
2335 tree body;
2337 #ifdef OBJCPLUS
2338 push_lang_context (lang_name_c); /* extern "C" */
2339 #endif
2341 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2342 objc_start_function (get_identifier (TAG_GNUINIT),
2343 build_function_type (void_type_node,
2344 OBJC_VOID_AT_END),
2345 NULL_TREE, objc_get_parm_info (0));
2347 body = c_begin_compound_stmt (true);
2348 add_stmt (build_function_call
2349 (execclass_decl,
2350 build_tree_list
2351 (NULL_TREE,
2352 build_unary_op (ADDR_EXPR,
2353 UOBJC_MODULES_decl, 0))));
2354 add_stmt (c_end_compound_stmt (body, true));
2356 TREE_PUBLIC (current_function_decl) = 0;
2358 #ifndef OBJCPLUS
2359 /* For Objective-C++, we will need to call __objc_gnu_init
2360 from objc_generate_static_init_call() below. */
2361 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2362 #endif
2364 GNU_INIT_decl = current_function_decl;
2365 finish_function ();
2367 #ifdef OBJCPLUS
2368 pop_lang_context ();
2369 #endif
2372 #ifdef OBJCPLUS
2373 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2374 to be called by the module initializer routine. */
2377 objc_static_init_needed_p (void)
2379 return (GNU_INIT_decl != NULL_TREE);
2382 /* Generate a call to the __objc_gnu_init initializer function. */
2384 tree
2385 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2387 add_stmt (build_stmt (EXPR_STMT,
2388 build_function_call (GNU_INIT_decl, NULL_TREE)));
2390 return ctors;
2392 #endif /* OBJCPLUS */
2394 /* Return the DECL of the string IDENT in the SECTION. */
2396 static tree
2397 get_objc_string_decl (tree ident, enum string_section section)
2399 tree chain;
2401 if (section == class_names)
2402 chain = class_names_chain;
2403 else if (section == meth_var_names)
2404 chain = meth_var_names_chain;
2405 else if (section == meth_var_types)
2406 chain = meth_var_types_chain;
2407 else
2408 abort ();
2410 for (; chain != 0; chain = TREE_CHAIN (chain))
2411 if (TREE_VALUE (chain) == ident)
2412 return (TREE_PURPOSE (chain));
2414 abort ();
2415 return NULL_TREE;
2418 /* Output references to all statically allocated objects. Return the DECL
2419 for the array built. */
2421 static void
2422 generate_static_references (void)
2424 tree decls = NULL_TREE, expr = NULL_TREE;
2425 tree class_name, class, decl, initlist;
2426 tree cl_chain, in_chain, type
2427 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2428 int num_inst, num_class;
2429 char buf[256];
2431 if (flag_next_runtime)
2432 abort ();
2434 for (cl_chain = objc_static_instances, num_class = 0;
2435 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2437 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2438 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2440 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2441 decl = start_var_decl (type, buf);
2443 /* Output {class_name, ...}. */
2444 class = TREE_VALUE (cl_chain);
2445 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2446 initlist = build_tree_list (NULL_TREE,
2447 build_unary_op (ADDR_EXPR, class_name, 1));
2449 /* Output {..., instance, ...}. */
2450 for (in_chain = TREE_PURPOSE (cl_chain);
2451 in_chain; in_chain = TREE_CHAIN (in_chain))
2453 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2454 initlist = tree_cons (NULL_TREE, expr, initlist);
2457 /* Output {..., NULL}. */
2458 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2460 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2461 finish_var_decl (decl, expr);
2462 decls
2463 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2466 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2467 expr = objc_build_constructor (type, nreverse (decls));
2468 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2469 finish_var_decl (static_instances_decl, expr);
2472 static GTY(()) int selector_reference_idx;
2474 static tree
2475 build_selector_reference_decl (void)
2477 tree decl;
2478 char buf[256];
2480 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2481 decl = start_var_decl (objc_selector_type, buf);
2483 return decl;
2486 static void
2487 build_selector_table_decl (void)
2489 tree temp;
2491 if (flag_typed_selectors)
2493 build_selector_template ();
2494 temp = build_array_type (objc_selector_template, NULL_TREE);
2496 else
2497 temp = build_array_type (objc_selector_type, NULL_TREE);
2499 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2502 /* Just a handy wrapper for add_objc_string. */
2504 static tree
2505 build_selector (tree ident)
2507 return convert (objc_selector_type,
2508 add_objc_string (ident, meth_var_names));
2511 static void
2512 build_selector_translation_table (void)
2514 tree chain, initlist = NULL_TREE;
2515 int offset = 0;
2516 tree decl = NULL_TREE;
2518 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2520 tree expr;
2522 if (warn_selector && objc_implementation_context)
2524 tree method_chain;
2525 bool found = false;
2526 for (method_chain = meth_var_names_chain;
2527 method_chain;
2528 method_chain = TREE_CHAIN (method_chain))
2530 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2532 found = true;
2533 break;
2536 if (!found)
2538 location_t *loc;
2539 if (flag_next_runtime && TREE_PURPOSE (chain))
2540 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2541 else
2542 loc = &input_location;
2543 warning (0, "%Hcreating selector for nonexistent method %qE",
2544 loc, TREE_VALUE (chain));
2548 expr = build_selector (TREE_VALUE (chain));
2549 /* add one for the '\0' character */
2550 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2552 if (flag_next_runtime)
2554 decl = TREE_PURPOSE (chain);
2555 finish_var_decl (decl, expr);
2557 else
2559 if (flag_typed_selectors)
2561 tree eltlist = NULL_TREE;
2562 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2563 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2564 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2565 expr = objc_build_constructor (objc_selector_template,
2566 nreverse (eltlist));
2569 initlist = tree_cons (NULL_TREE, expr, initlist);
2573 if (! flag_next_runtime)
2575 /* Cause the selector table (previously forward-declared)
2576 to be actually output. */
2577 initlist = tree_cons (NULL_TREE,
2578 flag_typed_selectors
2579 ? objc_build_constructor
2580 (objc_selector_template,
2581 tree_cons (NULL_TREE,
2582 build_int_cst (NULL_TREE, 0),
2583 tree_cons (NULL_TREE,
2584 build_int_cst (NULL_TREE, 0),
2585 NULL_TREE)))
2586 : build_int_cst (NULL_TREE, 0), initlist);
2587 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2588 nreverse (initlist));
2589 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2593 static tree
2594 get_proto_encoding (tree proto)
2596 tree encoding;
2597 if (proto)
2599 if (! METHOD_ENCODING (proto))
2601 encoding = encode_method_prototype (proto);
2602 METHOD_ENCODING (proto) = encoding;
2604 else
2605 encoding = METHOD_ENCODING (proto);
2607 return add_objc_string (encoding, meth_var_types);
2609 else
2610 return build_int_cst (NULL_TREE, 0);
2613 /* sel_ref_chain is a list whose "value" fields will be instances of
2614 identifier_node that represent the selector. */
2616 static tree
2617 build_typed_selector_reference (tree ident, tree prototype)
2619 tree *chain = &sel_ref_chain;
2620 tree expr;
2621 int index = 0;
2623 while (*chain)
2625 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2626 goto return_at_index;
2628 index++;
2629 chain = &TREE_CHAIN (*chain);
2632 *chain = tree_cons (prototype, ident, NULL_TREE);
2634 return_at_index:
2635 expr = build_unary_op (ADDR_EXPR,
2636 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2637 build_int_cst (NULL_TREE, index)),
2639 return convert (objc_selector_type, expr);
2642 static tree
2643 build_selector_reference (tree ident)
2645 tree *chain = &sel_ref_chain;
2646 tree expr;
2647 int index = 0;
2649 while (*chain)
2651 if (TREE_VALUE (*chain) == ident)
2652 return (flag_next_runtime
2653 ? TREE_PURPOSE (*chain)
2654 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2655 build_int_cst (NULL_TREE, index)));
2657 index++;
2658 chain = &TREE_CHAIN (*chain);
2661 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2663 *chain = tree_cons (expr, ident, NULL_TREE);
2665 return (flag_next_runtime
2666 ? expr
2667 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2668 build_int_cst (NULL_TREE, index)));
2671 static GTY(()) int class_reference_idx;
2673 static tree
2674 build_class_reference_decl (void)
2676 tree decl;
2677 char buf[256];
2679 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2680 decl = start_var_decl (objc_class_type, buf);
2682 return decl;
2685 /* Create a class reference, but don't create a variable to reference
2686 it. */
2688 static void
2689 add_class_reference (tree ident)
2691 tree chain;
2693 if ((chain = cls_ref_chain))
2695 tree tail;
2698 if (ident == TREE_VALUE (chain))
2699 return;
2701 tail = chain;
2702 chain = TREE_CHAIN (chain);
2704 while (chain);
2706 /* Append to the end of the list */
2707 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2709 else
2710 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2713 /* Get a class reference, creating it if necessary. Also create the
2714 reference variable. */
2716 tree
2717 objc_get_class_reference (tree ident)
2719 tree orig_ident = (DECL_P (ident)
2720 ? DECL_NAME (ident)
2721 : TYPE_P (ident)
2722 ? OBJC_TYPE_NAME (ident)
2723 : ident);
2724 bool local_scope = false;
2726 #ifdef OBJCPLUS
2727 if (processing_template_decl)
2728 /* Must wait until template instantiation time. */
2729 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2730 #endif
2732 if (TREE_CODE (ident) == TYPE_DECL)
2733 ident = (DECL_ORIGINAL_TYPE (ident)
2734 ? DECL_ORIGINAL_TYPE (ident)
2735 : TREE_TYPE (ident));
2737 #ifdef OBJCPLUS
2738 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2739 && TYPE_CONTEXT (ident) != global_namespace)
2740 local_scope = true;
2741 #endif
2743 if (local_scope || !(ident = objc_is_class_name (ident)))
2745 error ("%qs is not an Objective-C class name or alias",
2746 IDENTIFIER_POINTER (orig_ident));
2747 return error_mark_node;
2750 if (flag_next_runtime && !flag_zero_link)
2752 tree *chain;
2753 tree decl;
2755 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2756 if (TREE_VALUE (*chain) == ident)
2758 if (! TREE_PURPOSE (*chain))
2759 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2761 return TREE_PURPOSE (*chain);
2764 decl = build_class_reference_decl ();
2765 *chain = tree_cons (decl, ident, NULL_TREE);
2766 return decl;
2768 else
2770 tree params;
2772 add_class_reference (ident);
2774 params = build_tree_list (NULL_TREE,
2775 my_build_string_pointer
2776 (IDENTIFIER_LENGTH (ident) + 1,
2777 IDENTIFIER_POINTER (ident)));
2779 assemble_external (objc_get_class_decl);
2780 return build_function_call (objc_get_class_decl, params);
2784 /* For each string section we have a chain which maps identifier nodes
2785 to decls for the strings. */
2787 static tree
2788 add_objc_string (tree ident, enum string_section section)
2790 tree *chain, decl, type, string_expr;
2792 if (section == class_names)
2793 chain = &class_names_chain;
2794 else if (section == meth_var_names)
2795 chain = &meth_var_names_chain;
2796 else if (section == meth_var_types)
2797 chain = &meth_var_types_chain;
2798 else
2799 abort ();
2801 while (*chain)
2803 if (TREE_VALUE (*chain) == ident)
2804 return convert (string_type_node,
2805 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2807 chain = &TREE_CHAIN (*chain);
2810 decl = build_objc_string_decl (section);
2812 type = build_array_type
2813 (char_type_node,
2814 build_index_type
2815 (build_int_cst (NULL_TREE,
2816 IDENTIFIER_LENGTH (ident))));
2817 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2818 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2819 IDENTIFIER_POINTER (ident));
2820 finish_var_decl (decl, string_expr);
2822 *chain = tree_cons (decl, ident, NULL_TREE);
2824 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2827 static GTY(()) int class_names_idx;
2828 static GTY(()) int meth_var_names_idx;
2829 static GTY(()) int meth_var_types_idx;
2831 static tree
2832 build_objc_string_decl (enum string_section section)
2834 tree decl, ident;
2835 char buf[256];
2837 if (section == class_names)
2838 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2839 else if (section == meth_var_names)
2840 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2841 else if (section == meth_var_types)
2842 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2844 ident = get_identifier (buf);
2846 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2847 DECL_EXTERNAL (decl) = 1;
2848 TREE_PUBLIC (decl) = 0;
2849 TREE_USED (decl) = 1;
2850 TREE_CONSTANT (decl) = 1;
2851 DECL_CONTEXT (decl) = 0;
2852 DECL_ARTIFICIAL (decl) = 1;
2853 #ifdef OBJCPLUS
2854 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2855 #endif
2857 make_decl_rtl (decl);
2858 pushdecl_top_level (decl);
2860 return decl;
2864 void
2865 objc_declare_alias (tree alias_ident, tree class_ident)
2867 tree underlying_class;
2869 #ifdef OBJCPLUS
2870 if (current_namespace != global_namespace) {
2871 error ("Objective-C declarations may only appear in global scope");
2873 #endif /* OBJCPLUS */
2875 if (!(underlying_class = objc_is_class_name (class_ident)))
2876 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2877 else if (objc_is_class_name (alias_ident))
2878 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2879 else
2881 /* Implement @compatibility_alias as a typedef. */
2882 #ifdef OBJCPLUS
2883 push_lang_context (lang_name_c); /* extern "C" */
2884 #endif
2885 lang_hooks.decls.pushdecl (build_decl
2886 (TYPE_DECL,
2887 alias_ident,
2888 xref_tag (RECORD_TYPE, underlying_class)));
2889 #ifdef OBJCPLUS
2890 pop_lang_context ();
2891 #endif
2892 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2896 void
2897 objc_declare_class (tree ident_list)
2899 tree list;
2900 #ifdef OBJCPLUS
2901 if (current_namespace != global_namespace) {
2902 error ("Objective-C declarations may only appear in global scope");
2904 #endif /* OBJCPLUS */
2906 for (list = ident_list; list; list = TREE_CHAIN (list))
2908 tree ident = TREE_VALUE (list);
2910 if (! objc_is_class_name (ident))
2912 tree record = lookup_name (ident), type = record;
2914 if (record)
2916 if (TREE_CODE (record) == TYPE_DECL)
2917 type = DECL_ORIGINAL_TYPE (record);
2919 if (!TYPE_HAS_OBJC_INFO (type)
2920 || !TYPE_OBJC_INTERFACE (type))
2922 error ("%qs redeclared as different kind of symbol",
2923 IDENTIFIER_POINTER (ident));
2924 error ("previous declaration of %q+D",
2925 record);
2929 record = xref_tag (RECORD_TYPE, ident);
2930 INIT_TYPE_OBJC_INFO (record);
2931 TYPE_OBJC_INTERFACE (record) = ident;
2932 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2937 tree
2938 objc_is_class_name (tree ident)
2940 tree chain;
2942 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2943 && identifier_global_value (ident))
2944 ident = identifier_global_value (ident);
2945 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2946 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2948 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2949 ident = OBJC_TYPE_NAME (ident);
2950 #ifdef OBJCPLUS
2951 if (ident && TREE_CODE (ident) == TYPE_DECL)
2952 ident = DECL_NAME (ident);
2953 #endif
2954 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2955 return NULL_TREE;
2957 if (lookup_interface (ident))
2958 return ident;
2960 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2962 if (ident == TREE_VALUE (chain))
2963 return ident;
2966 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2968 if (ident == TREE_VALUE (chain))
2969 return TREE_PURPOSE (chain);
2972 return 0;
2975 /* Check whether TYPE is either 'id' or 'Class'. */
2977 tree
2978 objc_is_id (tree type)
2980 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2981 && identifier_global_value (type))
2982 type = identifier_global_value (type);
2984 if (type && TREE_CODE (type) == TYPE_DECL)
2985 type = TREE_TYPE (type);
2987 /* NB: This function may be called before the ObjC front-end has
2988 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2989 return (objc_object_type && type
2990 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2991 ? type
2992 : NULL_TREE);
2995 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2996 class instance. This is needed by other parts of the compiler to
2997 handle ObjC types gracefully. */
2999 tree
3000 objc_is_object_ptr (tree type)
3002 tree ret;
3004 type = TYPE_MAIN_VARIANT (type);
3005 if (!POINTER_TYPE_P (type))
3006 return 0;
3008 ret = objc_is_id (type);
3009 if (!ret)
3010 ret = objc_is_class_name (TREE_TYPE (type));
3012 return ret;
3015 static int
3016 objc_is_gcable_type (tree type, int or_strong_p)
3018 tree name;
3020 if (!TYPE_P (type))
3021 return 0;
3022 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3023 return 1;
3024 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3025 return 1;
3026 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3027 return 0;
3028 type = TREE_TYPE (type);
3029 if (TREE_CODE (type) != RECORD_TYPE)
3030 return 0;
3031 name = TYPE_NAME (type);
3032 return (objc_is_class_name (name) != NULL_TREE);
3035 static tree
3036 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3038 if (expr == oldexpr)
3039 return newexpr;
3041 switch (TREE_CODE (expr))
3043 case COMPONENT_REF:
3044 return objc_build_component_ref
3045 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3046 oldexpr,
3047 newexpr),
3048 DECL_NAME (TREE_OPERAND (expr, 1)));
3049 case ARRAY_REF:
3050 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3051 oldexpr,
3052 newexpr),
3053 TREE_OPERAND (expr, 1));
3054 case INDIRECT_REF:
3055 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3056 oldexpr,
3057 newexpr), "->");
3058 default:
3059 return expr;
3063 static tree
3064 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3066 tree func_params;
3067 /* The LHS parameter contains the expression 'outervar->memberspec';
3068 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3069 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3071 tree offs
3072 = objc_substitute_decl
3073 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3074 tree func
3075 = (flag_objc_direct_dispatch
3076 ? objc_assign_ivar_fast_decl
3077 : objc_assign_ivar_decl);
3079 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3080 offs = fold (offs);
3081 func_params = tree_cons (NULL_TREE,
3082 convert (objc_object_type, rhs),
3083 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3084 tree_cons (NULL_TREE, offs,
3085 NULL_TREE)));
3087 assemble_external (func);
3088 return build_function_call (func, func_params);
3091 static tree
3092 objc_build_global_assignment (tree lhs, tree rhs)
3094 tree func_params = tree_cons (NULL_TREE,
3095 convert (objc_object_type, rhs),
3096 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3097 build_unary_op (ADDR_EXPR, lhs, 0)),
3098 NULL_TREE));
3100 assemble_external (objc_assign_global_decl);
3101 return build_function_call (objc_assign_global_decl, func_params);
3104 static tree
3105 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3107 tree func_params = tree_cons (NULL_TREE,
3108 convert (objc_object_type, rhs),
3109 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3110 build_unary_op (ADDR_EXPR, lhs, 0)),
3111 NULL_TREE));
3113 assemble_external (objc_assign_strong_cast_decl);
3114 return build_function_call (objc_assign_strong_cast_decl, func_params);
3117 static int
3118 objc_is_gcable_p (tree expr)
3120 return (TREE_CODE (expr) == COMPONENT_REF
3121 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3122 : TREE_CODE (expr) == ARRAY_REF
3123 ? (objc_is_gcable_p (TREE_TYPE (expr))
3124 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3125 : TREE_CODE (expr) == ARRAY_TYPE
3126 ? objc_is_gcable_p (TREE_TYPE (expr))
3127 : TYPE_P (expr)
3128 ? objc_is_gcable_type (expr, 1)
3129 : (objc_is_gcable_p (TREE_TYPE (expr))
3130 || (DECL_P (expr)
3131 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3134 static int
3135 objc_is_ivar_reference_p (tree expr)
3137 return (TREE_CODE (expr) == ARRAY_REF
3138 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3139 : TREE_CODE (expr) == COMPONENT_REF
3140 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3141 : 0);
3144 static int
3145 objc_is_global_reference_p (tree expr)
3147 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3148 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3149 : DECL_P (expr)
3150 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3151 : 0);
3154 tree
3155 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3157 tree result = NULL_TREE, outer;
3158 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3160 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3161 will have been transformed to the form '*(type *)&expr'. */
3162 if (TREE_CODE (lhs) == INDIRECT_REF)
3164 outer = TREE_OPERAND (lhs, 0);
3166 while (!strong_cast_p
3167 && (CONVERT_EXPR_P (outer)
3168 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3170 tree lhstype = TREE_TYPE (outer);
3172 /* Descend down the cast chain, and record the first objc_gc
3173 attribute found. */
3174 if (POINTER_TYPE_P (lhstype))
3176 tree attr
3177 = lookup_attribute ("objc_gc",
3178 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3180 if (attr)
3181 strong_cast_p = 1;
3184 outer = TREE_OPERAND (outer, 0);
3188 /* If we have a __strong cast, it trumps all else. */
3189 if (strong_cast_p)
3191 if (modifycode != NOP_EXPR)
3192 goto invalid_pointer_arithmetic;
3194 if (warn_assign_intercept)
3195 warning (0, "strong-cast assignment has been intercepted");
3197 result = objc_build_strong_cast_assignment (lhs, rhs);
3199 goto exit_point;
3202 /* the lhs must be of a suitable type, regardless of its underlying
3203 structure. */
3204 if (!objc_is_gcable_p (lhs))
3205 goto exit_point;
3207 outer = lhs;
3209 while (outer
3210 && (TREE_CODE (outer) == COMPONENT_REF
3211 || TREE_CODE (outer) == ARRAY_REF))
3212 outer = TREE_OPERAND (outer, 0);
3214 if (TREE_CODE (outer) == INDIRECT_REF)
3216 outer = TREE_OPERAND (outer, 0);
3217 indirect_p = 1;
3220 outer_gc_p = objc_is_gcable_p (outer);
3222 /* Handle ivar assignments. */
3223 if (objc_is_ivar_reference_p (lhs))
3225 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3226 doesn't cut it here), the best we can do here is suggest a cast. */
3227 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3229 /* We may still be able to use the global write barrier... */
3230 if (!indirect_p && objc_is_global_reference_p (outer))
3231 goto global_reference;
3233 suggest_cast:
3234 if (modifycode == NOP_EXPR)
3236 if (warn_assign_intercept)
3237 warning (0, "strong-cast may possibly be needed");
3240 goto exit_point;
3243 if (modifycode != NOP_EXPR)
3244 goto invalid_pointer_arithmetic;
3246 if (warn_assign_intercept)
3247 warning (0, "instance variable assignment has been intercepted");
3249 result = objc_build_ivar_assignment (outer, lhs, rhs);
3251 goto exit_point;
3254 /* Likewise, intercept assignment to global/static variables if their type is
3255 GC-marked. */
3256 if (objc_is_global_reference_p (outer))
3258 if (indirect_p)
3259 goto suggest_cast;
3261 global_reference:
3262 if (modifycode != NOP_EXPR)
3264 invalid_pointer_arithmetic:
3265 if (outer_gc_p)
3266 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3268 goto exit_point;
3271 if (warn_assign_intercept)
3272 warning (0, "global/static variable assignment has been intercepted");
3274 result = objc_build_global_assignment (lhs, rhs);
3277 /* In all other cases, fall back to the normal mechanism. */
3278 exit_point:
3279 return result;
3282 struct interface_tuple GTY(())
3284 tree id;
3285 tree class_name;
3288 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3290 static hashval_t
3291 hash_interface (const void *p)
3293 const struct interface_tuple *d = p;
3294 return IDENTIFIER_HASH_VALUE (d->id);
3297 static int
3298 eq_interface (const void *p1, const void *p2)
3300 const struct interface_tuple *d = p1;
3301 return d->id == p2;
3304 static tree
3305 lookup_interface (tree ident)
3307 #ifdef OBJCPLUS
3308 if (ident && TREE_CODE (ident) == TYPE_DECL)
3309 ident = DECL_NAME (ident);
3310 #endif
3312 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3313 return NULL_TREE;
3316 struct interface_tuple **slot;
3317 tree i = NULL_TREE;
3319 if (interface_htab)
3321 slot = (struct interface_tuple **)
3322 htab_find_slot_with_hash (interface_htab, ident,
3323 IDENTIFIER_HASH_VALUE (ident),
3324 NO_INSERT);
3325 if (slot && *slot)
3326 i = (*slot)->class_name;
3328 return i;
3332 /* Implement @defs (<classname>) within struct bodies. */
3334 tree
3335 objc_get_class_ivars (tree class_name)
3337 tree interface = lookup_interface (class_name);
3339 if (interface)
3340 return get_class_ivars (interface, true);
3342 error ("cannot find interface declaration for %qs",
3343 IDENTIFIER_POINTER (class_name));
3345 return error_mark_node;
3348 /* Used by: build_private_template, continue_class,
3349 and for @defs constructs. */
3351 static tree
3352 get_class_ivars (tree interface, bool inherited)
3354 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3356 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3357 by the current class (i.e., they do not include super-class ivars).
3358 However, the CLASS_IVARS list will be side-effected by a call to
3359 finish_struct(), which will fill in field offsets. */
3360 if (!CLASS_IVARS (interface))
3361 CLASS_IVARS (interface) = ivar_chain;
3363 if (!inherited)
3364 return ivar_chain;
3366 while (CLASS_SUPER_NAME (interface))
3368 /* Prepend super-class ivars. */
3369 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3370 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3371 ivar_chain);
3374 return ivar_chain;
3377 static tree
3378 objc_create_temporary_var (tree type)
3380 tree decl;
3382 decl = build_decl (VAR_DECL, NULL_TREE, type);
3383 TREE_USED (decl) = 1;
3384 DECL_ARTIFICIAL (decl) = 1;
3385 DECL_IGNORED_P (decl) = 1;
3386 DECL_CONTEXT (decl) = current_function_decl;
3388 return decl;
3391 /* Exception handling constructs. We begin by having the parser do most
3392 of the work and passing us blocks. What we do next depends on whether
3393 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3394 We abstract all of this in a handful of appropriately named routines. */
3396 /* Stack of open try blocks. */
3398 struct objc_try_context
3400 struct objc_try_context *outer;
3402 /* Statements (or statement lists) as processed by the parser. */
3403 tree try_body;
3404 tree finally_body;
3406 /* Some file position locations. */
3407 location_t try_locus;
3408 location_t end_try_locus;
3409 location_t end_catch_locus;
3410 location_t finally_locus;
3411 location_t end_finally_locus;
3413 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3414 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3415 tree catch_list;
3417 /* The CATCH_EXPR of an open @catch clause. */
3418 tree current_catch;
3420 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3421 tree caught_decl;
3422 tree stack_decl;
3423 tree rethrow_decl;
3426 static struct objc_try_context *cur_try_context;
3428 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3429 that represents TYPE. For Objective-C, this is just the class name. */
3430 /* ??? Isn't there a class object or some such? Is it easy to get? */
3432 #ifndef OBJCPLUS
3433 static tree
3434 objc_eh_runtime_type (tree type)
3436 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3438 #endif
3440 /* Initialize exception handling. */
3442 static void
3443 objc_init_exceptions (void)
3445 static bool done = false;
3446 if (done)
3447 return;
3448 done = true;
3450 if (flag_objc_sjlj_exceptions)
3452 /* On Darwin, ObjC exceptions require a sufficiently recent
3453 version of the runtime, so the user must ask for them explicitly. */
3454 if (!flag_objc_exceptions)
3455 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3456 "exception syntax");
3458 #ifndef OBJCPLUS
3459 else
3461 c_eh_initialized_p = true;
3462 eh_personality_libfunc
3463 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3464 ? "__gnu_objc_personality_sj0"
3465 : "__gnu_objc_personality_v0");
3466 default_init_unwind_resume_libfunc ();
3467 using_eh_for_cleanups ();
3468 lang_eh_runtime_type = objc_eh_runtime_type;
3470 #endif
3473 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3474 we'll arrange for it to be initialized (and associated with a binding)
3475 later. */
3477 static tree
3478 objc_build_exc_ptr (void)
3480 if (flag_objc_sjlj_exceptions)
3482 tree var = cur_try_context->caught_decl;
3483 if (!var)
3485 var = objc_create_temporary_var (objc_object_type);
3486 cur_try_context->caught_decl = var;
3488 return var;
3490 else
3491 return build0 (EXC_PTR_EXPR, objc_object_type);
3494 /* Build "objc_exception_try_exit(&_stack)". */
3496 static tree
3497 next_sjlj_build_try_exit (void)
3499 tree t;
3500 t = build_fold_addr_expr (cur_try_context->stack_decl);
3501 t = tree_cons (NULL, t, NULL);
3502 t = build_function_call (objc_exception_try_exit_decl, t);
3503 return t;
3506 /* Build
3507 objc_exception_try_enter (&_stack);
3508 if (_setjmp(&_stack.buf))
3510 else
3512 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3513 empty, ready for the caller to fill them in. */
3515 static tree
3516 next_sjlj_build_enter_and_setjmp (void)
3518 tree t, enter, sj, cond;
3520 t = build_fold_addr_expr (cur_try_context->stack_decl);
3521 t = tree_cons (NULL, t, NULL);
3522 enter = build_function_call (objc_exception_try_enter_decl, t);
3524 t = objc_build_component_ref (cur_try_context->stack_decl,
3525 get_identifier ("buf"));
3526 t = build_fold_addr_expr (t);
3527 #ifdef OBJCPLUS
3528 /* Convert _setjmp argument to type that is expected. */
3529 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3530 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3531 else
3532 t = convert (ptr_type_node, t);
3533 #else
3534 t = convert (ptr_type_node, t);
3535 #endif
3536 t = tree_cons (NULL, t, NULL);
3537 sj = build_function_call (objc_setjmp_decl, t);
3539 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3540 cond = c_common_truthvalue_conversion (cond);
3542 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3545 /* Build:
3547 DECL = objc_exception_extract(&_stack); */
3549 static tree
3550 next_sjlj_build_exc_extract (tree decl)
3552 tree t;
3554 t = build_fold_addr_expr (cur_try_context->stack_decl);
3555 t = tree_cons (NULL, t, NULL);
3556 t = build_function_call (objc_exception_extract_decl, t);
3557 t = convert (TREE_TYPE (decl), t);
3558 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3560 return t;
3563 /* Build
3564 if (objc_exception_match(obj_get_class(TYPE), _caught)
3565 BODY
3566 else if (...)
3568 else
3570 _rethrow = _caught;
3571 objc_exception_try_exit(&_stack);
3573 from the sequence of CATCH_EXPRs in the current try context. */
3575 static tree
3576 next_sjlj_build_catch_list (void)
3578 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3579 tree catch_seq, t;
3580 tree *last = &catch_seq;
3581 bool saw_id = false;
3583 for (; !tsi_end_p (i); tsi_next (&i))
3585 tree stmt = tsi_stmt (i);
3586 tree type = CATCH_TYPES (stmt);
3587 tree body = CATCH_BODY (stmt);
3589 if (type == NULL)
3591 *last = body;
3592 saw_id = true;
3593 break;
3595 else
3597 tree args, cond;
3599 if (type == error_mark_node)
3600 cond = error_mark_node;
3601 else
3603 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3604 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3605 args = tree_cons (NULL, t, args);
3606 t = build_function_call (objc_exception_match_decl, args);
3607 cond = c_common_truthvalue_conversion (t);
3609 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3610 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3612 *last = t;
3613 last = &COND_EXPR_ELSE (t);
3617 if (!saw_id)
3619 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3620 cur_try_context->caught_decl);
3621 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3622 append_to_statement_list (t, last);
3624 t = next_sjlj_build_try_exit ();
3625 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3626 append_to_statement_list (t, last);
3629 return catch_seq;
3632 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3633 exception handling. We aim to build:
3636 struct _objc_exception_data _stack;
3637 id _rethrow = 0;
3640 objc_exception_try_enter (&_stack);
3641 if (_setjmp(&_stack.buf))
3643 id _caught = objc_exception_extract(&_stack);
3644 objc_exception_try_enter (&_stack);
3645 if (_setjmp(&_stack.buf))
3646 _rethrow = objc_exception_extract(&_stack);
3647 else
3648 CATCH-LIST
3650 else
3651 TRY-BLOCK
3653 finally
3655 if (!_rethrow)
3656 objc_exception_try_exit(&_stack);
3657 FINALLY-BLOCK
3658 if (_rethrow)
3659 objc_exception_throw(_rethrow);
3663 If CATCH-LIST is empty, we can omit all of the block containing
3664 "_caught" except for the setting of _rethrow. Note the use of
3665 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3666 but handles goto and other exits from the block. */
3668 static tree
3669 next_sjlj_build_try_catch_finally (void)
3671 tree rethrow_decl, stack_decl, t;
3672 tree catch_seq, try_fin, bind;
3674 /* Create the declarations involved. */
3675 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3676 stack_decl = objc_create_temporary_var (t);
3677 cur_try_context->stack_decl = stack_decl;
3679 rethrow_decl = objc_create_temporary_var (objc_object_type);
3680 cur_try_context->rethrow_decl = rethrow_decl;
3681 TREE_CHAIN (rethrow_decl) = stack_decl;
3683 /* Build the outermost variable binding level. */
3684 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3685 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3686 TREE_SIDE_EFFECTS (bind) = 1;
3688 /* Initialize rethrow_decl. */
3689 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3690 convert (objc_object_type, null_pointer_node));
3691 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3692 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3694 /* Build the outermost TRY_FINALLY_EXPR. */
3695 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3696 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3697 TREE_SIDE_EFFECTS (try_fin) = 1;
3698 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3700 /* Create the complete catch sequence. */
3701 if (cur_try_context->catch_list)
3703 tree caught_decl = objc_build_exc_ptr ();
3704 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3705 TREE_SIDE_EFFECTS (catch_seq) = 1;
3707 t = next_sjlj_build_exc_extract (caught_decl);
3708 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3710 t = next_sjlj_build_enter_and_setjmp ();
3711 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3712 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3713 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3715 else
3716 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3717 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3719 /* Build the main register-and-try if statement. */
3720 t = next_sjlj_build_enter_and_setjmp ();
3721 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3722 COND_EXPR_THEN (t) = catch_seq;
3723 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3724 TREE_OPERAND (try_fin, 0) = t;
3726 /* Build the complete FINALLY statement list. */
3727 t = next_sjlj_build_try_exit ();
3728 t = build_stmt (COND_EXPR,
3729 c_common_truthvalue_conversion (rethrow_decl),
3730 NULL, t);
3731 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3732 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3734 append_to_statement_list (cur_try_context->finally_body,
3735 &TREE_OPERAND (try_fin, 1));
3737 t = tree_cons (NULL, rethrow_decl, NULL);
3738 t = build_function_call (objc_exception_throw_decl, t);
3739 t = build_stmt (COND_EXPR,
3740 c_common_truthvalue_conversion (rethrow_decl),
3741 t, NULL);
3742 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3743 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3745 return bind;
3748 /* Called just after parsing the @try and its associated BODY. We now
3749 must prepare for the tricky bits -- handling the catches and finally. */
3751 void
3752 objc_begin_try_stmt (location_t try_locus, tree body)
3754 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3755 c->outer = cur_try_context;
3756 c->try_body = body;
3757 c->try_locus = try_locus;
3758 c->end_try_locus = input_location;
3759 cur_try_context = c;
3761 objc_init_exceptions ();
3763 if (flag_objc_sjlj_exceptions)
3764 objc_mark_locals_volatile (NULL);
3767 /* Called just after parsing "@catch (parm)". Open a binding level,
3768 enter DECL into the binding level, and initialize it. Leave the
3769 binding level open while the body of the compound statement is parsed. */
3771 void
3772 objc_begin_catch_clause (tree decl)
3774 tree compound, type, t;
3776 /* Begin a new scope that the entire catch clause will live in. */
3777 compound = c_begin_compound_stmt (true);
3779 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3780 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3781 lang_hooks.decls.pushdecl (decl);
3783 /* Since a decl is required here by syntax, don't warn if its unused. */
3784 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3785 be what the previous objc implementation did. */
3786 TREE_USED (decl) = 1;
3788 /* Verify that the type of the catch is valid. It must be a pointer
3789 to an Objective-C class, or "id" (which is catch-all). */
3790 type = TREE_TYPE (decl);
3792 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3793 type = NULL;
3794 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3796 error ("@catch parameter is not a known Objective-C class type");
3797 type = error_mark_node;
3799 else if (cur_try_context->catch_list)
3801 /* Examine previous @catch clauses and see if we've already
3802 caught the type in question. */
3803 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3804 for (; !tsi_end_p (i); tsi_next (&i))
3806 tree stmt = tsi_stmt (i);
3807 t = CATCH_TYPES (stmt);
3808 if (t == error_mark_node)
3809 continue;
3810 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3812 warning (0, "exception of type %<%T%> will be caught",
3813 TREE_TYPE (type));
3814 warning (0, "%H by earlier handler for %<%T%>",
3815 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3816 break;
3821 /* Record the data for the catch in the try context so that we can
3822 finalize it later. */
3823 t = build_stmt (CATCH_EXPR, type, compound);
3824 cur_try_context->current_catch = t;
3826 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3827 t = objc_build_exc_ptr ();
3828 t = convert (TREE_TYPE (decl), t);
3829 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3830 add_stmt (t);
3833 /* Called just after parsing the closing brace of a @catch clause. Close
3834 the open binding level, and record a CATCH_EXPR for it. */
3836 void
3837 objc_finish_catch_clause (void)
3839 tree c = cur_try_context->current_catch;
3840 cur_try_context->current_catch = NULL;
3841 cur_try_context->end_catch_locus = input_location;
3843 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3844 append_to_statement_list (c, &cur_try_context->catch_list);
3847 /* Called after parsing a @finally clause and its associated BODY.
3848 Record the body for later placement. */
3850 void
3851 objc_build_finally_clause (location_t finally_locus, tree body)
3853 cur_try_context->finally_body = body;
3854 cur_try_context->finally_locus = finally_locus;
3855 cur_try_context->end_finally_locus = input_location;
3858 /* Called to finalize a @try construct. */
3860 tree
3861 objc_finish_try_stmt (void)
3863 struct objc_try_context *c = cur_try_context;
3864 tree stmt;
3866 if (c->catch_list == NULL && c->finally_body == NULL)
3867 error ("%<@try%> without %<@catch%> or %<@finally%>");
3869 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3870 if (flag_objc_sjlj_exceptions)
3872 if (!cur_try_context->finally_body)
3874 cur_try_context->finally_locus = input_location;
3875 cur_try_context->end_finally_locus = input_location;
3877 stmt = next_sjlj_build_try_catch_finally ();
3879 else
3881 /* Otherwise, nest the CATCH inside a FINALLY. */
3882 stmt = c->try_body;
3883 if (c->catch_list)
3885 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3886 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3888 if (c->finally_body)
3890 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3891 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3894 add_stmt (stmt);
3896 cur_try_context = c->outer;
3897 free (c);
3898 return stmt;
3901 tree
3902 objc_build_throw_stmt (tree throw_expr)
3904 tree args;
3906 objc_init_exceptions ();
3908 if (throw_expr == NULL)
3910 /* If we're not inside a @catch block, there is no "current
3911 exception" to be rethrown. */
3912 if (cur_try_context == NULL
3913 || cur_try_context->current_catch == NULL)
3915 error ("%<@throw%> (rethrow) used outside of a @catch block");
3916 return NULL_TREE;
3919 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3920 value that we get from the runtime. */
3921 throw_expr = objc_build_exc_ptr ();
3924 /* A throw is just a call to the runtime throw function with the
3925 object as a parameter. */
3926 args = tree_cons (NULL, throw_expr, NULL);
3927 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3930 tree
3931 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3933 tree args, call;
3935 /* First lock the mutex. */
3936 mutex = save_expr (mutex);
3937 args = tree_cons (NULL, mutex, NULL);
3938 call = build_function_call (objc_sync_enter_decl, args);
3939 SET_EXPR_LOCATION (call, start_locus);
3940 add_stmt (call);
3942 /* Build the mutex unlock. */
3943 args = tree_cons (NULL, mutex, NULL);
3944 call = build_function_call (objc_sync_exit_decl, args);
3945 SET_EXPR_LOCATION (call, input_location);
3947 /* Put the that and the body in a TRY_FINALLY. */
3948 objc_begin_try_stmt (start_locus, body);
3949 objc_build_finally_clause (input_location, call);
3950 return objc_finish_try_stmt ();
3954 /* Predefine the following data type:
3956 struct _objc_exception_data
3958 int buf[OBJC_JBLEN];
3959 void *pointers[4];
3960 }; */
3962 /* The following yuckiness should prevent users from having to #include
3963 <setjmp.h> in their code... */
3965 /* Define to a harmless positive value so the below code doesn't die. */
3966 #ifndef OBJC_JBLEN
3967 #define OBJC_JBLEN 18
3968 #endif
3970 static void
3971 build_next_objc_exception_stuff (void)
3973 tree field_decl, field_decl_chain, index, temp_type;
3975 objc_exception_data_template
3976 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3978 /* int buf[OBJC_JBLEN]; */
3980 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3981 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3982 "buf");
3983 field_decl_chain = field_decl;
3985 /* void *pointers[4]; */
3987 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3988 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3989 "pointers");
3990 chainon (field_decl_chain, field_decl);
3992 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3994 /* int _setjmp(...); */
3995 /* If the user includes <setjmp.h>, this shall be superseded by
3996 'int _setjmp(jmp_buf);' */
3997 temp_type = build_function_type (integer_type_node, NULL_TREE);
3998 objc_setjmp_decl
3999 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4001 /* id objc_exception_extract(struct _objc_exception_data *); */
4002 temp_type
4003 = build_function_type (objc_object_type,
4004 tree_cons (NULL_TREE,
4005 build_pointer_type (objc_exception_data_template),
4006 OBJC_VOID_AT_END));
4007 objc_exception_extract_decl
4008 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4009 NULL_TREE);
4010 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4011 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4012 temp_type
4013 = build_function_type (void_type_node,
4014 tree_cons (NULL_TREE,
4015 build_pointer_type (objc_exception_data_template),
4016 OBJC_VOID_AT_END));
4017 objc_exception_try_enter_decl
4018 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4019 NULL_TREE);
4020 objc_exception_try_exit_decl
4021 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4022 NULL_TREE);
4024 /* int objc_exception_match(id, id); */
4025 temp_type
4026 = build_function_type (integer_type_node,
4027 tree_cons (NULL_TREE, objc_object_type,
4028 tree_cons (NULL_TREE, objc_object_type,
4029 OBJC_VOID_AT_END)));
4030 objc_exception_match_decl
4031 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4032 NULL_TREE);
4034 /* id objc_assign_ivar (id, id, unsigned int); */
4035 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4036 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4037 temp_type
4038 = build_function_type (objc_object_type,
4039 tree_cons
4040 (NULL_TREE, objc_object_type,
4041 tree_cons (NULL_TREE, objc_object_type,
4042 tree_cons (NULL_TREE,
4043 unsigned_type_node,
4044 OBJC_VOID_AT_END))));
4045 objc_assign_ivar_decl
4046 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4047 NULL, NULL_TREE);
4048 #ifdef OFFS_ASSIGNIVAR_FAST
4049 objc_assign_ivar_fast_decl
4050 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4051 NOT_BUILT_IN, NULL, NULL_TREE);
4052 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4053 = tree_cons (get_identifier ("hard_coded_address"),
4054 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4055 NULL_TREE);
4056 #else
4057 /* Default to slower ivar method. */
4058 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4059 #endif
4061 /* id objc_assign_global (id, id *); */
4062 /* id objc_assign_strongCast (id, id *); */
4063 temp_type = build_function_type (objc_object_type,
4064 tree_cons (NULL_TREE, objc_object_type,
4065 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4066 OBJC_VOID_AT_END)));
4067 objc_assign_global_decl
4068 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4069 NULL_TREE);
4070 objc_assign_strong_cast_decl
4071 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4072 NULL_TREE);
4075 static void
4076 build_objc_exception_stuff (void)
4078 tree noreturn_list, nothrow_list, temp_type;
4080 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4081 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4083 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4084 /* void objc_sync_enter(id); */
4085 /* void objc_sync_exit(id); */
4086 temp_type = build_function_type (void_type_node,
4087 tree_cons (NULL_TREE, objc_object_type,
4088 OBJC_VOID_AT_END));
4089 objc_exception_throw_decl
4090 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4091 noreturn_list);
4092 objc_sync_enter_decl
4093 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4094 NULL, nothrow_list);
4095 objc_sync_exit_decl
4096 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4097 NULL, nothrow_list);
4100 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4101 name as the class:
4103 struct <classname> {
4104 struct _objc_class *isa;
4106 }; */
4108 static void
4109 build_private_template (tree class)
4111 if (!CLASS_STATIC_TEMPLATE (class))
4113 tree record = objc_build_struct (class,
4114 get_class_ivars (class, false),
4115 CLASS_SUPER_NAME (class));
4117 /* Set the TREE_USED bit for this struct, so that stab generator
4118 can emit stabs for this struct type. */
4119 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4120 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4124 /* Begin code generation for protocols... */
4126 /* struct _objc_protocol {
4127 struct _objc_class *isa;
4128 char *protocol_name;
4129 struct _objc_protocol **protocol_list;
4130 struct _objc__method_prototype_list *instance_methods;
4131 struct _objc__method_prototype_list *class_methods;
4132 }; */
4134 static void
4135 build_protocol_template (void)
4137 tree field_decl, field_decl_chain;
4139 objc_protocol_template = start_struct (RECORD_TYPE,
4140 get_identifier (UTAG_PROTOCOL));
4142 /* struct _objc_class *isa; */
4143 field_decl = create_field_decl (build_pointer_type
4144 (xref_tag (RECORD_TYPE,
4145 get_identifier (UTAG_CLASS))),
4146 "isa");
4147 field_decl_chain = field_decl;
4149 /* char *protocol_name; */
4150 field_decl = create_field_decl (string_type_node, "protocol_name");
4151 chainon (field_decl_chain, field_decl);
4153 /* struct _objc_protocol **protocol_list; */
4154 field_decl = create_field_decl (build_pointer_type
4155 (build_pointer_type
4156 (objc_protocol_template)),
4157 "protocol_list");
4158 chainon (field_decl_chain, field_decl);
4160 /* struct _objc__method_prototype_list *instance_methods; */
4161 field_decl = create_field_decl (objc_method_proto_list_ptr,
4162 "instance_methods");
4163 chainon (field_decl_chain, field_decl);
4165 /* struct _objc__method_prototype_list *class_methods; */
4166 field_decl = create_field_decl (objc_method_proto_list_ptr,
4167 "class_methods");
4168 chainon (field_decl_chain, field_decl);
4170 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4173 static tree
4174 build_descriptor_table_initializer (tree type, tree entries)
4176 tree initlist = NULL_TREE;
4180 tree eltlist = NULL_TREE;
4182 eltlist
4183 = tree_cons (NULL_TREE,
4184 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4185 eltlist
4186 = tree_cons (NULL_TREE,
4187 add_objc_string (METHOD_ENCODING (entries),
4188 meth_var_types),
4189 eltlist);
4191 initlist
4192 = tree_cons (NULL_TREE,
4193 objc_build_constructor (type, nreverse (eltlist)),
4194 initlist);
4196 entries = TREE_CHAIN (entries);
4198 while (entries);
4200 return objc_build_constructor (build_array_type (type, 0),
4201 nreverse (initlist));
4204 /* struct objc_method_prototype_list {
4205 int count;
4206 struct objc_method_prototype {
4207 SEL name;
4208 char *types;
4209 } list[1];
4210 }; */
4212 static tree
4213 build_method_prototype_list_template (tree list_type, int size)
4215 tree objc_ivar_list_record;
4216 tree field_decl, field_decl_chain;
4218 /* Generate an unnamed struct definition. */
4220 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4222 /* int method_count; */
4223 field_decl = create_field_decl (integer_type_node, "method_count");
4224 field_decl_chain = field_decl;
4226 /* struct objc_method method_list[]; */
4227 field_decl = create_field_decl (build_array_type
4228 (list_type,
4229 build_index_type
4230 (build_int_cst (NULL_TREE, size - 1))),
4231 "method_list");
4232 chainon (field_decl_chain, field_decl);
4234 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4236 return objc_ivar_list_record;
4239 static tree
4240 build_method_prototype_template (void)
4242 tree proto_record;
4243 tree field_decl, field_decl_chain;
4245 proto_record
4246 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4248 /* SEL _cmd; */
4249 field_decl = create_field_decl (objc_selector_type, "_cmd");
4250 field_decl_chain = field_decl;
4252 /* char *method_types; */
4253 field_decl = create_field_decl (string_type_node, "method_types");
4254 chainon (field_decl_chain, field_decl);
4256 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4258 return proto_record;
4261 static tree
4262 objc_method_parm_type (tree type)
4264 type = TREE_VALUE (TREE_TYPE (type));
4265 if (TREE_CODE (type) == TYPE_DECL)
4266 type = TREE_TYPE (type);
4267 return type;
4270 static int
4271 objc_encoded_type_size (tree type)
4273 int sz = int_size_in_bytes (type);
4275 /* Make all integer and enum types at least as large
4276 as an int. */
4277 if (sz > 0 && INTEGRAL_TYPE_P (type))
4278 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4279 /* Treat arrays as pointers, since that's how they're
4280 passed in. */
4281 else if (TREE_CODE (type) == ARRAY_TYPE)
4282 sz = int_size_in_bytes (ptr_type_node);
4283 return sz;
4286 static tree
4287 encode_method_prototype (tree method_decl)
4289 tree parms;
4290 int parm_offset, i;
4291 char buf[40];
4292 tree result;
4294 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4295 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4297 /* Encode return type. */
4298 encode_type (objc_method_parm_type (method_decl),
4299 obstack_object_size (&util_obstack),
4300 OBJC_ENCODE_INLINE_DEFS);
4302 /* Stack size. */
4303 /* The first two arguments (self and _cmd) are pointers; account for
4304 their size. */
4305 i = int_size_in_bytes (ptr_type_node);
4306 parm_offset = 2 * i;
4307 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4308 parms = TREE_CHAIN (parms))
4310 tree type = objc_method_parm_type (parms);
4311 int sz = objc_encoded_type_size (type);
4313 /* If a type size is not known, bail out. */
4314 if (sz < 0)
4316 error ("type %q+D does not have a known size",
4317 type);
4318 /* Pretend that the encoding succeeded; the compilation will
4319 fail nevertheless. */
4320 goto finish_encoding;
4322 parm_offset += sz;
4325 sprintf (buf, "%d@0:%d", parm_offset, i);
4326 obstack_grow (&util_obstack, buf, strlen (buf));
4328 /* Argument types. */
4329 parm_offset = 2 * i;
4330 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4331 parms = TREE_CHAIN (parms))
4333 tree type = objc_method_parm_type (parms);
4335 /* Process argument qualifiers for user supplied arguments. */
4336 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4338 /* Type. */
4339 encode_type (type, obstack_object_size (&util_obstack),
4340 OBJC_ENCODE_INLINE_DEFS);
4342 /* Compute offset. */
4343 sprintf (buf, "%d", parm_offset);
4344 parm_offset += objc_encoded_type_size (type);
4346 obstack_grow (&util_obstack, buf, strlen (buf));
4349 finish_encoding:
4350 obstack_1grow (&util_obstack, '\0');
4351 result = get_identifier (obstack_finish (&util_obstack));
4352 obstack_free (&util_obstack, util_firstobj);
4353 return result;
4356 static tree
4357 generate_descriptor_table (tree type, const char *name, int size, tree list,
4358 tree proto)
4360 tree decl, initlist;
4362 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4364 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4365 initlist = tree_cons (NULL_TREE, list, initlist);
4367 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4369 return decl;
4372 static void
4373 generate_method_descriptors (tree protocol)
4375 tree initlist, chain, method_list_template;
4376 int size;
4378 if (!objc_method_prototype_template)
4379 objc_method_prototype_template = build_method_prototype_template ();
4381 chain = PROTOCOL_CLS_METHODS (protocol);
4382 if (chain)
4384 size = list_length (chain);
4386 method_list_template
4387 = build_method_prototype_list_template (objc_method_prototype_template,
4388 size);
4390 initlist
4391 = build_descriptor_table_initializer (objc_method_prototype_template,
4392 chain);
4394 UOBJC_CLASS_METHODS_decl
4395 = generate_descriptor_table (method_list_template,
4396 "_OBJC_PROTOCOL_CLASS_METHODS",
4397 size, initlist, protocol);
4399 else
4400 UOBJC_CLASS_METHODS_decl = 0;
4402 chain = PROTOCOL_NST_METHODS (protocol);
4403 if (chain)
4405 size = list_length (chain);
4407 method_list_template
4408 = build_method_prototype_list_template (objc_method_prototype_template,
4409 size);
4410 initlist
4411 = build_descriptor_table_initializer (objc_method_prototype_template,
4412 chain);
4414 UOBJC_INSTANCE_METHODS_decl
4415 = generate_descriptor_table (method_list_template,
4416 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4417 size, initlist, protocol);
4419 else
4420 UOBJC_INSTANCE_METHODS_decl = 0;
4423 static void
4424 generate_protocol_references (tree plist)
4426 tree lproto;
4428 /* Forward declare protocols referenced. */
4429 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4431 tree proto = TREE_VALUE (lproto);
4433 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4434 && PROTOCOL_NAME (proto))
4436 if (! PROTOCOL_FORWARD_DECL (proto))
4437 build_protocol_reference (proto);
4439 if (PROTOCOL_LIST (proto))
4440 generate_protocol_references (PROTOCOL_LIST (proto));
4445 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4446 current class. */
4447 #ifdef OBJCPLUS
4448 static void
4449 objc_generate_cxx_ctor_or_dtor (bool dtor)
4451 tree fn, body, compound_stmt, ivar;
4453 /* - (id) .cxx_construct { ... return self; } */
4454 /* - (void) .cxx_construct { ... } */
4456 objc_set_method_type (MINUS_EXPR);
4457 objc_start_method_definition
4458 (objc_build_method_signature (build_tree_list (NULL_TREE,
4459 dtor
4460 ? void_type_node
4461 : objc_object_type),
4462 get_identifier (dtor
4463 ? TAG_CXX_DESTRUCT
4464 : TAG_CXX_CONSTRUCT),
4465 make_node (TREE_LIST),
4466 false));
4467 body = begin_function_body ();
4468 compound_stmt = begin_compound_stmt (0);
4470 ivar = CLASS_IVARS (implementation_template);
4471 /* Destroy ivars in reverse order. */
4472 if (dtor)
4473 ivar = nreverse (copy_list (ivar));
4475 for (; ivar; ivar = TREE_CHAIN (ivar))
4477 if (TREE_CODE (ivar) == FIELD_DECL)
4479 tree type = TREE_TYPE (ivar);
4481 /* Call the ivar's default constructor or destructor. Do not
4482 call the destructor unless a corresponding constructor call
4483 has also been made (or is not needed). */
4484 if (MAYBE_CLASS_TYPE_P (type)
4485 && (dtor
4486 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4487 && (!TYPE_NEEDS_CONSTRUCTING (type)
4488 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4489 : (TYPE_NEEDS_CONSTRUCTING (type)
4490 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4491 finish_expr_stmt
4492 (build_special_member_call
4493 (build_ivar_reference (DECL_NAME (ivar)),
4494 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4495 NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
4499 /* The constructor returns 'self'. */
4500 if (!dtor)
4501 finish_return_stmt (self_decl);
4503 finish_compound_stmt (compound_stmt);
4504 finish_function_body (body);
4505 fn = current_function_decl;
4506 finish_function ();
4507 objc_finish_method_definition (fn);
4510 /* The following routine will examine the current @interface for any
4511 non-POD C++ ivars requiring non-trivial construction and/or
4512 destruction, and then synthesize special '- .cxx_construct' and/or
4513 '- .cxx_destruct' methods which will run the appropriate
4514 construction or destruction code. Note that ivars inherited from
4515 super-classes are _not_ considered. */
4516 static void
4517 objc_generate_cxx_cdtors (void)
4519 bool need_ctor = false, need_dtor = false;
4520 tree ivar;
4522 /* We do not want to do this for categories, since they do not have
4523 their own ivars. */
4525 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4526 return;
4528 /* First, determine if we even need a constructor and/or destructor. */
4530 for (ivar = CLASS_IVARS (implementation_template); ivar;
4531 ivar = TREE_CHAIN (ivar))
4533 if (TREE_CODE (ivar) == FIELD_DECL)
4535 tree type = TREE_TYPE (ivar);
4537 if (MAYBE_CLASS_TYPE_P (type))
4539 if (TYPE_NEEDS_CONSTRUCTING (type)
4540 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4541 /* NB: If a default constructor is not available, we will not
4542 be able to initialize this ivar; the add_instance_variable()
4543 routine will already have warned about this. */
4544 need_ctor = true;
4546 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4547 && (!TYPE_NEEDS_CONSTRUCTING (type)
4548 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4549 /* NB: If a default constructor is not available, we will not
4550 call the destructor either, for symmetry. */
4551 need_dtor = true;
4556 /* Generate '- .cxx_construct' if needed. */
4558 if (need_ctor)
4559 objc_generate_cxx_ctor_or_dtor (false);
4561 /* Generate '- .cxx_destruct' if needed. */
4563 if (need_dtor)
4564 objc_generate_cxx_ctor_or_dtor (true);
4566 /* The 'imp_list' variable points at an imp_entry record for the current
4567 @implementation. Record the existence of '- .cxx_construct' and/or
4568 '- .cxx_destruct' methods therein; it will be included in the
4569 metadata for the class. */
4570 if (flag_next_runtime)
4571 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4573 #endif
4575 /* For each protocol which was referenced either from a @protocol()
4576 expression, or because a class/category implements it (then a
4577 pointer to the protocol is stored in the struct describing the
4578 class/category), we create a statically allocated instance of the
4579 Protocol class. The code is written in such a way as to generate
4580 as few Protocol objects as possible; we generate a unique Protocol
4581 instance for each protocol, and we don't generate a Protocol
4582 instance if the protocol is never referenced (either from a
4583 @protocol() or from a class/category implementation). These
4584 statically allocated objects can be referred to via the static
4585 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4587 The statically allocated Protocol objects that we generate here
4588 need to be fixed up at runtime in order to be used: the 'isa'
4589 pointer of the objects need to be set up to point to the 'Protocol'
4590 class, as known at runtime.
4592 The NeXT runtime fixes up all protocols at program startup time,
4593 before main() is entered. It uses a low-level trick to look up all
4594 those symbols, then loops on them and fixes them up.
4596 The GNU runtime as well fixes up all protocols before user code
4597 from the module is executed; it requires pointers to those symbols
4598 to be put in the objc_symtab (which is then passed as argument to
4599 the function __objc_exec_class() which the compiler sets up to be
4600 executed automatically when the module is loaded); setup of those
4601 Protocol objects happen in two ways in the GNU runtime: all
4602 Protocol objects referred to by a class or category implementation
4603 are fixed up when the class/category is loaded; all Protocol
4604 objects referred to by a @protocol() expression are added by the
4605 compiler to the list of statically allocated instances to fixup
4606 (the same list holding the statically allocated constant string
4607 objects). Because, as explained above, the compiler generates as
4608 few Protocol objects as possible, some Protocol object might end up
4609 being referenced multiple times when compiled with the GNU runtime,
4610 and end up being fixed up multiple times at runtime initialization.
4611 But that doesn't hurt, it's just a little inefficient. */
4613 static void
4614 generate_protocols (void)
4616 tree p, encoding;
4617 tree decl;
4618 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4620 /* If a protocol was directly referenced, pull in indirect references. */
4621 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4622 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4623 generate_protocol_references (PROTOCOL_LIST (p));
4625 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4627 tree nst_methods = PROTOCOL_NST_METHODS (p);
4628 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4630 /* If protocol wasn't referenced, don't generate any code. */
4631 decl = PROTOCOL_FORWARD_DECL (p);
4633 if (!decl)
4634 continue;
4636 /* Make sure we link in the Protocol class. */
4637 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4639 while (nst_methods)
4641 if (! METHOD_ENCODING (nst_methods))
4643 encoding = encode_method_prototype (nst_methods);
4644 METHOD_ENCODING (nst_methods) = encoding;
4646 nst_methods = TREE_CHAIN (nst_methods);
4649 while (cls_methods)
4651 if (! METHOD_ENCODING (cls_methods))
4653 encoding = encode_method_prototype (cls_methods);
4654 METHOD_ENCODING (cls_methods) = encoding;
4657 cls_methods = TREE_CHAIN (cls_methods);
4659 generate_method_descriptors (p);
4661 if (PROTOCOL_LIST (p))
4662 refs_decl = generate_protocol_list (p);
4663 else
4664 refs_decl = 0;
4666 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4667 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4669 if (refs_decl)
4670 refs_expr = convert (build_pointer_type (build_pointer_type
4671 (objc_protocol_template)),
4672 build_unary_op (ADDR_EXPR, refs_decl, 0));
4673 else
4674 refs_expr = build_int_cst (NULL_TREE, 0);
4676 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4677 by generate_method_descriptors, which is called above. */
4678 initlist = build_protocol_initializer (TREE_TYPE (decl),
4679 protocol_name_expr, refs_expr,
4680 UOBJC_INSTANCE_METHODS_decl,
4681 UOBJC_CLASS_METHODS_decl);
4682 finish_var_decl (decl, initlist);
4686 static tree
4687 build_protocol_initializer (tree type, tree protocol_name,
4688 tree protocol_list, tree instance_methods,
4689 tree class_methods)
4691 tree initlist = NULL_TREE, expr;
4692 tree cast_type = build_pointer_type
4693 (xref_tag (RECORD_TYPE,
4694 get_identifier (UTAG_CLASS)));
4696 /* Filling the "isa" in with one allows the runtime system to
4697 detect that the version change...should remove before final release. */
4699 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4700 initlist = tree_cons (NULL_TREE, expr, initlist);
4701 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4702 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4704 if (!instance_methods)
4705 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4706 else
4708 expr = convert (objc_method_proto_list_ptr,
4709 build_unary_op (ADDR_EXPR, instance_methods, 0));
4710 initlist = tree_cons (NULL_TREE, expr, initlist);
4713 if (!class_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, class_methods, 0));
4719 initlist = tree_cons (NULL_TREE, expr, initlist);
4722 return objc_build_constructor (type, nreverse (initlist));
4725 /* struct _objc_category {
4726 char *category_name;
4727 char *class_name;
4728 struct _objc_method_list *instance_methods;
4729 struct _objc_method_list *class_methods;
4730 struct _objc_protocol_list *protocols;
4731 }; */
4733 static void
4734 build_category_template (void)
4736 tree field_decl, field_decl_chain;
4738 objc_category_template = start_struct (RECORD_TYPE,
4739 get_identifier (UTAG_CATEGORY));
4741 /* char *category_name; */
4742 field_decl = create_field_decl (string_type_node, "category_name");
4743 field_decl_chain = field_decl;
4745 /* char *class_name; */
4746 field_decl = create_field_decl (string_type_node, "class_name");
4747 chainon (field_decl_chain, field_decl);
4749 /* struct _objc_method_list *instance_methods; */
4750 field_decl = create_field_decl (objc_method_list_ptr,
4751 "instance_methods");
4752 chainon (field_decl_chain, field_decl);
4754 /* struct _objc_method_list *class_methods; */
4755 field_decl = create_field_decl (objc_method_list_ptr,
4756 "class_methods");
4757 chainon (field_decl_chain, field_decl);
4759 /* struct _objc_protocol **protocol_list; */
4760 field_decl = create_field_decl (build_pointer_type
4761 (build_pointer_type
4762 (objc_protocol_template)),
4763 "protocol_list");
4764 chainon (field_decl_chain, field_decl);
4766 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4769 /* struct _objc_selector {
4770 SEL sel_id;
4771 char *sel_type;
4772 }; */
4774 static void
4775 build_selector_template (void)
4778 tree field_decl, field_decl_chain;
4780 objc_selector_template
4781 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4783 /* SEL sel_id; */
4784 field_decl = create_field_decl (objc_selector_type, "sel_id");
4785 field_decl_chain = field_decl;
4787 /* char *sel_type; */
4788 field_decl = create_field_decl (string_type_node, "sel_type");
4789 chainon (field_decl_chain, field_decl);
4791 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4794 /* struct _objc_class {
4795 struct _objc_class *isa;
4796 struct _objc_class *super_class;
4797 char *name;
4798 long version;
4799 long info;
4800 long instance_size;
4801 struct _objc_ivar_list *ivars;
4802 struct _objc_method_list *methods;
4803 #ifdef __NEXT_RUNTIME__
4804 struct objc_cache *cache;
4805 #else
4806 struct sarray *dtable;
4807 struct _objc_class *subclass_list;
4808 struct _objc_class *sibling_class;
4809 #endif
4810 struct _objc_protocol_list *protocols;
4811 #ifdef __NEXT_RUNTIME__
4812 void *sel_id;
4813 #endif
4814 void *gc_object_type;
4815 }; */
4817 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4818 the NeXT/Apple runtime; still, the compiler must generate them to
4819 maintain backward binary compatibility (and to allow for future
4820 expansion). */
4822 static void
4823 build_class_template (void)
4825 tree field_decl, field_decl_chain;
4827 objc_class_template
4828 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4830 /* struct _objc_class *isa; */
4831 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4832 "isa");
4833 field_decl_chain = field_decl;
4835 /* struct _objc_class *super_class; */
4836 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4837 "super_class");
4838 chainon (field_decl_chain, field_decl);
4840 /* char *name; */
4841 field_decl = create_field_decl (string_type_node, "name");
4842 chainon (field_decl_chain, field_decl);
4844 /* long version; */
4845 field_decl = create_field_decl (long_integer_type_node, "version");
4846 chainon (field_decl_chain, field_decl);
4848 /* long info; */
4849 field_decl = create_field_decl (long_integer_type_node, "info");
4850 chainon (field_decl_chain, field_decl);
4852 /* long instance_size; */
4853 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4854 chainon (field_decl_chain, field_decl);
4856 /* struct _objc_ivar_list *ivars; */
4857 field_decl = create_field_decl (objc_ivar_list_ptr,
4858 "ivars");
4859 chainon (field_decl_chain, field_decl);
4861 /* struct _objc_method_list *methods; */
4862 field_decl = create_field_decl (objc_method_list_ptr,
4863 "methods");
4864 chainon (field_decl_chain, field_decl);
4866 if (flag_next_runtime)
4868 /* struct objc_cache *cache; */
4869 field_decl = create_field_decl (build_pointer_type
4870 (xref_tag (RECORD_TYPE,
4871 get_identifier
4872 ("objc_cache"))),
4873 "cache");
4874 chainon (field_decl_chain, field_decl);
4876 else
4878 /* struct sarray *dtable; */
4879 field_decl = create_field_decl (build_pointer_type
4880 (xref_tag (RECORD_TYPE,
4881 get_identifier
4882 ("sarray"))),
4883 "dtable");
4884 chainon (field_decl_chain, field_decl);
4886 /* struct objc_class *subclass_list; */
4887 field_decl = create_field_decl (build_pointer_type
4888 (objc_class_template),
4889 "subclass_list");
4890 chainon (field_decl_chain, field_decl);
4892 /* struct objc_class *sibling_class; */
4893 field_decl = create_field_decl (build_pointer_type
4894 (objc_class_template),
4895 "sibling_class");
4896 chainon (field_decl_chain, field_decl);
4899 /* struct _objc_protocol **protocol_list; */
4900 field_decl = create_field_decl (build_pointer_type
4901 (build_pointer_type
4902 (xref_tag (RECORD_TYPE,
4903 get_identifier
4904 (UTAG_PROTOCOL)))),
4905 "protocol_list");
4906 chainon (field_decl_chain, field_decl);
4908 if (flag_next_runtime)
4910 /* void *sel_id; */
4911 field_decl = create_field_decl (build_pointer_type (void_type_node),
4912 "sel_id");
4913 chainon (field_decl_chain, field_decl);
4916 /* void *gc_object_type; */
4917 field_decl = create_field_decl (build_pointer_type (void_type_node),
4918 "gc_object_type");
4919 chainon (field_decl_chain, field_decl);
4921 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4924 /* Generate appropriate forward declarations for an implementation. */
4926 static void
4927 synth_forward_declarations (void)
4929 tree an_id;
4931 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4932 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4933 objc_class_template);
4935 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4936 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4937 objc_class_template);
4939 /* Pre-build the following entities - for speed/convenience. */
4941 an_id = get_identifier ("super_class");
4942 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4943 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4946 static void
4947 error_with_ivar (const char *message, tree decl)
4949 error ("%J%s %qs", decl,
4950 message, gen_declaration (decl));
4954 static void
4955 check_ivars (tree inter, tree imp)
4957 tree intdecls = CLASS_RAW_IVARS (inter);
4958 tree impdecls = CLASS_RAW_IVARS (imp);
4960 while (1)
4962 tree t1, t2;
4964 #ifdef OBJCPLUS
4965 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4966 intdecls = TREE_CHAIN (intdecls);
4967 #endif
4968 if (intdecls == 0 && impdecls == 0)
4969 break;
4970 if (intdecls == 0 || impdecls == 0)
4972 error ("inconsistent instance variable specification");
4973 break;
4976 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4978 if (!comptypes (t1, t2)
4979 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4980 DECL_INITIAL (impdecls)))
4982 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4984 error_with_ivar ("conflicting instance variable type",
4985 impdecls);
4986 error_with_ivar ("previous declaration of",
4987 intdecls);
4989 else /* both the type and the name don't match */
4991 error ("inconsistent instance variable specification");
4992 break;
4996 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4998 error_with_ivar ("conflicting instance variable name",
4999 impdecls);
5000 error_with_ivar ("previous declaration of",
5001 intdecls);
5004 intdecls = TREE_CHAIN (intdecls);
5005 impdecls = TREE_CHAIN (impdecls);
5009 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5010 This needs to be done just once per compilation. */
5012 /* struct _objc_super {
5013 struct _objc_object *self;
5014 struct _objc_class *super_class;
5015 }; */
5017 static void
5018 build_super_template (void)
5020 tree field_decl, field_decl_chain;
5022 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5024 /* struct _objc_object *self; */
5025 field_decl = create_field_decl (objc_object_type, "self");
5026 field_decl_chain = field_decl;
5028 /* struct _objc_class *super_class; */
5029 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5030 "super_class");
5031 chainon (field_decl_chain, field_decl);
5033 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5036 /* struct _objc_ivar {
5037 char *ivar_name;
5038 char *ivar_type;
5039 int ivar_offset;
5040 }; */
5042 static tree
5043 build_ivar_template (void)
5045 tree objc_ivar_id, objc_ivar_record;
5046 tree field_decl, field_decl_chain;
5048 objc_ivar_id = get_identifier (UTAG_IVAR);
5049 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5051 /* char *ivar_name; */
5052 field_decl = create_field_decl (string_type_node, "ivar_name");
5053 field_decl_chain = field_decl;
5055 /* char *ivar_type; */
5056 field_decl = create_field_decl (string_type_node, "ivar_type");
5057 chainon (field_decl_chain, field_decl);
5059 /* int ivar_offset; */
5060 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5061 chainon (field_decl_chain, field_decl);
5063 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5065 return objc_ivar_record;
5068 /* struct {
5069 int ivar_count;
5070 struct objc_ivar ivar_list[ivar_count];
5071 }; */
5073 static tree
5074 build_ivar_list_template (tree list_type, int size)
5076 tree objc_ivar_list_record;
5077 tree field_decl, field_decl_chain;
5079 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5081 /* int ivar_count; */
5082 field_decl = create_field_decl (integer_type_node, "ivar_count");
5083 field_decl_chain = field_decl;
5085 /* struct objc_ivar ivar_list[]; */
5086 field_decl = create_field_decl (build_array_type
5087 (list_type,
5088 build_index_type
5089 (build_int_cst (NULL_TREE, size - 1))),
5090 "ivar_list");
5091 chainon (field_decl_chain, field_decl);
5093 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5095 return objc_ivar_list_record;
5098 /* struct {
5099 struct _objc__method_prototype_list *method_next;
5100 int method_count;
5101 struct objc_method method_list[method_count];
5102 }; */
5104 static tree
5105 build_method_list_template (tree list_type, int size)
5107 tree objc_ivar_list_record;
5108 tree field_decl, field_decl_chain;
5110 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5112 /* struct _objc__method_prototype_list *method_next; */
5113 field_decl = create_field_decl (objc_method_proto_list_ptr,
5114 "method_next");
5115 field_decl_chain = field_decl;
5117 /* int method_count; */
5118 field_decl = create_field_decl (integer_type_node, "method_count");
5119 chainon (field_decl_chain, field_decl);
5121 /* struct objc_method method_list[]; */
5122 field_decl = create_field_decl (build_array_type
5123 (list_type,
5124 build_index_type
5125 (build_int_cst (NULL_TREE, size - 1))),
5126 "method_list");
5127 chainon (field_decl_chain, field_decl);
5129 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5131 return objc_ivar_list_record;
5134 static tree
5135 build_ivar_list_initializer (tree type, tree field_decl)
5137 tree initlist = NULL_TREE;
5141 tree ivar = NULL_TREE;
5143 /* Set name. */
5144 if (DECL_NAME (field_decl))
5145 ivar = tree_cons (NULL_TREE,
5146 add_objc_string (DECL_NAME (field_decl),
5147 meth_var_names),
5148 ivar);
5149 else
5150 /* Unnamed bit-field ivar (yuck). */
5151 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5153 /* Set type. */
5154 encode_field_decl (field_decl,
5155 obstack_object_size (&util_obstack),
5156 OBJC_ENCODE_DONT_INLINE_DEFS);
5158 /* Null terminate string. */
5159 obstack_1grow (&util_obstack, 0);
5160 ivar
5161 = tree_cons
5162 (NULL_TREE,
5163 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5164 meth_var_types),
5165 ivar);
5166 obstack_free (&util_obstack, util_firstobj);
5168 /* Set offset. */
5169 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5170 initlist = tree_cons (NULL_TREE,
5171 objc_build_constructor (type, nreverse (ivar)),
5172 initlist);
5174 field_decl = TREE_CHAIN (field_decl);
5175 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5177 while (field_decl);
5179 return objc_build_constructor (build_array_type (type, 0),
5180 nreverse (initlist));
5183 static tree
5184 generate_ivars_list (tree type, const char *name, int size, tree list)
5186 tree decl, initlist;
5188 decl = start_var_decl (type, synth_id_with_class_suffix
5189 (name, objc_implementation_context));
5191 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5192 initlist = tree_cons (NULL_TREE, list, initlist);
5194 finish_var_decl (decl,
5195 objc_build_constructor (TREE_TYPE (decl),
5196 nreverse (initlist)));
5198 return decl;
5201 /* Count only the fields occurring in T. */
5203 static int
5204 ivar_list_length (tree t)
5206 int count = 0;
5208 for (; t; t = TREE_CHAIN (t))
5209 if (TREE_CODE (t) == FIELD_DECL)
5210 ++count;
5212 return count;
5215 static void
5216 generate_ivar_lists (void)
5218 tree initlist, ivar_list_template, chain;
5219 int size;
5221 generating_instance_variables = 1;
5223 if (!objc_ivar_template)
5224 objc_ivar_template = build_ivar_template ();
5226 /* Only generate class variables for the root of the inheritance
5227 hierarchy since these will be the same for every class. */
5229 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5230 && (chain = TYPE_FIELDS (objc_class_template)))
5232 size = ivar_list_length (chain);
5234 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5235 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5237 UOBJC_CLASS_VARIABLES_decl
5238 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5239 size, initlist);
5241 else
5242 UOBJC_CLASS_VARIABLES_decl = 0;
5244 chain = CLASS_IVARS (implementation_template);
5245 if (chain)
5247 size = ivar_list_length (chain);
5248 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5249 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5251 UOBJC_INSTANCE_VARIABLES_decl
5252 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5253 size, initlist);
5255 else
5256 UOBJC_INSTANCE_VARIABLES_decl = 0;
5258 generating_instance_variables = 0;
5261 static tree
5262 build_dispatch_table_initializer (tree type, tree entries)
5264 tree initlist = NULL_TREE;
5268 tree elemlist = NULL_TREE;
5270 elemlist = tree_cons (NULL_TREE,
5271 build_selector (METHOD_SEL_NAME (entries)),
5272 NULL_TREE);
5274 /* Generate the method encoding if we don't have one already. */
5275 if (! METHOD_ENCODING (entries))
5276 METHOD_ENCODING (entries) =
5277 encode_method_prototype (entries);
5279 elemlist = tree_cons (NULL_TREE,
5280 add_objc_string (METHOD_ENCODING (entries),
5281 meth_var_types),
5282 elemlist);
5284 elemlist
5285 = tree_cons (NULL_TREE,
5286 convert (ptr_type_node,
5287 build_unary_op (ADDR_EXPR,
5288 METHOD_DEFINITION (entries), 1)),
5289 elemlist);
5291 initlist = tree_cons (NULL_TREE,
5292 objc_build_constructor (type, nreverse (elemlist)),
5293 initlist);
5295 entries = TREE_CHAIN (entries);
5297 while (entries);
5299 return objc_build_constructor (build_array_type (type, 0),
5300 nreverse (initlist));
5303 /* To accomplish method prototyping without generating all kinds of
5304 inane warnings, the definition of the dispatch table entries were
5305 changed from:
5307 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5309 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5311 static tree
5312 build_method_template (void)
5314 tree _SLT_record;
5315 tree field_decl, field_decl_chain;
5317 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5319 /* SEL _cmd; */
5320 field_decl = create_field_decl (objc_selector_type, "_cmd");
5321 field_decl_chain = field_decl;
5323 /* char *method_types; */
5324 field_decl = create_field_decl (string_type_node, "method_types");
5325 chainon (field_decl_chain, field_decl);
5327 /* void *_imp; */
5328 field_decl = create_field_decl (build_pointer_type (void_type_node),
5329 "_imp");
5330 chainon (field_decl_chain, field_decl);
5332 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5334 return _SLT_record;
5338 static tree
5339 generate_dispatch_table (tree type, const char *name, int size, tree list)
5341 tree decl, initlist;
5343 decl = start_var_decl (type, synth_id_with_class_suffix
5344 (name, objc_implementation_context));
5346 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5347 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5348 initlist = tree_cons (NULL_TREE, list, initlist);
5350 finish_var_decl (decl,
5351 objc_build_constructor (TREE_TYPE (decl),
5352 nreverse (initlist)));
5354 return decl;
5357 static void
5358 mark_referenced_methods (void)
5360 struct imp_entry *impent;
5361 tree chain;
5363 for (impent = imp_list; impent; impent = impent->next)
5365 chain = CLASS_CLS_METHODS (impent->imp_context);
5366 while (chain)
5368 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5369 chain = TREE_CHAIN (chain);
5372 chain = CLASS_NST_METHODS (impent->imp_context);
5373 while (chain)
5375 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5376 chain = TREE_CHAIN (chain);
5381 static void
5382 generate_dispatch_tables (void)
5384 tree initlist, chain, method_list_template;
5385 int size;
5387 if (!objc_method_template)
5388 objc_method_template = build_method_template ();
5390 chain = CLASS_CLS_METHODS (objc_implementation_context);
5391 if (chain)
5393 size = list_length (chain);
5395 method_list_template
5396 = build_method_list_template (objc_method_template, size);
5397 initlist
5398 = build_dispatch_table_initializer (objc_method_template, chain);
5400 UOBJC_CLASS_METHODS_decl
5401 = generate_dispatch_table (method_list_template,
5402 ((TREE_CODE (objc_implementation_context)
5403 == CLASS_IMPLEMENTATION_TYPE)
5404 ? "_OBJC_CLASS_METHODS"
5405 : "_OBJC_CATEGORY_CLASS_METHODS"),
5406 size, initlist);
5408 else
5409 UOBJC_CLASS_METHODS_decl = 0;
5411 chain = CLASS_NST_METHODS (objc_implementation_context);
5412 if (chain)
5414 size = list_length (chain);
5416 method_list_template
5417 = build_method_list_template (objc_method_template, size);
5418 initlist
5419 = build_dispatch_table_initializer (objc_method_template, chain);
5421 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5422 UOBJC_INSTANCE_METHODS_decl
5423 = generate_dispatch_table (method_list_template,
5424 "_OBJC_INSTANCE_METHODS",
5425 size, initlist);
5426 else
5427 /* We have a category. */
5428 UOBJC_INSTANCE_METHODS_decl
5429 = generate_dispatch_table (method_list_template,
5430 "_OBJC_CATEGORY_INSTANCE_METHODS",
5431 size, initlist);
5433 else
5434 UOBJC_INSTANCE_METHODS_decl = 0;
5437 static tree
5438 generate_protocol_list (tree i_or_p)
5440 tree initlist;
5441 tree refs_decl, lproto, e, plist;
5442 int size = 0;
5443 const char *ref_name;
5445 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5446 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5447 plist = CLASS_PROTOCOL_LIST (i_or_p);
5448 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5449 plist = PROTOCOL_LIST (i_or_p);
5450 else
5451 abort ();
5453 /* Compute size. */
5454 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5455 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5456 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5457 size++;
5459 /* Build initializer. */
5460 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5461 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5462 initlist = tree_cons (NULL_TREE, e, initlist);
5464 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5466 tree pval = TREE_VALUE (lproto);
5468 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5469 && PROTOCOL_FORWARD_DECL (pval))
5471 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5472 initlist = tree_cons (NULL_TREE, e, initlist);
5476 /* static struct objc_protocol *refs[n]; */
5478 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5479 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5480 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5481 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5482 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5483 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5484 else
5485 abort ();
5487 refs_decl = start_var_decl
5488 (build_array_type
5489 (build_pointer_type (objc_protocol_template),
5490 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5491 ref_name);
5493 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5494 nreverse (initlist)));
5496 return refs_decl;
5499 static tree
5500 build_category_initializer (tree type, tree cat_name, tree class_name,
5501 tree instance_methods, tree class_methods,
5502 tree protocol_list)
5504 tree initlist = NULL_TREE, expr;
5506 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5507 initlist = tree_cons (NULL_TREE, class_name, initlist);
5509 if (!instance_methods)
5510 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5511 else
5513 expr = convert (objc_method_list_ptr,
5514 build_unary_op (ADDR_EXPR, instance_methods, 0));
5515 initlist = tree_cons (NULL_TREE, expr, initlist);
5517 if (!class_methods)
5518 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5519 else
5521 expr = convert (objc_method_list_ptr,
5522 build_unary_op (ADDR_EXPR, class_methods, 0));
5523 initlist = tree_cons (NULL_TREE, expr, initlist);
5526 /* protocol_list = */
5527 if (!protocol_list)
5528 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5529 else
5531 expr = convert (build_pointer_type
5532 (build_pointer_type
5533 (objc_protocol_template)),
5534 build_unary_op (ADDR_EXPR, protocol_list, 0));
5535 initlist = tree_cons (NULL_TREE, expr, initlist);
5538 return objc_build_constructor (type, nreverse (initlist));
5541 /* struct _objc_class {
5542 struct objc_class *isa;
5543 struct objc_class *super_class;
5544 char *name;
5545 long version;
5546 long info;
5547 long instance_size;
5548 struct objc_ivar_list *ivars;
5549 struct objc_method_list *methods;
5550 if (flag_next_runtime)
5551 struct objc_cache *cache;
5552 else {
5553 struct sarray *dtable;
5554 struct objc_class *subclass_list;
5555 struct objc_class *sibling_class;
5557 struct objc_protocol_list *protocols;
5558 if (flag_next_runtime)
5559 void *sel_id;
5560 void *gc_object_type;
5561 }; */
5563 static tree
5564 build_shared_structure_initializer (tree type, tree isa, tree super,
5565 tree name, tree size, int status,
5566 tree dispatch_table, tree ivar_list,
5567 tree protocol_list)
5569 tree initlist = NULL_TREE, expr;
5571 /* isa = */
5572 initlist = tree_cons (NULL_TREE, isa, initlist);
5574 /* super_class = */
5575 initlist = tree_cons (NULL_TREE, super, initlist);
5577 /* name = */
5578 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5580 /* version = */
5581 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5582 initlist);
5584 /* info = */
5585 initlist = tree_cons (NULL_TREE,
5586 build_int_cst (long_integer_type_node, status),
5587 initlist);
5589 /* instance_size = */
5590 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5591 initlist);
5593 /* objc_ivar_list = */
5594 if (!ivar_list)
5595 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5596 else
5598 expr = convert (objc_ivar_list_ptr,
5599 build_unary_op (ADDR_EXPR, ivar_list, 0));
5600 initlist = tree_cons (NULL_TREE, expr, initlist);
5603 /* objc_method_list = */
5604 if (!dispatch_table)
5605 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5606 else
5608 expr = convert (objc_method_list_ptr,
5609 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5610 initlist = tree_cons (NULL_TREE, expr, initlist);
5613 if (flag_next_runtime)
5614 /* method_cache = */
5615 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5616 else
5618 /* dtable = */
5619 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5621 /* subclass_list = */
5622 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5624 /* sibling_class = */
5625 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5628 /* protocol_list = */
5629 if (! protocol_list)
5630 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5631 else
5633 expr = convert (build_pointer_type
5634 (build_pointer_type
5635 (objc_protocol_template)),
5636 build_unary_op (ADDR_EXPR, protocol_list, 0));
5637 initlist = tree_cons (NULL_TREE, expr, initlist);
5640 if (flag_next_runtime)
5641 /* sel_id = NULL */
5642 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5644 /* gc_object_type = NULL */
5645 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5647 return objc_build_constructor (type, nreverse (initlist));
5650 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5652 static inline tree
5653 lookup_category (tree class, tree cat_name)
5655 tree category = CLASS_CATEGORY_LIST (class);
5657 while (category && CLASS_SUPER_NAME (category) != cat_name)
5658 category = CLASS_CATEGORY_LIST (category);
5659 return category;
5662 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5664 static void
5665 generate_category (tree cat)
5667 tree decl;
5668 tree initlist, cat_name_expr, class_name_expr;
5669 tree protocol_decl, category;
5671 add_class_reference (CLASS_NAME (cat));
5672 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5674 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5676 category = lookup_category (implementation_template,
5677 CLASS_SUPER_NAME (cat));
5679 if (category && CLASS_PROTOCOL_LIST (category))
5681 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5682 protocol_decl = generate_protocol_list (category);
5684 else
5685 protocol_decl = 0;
5687 decl = start_var_decl (objc_category_template,
5688 synth_id_with_class_suffix
5689 ("_OBJC_CATEGORY", objc_implementation_context));
5691 initlist = build_category_initializer (TREE_TYPE (decl),
5692 cat_name_expr, class_name_expr,
5693 UOBJC_INSTANCE_METHODS_decl,
5694 UOBJC_CLASS_METHODS_decl,
5695 protocol_decl);
5697 finish_var_decl (decl, initlist);
5700 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5701 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5703 static void
5704 generate_shared_structures (int cls_flags)
5706 tree sc_spec, decl_specs, decl;
5707 tree name_expr, super_expr, root_expr;
5708 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5709 tree cast_type, initlist, protocol_decl;
5711 my_super_id = CLASS_SUPER_NAME (implementation_template);
5712 if (my_super_id)
5714 add_class_reference (my_super_id);
5716 /* Compute "my_root_id" - this is required for code generation.
5717 the "isa" for all meta class structures points to the root of
5718 the inheritance hierarchy (e.g. "__Object")... */
5719 my_root_id = my_super_id;
5722 tree my_root_int = lookup_interface (my_root_id);
5724 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5725 my_root_id = CLASS_SUPER_NAME (my_root_int);
5726 else
5727 break;
5729 while (1);
5731 else
5732 /* No super class. */
5733 my_root_id = CLASS_NAME (implementation_template);
5735 cast_type = build_pointer_type (objc_class_template);
5736 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5737 class_names);
5739 /* Install class `isa' and `super' pointers at runtime. */
5740 if (my_super_id)
5742 super_expr = add_objc_string (my_super_id, class_names);
5743 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5745 else
5746 super_expr = build_int_cst (NULL_TREE, 0);
5748 root_expr = add_objc_string (my_root_id, class_names);
5749 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5751 if (CLASS_PROTOCOL_LIST (implementation_template))
5753 generate_protocol_references
5754 (CLASS_PROTOCOL_LIST (implementation_template));
5755 protocol_decl = generate_protocol_list (implementation_template);
5757 else
5758 protocol_decl = 0;
5760 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5762 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5763 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5765 decl = start_var_decl (objc_class_template,
5766 IDENTIFIER_POINTER
5767 (DECL_NAME (UOBJC_METACLASS_decl)));
5769 initlist
5770 = build_shared_structure_initializer
5771 (TREE_TYPE (decl),
5772 root_expr, super_expr, name_expr,
5773 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5774 2 /*CLS_META*/,
5775 UOBJC_CLASS_METHODS_decl,
5776 UOBJC_CLASS_VARIABLES_decl,
5777 protocol_decl);
5779 finish_var_decl (decl, initlist);
5781 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5783 decl = start_var_decl (objc_class_template,
5784 IDENTIFIER_POINTER
5785 (DECL_NAME (UOBJC_CLASS_decl)));
5787 initlist
5788 = build_shared_structure_initializer
5789 (TREE_TYPE (decl),
5790 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5791 super_expr, name_expr,
5792 convert (integer_type_node,
5793 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5794 (implementation_template))),
5795 1 /*CLS_FACTORY*/ | cls_flags,
5796 UOBJC_INSTANCE_METHODS_decl,
5797 UOBJC_INSTANCE_VARIABLES_decl,
5798 protocol_decl);
5800 finish_var_decl (decl, initlist);
5804 static const char *
5805 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5807 static char string[BUFSIZE];
5809 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5810 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5812 sprintf (string, "%s_%s", preamble,
5813 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5815 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5816 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5818 /* We have a category. */
5819 const char *const class_name
5820 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5821 const char *const class_super_name
5822 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5823 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5825 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5827 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5828 sprintf (string, "%s_%s", preamble, protocol_name);
5830 else
5831 abort ();
5833 return string;
5836 /* If type is empty or only type qualifiers are present, add default
5837 type of id (otherwise grokdeclarator will default to int). */
5839 static tree
5840 adjust_type_for_id_default (tree type)
5842 if (!type)
5843 type = make_node (TREE_LIST);
5845 if (!TREE_VALUE (type))
5846 TREE_VALUE (type) = objc_object_type;
5847 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5848 && TYPED_OBJECT (TREE_VALUE (type)))
5849 error ("can not use an object as parameter to a method");
5851 return type;
5854 /* Usage:
5855 keyworddecl:
5856 selector ':' '(' typename ')' identifier
5858 Purpose:
5859 Transform an Objective-C keyword argument into
5860 the C equivalent parameter declarator.
5862 In: key_name, an "identifier_node" (optional).
5863 arg_type, a "tree_list" (optional).
5864 arg_name, an "identifier_node".
5866 Note: It would be really nice to strongly type the preceding
5867 arguments in the function prototype; however, then I
5868 could not use the "accessor" macros defined in "tree.h".
5870 Out: an instance of "keyword_decl". */
5872 tree
5873 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5875 tree keyword_decl;
5877 /* If no type is specified, default to "id". */
5878 arg_type = adjust_type_for_id_default (arg_type);
5880 keyword_decl = make_node (KEYWORD_DECL);
5882 TREE_TYPE (keyword_decl) = arg_type;
5883 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5884 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5886 return keyword_decl;
5889 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5891 static tree
5892 build_keyword_selector (tree selector)
5894 int len = 0;
5895 tree key_chain, key_name;
5896 char *buf;
5898 /* Scan the selector to see how much space we'll need. */
5899 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5901 if (TREE_CODE (selector) == KEYWORD_DECL)
5902 key_name = KEYWORD_KEY_NAME (key_chain);
5903 else if (TREE_CODE (selector) == TREE_LIST)
5904 key_name = TREE_PURPOSE (key_chain);
5905 else
5906 abort ();
5908 if (key_name)
5909 len += IDENTIFIER_LENGTH (key_name) + 1;
5910 else
5911 /* Just a ':' arg. */
5912 len++;
5915 buf = (char *) alloca (len + 1);
5916 /* Start the buffer out as an empty string. */
5917 buf[0] = '\0';
5919 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5921 if (TREE_CODE (selector) == KEYWORD_DECL)
5922 key_name = KEYWORD_KEY_NAME (key_chain);
5923 else if (TREE_CODE (selector) == TREE_LIST)
5925 key_name = TREE_PURPOSE (key_chain);
5926 /* The keyword decl chain will later be used as a function argument
5927 chain. Unhook the selector itself so as to not confuse other
5928 parts of the compiler. */
5929 TREE_PURPOSE (key_chain) = NULL_TREE;
5931 else
5932 abort ();
5934 if (key_name)
5935 strcat (buf, IDENTIFIER_POINTER (key_name));
5936 strcat (buf, ":");
5939 return get_identifier (buf);
5942 /* Used for declarations and definitions. */
5944 static tree
5945 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5946 tree add_args, bool ellipsis)
5948 tree method_decl;
5950 /* If no type is specified, default to "id". */
5951 ret_type = adjust_type_for_id_default (ret_type);
5953 method_decl = make_node (code);
5954 TREE_TYPE (method_decl) = ret_type;
5956 /* If we have a keyword selector, create an identifier_node that
5957 represents the full selector name (`:' included)... */
5958 if (TREE_CODE (selector) == KEYWORD_DECL)
5960 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5961 METHOD_SEL_ARGS (method_decl) = selector;
5962 METHOD_ADD_ARGS (method_decl) = add_args;
5963 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5965 else
5967 METHOD_SEL_NAME (method_decl) = selector;
5968 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5969 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5972 return method_decl;
5975 #define METHOD_DEF 0
5976 #define METHOD_REF 1
5978 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5979 an argument list for method METH. CONTEXT is either METHOD_DEF or
5980 METHOD_REF, saying whether we are trying to define a method or call
5981 one. SUPERFLAG says this is for a send to super; this makes a
5982 difference for the NeXT calling sequence in which the lookup and
5983 the method call are done together. If METH is null, user-defined
5984 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5986 static tree
5987 get_arg_type_list (tree meth, int context, int superflag)
5989 tree arglist, akey;
5991 /* Receiver type. */
5992 if (flag_next_runtime && superflag)
5993 arglist = build_tree_list (NULL_TREE, objc_super_type);
5994 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5995 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5996 else
5997 arglist = build_tree_list (NULL_TREE, objc_object_type);
5999 /* Selector type - will eventually change to `int'. */
6000 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6002 /* No actual method prototype given -- assume that remaining arguments
6003 are `...'. */
6004 if (!meth)
6005 return arglist;
6007 /* Build a list of argument types. */
6008 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6010 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6012 /* Decay arrays and functions into pointers. */
6013 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6014 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6015 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6016 arg_type = build_pointer_type (arg_type);
6018 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6021 if (METHOD_ADD_ARGS (meth))
6023 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6024 akey; akey = TREE_CHAIN (akey))
6026 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6028 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6031 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6032 goto lack_of_ellipsis;
6034 else
6036 lack_of_ellipsis:
6037 chainon (arglist, OBJC_VOID_AT_END);
6040 return arglist;
6043 static tree
6044 check_duplicates (hash hsh, int methods, int is_class)
6046 tree meth = NULL_TREE;
6048 if (hsh)
6050 meth = hsh->key;
6052 if (hsh->list)
6054 /* We have two or more methods with the same name but
6055 different types. */
6056 attr loop;
6058 /* But just how different are those types? If
6059 -Wno-strict-selector-match is specified, we shall not
6060 complain if the differences are solely among types with
6061 identical size and alignment. */
6062 if (!warn_strict_selector_match)
6064 for (loop = hsh->list; loop; loop = loop->next)
6065 if (!comp_proto_with_proto (meth, loop->value, 0))
6066 goto issue_warning;
6068 return meth;
6071 issue_warning:
6072 warning (0, "multiple %s named %<%c%s%> found",
6073 methods ? "methods" : "selectors",
6074 (is_class ? '+' : '-'),
6075 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6077 warn_with_method (methods ? "using" : "found",
6078 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6079 ? '-'
6080 : '+'),
6081 meth);
6082 for (loop = hsh->list; loop; loop = loop->next)
6083 warn_with_method ("also found",
6084 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6085 ? '-'
6086 : '+'),
6087 loop->value);
6090 return meth;
6093 /* If RECEIVER is a class reference, return the identifier node for
6094 the referenced class. RECEIVER is created by objc_get_class_reference,
6095 so we check the exact form created depending on which runtimes are
6096 used. */
6098 static tree
6099 receiver_is_class_object (tree receiver, int self, int super)
6101 tree chain, exp, arg;
6103 /* The receiver is 'self' or 'super' in the context of a class method. */
6104 if (objc_method_context
6105 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6106 && (self || super))
6107 return (super
6108 ? CLASS_SUPER_NAME (implementation_template)
6109 : CLASS_NAME (implementation_template));
6111 if (flag_next_runtime)
6113 /* The receiver is a variable created by
6114 build_class_reference_decl. */
6115 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6116 /* Look up the identifier. */
6117 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6118 if (TREE_PURPOSE (chain) == receiver)
6119 return TREE_VALUE (chain);
6122 /* The receiver is a function call that returns an id. Check if
6123 it is a call to objc_getClass, if so, pick up the class name. */
6124 if (TREE_CODE (receiver) == CALL_EXPR
6125 && (exp = CALL_EXPR_FN (receiver))
6126 && TREE_CODE (exp) == ADDR_EXPR
6127 && (exp = TREE_OPERAND (exp, 0))
6128 && TREE_CODE (exp) == FUNCTION_DECL
6129 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6130 prototypes for objc_get_class(). Thankfully, they seem to share the
6131 same function type. */
6132 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6133 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6134 /* We have a call to objc_get_class/objc_getClass! */
6135 && (arg = CALL_EXPR_ARG (receiver, 0)))
6137 STRIP_NOPS (arg);
6138 if (TREE_CODE (arg) == ADDR_EXPR
6139 && (arg = TREE_OPERAND (arg, 0))
6140 && TREE_CODE (arg) == STRING_CST)
6141 /* Finally, we have the class name. */
6142 return get_identifier (TREE_STRING_POINTER (arg));
6144 return 0;
6147 /* If we are currently building a message expr, this holds
6148 the identifier of the selector of the message. This is
6149 used when printing warnings about argument mismatches. */
6151 static tree current_objc_message_selector = 0;
6153 tree
6154 objc_message_selector (void)
6156 return current_objc_message_selector;
6159 /* Construct an expression for sending a message.
6160 MESS has the object to send to in TREE_PURPOSE
6161 and the argument list (including selector) in TREE_VALUE.
6163 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6164 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6166 tree
6167 objc_build_message_expr (tree mess)
6169 tree receiver = TREE_PURPOSE (mess);
6170 tree sel_name;
6171 #ifdef OBJCPLUS
6172 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6173 #else
6174 tree args = TREE_VALUE (mess);
6175 #endif
6176 tree method_params = NULL_TREE;
6178 if (TREE_CODE (receiver) == ERROR_MARK)
6179 return error_mark_node;
6181 /* Obtain the full selector name. */
6182 if (TREE_CODE (args) == IDENTIFIER_NODE)
6183 /* A unary selector. */
6184 sel_name = args;
6185 else if (TREE_CODE (args) == TREE_LIST)
6186 sel_name = build_keyword_selector (args);
6187 else
6188 abort ();
6190 /* Build the parameter list to give to the method. */
6191 if (TREE_CODE (args) == TREE_LIST)
6192 #ifdef OBJCPLUS
6193 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6194 #else
6196 tree chain = args, prev = NULL_TREE;
6198 /* We have a keyword selector--check for comma expressions. */
6199 while (chain)
6201 tree element = TREE_VALUE (chain);
6203 /* We have a comma expression, must collapse... */
6204 if (TREE_CODE (element) == TREE_LIST)
6206 if (prev)
6207 TREE_CHAIN (prev) = element;
6208 else
6209 args = element;
6211 prev = chain;
6212 chain = TREE_CHAIN (chain);
6214 method_params = args;
6216 #endif
6218 #ifdef OBJCPLUS
6219 if (processing_template_decl)
6220 /* Must wait until template instantiation time. */
6221 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6222 method_params);
6223 #endif
6225 return objc_finish_message_expr (receiver, sel_name, method_params);
6228 /* Look up method SEL_NAME that would be suitable for receiver
6229 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6230 nonzero), and report on any duplicates. */
6232 static tree
6233 lookup_method_in_hash_lists (tree sel_name, int is_class)
6235 hash method_prototype = NULL;
6237 if (!is_class)
6238 method_prototype = hash_lookup (nst_method_hash_list,
6239 sel_name);
6241 if (!method_prototype)
6243 method_prototype = hash_lookup (cls_method_hash_list,
6244 sel_name);
6245 is_class = 1;
6248 return check_duplicates (method_prototype, 1, is_class);
6251 /* The 'objc_finish_message_expr' routine is called from within
6252 'objc_build_message_expr' for non-template functions. In the case of
6253 C++ template functions, it is called from 'build_expr_from_tree'
6254 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6256 tree
6257 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6259 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6260 tree selector, retval, class_tree;
6261 int self, super, have_cast;
6263 /* Extract the receiver of the message, as well as its type
6264 (where the latter may take the form of a cast or be inferred
6265 from the implementation context). */
6266 rtype = receiver;
6267 while (TREE_CODE (rtype) == COMPOUND_EXPR
6268 || TREE_CODE (rtype) == MODIFY_EXPR
6269 || CONVERT_EXPR_P (rtype)
6270 || TREE_CODE (rtype) == COMPONENT_REF)
6271 rtype = TREE_OPERAND (rtype, 0);
6272 self = (rtype == self_decl);
6273 super = (rtype == UOBJC_SUPER_decl);
6274 rtype = TREE_TYPE (receiver);
6275 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6276 || (TREE_CODE (receiver) == COMPOUND_EXPR
6277 && !IS_SUPER (rtype)));
6279 /* If we are calling [super dealloc], reset our warning flag. */
6280 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6281 should_call_super_dealloc = 0;
6283 /* If the receiver is a class object, retrieve the corresponding
6284 @interface, if one exists. */
6285 class_tree = receiver_is_class_object (receiver, self, super);
6287 /* Now determine the receiver type (if an explicit cast has not been
6288 provided). */
6289 if (!have_cast)
6291 if (class_tree)
6292 rtype = lookup_interface (class_tree);
6293 /* Handle `self' and `super'. */
6294 else if (super)
6296 if (!CLASS_SUPER_NAME (implementation_template))
6298 error ("no super class declared in @interface for %qs",
6299 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6300 return error_mark_node;
6302 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6304 else if (self)
6305 rtype = lookup_interface (CLASS_NAME (implementation_template));
6308 /* If receiver is of type `id' or `Class' (or if the @interface for a
6309 class is not visible), we shall be satisfied with the existence of
6310 any instance or class method. */
6311 if (objc_is_id (rtype))
6313 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6314 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6315 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6316 : NULL_TREE);
6317 rtype = NULL_TREE;
6319 if (rprotos)
6321 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6322 in protocols themselves for the method prototype. */
6323 method_prototype
6324 = lookup_method_in_protocol_list (rprotos, sel_name,
6325 class_tree != NULL_TREE);
6327 /* If messaging 'Class <Proto>' but did not find a class method
6328 prototype, search for an instance method instead, and warn
6329 about having done so. */
6330 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6332 method_prototype
6333 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6335 if (method_prototype)
6336 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6337 IDENTIFIER_POINTER (sel_name),
6338 IDENTIFIER_POINTER (sel_name));
6342 else if (rtype)
6344 tree orig_rtype = rtype, saved_rtype;
6346 if (TREE_CODE (rtype) == POINTER_TYPE)
6347 rtype = TREE_TYPE (rtype);
6348 /* Traverse typedef aliases */
6349 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6350 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6351 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6352 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6353 saved_rtype = rtype;
6354 if (TYPED_OBJECT (rtype))
6356 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6357 rtype = TYPE_OBJC_INTERFACE (rtype);
6359 /* If we could not find an @interface declaration, we must have
6360 only seen a @class declaration; so, we cannot say anything
6361 more intelligent about which methods the receiver will
6362 understand. */
6363 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6364 rtype = NULL_TREE;
6365 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6366 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6368 /* We have a valid ObjC class name. Look up the method name
6369 in the published @interface for the class (and its
6370 superclasses). */
6371 method_prototype
6372 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6374 /* If the method was not found in the @interface, it may still
6375 exist locally as part of the @implementation. */
6376 if (!method_prototype && objc_implementation_context
6377 && CLASS_NAME (objc_implementation_context)
6378 == OBJC_TYPE_NAME (rtype))
6379 method_prototype
6380 = lookup_method
6381 ((class_tree
6382 ? CLASS_CLS_METHODS (objc_implementation_context)
6383 : CLASS_NST_METHODS (objc_implementation_context)),
6384 sel_name);
6386 /* If we haven't found a candidate method by now, try looking for
6387 it in the protocol list. */
6388 if (!method_prototype && rprotos)
6389 method_prototype
6390 = lookup_method_in_protocol_list (rprotos, sel_name,
6391 class_tree != NULL_TREE);
6393 else
6395 warning (0, "invalid receiver type %qs",
6396 gen_type_name (orig_rtype));
6397 /* After issuing the "invalid receiver" warning, perform method
6398 lookup as if we were messaging 'id'. */
6399 rtype = rprotos = NULL_TREE;
6404 /* For 'id' or 'Class' receivers, search in the global hash table
6405 as a last resort. For all receivers, warn if protocol searches
6406 have failed. */
6407 if (!method_prototype)
6409 if (rprotos)
6410 warning (0, "%<%c%s%> not found in protocol(s)",
6411 (class_tree ? '+' : '-'),
6412 IDENTIFIER_POINTER (sel_name));
6414 if (!rtype)
6415 method_prototype
6416 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6419 if (!method_prototype)
6421 static bool warn_missing_methods = false;
6423 if (rtype)
6424 warning (0, "%qs may not respond to %<%c%s%>",
6425 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6426 (class_tree ? '+' : '-'),
6427 IDENTIFIER_POINTER (sel_name));
6428 /* If we are messaging an 'id' or 'Class' object and made it here,
6429 then we have failed to find _any_ instance or class method,
6430 respectively. */
6431 else
6432 warning (0, "no %<%c%s%> method found",
6433 (class_tree ? '+' : '-'),
6434 IDENTIFIER_POINTER (sel_name));
6436 if (!warn_missing_methods)
6438 warning (0, "(Messages without a matching method signature");
6439 warning (0, "will be assumed to return %<id%> and accept");
6440 warning (0, "%<...%> as arguments.)");
6441 warn_missing_methods = true;
6445 /* Save the selector name for printing error messages. */
6446 current_objc_message_selector = sel_name;
6448 /* Build the parameters list for looking up the method.
6449 These are the object itself and the selector. */
6451 if (flag_typed_selectors)
6452 selector = build_typed_selector_reference (sel_name, method_prototype);
6453 else
6454 selector = build_selector_reference (sel_name);
6456 retval = build_objc_method_call (super, method_prototype,
6457 receiver,
6458 selector, method_params);
6460 current_objc_message_selector = 0;
6462 return retval;
6465 /* Build a tree expression to send OBJECT the operation SELECTOR,
6466 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6467 assuming the method has prototype METHOD_PROTOTYPE.
6468 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6469 Use METHOD_PARAMS as list of args to pass to the method.
6470 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6472 static tree
6473 build_objc_method_call (int super_flag, tree method_prototype,
6474 tree lookup_object, tree selector,
6475 tree method_params)
6477 tree sender = (super_flag ? umsg_super_decl :
6478 (!flag_next_runtime || flag_nil_receivers
6479 ? (flag_objc_direct_dispatch
6480 ? umsg_fast_decl
6481 : umsg_decl)
6482 : umsg_nonnil_decl));
6483 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6485 /* If a prototype for the method to be called exists, then cast
6486 the sender's return type and arguments to match that of the method.
6487 Otherwise, leave sender as is. */
6488 tree ret_type
6489 = (method_prototype
6490 ? TREE_VALUE (TREE_TYPE (method_prototype))
6491 : objc_object_type);
6492 tree sender_cast
6493 = build_pointer_type
6494 (build_function_type
6495 (ret_type,
6496 get_arg_type_list
6497 (method_prototype, METHOD_REF, super_flag)));
6498 tree method, t;
6500 lookup_object = build_c_cast (rcv_p, lookup_object);
6502 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6503 lookup_object = save_expr (lookup_object);
6505 if (flag_next_runtime)
6507 /* If we are returning a struct in memory, and the address
6508 of that memory location is passed as a hidden first
6509 argument, then change which messenger entry point this
6510 expr will call. NB: Note that sender_cast remains
6511 unchanged (it already has a struct return type). */
6512 if (!targetm.calls.struct_value_rtx (0, 0)
6513 && (TREE_CODE (ret_type) == RECORD_TYPE
6514 || TREE_CODE (ret_type) == UNION_TYPE)
6515 && targetm.calls.return_in_memory (ret_type, 0))
6516 sender = (super_flag ? umsg_super_stret_decl :
6517 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6519 method_params = tree_cons (NULL_TREE, lookup_object,
6520 tree_cons (NULL_TREE, selector,
6521 method_params));
6522 method = build_fold_addr_expr (sender);
6524 else
6526 /* This is the portable (GNU) way. */
6527 tree object;
6529 /* First, call the lookup function to get a pointer to the method,
6530 then cast the pointer, then call it with the method arguments. */
6532 object = (super_flag ? self_decl : lookup_object);
6534 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6535 t = tree_cons (NULL_TREE, lookup_object, t);
6536 method = build_function_call (sender, t);
6538 /* Pass the object to the method. */
6539 method_params = tree_cons (NULL_TREE, object,
6540 tree_cons (NULL_TREE, selector,
6541 method_params));
6544 /* ??? Selector is not at this point something we can use inside
6545 the compiler itself. Set it to garbage for the nonce. */
6546 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6547 return build_function_call (t, method_params);
6550 static void
6551 build_protocol_reference (tree p)
6553 tree decl;
6554 const char *proto_name;
6556 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6558 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6559 decl = start_var_decl (objc_protocol_template, proto_name);
6561 PROTOCOL_FORWARD_DECL (p) = decl;
6564 /* This function is called by the parser when (and only when) a
6565 @protocol() expression is found, in order to compile it. */
6566 tree
6567 objc_build_protocol_expr (tree protoname)
6569 tree expr;
6570 tree p = lookup_protocol (protoname);
6572 if (!p)
6574 error ("cannot find protocol declaration for %qs",
6575 IDENTIFIER_POINTER (protoname));
6576 return error_mark_node;
6579 if (!PROTOCOL_FORWARD_DECL (p))
6580 build_protocol_reference (p);
6582 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6584 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6585 if we have it, rather than converting it here. */
6586 expr = convert (objc_protocol_type, expr);
6588 /* The @protocol() expression is being compiled into a pointer to a
6589 statically allocated instance of the Protocol class. To become
6590 usable at runtime, the 'isa' pointer of the instance need to be
6591 fixed up at runtime by the runtime library, to point to the
6592 actual 'Protocol' class. */
6594 /* For the GNU runtime, put the static Protocol instance in the list
6595 of statically allocated instances, so that we make sure that its
6596 'isa' pointer is fixed up at runtime by the GNU runtime library
6597 to point to the Protocol class (at runtime, when loading the
6598 module, the GNU runtime library loops on the statically allocated
6599 instances (as found in the defs field in objc_symtab) and fixups
6600 all the 'isa' pointers of those objects). */
6601 if (! flag_next_runtime)
6603 /* This type is a struct containing the fields of a Protocol
6604 object. (Cfr. objc_protocol_type instead is the type of a pointer
6605 to such a struct). */
6606 tree protocol_struct_type = xref_tag
6607 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6608 tree *chain;
6610 /* Look for the list of Protocol statically allocated instances
6611 to fixup at runtime. Create a new list to hold Protocol
6612 statically allocated instances, if the list is not found. At
6613 present there is only another list, holding NSConstantString
6614 static instances to be fixed up at runtime. */
6615 for (chain = &objc_static_instances;
6616 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6617 chain = &TREE_CHAIN (*chain));
6618 if (!*chain)
6620 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6621 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6622 class_names);
6625 /* Add this statically allocated instance to the Protocol list. */
6626 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6627 PROTOCOL_FORWARD_DECL (p),
6628 TREE_PURPOSE (*chain));
6632 return expr;
6635 /* This function is called by the parser when a @selector() expression
6636 is found, in order to compile it. It is only called by the parser
6637 and only to compile a @selector(). */
6638 tree
6639 objc_build_selector_expr (tree selnamelist)
6641 tree selname;
6643 /* Obtain the full selector name. */
6644 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6645 /* A unary selector. */
6646 selname = selnamelist;
6647 else if (TREE_CODE (selnamelist) == TREE_LIST)
6648 selname = build_keyword_selector (selnamelist);
6649 else
6650 abort ();
6652 /* If we are required to check @selector() expressions as they
6653 are found, check that the selector has been declared. */
6654 if (warn_undeclared_selector)
6656 /* Look the selector up in the list of all known class and
6657 instance methods (up to this line) to check that the selector
6658 exists. */
6659 hash hsh;
6661 /* First try with instance methods. */
6662 hsh = hash_lookup (nst_method_hash_list, selname);
6664 /* If not found, try with class methods. */
6665 if (!hsh)
6667 hsh = hash_lookup (cls_method_hash_list, selname);
6670 /* If still not found, print out a warning. */
6671 if (!hsh)
6673 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6678 if (flag_typed_selectors)
6679 return build_typed_selector_reference (selname, 0);
6680 else
6681 return build_selector_reference (selname);
6684 tree
6685 objc_build_encode_expr (tree type)
6687 tree result;
6688 const char *string;
6690 encode_type (type, obstack_object_size (&util_obstack),
6691 OBJC_ENCODE_INLINE_DEFS);
6692 obstack_1grow (&util_obstack, 0); /* null terminate string */
6693 string = obstack_finish (&util_obstack);
6695 /* Synthesize a string that represents the encoded struct/union. */
6696 result = my_build_string (strlen (string) + 1, string);
6697 obstack_free (&util_obstack, util_firstobj);
6698 return result;
6701 static tree
6702 build_ivar_reference (tree id)
6704 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6706 /* Historically, a class method that produced objects (factory
6707 method) would assign `self' to the instance that it
6708 allocated. This would effectively turn the class method into
6709 an instance method. Following this assignment, the instance
6710 variables could be accessed. That practice, while safe,
6711 violates the simple rule that a class method should not refer
6712 to an instance variable. It's better to catch the cases
6713 where this is done unknowingly than to support the above
6714 paradigm. */
6715 warning (0, "instance variable %qs accessed in class method",
6716 IDENTIFIER_POINTER (id));
6717 self_decl = convert (objc_instance_type, self_decl); /* cast */
6720 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6723 /* Compute a hash value for a given method SEL_NAME. */
6725 static size_t
6726 hash_func (tree sel_name)
6728 const unsigned char *s
6729 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6730 size_t h = 0;
6732 while (*s)
6733 h = h * 67 + *s++ - 113;
6734 return h;
6737 static void
6738 hash_init (void)
6740 nst_method_hash_list
6741 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6742 cls_method_hash_list
6743 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6745 /* Initialize the hash table used to hold the constant string objects. */
6746 string_htab = htab_create_ggc (31, string_hash,
6747 string_eq, NULL);
6749 /* Initialize the hash table used to hold EH-volatilized types. */
6750 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6751 volatilized_eq, NULL);
6754 /* WARNING!!!! hash_enter is called with a method, and will peek
6755 inside to find its selector! But hash_lookup is given a selector
6756 directly, and looks for the selector that's inside the found
6757 entry's key (method) for comparison. */
6759 static void
6760 hash_enter (hash *hashlist, tree method)
6762 hash obj;
6763 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6765 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6766 obj->list = 0;
6767 obj->next = hashlist[slot];
6768 obj->key = method;
6770 hashlist[slot] = obj; /* append to front */
6773 static hash
6774 hash_lookup (hash *hashlist, tree sel_name)
6776 hash target;
6778 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6780 while (target)
6782 if (sel_name == METHOD_SEL_NAME (target->key))
6783 return target;
6785 target = target->next;
6787 return 0;
6790 static void
6791 hash_add_attr (hash entry, tree value)
6793 attr obj;
6795 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6796 obj->next = entry->list;
6797 obj->value = value;
6799 entry->list = obj; /* append to front */
6802 static tree
6803 lookup_method (tree mchain, tree method)
6805 tree key;
6807 if (TREE_CODE (method) == IDENTIFIER_NODE)
6808 key = method;
6809 else
6810 key = METHOD_SEL_NAME (method);
6812 while (mchain)
6814 if (METHOD_SEL_NAME (mchain) == key)
6815 return mchain;
6817 mchain = TREE_CHAIN (mchain);
6819 return NULL_TREE;
6822 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6823 in INTERFACE, along with any categories and protocols attached thereto.
6824 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6825 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6826 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6827 be found in INTERFACE or any of its superclasses, look for an _instance_
6828 method of the same name in the root class as a last resort.
6830 If a suitable method cannot be found, return NULL_TREE. */
6832 static tree
6833 lookup_method_static (tree interface, tree ident, int flags)
6835 tree meth = NULL_TREE, root_inter = NULL_TREE;
6836 tree inter = interface;
6837 int is_class = (flags & OBJC_LOOKUP_CLASS);
6838 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6840 while (inter)
6842 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6843 tree category = inter;
6845 /* First, look up the method in the class itself. */
6846 if ((meth = lookup_method (chain, ident)))
6847 return meth;
6849 /* Failing that, look for the method in each category of the class. */
6850 while ((category = CLASS_CATEGORY_LIST (category)))
6852 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6854 /* Check directly in each category. */
6855 if ((meth = lookup_method (chain, ident)))
6856 return meth;
6858 /* Failing that, check in each category's protocols. */
6859 if (CLASS_PROTOCOL_LIST (category))
6861 if ((meth = (lookup_method_in_protocol_list
6862 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6863 return meth;
6867 /* If not found in categories, check in protocols of the main class. */
6868 if (CLASS_PROTOCOL_LIST (inter))
6870 if ((meth = (lookup_method_in_protocol_list
6871 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6872 return meth;
6875 /* If we were instructed not to look in superclasses, don't. */
6876 if (no_superclasses)
6877 return NULL_TREE;
6879 /* Failing that, climb up the inheritance hierarchy. */
6880 root_inter = inter;
6881 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6883 while (inter);
6885 /* If no class (factory) method was found, check if an _instance_
6886 method of the same name exists in the root class. This is what
6887 the Objective-C runtime will do. If an instance method was not
6888 found, return 0. */
6889 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6892 /* Add the method to the hash list if it doesn't contain an identical
6893 method already. */
6895 static void
6896 add_method_to_hash_list (hash *hash_list, tree method)
6898 hash hsh;
6900 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6902 /* Install on a global chain. */
6903 hash_enter (hash_list, method);
6905 else
6907 /* Check types against those; if different, add to a list. */
6908 attr loop;
6909 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6910 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6911 already_there |= comp_proto_with_proto (method, loop->value, 1);
6912 if (!already_there)
6913 hash_add_attr (hsh, method);
6917 static tree
6918 objc_add_method (tree class, tree method, int is_class)
6920 tree mth;
6922 if (!(mth = lookup_method (is_class
6923 ? CLASS_CLS_METHODS (class)
6924 : CLASS_NST_METHODS (class), method)))
6926 /* put method on list in reverse order */
6927 if (is_class)
6929 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6930 CLASS_CLS_METHODS (class) = method;
6932 else
6934 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6935 CLASS_NST_METHODS (class) = method;
6938 else
6940 /* When processing an @interface for a class or category, give hard
6941 errors on methods with identical selectors but differing argument
6942 and/or return types. We do not do this for @implementations, because
6943 C/C++ will do it for us (i.e., there will be duplicate function
6944 definition errors). */
6945 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6946 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6947 && !comp_proto_with_proto (method, mth, 1))
6948 error ("duplicate declaration of method %<%c%s%>",
6949 is_class ? '+' : '-',
6950 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6953 if (is_class)
6954 add_method_to_hash_list (cls_method_hash_list, method);
6955 else
6957 add_method_to_hash_list (nst_method_hash_list, method);
6959 /* Instance methods in root classes (and categories thereof)
6960 may act as class methods as a last resort. We also add
6961 instance methods listed in @protocol declarations to
6962 the class hash table, on the assumption that @protocols
6963 may be adopted by root classes or categories. */
6964 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6965 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6966 class = lookup_interface (CLASS_NAME (class));
6968 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6969 || !CLASS_SUPER_NAME (class))
6970 add_method_to_hash_list (cls_method_hash_list, method);
6973 return method;
6976 static tree
6977 add_class (tree class_name, tree name)
6979 struct interface_tuple **slot;
6981 /* Put interfaces on list in reverse order. */
6982 TREE_CHAIN (class_name) = interface_chain;
6983 interface_chain = class_name;
6985 if (interface_htab == NULL)
6986 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6987 slot = (struct interface_tuple **)
6988 htab_find_slot_with_hash (interface_htab, name,
6989 IDENTIFIER_HASH_VALUE (name),
6990 INSERT);
6991 if (!*slot)
6993 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6994 (*slot)->id = name;
6996 (*slot)->class_name = class_name;
6998 return interface_chain;
7001 static void
7002 add_category (tree class, tree category)
7004 /* Put categories on list in reverse order. */
7005 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7007 if (cat)
7009 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7010 IDENTIFIER_POINTER (CLASS_NAME (class)),
7011 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7013 else
7015 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7016 CLASS_CATEGORY_LIST (class) = category;
7020 /* Called after parsing each instance variable declaration. Necessary to
7021 preserve typedefs and implement public/private...
7023 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7025 static tree
7026 add_instance_variable (tree class, int public, tree field_decl)
7028 tree field_type = TREE_TYPE (field_decl);
7029 const char *ivar_name = DECL_NAME (field_decl)
7030 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7031 : "<unnamed>";
7033 #ifdef OBJCPLUS
7034 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7036 error ("illegal reference type specified for instance variable %qs",
7037 ivar_name);
7038 /* Return class as is without adding this ivar. */
7039 return class;
7041 #endif
7043 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7044 || TYPE_SIZE (field_type) == error_mark_node)
7045 /* 'type[0]' is allowed, but 'type[]' is not! */
7047 error ("instance variable %qs has unknown size", ivar_name);
7048 /* Return class as is without adding this ivar. */
7049 return class;
7052 #ifdef OBJCPLUS
7053 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7054 need to either (1) warn the user about it or (2) generate suitable
7055 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7056 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7057 if (MAYBE_CLASS_TYPE_P (field_type)
7058 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7059 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7060 || TYPE_POLYMORPHIC_P (field_type)))
7062 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7064 if (flag_objc_call_cxx_cdtors)
7066 /* Since the ObjC runtime will be calling the constructors and
7067 destructors for us, the only thing we can't handle is the lack
7068 of a default constructor. */
7069 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7070 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7072 warning (0, "type %qs has no default constructor to call",
7073 type_name);
7075 /* If we cannot call a constructor, we should also avoid
7076 calling the destructor, for symmetry. */
7077 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7078 warning (0, "destructor for %qs shall not be run either",
7079 type_name);
7082 else
7084 static bool warn_cxx_ivars = false;
7086 if (TYPE_POLYMORPHIC_P (field_type))
7088 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7089 initialize them. */
7090 error ("type %qs has virtual member functions", type_name);
7091 error ("illegal aggregate type %qs specified "
7092 "for instance variable %qs",
7093 type_name, ivar_name);
7094 /* Return class as is without adding this ivar. */
7095 return class;
7098 /* User-defined constructors and destructors are not known to Obj-C
7099 and hence will not be called. This may or may not be a problem. */
7100 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7101 warning (0, "type %qs has a user-defined constructor", type_name);
7102 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7103 warning (0, "type %qs has a user-defined destructor", type_name);
7105 if (!warn_cxx_ivars)
7107 warning (0, "C++ constructors and destructors will not "
7108 "be invoked for Objective-C fields");
7109 warn_cxx_ivars = true;
7113 #endif
7115 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7116 switch (public)
7118 case 0:
7119 TREE_PUBLIC (field_decl) = 0;
7120 TREE_PRIVATE (field_decl) = 0;
7121 TREE_PROTECTED (field_decl) = 1;
7122 break;
7124 case 1:
7125 TREE_PUBLIC (field_decl) = 1;
7126 TREE_PRIVATE (field_decl) = 0;
7127 TREE_PROTECTED (field_decl) = 0;
7128 break;
7130 case 2:
7131 TREE_PUBLIC (field_decl) = 0;
7132 TREE_PRIVATE (field_decl) = 1;
7133 TREE_PROTECTED (field_decl) = 0;
7134 break;
7138 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7140 return class;
7143 static tree
7144 is_ivar (tree decl_chain, tree ident)
7146 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7147 if (DECL_NAME (decl_chain) == ident)
7148 return decl_chain;
7149 return NULL_TREE;
7152 /* True if the ivar is private and we are not in its implementation. */
7154 static int
7155 is_private (tree decl)
7157 return (TREE_PRIVATE (decl)
7158 && ! is_ivar (CLASS_IVARS (implementation_template),
7159 DECL_NAME (decl)));
7162 /* We have an instance variable reference;, check to see if it is public. */
7165 objc_is_public (tree expr, tree identifier)
7167 tree basetype, decl;
7169 #ifdef OBJCPLUS
7170 if (processing_template_decl)
7171 return 1;
7172 #endif
7174 if (TREE_TYPE (expr) == error_mark_node)
7175 return 1;
7177 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7179 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7181 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7183 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7185 if (!class)
7187 error ("cannot find interface declaration for %qs",
7188 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7189 return 0;
7192 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7194 if (TREE_PUBLIC (decl))
7195 return 1;
7197 /* Important difference between the Stepstone translator:
7198 all instance variables should be public within the context
7199 of the implementation. */
7200 if (objc_implementation_context
7201 && ((TREE_CODE (objc_implementation_context)
7202 == CLASS_IMPLEMENTATION_TYPE)
7203 || (TREE_CODE (objc_implementation_context)
7204 == CATEGORY_IMPLEMENTATION_TYPE)))
7206 tree curtype = TYPE_MAIN_VARIANT
7207 (CLASS_STATIC_TEMPLATE
7208 (implementation_template));
7210 if (basetype == curtype
7211 || DERIVED_FROM_P (basetype, curtype))
7213 int private = is_private (decl);
7215 if (private)
7216 error ("instance variable %qs is declared private",
7217 IDENTIFIER_POINTER (DECL_NAME (decl)));
7219 return !private;
7223 /* The 2.95.2 compiler sometimes allowed C functions to access
7224 non-@public ivars. We will let this slide for now... */
7225 if (!objc_method_context)
7227 warning (0, "instance variable %qs is %s; "
7228 "this will be a hard error in the future",
7229 IDENTIFIER_POINTER (identifier),
7230 TREE_PRIVATE (decl) ? "@private" : "@protected");
7231 return 1;
7234 error ("instance variable %qs is declared %s",
7235 IDENTIFIER_POINTER (identifier),
7236 TREE_PRIVATE (decl) ? "private" : "protected");
7237 return 0;
7242 return 1;
7245 /* Make sure all entries in CHAIN are also in LIST. */
7247 static int
7248 check_methods (tree chain, tree list, int mtype)
7250 int first = 1;
7252 while (chain)
7254 if (!lookup_method (list, chain))
7256 if (first)
7258 if (TREE_CODE (objc_implementation_context)
7259 == CLASS_IMPLEMENTATION_TYPE)
7260 warning (0, "incomplete implementation of class %qs",
7261 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7262 else if (TREE_CODE (objc_implementation_context)
7263 == CATEGORY_IMPLEMENTATION_TYPE)
7264 warning (0, "incomplete implementation of category %qs",
7265 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7266 first = 0;
7269 warning (0, "method definition for %<%c%s%> not found",
7270 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7273 chain = TREE_CHAIN (chain);
7276 return first;
7279 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7281 static int
7282 conforms_to_protocol (tree class, tree protocol)
7284 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7286 tree p = CLASS_PROTOCOL_LIST (class);
7287 while (p && TREE_VALUE (p) != protocol)
7288 p = TREE_CHAIN (p);
7290 if (!p)
7292 tree super = (CLASS_SUPER_NAME (class)
7293 ? lookup_interface (CLASS_SUPER_NAME (class))
7294 : NULL_TREE);
7295 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7296 if (!tmp)
7297 return 0;
7301 return 1;
7304 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7305 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7307 static int
7308 check_methods_accessible (tree chain, tree context, int mtype)
7310 int first = 1;
7311 tree list;
7312 tree base_context = context;
7314 while (chain)
7316 context = base_context;
7317 while (context)
7319 if (mtype == '+')
7320 list = CLASS_CLS_METHODS (context);
7321 else
7322 list = CLASS_NST_METHODS (context);
7324 if (lookup_method (list, chain))
7325 break;
7327 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7328 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7329 context = (CLASS_SUPER_NAME (context)
7330 ? lookup_interface (CLASS_SUPER_NAME (context))
7331 : NULL_TREE);
7333 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7334 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7335 context = (CLASS_NAME (context)
7336 ? lookup_interface (CLASS_NAME (context))
7337 : NULL_TREE);
7338 else
7339 abort ();
7342 if (context == NULL_TREE)
7344 if (first)
7346 if (TREE_CODE (objc_implementation_context)
7347 == CLASS_IMPLEMENTATION_TYPE)
7348 warning (0, "incomplete implementation of class %qs",
7349 IDENTIFIER_POINTER
7350 (CLASS_NAME (objc_implementation_context)));
7351 else if (TREE_CODE (objc_implementation_context)
7352 == CATEGORY_IMPLEMENTATION_TYPE)
7353 warning (0, "incomplete implementation of category %qs",
7354 IDENTIFIER_POINTER
7355 (CLASS_SUPER_NAME (objc_implementation_context)));
7356 first = 0;
7358 warning (0, "method definition for %<%c%s%> not found",
7359 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7362 chain = TREE_CHAIN (chain); /* next method... */
7364 return first;
7367 /* Check whether the current interface (accessible via
7368 'objc_implementation_context') actually implements protocol P, along
7369 with any protocols that P inherits. */
7371 static void
7372 check_protocol (tree p, const char *type, const char *name)
7374 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7376 int f1, f2;
7378 /* Ensure that all protocols have bodies! */
7379 if (warn_protocol)
7381 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7382 CLASS_CLS_METHODS (objc_implementation_context),
7383 '+');
7384 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7385 CLASS_NST_METHODS (objc_implementation_context),
7386 '-');
7388 else
7390 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7391 objc_implementation_context,
7392 '+');
7393 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7394 objc_implementation_context,
7395 '-');
7398 if (!f1 || !f2)
7399 warning (0, "%s %qs does not fully implement the %qs protocol",
7400 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7403 /* Check protocols recursively. */
7404 if (PROTOCOL_LIST (p))
7406 tree subs = PROTOCOL_LIST (p);
7407 tree super_class =
7408 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7410 while (subs)
7412 tree sub = TREE_VALUE (subs);
7414 /* If the superclass does not conform to the protocols
7415 inherited by P, then we must! */
7416 if (!super_class || !conforms_to_protocol (super_class, sub))
7417 check_protocol (sub, type, name);
7418 subs = TREE_CHAIN (subs);
7423 /* Check whether the current interface (accessible via
7424 'objc_implementation_context') actually implements the protocols listed
7425 in PROTO_LIST. */
7427 static void
7428 check_protocols (tree proto_list, const char *type, const char *name)
7430 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7432 tree p = TREE_VALUE (proto_list);
7434 check_protocol (p, type, name);
7438 /* Make sure that the class CLASS_NAME is defined
7439 CODE says which kind of thing CLASS_NAME ought to be.
7440 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7441 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7443 static tree
7444 start_class (enum tree_code code, tree class_name, tree super_name,
7445 tree protocol_list)
7447 tree class, decl;
7449 #ifdef OBJCPLUS
7450 if (current_namespace != global_namespace) {
7451 error ("Objective-C declarations may only appear in global scope");
7453 #endif /* OBJCPLUS */
7455 if (objc_implementation_context)
7457 warning (0, "%<@end%> missing in implementation context");
7458 finish_class (objc_implementation_context);
7459 objc_ivar_chain = NULL_TREE;
7460 objc_implementation_context = NULL_TREE;
7463 class = make_node (code);
7464 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7466 /* Check for existence of the super class, if one was specified. Note
7467 that we must have seen an @interface, not just a @class. If we
7468 are looking at a @compatibility_alias, traverse it first. */
7469 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7470 && super_name)
7472 tree super = objc_is_class_name (super_name);
7474 if (!super || !lookup_interface (super))
7476 error ("cannot find interface declaration for %qs, superclass of %qs",
7477 IDENTIFIER_POINTER (super ? super : super_name),
7478 IDENTIFIER_POINTER (class_name));
7479 super_name = NULL_TREE;
7481 else
7482 super_name = super;
7485 CLASS_NAME (class) = class_name;
7486 CLASS_SUPER_NAME (class) = super_name;
7487 CLASS_CLS_METHODS (class) = NULL_TREE;
7489 if (! objc_is_class_name (class_name)
7490 && (decl = lookup_name (class_name)))
7492 error ("%qs redeclared as different kind of symbol",
7493 IDENTIFIER_POINTER (class_name));
7494 error ("previous declaration of %q+D",
7495 decl);
7498 if (code == CLASS_IMPLEMENTATION_TYPE)
7501 tree chain;
7503 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7504 if (TREE_VALUE (chain) == class_name)
7506 error ("reimplementation of class %qs",
7507 IDENTIFIER_POINTER (class_name));
7508 return error_mark_node;
7510 implemented_classes = tree_cons (NULL_TREE, class_name,
7511 implemented_classes);
7514 /* Reset for multiple classes per file. */
7515 method_slot = 0;
7517 objc_implementation_context = class;
7519 /* Lookup the interface for this implementation. */
7521 if (!(implementation_template = lookup_interface (class_name)))
7523 warning (0, "cannot find interface declaration for %qs",
7524 IDENTIFIER_POINTER (class_name));
7525 add_class (implementation_template = objc_implementation_context,
7526 class_name);
7529 /* If a super class has been specified in the implementation,
7530 insure it conforms to the one specified in the interface. */
7532 if (super_name
7533 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7535 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7536 const char *const name =
7537 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7538 error ("conflicting super class name %qs",
7539 IDENTIFIER_POINTER (super_name));
7540 error ("previous declaration of %qs", name);
7543 else if (! super_name)
7545 CLASS_SUPER_NAME (objc_implementation_context)
7546 = CLASS_SUPER_NAME (implementation_template);
7550 else if (code == CLASS_INTERFACE_TYPE)
7552 if (lookup_interface (class_name))
7553 #ifdef OBJCPLUS
7554 error ("duplicate interface declaration for class %qs",
7555 #else
7556 warning (0, "duplicate interface declaration for class %qs",
7557 #endif
7558 IDENTIFIER_POINTER (class_name));
7559 else
7560 add_class (class, class_name);
7562 if (protocol_list)
7563 CLASS_PROTOCOL_LIST (class)
7564 = lookup_and_install_protocols (protocol_list);
7567 else if (code == CATEGORY_INTERFACE_TYPE)
7569 tree class_category_is_assoc_with;
7571 /* For a category, class_name is really the name of the class that
7572 the following set of methods will be associated with. We must
7573 find the interface so that can derive the objects template. */
7575 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7577 error ("cannot find interface declaration for %qs",
7578 IDENTIFIER_POINTER (class_name));
7579 exit (FATAL_EXIT_CODE);
7581 else
7582 add_category (class_category_is_assoc_with, class);
7584 if (protocol_list)
7585 CLASS_PROTOCOL_LIST (class)
7586 = lookup_and_install_protocols (protocol_list);
7589 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7591 /* Reset for multiple classes per file. */
7592 method_slot = 0;
7594 objc_implementation_context = class;
7596 /* For a category, class_name is really the name of the class that
7597 the following set of methods will be associated with. We must
7598 find the interface so that can derive the objects template. */
7600 if (!(implementation_template = lookup_interface (class_name)))
7602 error ("cannot find interface declaration for %qs",
7603 IDENTIFIER_POINTER (class_name));
7604 exit (FATAL_EXIT_CODE);
7607 return class;
7610 static tree
7611 continue_class (tree class)
7613 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7614 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7616 struct imp_entry *imp_entry;
7618 /* Check consistency of the instance variables. */
7620 if (CLASS_RAW_IVARS (class))
7621 check_ivars (implementation_template, class);
7623 /* code generation */
7625 #ifdef OBJCPLUS
7626 push_lang_context (lang_name_c);
7627 #endif
7629 build_private_template (implementation_template);
7630 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7631 objc_instance_type = build_pointer_type (uprivate_record);
7633 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7635 imp_entry->next = imp_list;
7636 imp_entry->imp_context = class;
7637 imp_entry->imp_template = implementation_template;
7639 synth_forward_declarations ();
7640 imp_entry->class_decl = UOBJC_CLASS_decl;
7641 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7642 imp_entry->has_cxx_cdtors = 0;
7644 /* Append to front and increment count. */
7645 imp_list = imp_entry;
7646 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7647 imp_count++;
7648 else
7649 cat_count++;
7651 #ifdef OBJCPLUS
7652 pop_lang_context ();
7653 #endif /* OBJCPLUS */
7655 return get_class_ivars (implementation_template, true);
7658 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7660 #ifdef OBJCPLUS
7661 push_lang_context (lang_name_c);
7662 #endif /* OBJCPLUS */
7664 build_private_template (class);
7666 #ifdef OBJCPLUS
7667 pop_lang_context ();
7668 #endif /* OBJCPLUS */
7670 return NULL_TREE;
7673 else
7674 return error_mark_node;
7677 /* This is called once we see the "@end" in an interface/implementation. */
7679 static void
7680 finish_class (tree class)
7682 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7684 /* All code generation is done in finish_objc. */
7686 if (implementation_template != objc_implementation_context)
7688 /* Ensure that all method listed in the interface contain bodies. */
7689 check_methods (CLASS_CLS_METHODS (implementation_template),
7690 CLASS_CLS_METHODS (objc_implementation_context), '+');
7691 check_methods (CLASS_NST_METHODS (implementation_template),
7692 CLASS_NST_METHODS (objc_implementation_context), '-');
7694 if (CLASS_PROTOCOL_LIST (implementation_template))
7695 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7696 "class",
7697 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7701 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7703 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7705 if (category)
7707 /* Ensure all method listed in the interface contain bodies. */
7708 check_methods (CLASS_CLS_METHODS (category),
7709 CLASS_CLS_METHODS (objc_implementation_context), '+');
7710 check_methods (CLASS_NST_METHODS (category),
7711 CLASS_NST_METHODS (objc_implementation_context), '-');
7713 if (CLASS_PROTOCOL_LIST (category))
7714 check_protocols (CLASS_PROTOCOL_LIST (category),
7715 "category",
7716 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7721 static tree
7722 add_protocol (tree protocol)
7724 /* Put protocol on list in reverse order. */
7725 TREE_CHAIN (protocol) = protocol_chain;
7726 protocol_chain = protocol;
7727 return protocol_chain;
7730 static tree
7731 lookup_protocol (tree ident)
7733 tree chain;
7735 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7736 if (ident == PROTOCOL_NAME (chain))
7737 return chain;
7739 return NULL_TREE;
7742 /* This function forward declares the protocols named by NAMES. If
7743 they are already declared or defined, the function has no effect. */
7745 void
7746 objc_declare_protocols (tree names)
7748 tree list;
7750 #ifdef OBJCPLUS
7751 if (current_namespace != global_namespace) {
7752 error ("Objective-C declarations may only appear in global scope");
7754 #endif /* OBJCPLUS */
7756 for (list = names; list; list = TREE_CHAIN (list))
7758 tree name = TREE_VALUE (list);
7760 if (lookup_protocol (name) == NULL_TREE)
7762 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7764 TYPE_LANG_SLOT_1 (protocol)
7765 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7766 PROTOCOL_NAME (protocol) = name;
7767 PROTOCOL_LIST (protocol) = NULL_TREE;
7768 add_protocol (protocol);
7769 PROTOCOL_DEFINED (protocol) = 0;
7770 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7775 static tree
7776 start_protocol (enum tree_code code, tree name, tree list)
7778 tree protocol;
7780 #ifdef OBJCPLUS
7781 if (current_namespace != global_namespace) {
7782 error ("Objective-C declarations may only appear in global scope");
7784 #endif /* OBJCPLUS */
7786 protocol = lookup_protocol (name);
7788 if (!protocol)
7790 protocol = make_node (code);
7791 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7793 PROTOCOL_NAME (protocol) = name;
7794 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7795 add_protocol (protocol);
7796 PROTOCOL_DEFINED (protocol) = 1;
7797 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7799 check_protocol_recursively (protocol, list);
7801 else if (! PROTOCOL_DEFINED (protocol))
7803 PROTOCOL_DEFINED (protocol) = 1;
7804 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7806 check_protocol_recursively (protocol, list);
7808 else
7810 warning (0, "duplicate declaration for protocol %qs",
7811 IDENTIFIER_POINTER (name));
7813 return protocol;
7817 /* "Encode" a data type into a string, which grows in util_obstack.
7818 ??? What is the FORMAT? Someone please document this! */
7820 static void
7821 encode_type_qualifiers (tree declspecs)
7823 tree spec;
7825 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7827 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7828 obstack_1grow (&util_obstack, 'n');
7829 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7830 obstack_1grow (&util_obstack, 'N');
7831 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7832 obstack_1grow (&util_obstack, 'o');
7833 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7834 obstack_1grow (&util_obstack, 'O');
7835 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7836 obstack_1grow (&util_obstack, 'R');
7837 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7838 obstack_1grow (&util_obstack, 'V');
7842 /* Encode a pointer type. */
7844 static void
7845 encode_pointer (tree type, int curtype, int format)
7847 tree pointer_to = TREE_TYPE (type);
7849 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7851 if (OBJC_TYPE_NAME (pointer_to)
7852 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7854 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7856 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7858 obstack_1grow (&util_obstack, '@');
7859 return;
7861 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7862 && TYPE_OBJC_INTERFACE (pointer_to))
7864 if (generating_instance_variables)
7866 obstack_1grow (&util_obstack, '@');
7867 obstack_1grow (&util_obstack, '"');
7868 obstack_grow (&util_obstack, name, strlen (name));
7869 obstack_1grow (&util_obstack, '"');
7870 return;
7872 else
7874 obstack_1grow (&util_obstack, '@');
7875 return;
7878 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7880 obstack_1grow (&util_obstack, '#');
7881 return;
7883 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7885 obstack_1grow (&util_obstack, ':');
7886 return;
7890 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7891 && TYPE_MODE (pointer_to) == QImode)
7893 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7894 ? OBJC_TYPE_NAME (pointer_to)
7895 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7897 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7899 /* It appears that "r*" means "const char *" rather than
7900 "char *const". */
7901 if (TYPE_READONLY (pointer_to))
7902 obstack_1grow (&util_obstack, 'r');
7904 obstack_1grow (&util_obstack, '*');
7905 return;
7909 /* We have a type that does not get special treatment. */
7911 /* NeXT extension */
7912 obstack_1grow (&util_obstack, '^');
7913 encode_type (pointer_to, curtype, format);
7916 static void
7917 encode_array (tree type, int curtype, int format)
7919 tree an_int_cst = TYPE_SIZE (type);
7920 tree array_of = TREE_TYPE (type);
7921 char buffer[40];
7923 /* An incomplete array is treated like a pointer. */
7924 if (an_int_cst == NULL)
7926 encode_pointer (type, curtype, format);
7927 return;
7930 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7931 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7932 else
7933 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7934 TREE_INT_CST_LOW (an_int_cst)
7935 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7937 obstack_grow (&util_obstack, buffer, strlen (buffer));
7938 encode_type (array_of, curtype, format);
7939 obstack_1grow (&util_obstack, ']');
7940 return;
7943 static void
7944 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7946 tree field = TYPE_FIELDS (type);
7948 for (; field; field = TREE_CHAIN (field))
7950 #ifdef OBJCPLUS
7951 /* C++ static members, and things that are not field at all,
7952 should not appear in the encoding. */
7953 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7954 continue;
7955 #endif
7957 /* Recursively encode fields of embedded base classes. */
7958 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7959 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7961 encode_aggregate_fields (TREE_TYPE (field),
7962 pointed_to, curtype, format);
7963 continue;
7966 if (generating_instance_variables && !pointed_to)
7968 tree fname = DECL_NAME (field);
7970 obstack_1grow (&util_obstack, '"');
7972 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7973 obstack_grow (&util_obstack,
7974 IDENTIFIER_POINTER (fname),
7975 strlen (IDENTIFIER_POINTER (fname)));
7977 obstack_1grow (&util_obstack, '"');
7980 encode_field_decl (field, curtype, format);
7984 static void
7985 encode_aggregate_within (tree type, int curtype, int format, int left,
7986 int right)
7988 tree name;
7989 /* NB: aggregates that are pointed to have slightly different encoding
7990 rules in that you never encode the names of instance variables. */
7991 int ob_size = obstack_object_size (&util_obstack);
7992 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7993 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7994 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7995 int inline_contents
7996 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7997 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7999 /* Traverse struct aliases; it is important to get the
8000 original struct and its tag name (if any). */
8001 type = TYPE_MAIN_VARIANT (type);
8002 name = OBJC_TYPE_NAME (type);
8003 /* Open parenth/bracket. */
8004 obstack_1grow (&util_obstack, left);
8006 /* Encode the struct/union tag name, or '?' if a tag was
8007 not provided. Typedef aliases do not qualify. */
8008 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8009 #ifdef OBJCPLUS
8010 /* Did this struct have a tag? */
8011 && !TYPE_WAS_ANONYMOUS (type)
8012 #endif
8014 obstack_grow (&util_obstack,
8015 IDENTIFIER_POINTER (name),
8016 strlen (IDENTIFIER_POINTER (name)));
8017 else
8018 obstack_1grow (&util_obstack, '?');
8020 /* Encode the types (and possibly names) of the inner fields,
8021 if required. */
8022 if (inline_contents)
8024 obstack_1grow (&util_obstack, '=');
8025 encode_aggregate_fields (type, pointed_to, curtype, format);
8027 /* Close parenth/bracket. */
8028 obstack_1grow (&util_obstack, right);
8031 static void
8032 encode_aggregate (tree type, int curtype, int format)
8034 enum tree_code code = TREE_CODE (type);
8036 switch (code)
8038 case RECORD_TYPE:
8040 encode_aggregate_within (type, curtype, format, '{', '}');
8041 break;
8043 case UNION_TYPE:
8045 encode_aggregate_within (type, curtype, format, '(', ')');
8046 break;
8049 case ENUMERAL_TYPE:
8050 obstack_1grow (&util_obstack, 'i');
8051 break;
8053 default:
8054 break;
8058 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8059 field type. */
8061 static void
8062 encode_next_bitfield (int width)
8064 char buffer[40];
8065 sprintf (buffer, "b%d", width);
8066 obstack_grow (&util_obstack, buffer, strlen (buffer));
8069 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8070 static void
8071 encode_type (tree type, int curtype, int format)
8073 enum tree_code code = TREE_CODE (type);
8074 char c;
8076 if (type == error_mark_node)
8077 return;
8079 if (TYPE_READONLY (type))
8080 obstack_1grow (&util_obstack, 'r');
8082 if (code == INTEGER_TYPE)
8084 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8086 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8087 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8088 case 32:
8089 if (type == long_unsigned_type_node
8090 || type == long_integer_type_node)
8091 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8092 else
8093 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8094 break;
8095 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8096 default: abort ();
8098 obstack_1grow (&util_obstack, c);
8101 else if (code == REAL_TYPE)
8103 /* Floating point types. */
8104 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8106 case 32: c = 'f'; break;
8107 case 64:
8108 case 96:
8109 case 128: c = 'd'; break;
8110 default: abort ();
8112 obstack_1grow (&util_obstack, c);
8115 else if (code == VOID_TYPE)
8116 obstack_1grow (&util_obstack, 'v');
8118 else if (code == BOOLEAN_TYPE)
8119 obstack_1grow (&util_obstack, 'B');
8121 else if (code == ARRAY_TYPE)
8122 encode_array (type, curtype, format);
8124 else if (code == POINTER_TYPE)
8125 encode_pointer (type, curtype, format);
8127 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8128 encode_aggregate (type, curtype, format);
8130 else if (code == FUNCTION_TYPE) /* '?' */
8131 obstack_1grow (&util_obstack, '?');
8133 else if (code == COMPLEX_TYPE)
8135 obstack_1grow (&util_obstack, 'j');
8136 encode_type (TREE_TYPE (type), curtype, format);
8140 static void
8141 encode_gnu_bitfield (int position, tree type, int size)
8143 enum tree_code code = TREE_CODE (type);
8144 char buffer[40];
8145 char charType = '?';
8147 if (code == INTEGER_TYPE)
8149 if (integer_zerop (TYPE_MIN_VALUE (type)))
8151 /* Unsigned integer types. */
8153 if (TYPE_MODE (type) == QImode)
8154 charType = 'C';
8155 else if (TYPE_MODE (type) == HImode)
8156 charType = 'S';
8157 else if (TYPE_MODE (type) == SImode)
8159 if (type == long_unsigned_type_node)
8160 charType = 'L';
8161 else
8162 charType = 'I';
8164 else if (TYPE_MODE (type) == DImode)
8165 charType = 'Q';
8168 else
8169 /* Signed integer types. */
8171 if (TYPE_MODE (type) == QImode)
8172 charType = 'c';
8173 else if (TYPE_MODE (type) == HImode)
8174 charType = 's';
8175 else if (TYPE_MODE (type) == SImode)
8177 if (type == long_integer_type_node)
8178 charType = 'l';
8179 else
8180 charType = 'i';
8183 else if (TYPE_MODE (type) == DImode)
8184 charType = 'q';
8187 else if (code == ENUMERAL_TYPE)
8188 charType = 'i';
8189 else
8190 abort ();
8192 sprintf (buffer, "b%d%c%d", position, charType, size);
8193 obstack_grow (&util_obstack, buffer, strlen (buffer));
8196 static void
8197 encode_field_decl (tree field_decl, int curtype, int format)
8199 tree type;
8201 #ifdef OBJCPLUS
8202 /* C++ static members, and things that are not fields at all,
8203 should not appear in the encoding. */
8204 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8205 return;
8206 #endif
8208 type = TREE_TYPE (field_decl);
8210 /* Generate the bitfield typing information, if needed. Note the difference
8211 between GNU and NeXT runtimes. */
8212 if (DECL_BIT_FIELD_TYPE (field_decl))
8214 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8216 if (flag_next_runtime)
8217 encode_next_bitfield (size);
8218 else
8219 encode_gnu_bitfield (int_bit_position (field_decl),
8220 DECL_BIT_FIELD_TYPE (field_decl), size);
8222 else
8223 encode_type (TREE_TYPE (field_decl), curtype, format);
8226 static GTY(()) tree objc_parmlist = NULL_TREE;
8228 /* Append PARM to a list of formal parameters of a method, making a necessary
8229 array-to-pointer adjustment along the way. */
8231 static void
8232 objc_push_parm (tree parm)
8234 bool relayout_needed = false;
8236 if (TREE_TYPE (parm) == error_mark_node)
8238 objc_parmlist = chainon (objc_parmlist, parm);
8239 return;
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 (const_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"