Create branch to syn ICI 2.0 with gcc mainline.
[official-gcc.git] / gcc / objc / objc-act.c
blobeac7ff02f0937de90b8abf12c83453cc0a8b625e
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #include "c-lang.h"
56 #endif
58 #include "c-common.h"
59 #include "c-pragma.h"
60 #include "flags.h"
61 #include "langhooks.h"
62 #include "objc-act.h"
63 #include "input.h"
64 #include "except.h"
65 #include "function.h"
66 #include "output.h"
67 #include "toplev.h"
68 #include "ggc.h"
69 #include "varray.h"
70 #include "debug.h"
71 #include "target.h"
72 #include "diagnostic.h"
73 #include "intl.h"
74 #include "cgraph.h"
75 #include "tree-iterator.h"
76 #include "libfuncs.h"
77 #include "hashtab.h"
78 #include "langhooks-def.h"
80 #define OBJC_VOID_AT_END void_list_node
82 static unsigned int should_call_super_dealloc = 0;
84 /* When building Objective-C++, we need in_late_binary_op. */
85 #ifdef OBJCPLUS
86 bool in_late_binary_op = false;
87 #endif /* OBJCPLUS */
89 /* When building Objective-C++, we are not linking against the C front-end
90 and so need to replicate the C tree-construction functions in some way. */
91 #ifdef OBJCPLUS
92 #define OBJCP_REMAP_FUNCTIONS
93 #include "objcp-decl.h"
94 #endif /* OBJCPLUS */
96 /* This is the default way of generating a method name. */
97 /* I am not sure it is really correct.
98 Perhaps there's a danger that it will make name conflicts
99 if method names contain underscores. -- rms. */
100 #ifndef OBJC_GEN_METHOD_LABEL
101 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
102 do { \
103 char *temp; \
104 sprintf ((BUF), "_%s_%s_%s_%s", \
105 ((IS_INST) ? "i" : "c"), \
106 (CLASS_NAME), \
107 ((CAT_NAME)? (CAT_NAME) : ""), \
108 (SEL_NAME)); \
109 for (temp = (BUF); *temp; temp++) \
110 if (*temp == ':') *temp = '_'; \
111 } while (0)
112 #endif
114 /* These need specifying. */
115 #ifndef OBJC_FORWARDING_STACK_OFFSET
116 #define OBJC_FORWARDING_STACK_OFFSET 0
117 #endif
119 #ifndef OBJC_FORWARDING_MIN_OFFSET
120 #define OBJC_FORWARDING_MIN_OFFSET 0
121 #endif
123 /* Set up for use of obstacks. */
125 #include "obstack.h"
127 /* This obstack is used to accumulate the encoding of a data type. */
128 static struct obstack util_obstack;
130 /* This points to the beginning of obstack contents, so we can free
131 the whole contents. */
132 char *util_firstobj;
134 /* The version identifies which language generation and runtime
135 the module (file) was compiled for, and is recorded in the
136 module descriptor. */
138 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
139 #define PROTOCOL_VERSION 2
141 /* (Decide if these can ever be validly changed.) */
142 #define OBJC_ENCODE_INLINE_DEFS 0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
145 /*** Private Interface (procedures) ***/
147 /* Used by compile_file. */
149 static void init_objc (void);
150 static void finish_objc (void);
152 /* Code generation. */
154 static tree objc_build_constructor (tree, tree);
155 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
156 static tree get_proto_encoding (tree);
157 static tree lookup_interface (tree);
158 static tree objc_add_static_instance (tree, tree);
160 static tree start_class (enum tree_code, tree, tree, tree);
161 static tree continue_class (tree);
162 static void finish_class (tree);
163 static void start_method_def (tree);
164 #ifdef OBJCPLUS
165 static void objc_start_function (tree, tree, tree, tree);
166 #else
167 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
168 #endif
169 static tree start_protocol (enum tree_code, tree, tree);
170 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
171 static tree objc_add_method (tree, tree, int);
172 static tree add_instance_variable (tree, int, tree);
173 static tree build_ivar_reference (tree);
174 static tree is_ivar (tree, tree);
176 static void build_objc_exception_stuff (void);
177 static void build_next_objc_exception_stuff (void);
179 /* We only need the following for ObjC; ObjC++ will use C++'s definition
180 of DERIVED_FROM_P. */
181 #ifndef OBJCPLUS
182 static bool objc_derived_from_p (tree, tree);
183 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
184 #endif
185 static void objc_xref_basetypes (tree, tree);
187 static void build_class_template (void);
188 static void build_selector_template (void);
189 static void build_category_template (void);
190 static void build_super_template (void);
191 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
192 static tree get_class_ivars (tree, bool);
193 static tree generate_protocol_list (tree);
194 static void build_protocol_reference (tree);
196 #ifdef OBJCPLUS
197 static void objc_generate_cxx_cdtors (void);
198 #endif
200 static const char *synth_id_with_class_suffix (const char *, tree);
202 /* Hash tables to manage the global pool of method prototypes. */
204 hash *nst_method_hash_list = 0;
205 hash *cls_method_hash_list = 0;
207 static hash hash_lookup (hash *, tree);
208 static tree lookup_method (tree, tree);
209 static tree lookup_method_static (tree, tree, int);
211 enum string_section
213 class_names, /* class, category, protocol, module names */
214 meth_var_names, /* method and variable names */
215 meth_var_types /* method and variable type descriptors */
218 static tree add_objc_string (tree, enum string_section);
219 static tree build_objc_string_decl (enum string_section);
220 static void build_selector_table_decl (void);
222 /* Protocol additions. */
224 static tree lookup_protocol (tree);
225 static tree lookup_and_install_protocols (tree);
227 /* Type encoding. */
229 static void encode_type_qualifiers (tree);
230 static void encode_type (tree, int, int);
231 static void encode_field_decl (tree, int, int);
233 #ifdef OBJCPLUS
234 static void really_start_method (tree, tree);
235 #else
236 static void really_start_method (tree, struct c_arg_info *);
237 #endif
238 static int comp_proto_with_proto (tree, tree, int);
239 static void objc_push_parm (tree);
240 #ifdef OBJCPLUS
241 static tree objc_get_parm_info (int);
242 #else
243 static struct c_arg_info *objc_get_parm_info (int);
244 #endif
246 /* Utilities for debugging and error diagnostics. */
248 static char *gen_type_name (tree);
249 static char *gen_type_name_0 (tree);
250 static char *gen_method_decl (tree);
251 static char *gen_declaration (tree);
253 /* Everything else. */
255 static tree create_field_decl (tree, const char *);
256 static void add_class_reference (tree);
257 static void build_protocol_template (void);
258 static tree encode_method_prototype (tree);
259 static void generate_classref_translation_entry (tree);
260 static void handle_class_ref (tree);
261 static void generate_struct_by_value_array (void)
262 ATTRIBUTE_NORETURN;
263 static void mark_referenced_methods (void);
264 static void generate_objc_image_info (void);
266 /*** Private Interface (data) ***/
268 /* Reserved tag definitions. */
270 #define OBJECT_TYPEDEF_NAME "id"
271 #define CLASS_TYPEDEF_NAME "Class"
273 #define TAG_OBJECT "objc_object"
274 #define TAG_CLASS "objc_class"
275 #define TAG_SUPER "objc_super"
276 #define TAG_SELECTOR "objc_selector"
278 #define UTAG_CLASS "_objc_class"
279 #define UTAG_IVAR "_objc_ivar"
280 #define UTAG_IVAR_LIST "_objc_ivar_list"
281 #define UTAG_METHOD "_objc_method"
282 #define UTAG_METHOD_LIST "_objc_method_list"
283 #define UTAG_CATEGORY "_objc_category"
284 #define UTAG_MODULE "_objc_module"
285 #define UTAG_SYMTAB "_objc_symtab"
286 #define UTAG_SUPER "_objc_super"
287 #define UTAG_SELECTOR "_objc_selector"
289 #define UTAG_PROTOCOL "_objc_protocol"
290 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
291 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
293 /* Note that the string object global name is only needed for the
294 NeXT runtime. */
295 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
297 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
299 static const char *TAG_GETCLASS;
300 static const char *TAG_GETMETACLASS;
301 static const char *TAG_MSGSEND;
302 static const char *TAG_MSGSENDSUPER;
303 /* The NeXT Objective-C messenger may have two extra entry points, for use
304 when returning a structure. */
305 static const char *TAG_MSGSEND_STRET;
306 static const char *TAG_MSGSENDSUPER_STRET;
307 static const char *default_constant_string_class_name;
309 /* Runtime metadata flags. */
310 #define CLS_FACTORY 0x0001L
311 #define CLS_META 0x0002L
312 #define CLS_HAS_CXX_STRUCTORS 0x2000L
314 #define OBJC_MODIFIER_STATIC 0x00000001
315 #define OBJC_MODIFIER_FINAL 0x00000002
316 #define OBJC_MODIFIER_PUBLIC 0x00000004
317 #define OBJC_MODIFIER_PRIVATE 0x00000008
318 #define OBJC_MODIFIER_PROTECTED 0x00000010
319 #define OBJC_MODIFIER_NATIVE 0x00000020
320 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
321 #define OBJC_MODIFIER_ABSTRACT 0x00000080
322 #define OBJC_MODIFIER_VOLATILE 0x00000100
323 #define OBJC_MODIFIER_TRANSIENT 0x00000200
324 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
326 /* NeXT-specific tags. */
328 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
329 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
330 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
331 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
332 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
333 #define TAG_EXCEPTIONMATCH "objc_exception_match"
334 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
335 #define TAG_SYNCENTER "objc_sync_enter"
336 #define TAG_SYNCEXIT "objc_sync_exit"
337 #define TAG_SETJMP "_setjmp"
338 #define UTAG_EXCDATA "_objc_exception_data"
340 #define TAG_ASSIGNIVAR "objc_assign_ivar"
341 #define TAG_ASSIGNGLOBAL "objc_assign_global"
342 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
344 /* Branch entry points. All that matters here are the addresses;
345 functions with these names do not really exist in libobjc. */
347 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
348 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
350 #define TAG_CXX_CONSTRUCT ".cxx_construct"
351 #define TAG_CXX_DESTRUCT ".cxx_destruct"
353 /* GNU-specific tags. */
355 #define TAG_EXECCLASS "__objc_exec_class"
356 #define TAG_GNUINIT "__objc_gnu_init"
358 /* Flags for lookup_method_static(). */
359 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
360 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
362 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
363 tree objc_global_trees[OCTI_MAX];
365 static void handle_impent (struct imp_entry *);
367 struct imp_entry *imp_list = 0;
368 int imp_count = 0; /* `@implementation' */
369 int cat_count = 0; /* `@category' */
371 enum tree_code objc_inherit_code;
372 int objc_public_flag;
374 /* Use to generate method labels. */
375 static int method_slot = 0;
377 #define BUFSIZE 1024
379 static char *errbuf; /* Buffer for error diagnostics */
381 /* Data imported from tree.c. */
383 extern enum debug_info_type write_symbols;
385 /* Data imported from toplev.c. */
387 extern const char *dump_base_name;
389 static int flag_typed_selectors;
391 /* Store all constructed constant strings in a hash table so that
392 they get uniqued properly. */
394 struct GTY(()) string_descriptor {
395 /* The literal argument . */
396 tree literal;
398 /* The resulting constant string. */
399 tree constructor;
402 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
404 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
405 struct GTY(()) volatilized_type {
406 tree type;
409 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
411 FILE *gen_declaration_file;
413 /* Tells "encode_pointer/encode_aggregate" whether we are generating
414 type descriptors for instance variables (as opposed to methods).
415 Type descriptors for instance variables contain more information
416 than methods (for static typing and embedded structures). */
418 static int generating_instance_variables = 0;
420 /* For building an objc struct. These may not be used when this file
421 is compiled as part of obj-c++. */
423 static bool objc_building_struct;
424 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
426 /* Start building a struct for objc. */
428 static tree
429 objc_start_struct (tree name)
431 gcc_assert (!objc_building_struct);
432 objc_building_struct = true;
433 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
436 /* Finish building a struct for objc. */
438 static tree
439 objc_finish_struct (tree type, tree fieldlist)
441 gcc_assert (objc_building_struct);
442 objc_building_struct = false;
443 return finish_struct (input_location, type, fieldlist, NULL_TREE,
444 objc_struct_info);
447 /* Some platforms pass small structures through registers versus
448 through an invisible pointer. Determine at what size structure is
449 the transition point between the two possibilities. */
451 static void
452 generate_struct_by_value_array (void)
454 tree type;
455 tree field_decl, field_decl_chain;
456 int i, j;
457 int aggregate_in_mem[32];
458 int found = 0;
460 /* Presumably no platform passes 32 byte structures in a register. */
461 for (i = 1; i < 32; i++)
463 char buffer[5];
465 /* Create an unnamed struct that has `i' character components */
466 type = objc_start_struct (NULL_TREE);
468 strcpy (buffer, "c1");
469 field_decl = create_field_decl (char_type_node,
470 buffer);
471 field_decl_chain = field_decl;
473 for (j = 1; j < i; j++)
475 sprintf (buffer, "c%d", j + 1);
476 field_decl = create_field_decl (char_type_node,
477 buffer);
478 chainon (field_decl_chain, field_decl);
480 objc_finish_struct (type, field_decl_chain);
482 aggregate_in_mem[i] = aggregate_value_p (type, 0);
483 if (!aggregate_in_mem[i])
484 found = 1;
487 /* We found some structures that are returned in registers instead of memory
488 so output the necessary data. */
489 if (found)
491 for (i = 31; i >= 0; i--)
492 if (!aggregate_in_mem[i])
493 break;
494 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
496 /* The first member of the structure is always 0 because we don't handle
497 structures with 0 members */
498 printf ("static int struct_forward_array[] = {\n 0");
500 for (j = 1; j <= i; j++)
501 printf (", %d", aggregate_in_mem[j]);
502 printf ("\n};\n");
505 exit (0);
508 bool
509 objc_init (void)
511 #ifdef OBJCPLUS
512 if (cxx_init () == false)
513 #else
514 if (c_objc_common_init () == false)
515 #endif
516 return false;
518 /* If gen_declaration desired, open the output file. */
519 if (flag_gen_declaration)
521 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
522 gen_declaration_file = fopen (dumpname, "w");
523 if (gen_declaration_file == 0)
524 fatal_error ("can't open %s: %m", dumpname);
525 free (dumpname);
528 if (flag_next_runtime)
530 TAG_GETCLASS = "objc_getClass";
531 TAG_GETMETACLASS = "objc_getMetaClass";
532 TAG_MSGSEND = "objc_msgSend";
533 TAG_MSGSENDSUPER = "objc_msgSendSuper";
534 TAG_MSGSEND_STRET = "objc_msgSend_stret";
535 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
536 default_constant_string_class_name = "NSConstantString";
538 else
540 TAG_GETCLASS = "objc_get_class";
541 TAG_GETMETACLASS = "objc_get_meta_class";
542 TAG_MSGSEND = "objc_msg_lookup";
543 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
544 /* GNU runtime does not provide special functions to support
545 structure-returning methods. */
546 default_constant_string_class_name = "NXConstantString";
547 flag_typed_selectors = 1;
550 init_objc ();
552 if (print_struct_values && !flag_compare_debug)
553 generate_struct_by_value_array ();
555 return true;
558 void
559 objc_finish_file (void)
561 mark_referenced_methods ();
563 #ifdef OBJCPLUS
564 /* We need to instantiate templates _before_ we emit ObjC metadata;
565 if we do not, some metadata (such as selectors) may go missing. */
566 at_eof = 1;
567 instantiate_pending_templates (0);
568 #endif
570 /* Finalize Objective-C runtime data. No need to generate tables
571 and code if only checking syntax, or if generating a PCH file. */
572 if (!flag_syntax_only && !pch_file)
573 finish_objc ();
575 if (gen_declaration_file)
576 fclose (gen_declaration_file);
579 /* Return the first occurrence of a method declaration corresponding
580 to sel_name in rproto_list. Search rproto_list recursively.
581 If is_class is 0, search for instance methods, otherwise for class
582 methods. */
583 static tree
584 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
585 int is_class)
587 tree rproto, p;
588 tree fnd = 0;
590 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
592 p = TREE_VALUE (rproto);
594 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
596 if ((fnd = lookup_method (is_class
597 ? PROTOCOL_CLS_METHODS (p)
598 : PROTOCOL_NST_METHODS (p), sel_name)))
600 else if (PROTOCOL_LIST (p))
601 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
602 sel_name, is_class);
604 else
606 ; /* An identifier...if we could not find a protocol. */
609 if (fnd)
610 return fnd;
613 return 0;
616 static tree
617 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
619 tree rproto, p;
621 /* Make sure the protocol is supported by the object on the rhs. */
622 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
624 tree fnd = 0;
625 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
627 p = TREE_VALUE (rproto);
629 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
631 if (lproto == p)
632 fnd = lproto;
634 else if (PROTOCOL_LIST (p))
635 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
638 if (fnd)
639 return fnd;
642 else
644 ; /* An identifier...if we could not find a protocol. */
647 return 0;
650 void
651 objc_start_class_interface (tree klass, tree super_class, tree protos)
653 objc_interface_context
654 = objc_ivar_context
655 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
656 objc_public_flag = 0;
659 void
660 objc_start_category_interface (tree klass, tree categ, tree protos)
662 objc_interface_context
663 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
664 objc_ivar_chain
665 = continue_class (objc_interface_context);
668 void
669 objc_start_protocol (tree name, tree protos)
671 objc_interface_context
672 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
675 void
676 objc_continue_interface (void)
678 objc_ivar_chain
679 = continue_class (objc_interface_context);
682 void
683 objc_finish_interface (void)
685 finish_class (objc_interface_context);
686 objc_interface_context = NULL_TREE;
689 void
690 objc_start_class_implementation (tree klass, tree super_class)
692 objc_implementation_context
693 = objc_ivar_context
694 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
695 objc_public_flag = 0;
698 void
699 objc_start_category_implementation (tree klass, tree categ)
701 objc_implementation_context
702 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
703 objc_ivar_chain
704 = continue_class (objc_implementation_context);
707 void
708 objc_continue_implementation (void)
710 objc_ivar_chain
711 = continue_class (objc_implementation_context);
714 void
715 objc_finish_implementation (void)
717 #ifdef OBJCPLUS
718 if (flag_objc_call_cxx_cdtors)
719 objc_generate_cxx_cdtors ();
720 #endif
722 if (objc_implementation_context)
724 finish_class (objc_implementation_context);
725 objc_ivar_chain = NULL_TREE;
726 objc_implementation_context = NULL_TREE;
728 else
729 warning (0, "%<@end%> must appear in an @implementation context");
732 void
733 objc_set_visibility (int visibility)
735 objc_public_flag = visibility;
738 void
739 objc_set_method_type (enum tree_code type)
741 objc_inherit_code = (type == PLUS_EXPR
742 ? CLASS_METHOD_DECL
743 : INSTANCE_METHOD_DECL);
746 tree
747 objc_build_method_signature (tree rettype, tree selector,
748 tree optparms, bool ellipsis)
750 return build_method_decl (objc_inherit_code, rettype, selector,
751 optparms, ellipsis);
754 void
755 objc_add_method_declaration (tree decl)
757 if (!objc_interface_context)
758 fatal_error ("method declaration not in @interface context");
760 objc_add_method (objc_interface_context,
761 decl,
762 objc_inherit_code == CLASS_METHOD_DECL);
765 void
766 objc_start_method_definition (tree decl)
768 if (!objc_implementation_context)
769 fatal_error ("method definition not in @implementation context");
771 objc_add_method (objc_implementation_context,
772 decl,
773 objc_inherit_code == CLASS_METHOD_DECL);
774 start_method_def (decl);
777 void
778 objc_add_instance_variable (tree decl)
780 (void) add_instance_variable (objc_ivar_context,
781 objc_public_flag,
782 decl);
785 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
786 an '@'. */
789 objc_is_reserved_word (tree ident)
791 unsigned char code = C_RID_CODE (ident);
793 return (OBJC_IS_AT_KEYWORD (code)
794 || code == RID_CLASS || code == RID_PUBLIC
795 || code == RID_PROTECTED || code == RID_PRIVATE
796 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
799 /* Return true if TYPE is 'id'. */
801 static bool
802 objc_is_object_id (tree type)
804 return OBJC_TYPE_NAME (type) == objc_object_id;
807 static bool
808 objc_is_class_id (tree type)
810 return OBJC_TYPE_NAME (type) == objc_class_id;
813 /* Construct a C struct with same name as KLASS, a base struct with tag
814 SUPER_NAME (if any), and FIELDS indicated. */
816 static tree
817 objc_build_struct (tree klass, tree fields, tree super_name)
819 tree name = CLASS_NAME (klass);
820 tree s = objc_start_struct (name);
821 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
822 tree t, objc_info = NULL_TREE;
824 if (super)
826 /* Prepend a packed variant of the base class into the layout. This
827 is necessary to preserve ObjC ABI compatibility. */
828 tree base = build_decl (input_location,
829 FIELD_DECL, NULL_TREE, super);
830 tree field = TYPE_FIELDS (super);
832 while (field && TREE_CHAIN (field)
833 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
834 field = TREE_CHAIN (field);
836 /* For ObjC ABI purposes, the "packed" size of a base class is
837 the sum of the offset and the size (in bits) of the last field
838 in the class. */
839 DECL_SIZE (base)
840 = (field && TREE_CODE (field) == FIELD_DECL
841 ? size_binop (PLUS_EXPR,
842 size_binop (PLUS_EXPR,
843 size_binop
844 (MULT_EXPR,
845 convert (bitsizetype,
846 DECL_FIELD_OFFSET (field)),
847 bitsize_int (BITS_PER_UNIT)),
848 DECL_FIELD_BIT_OFFSET (field)),
849 DECL_SIZE (field))
850 : bitsize_zero_node);
851 DECL_SIZE_UNIT (base)
852 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
853 size_int (BITS_PER_UNIT));
854 DECL_ARTIFICIAL (base) = 1;
855 DECL_ALIGN (base) = 1;
856 DECL_FIELD_CONTEXT (base) = s;
857 #ifdef OBJCPLUS
858 DECL_FIELD_IS_BASE (base) = 1;
860 if (fields)
861 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
862 #endif /* are following the ObjC ABI here. */
863 TREE_CHAIN (base) = fields;
864 fields = base;
867 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
868 in all variants of this RECORD_TYPE to be clobbered, but it is therein
869 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
870 Hence, we must squirrel away the ObjC-specific information before calling
871 finish_struct(), and then reinstate it afterwards. */
873 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
874 objc_info
875 = chainon (objc_info,
876 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
878 /* Point the struct at its related Objective-C class. */
879 INIT_TYPE_OBJC_INFO (s);
880 TYPE_OBJC_INTERFACE (s) = klass;
882 s = objc_finish_struct (s, fields);
884 for (t = TYPE_NEXT_VARIANT (s); t;
885 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
887 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
888 /* Replace the IDENTIFIER_NODE with an actual @interface. */
889 TYPE_OBJC_INTERFACE (t) = klass;
892 /* Use TYPE_BINFO structures to point at the super class, if any. */
893 objc_xref_basetypes (s, super);
895 /* Mark this struct as a class template. */
896 CLASS_STATIC_TEMPLATE (klass) = s;
898 return s;
901 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
902 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
903 process. */
904 static tree
905 objc_build_volatilized_type (tree type)
907 tree t;
909 /* Check if we have not constructed the desired variant already. */
910 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
912 /* The type qualifiers must (obviously) match up. */
913 if (!TYPE_VOLATILE (t)
914 || (TYPE_READONLY (t) != TYPE_READONLY (type))
915 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
916 continue;
918 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
919 info, if any) must match up. */
920 if (POINTER_TYPE_P (t)
921 && (TREE_TYPE (t) != TREE_TYPE (type)))
922 continue;
924 /* Everything matches up! */
925 return t;
928 /* Ok, we could not re-use any of the pre-existing variants. Create
929 a new one. */
930 t = build_variant_type_copy (type);
931 TYPE_VOLATILE (t) = 1;
933 /* Set up the canonical type information. */
934 if (TYPE_STRUCTURAL_EQUALITY_P (type))
935 SET_TYPE_STRUCTURAL_EQUALITY (t);
936 else if (TYPE_CANONICAL (type) != type)
937 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
938 else
939 TYPE_CANONICAL (t) = t;
941 return t;
944 /* Mark DECL as being 'volatile' for purposes of Darwin
945 _setjmp()/_longjmp() exception handling. Called from
946 objc_mark_locals_volatile(). */
947 void
948 objc_volatilize_decl (tree decl)
950 /* Do not mess with variables that are 'static' or (already)
951 'volatile'. */
952 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
953 && (TREE_CODE (decl) == VAR_DECL
954 || TREE_CODE (decl) == PARM_DECL))
956 tree t = TREE_TYPE (decl);
957 struct volatilized_type key;
958 void **loc;
960 t = objc_build_volatilized_type (t);
961 key.type = t;
962 loc = htab_find_slot (volatilized_htab, &key, INSERT);
964 if (!*loc)
966 *loc = ggc_alloc (sizeof (key));
967 ((struct volatilized_type *) *loc)->type = t;
970 TREE_TYPE (decl) = t;
971 TREE_THIS_VOLATILE (decl) = 1;
972 TREE_SIDE_EFFECTS (decl) = 1;
973 DECL_REGISTER (decl) = 0;
974 #ifndef OBJCPLUS
975 C_DECL_REGISTER (decl) = 0;
976 #endif
980 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
981 (including its categories and superclasses) or by object type TYP.
982 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
984 static bool
985 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
987 bool class_type = (cls != NULL_TREE);
989 while (cls)
991 tree c;
993 /* Check protocols adopted by the class and its categories. */
994 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
996 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
997 return true;
1000 /* Repeat for superclasses. */
1001 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1004 /* Check for any protocols attached directly to the object type. */
1005 if (TYPE_HAS_OBJC_INFO (typ))
1007 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1008 return true;
1011 if (warn)
1013 *errbuf = 0;
1014 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1015 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1016 "implementing" a given protocol, since they do not have an
1017 implementation. */
1018 if (class_type)
1019 warning (0, "class %qs does not implement the %qE protocol",
1020 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1021 else
1022 warning (0, "type %qs does not conform to the %qE protocol",
1023 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1026 return false;
1029 /* Check if class RCLS and instance struct type RTYP conform to at least the
1030 same protocols that LCLS and LTYP conform to. */
1032 static bool
1033 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1035 tree p;
1036 bool have_lproto = false;
1038 while (lcls)
1040 /* NB: We do _not_ look at categories defined for LCLS; these may or
1041 may not get loaded in, and therefore it is unreasonable to require
1042 that RCLS/RTYP must implement any of their protocols. */
1043 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1045 have_lproto = true;
1047 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1048 return warn;
1051 /* Repeat for superclasses. */
1052 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1055 /* Check for any protocols attached directly to the object type. */
1056 if (TYPE_HAS_OBJC_INFO (ltyp))
1058 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1060 have_lproto = true;
1062 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1063 return warn;
1067 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1068 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1069 away with simply checking for 'id' or 'Class' (!RCLS), since this
1070 routine will not get called in other cases. */
1071 return have_lproto || (rcls != NULL_TREE);
1074 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1075 an instance of RTYP to an instance of LTYP or to compare the two
1076 (if ARGNO is equal to -3), per ObjC type system rules. Before
1077 returning 'true', this routine may issue warnings related to, e.g.,
1078 protocol conformance. When returning 'false', the routine must
1079 produce absolutely no warnings; the C or C++ front-end will do so
1080 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1081 the routine must return 'false'.
1083 The ARGNO parameter is encoded as follows:
1084 >= 1 Parameter number (CALLEE contains function being called);
1085 0 Return value;
1086 -1 Assignment;
1087 -2 Initialization;
1088 -3 Comparison (LTYP and RTYP may match in either direction). */
1090 bool
1091 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1093 tree lcls, rcls, lproto, rproto;
1094 bool pointers_compatible;
1096 /* We must be dealing with pointer types */
1097 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1098 return false;
1102 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1103 rtyp = TREE_TYPE (rtyp);
1105 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1107 /* Past this point, we are only interested in ObjC class instances,
1108 or 'id' or 'Class'. */
1109 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1110 return false;
1112 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1113 && !TYPE_HAS_OBJC_INFO (ltyp))
1114 return false;
1116 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1117 && !TYPE_HAS_OBJC_INFO (rtyp))
1118 return false;
1120 /* Past this point, we are committed to returning 'true' to the caller.
1121 However, we can still warn about type and/or protocol mismatches. */
1123 if (TYPE_HAS_OBJC_INFO (ltyp))
1125 lcls = TYPE_OBJC_INTERFACE (ltyp);
1126 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1128 else
1129 lcls = lproto = NULL_TREE;
1131 if (TYPE_HAS_OBJC_INFO (rtyp))
1133 rcls = TYPE_OBJC_INTERFACE (rtyp);
1134 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1136 else
1137 rcls = rproto = NULL_TREE;
1139 /* If we could not find an @interface declaration, we must have
1140 only seen a @class declaration; for purposes of type comparison,
1141 treat it as a stand-alone (root) class. */
1143 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1144 lcls = NULL_TREE;
1146 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1147 rcls = NULL_TREE;
1149 /* If either type is an unqualified 'id', we're done. */
1150 if ((!lproto && objc_is_object_id (ltyp))
1151 || (!rproto && objc_is_object_id (rtyp)))
1152 return true;
1154 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1156 /* If the underlying types are the same, and at most one of them has
1157 a protocol list, we do not need to issue any diagnostics. */
1158 if (pointers_compatible && (!lproto || !rproto))
1159 return true;
1161 /* If exactly one of the types is 'Class', issue a diagnostic; any
1162 exceptions of this rule have already been handled. */
1163 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1164 pointers_compatible = false;
1165 /* Otherwise, check for inheritance relations. */
1166 else
1168 if (!pointers_compatible)
1169 pointers_compatible
1170 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1172 if (!pointers_compatible)
1173 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1175 if (!pointers_compatible && argno == -3)
1176 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1179 /* If the pointers match modulo protocols, check for protocol conformance
1180 mismatches. */
1181 if (pointers_compatible)
1183 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1184 argno != -3);
1186 if (!pointers_compatible && argno == -3)
1187 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1188 argno != -3);
1191 if (!pointers_compatible)
1193 /* NB: For the time being, we shall make our warnings look like their
1194 C counterparts. In the future, we may wish to make them more
1195 ObjC-specific. */
1196 switch (argno)
1198 case -3:
1199 warning (0, "comparison of distinct Objective-C types lacks a cast");
1200 break;
1202 case -2:
1203 warning (0, "initialization from distinct Objective-C type");
1204 break;
1206 case -1:
1207 warning (0, "assignment from distinct Objective-C type");
1208 break;
1210 case 0:
1211 warning (0, "distinct Objective-C type in return");
1212 break;
1214 default:
1215 warning (0, "passing argument %d of %qE from distinct "
1216 "Objective-C type", argno, callee);
1217 break;
1221 return true;
1224 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1225 lives in the volatilized hash table, ignore the 'volatile' bit when
1226 making the comparison. */
1228 bool
1229 objc_type_quals_match (tree ltyp, tree rtyp)
1231 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1232 struct volatilized_type key;
1234 key.type = ltyp;
1236 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1237 lquals &= ~TYPE_QUAL_VOLATILE;
1239 key.type = rtyp;
1241 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1242 rquals &= ~TYPE_QUAL_VOLATILE;
1244 return (lquals == rquals);
1247 #ifndef OBJCPLUS
1248 /* Determine if CHILD is derived from PARENT. The routine assumes that
1249 both parameters are RECORD_TYPEs, and is non-reflexive. */
1251 static bool
1252 objc_derived_from_p (tree parent, tree child)
1254 parent = TYPE_MAIN_VARIANT (parent);
1256 for (child = TYPE_MAIN_VARIANT (child);
1257 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1259 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1260 (TYPE_BINFO (child),
1261 0)));
1263 if (child == parent)
1264 return true;
1267 return false;
1269 #endif
1271 static tree
1272 objc_build_component_ref (tree datum, tree component)
1274 /* If COMPONENT is NULL, the caller is referring to the anonymous
1275 base class field. */
1276 if (!component)
1278 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1280 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1283 /* The 'build_component_ref' routine has been removed from the C++
1284 front-end, but 'finish_class_member_access_expr' seems to be
1285 a worthy substitute. */
1286 #ifdef OBJCPLUS
1287 return finish_class_member_access_expr (datum, component, false,
1288 tf_warning_or_error);
1289 #else
1290 return build_component_ref (input_location, datum, component);
1291 #endif
1294 /* Recursively copy inheritance information rooted at BINFO. To do this,
1295 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1297 static tree
1298 objc_copy_binfo (tree binfo)
1300 tree btype = BINFO_TYPE (binfo);
1301 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1302 tree base_binfo;
1303 int ix;
1305 BINFO_TYPE (binfo2) = btype;
1306 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1307 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1309 /* Recursively copy base binfos of BINFO. */
1310 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1312 tree base_binfo2 = objc_copy_binfo (base_binfo);
1314 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1315 BINFO_BASE_APPEND (binfo2, base_binfo2);
1318 return binfo2;
1321 /* Record superclass information provided in BASETYPE for ObjC class REF.
1322 This is loosely based on cp/decl.c:xref_basetypes(). */
1324 static void
1325 objc_xref_basetypes (tree ref, tree basetype)
1327 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1329 TYPE_BINFO (ref) = binfo;
1330 BINFO_OFFSET (binfo) = size_zero_node;
1331 BINFO_TYPE (binfo) = ref;
1333 if (basetype)
1335 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1337 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1338 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1339 BINFO_BASE_APPEND (binfo, base_binfo);
1340 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1344 static hashval_t
1345 volatilized_hash (const void *ptr)
1347 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1349 return htab_hash_pointer(typ);
1352 static int
1353 volatilized_eq (const void *ptr1, const void *ptr2)
1355 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1356 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1358 return typ1 == typ2;
1361 /* Called from finish_decl. */
1363 void
1364 objc_check_decl (tree decl)
1366 tree type = TREE_TYPE (decl);
1368 if (TREE_CODE (type) != RECORD_TYPE)
1369 return;
1370 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1371 error ("statically allocated instance of Objective-C class %qE",
1372 type);
1375 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1376 either name an Objective-C class, or refer to the special 'id' or 'Class'
1377 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1379 tree
1380 objc_get_protocol_qualified_type (tree interface, tree protocols)
1382 /* If INTERFACE is not provided, default to 'id'. */
1383 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1384 bool is_ptr = (type != NULL_TREE);
1386 if (!is_ptr)
1388 type = objc_is_class_name (interface);
1390 if (type)
1391 type = xref_tag (RECORD_TYPE, type);
1392 else
1393 return interface;
1396 if (protocols)
1398 type = build_variant_type_copy (type);
1400 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1401 to the pointee. */
1402 if (is_ptr)
1404 tree orig_pointee_type = TREE_TYPE (type);
1405 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1407 /* Set up the canonical type information. */
1408 TYPE_CANONICAL (type)
1409 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1411 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1412 type = TREE_TYPE (type);
1415 /* Look up protocols and install in lang specific list. */
1416 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1417 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1419 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1420 return the pointer to the new pointee variant. */
1421 if (is_ptr)
1422 type = TYPE_POINTER_TO (type);
1423 else
1424 TYPE_OBJC_INTERFACE (type)
1425 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1428 return type;
1431 /* Check for circular dependencies in protocols. The arguments are
1432 PROTO, the protocol to check, and LIST, a list of protocol it
1433 conforms to. */
1435 static void
1436 check_protocol_recursively (tree proto, tree list)
1438 tree p;
1440 for (p = list; p; p = TREE_CHAIN (p))
1442 tree pp = TREE_VALUE (p);
1444 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1445 pp = lookup_protocol (pp);
1447 if (pp == proto)
1448 fatal_error ("protocol %qE has circular dependency",
1449 PROTOCOL_NAME (pp));
1450 if (pp)
1451 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1455 /* Look up PROTOCOLS, and return a list of those that are found.
1456 If none are found, return NULL. */
1458 static tree
1459 lookup_and_install_protocols (tree protocols)
1461 tree proto;
1462 tree return_value = NULL_TREE;
1464 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1466 tree ident = TREE_VALUE (proto);
1467 tree p = lookup_protocol (ident);
1469 if (p)
1470 return_value = chainon (return_value,
1471 build_tree_list (NULL_TREE, p));
1472 else if (ident != error_mark_node)
1473 error ("cannot find protocol declaration for %qE",
1474 ident);
1477 return return_value;
1480 /* Create a declaration for field NAME of a given TYPE. */
1482 static tree
1483 create_field_decl (tree type, const char *name)
1485 return build_decl (input_location,
1486 FIELD_DECL, get_identifier (name), type);
1489 /* Create a global, static declaration for variable NAME of a given TYPE. The
1490 finish_var_decl() routine will need to be called on it afterwards. */
1492 static tree
1493 start_var_decl (tree type, const char *name)
1495 tree var = build_decl (input_location,
1496 VAR_DECL, get_identifier (name), type);
1498 TREE_STATIC (var) = 1;
1499 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1500 DECL_IGNORED_P (var) = 1;
1501 DECL_ARTIFICIAL (var) = 1;
1502 DECL_CONTEXT (var) = NULL_TREE;
1503 #ifdef OBJCPLUS
1504 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1505 #endif
1507 return var;
1510 /* Finish off the variable declaration created by start_var_decl(). */
1512 static void
1513 finish_var_decl (tree var, tree initializer)
1515 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
1516 /* Ensure that the variable actually gets output. */
1517 mark_decl_referenced (var);
1518 /* Mark the decl to avoid "defined but not used" warning. */
1519 TREE_USED (var) = 1;
1522 /* Find the decl for the constant string class reference. This is only
1523 used for the NeXT runtime. */
1525 static tree
1526 setup_string_decl (void)
1528 char *name;
1529 size_t length;
1531 /* %s in format will provide room for terminating null */
1532 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1533 + strlen (constant_string_class_name);
1534 name = XNEWVEC (char, length);
1535 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1536 constant_string_class_name);
1537 constant_string_global_id = get_identifier (name);
1538 string_class_decl = lookup_name (constant_string_global_id);
1540 return string_class_decl;
1543 /* Purpose: "play" parser, creating/installing representations
1544 of the declarations that are required by Objective-C.
1546 Model:
1548 type_spec--------->sc_spec
1549 (tree_list) (tree_list)
1552 identifier_node identifier_node */
1554 static void
1555 synth_module_prologue (void)
1557 tree type;
1558 enum debug_info_type save_write_symbols = write_symbols;
1559 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1561 /* Suppress outputting debug symbols, because
1562 dbxout_init hasn't been called yet. */
1563 write_symbols = NO_DEBUG;
1564 debug_hooks = &do_nothing_debug_hooks;
1566 #ifdef OBJCPLUS
1567 push_lang_context (lang_name_c); /* extern "C" */
1568 #endif
1570 /* The following are also defined in <objc/objc.h> and friends. */
1572 objc_object_id = get_identifier (TAG_OBJECT);
1573 objc_class_id = get_identifier (TAG_CLASS);
1575 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1576 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1578 objc_object_type = build_pointer_type (objc_object_reference);
1579 objc_class_type = build_pointer_type (objc_class_reference);
1581 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1582 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1584 /* Declare the 'id' and 'Class' typedefs. */
1586 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1587 TYPE_DECL,
1588 objc_object_name,
1589 objc_object_type));
1590 TREE_NO_WARNING (type) = 1;
1591 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1592 TYPE_DECL,
1593 objc_class_name,
1594 objc_class_type));
1595 TREE_NO_WARNING (type) = 1;
1597 /* Forward-declare '@interface Protocol'. */
1599 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1600 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1601 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1602 type));
1604 /* Declare type of selector-objects that represent an operation name. */
1606 if (flag_next_runtime)
1607 /* `struct objc_selector *' */
1608 objc_selector_type
1609 = build_pointer_type (xref_tag (RECORD_TYPE,
1610 get_identifier (TAG_SELECTOR)));
1611 else
1612 /* `const struct objc_selector *' */
1613 objc_selector_type
1614 = build_pointer_type
1615 (build_qualified_type (xref_tag (RECORD_TYPE,
1616 get_identifier (TAG_SELECTOR)),
1617 TYPE_QUAL_CONST));
1619 /* Declare receiver type used for dispatching messages to 'super'. */
1621 /* `struct objc_super *' */
1622 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1623 get_identifier (TAG_SUPER)));
1625 /* Declare pointers to method and ivar lists. */
1626 objc_method_list_ptr = build_pointer_type
1627 (xref_tag (RECORD_TYPE,
1628 get_identifier (UTAG_METHOD_LIST)));
1629 objc_method_proto_list_ptr
1630 = build_pointer_type (xref_tag (RECORD_TYPE,
1631 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1632 objc_ivar_list_ptr = build_pointer_type
1633 (xref_tag (RECORD_TYPE,
1634 get_identifier (UTAG_IVAR_LIST)));
1636 /* TREE_NOTHROW is cleared for the message-sending functions,
1637 because the function that gets called can throw in Obj-C++, or
1638 could itself call something that can throw even in Obj-C. */
1640 if (flag_next_runtime)
1642 /* NB: In order to call one of the ..._stret (struct-returning)
1643 functions, the function *MUST* first be cast to a signature that
1644 corresponds to the actual ObjC method being invoked. This is
1645 what is done by the build_objc_method_call() routine below. */
1647 /* id objc_msgSend (id, SEL, ...); */
1648 /* id objc_msgSendNonNil (id, SEL, ...); */
1649 /* id objc_msgSend_stret (id, SEL, ...); */
1650 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1651 type
1652 = build_function_type (objc_object_type,
1653 tree_cons (NULL_TREE, objc_object_type,
1654 tree_cons (NULL_TREE, objc_selector_type,
1655 NULL_TREE)));
1656 umsg_decl = add_builtin_function (TAG_MSGSEND,
1657 type, 0, NOT_BUILT_IN,
1658 NULL, NULL_TREE);
1659 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1660 type, 0, NOT_BUILT_IN,
1661 NULL, NULL_TREE);
1662 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1663 type, 0, NOT_BUILT_IN,
1664 NULL, NULL_TREE);
1665 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1666 type, 0, NOT_BUILT_IN,
1667 NULL, NULL_TREE);
1669 /* These can throw, because the function that gets called can throw
1670 in Obj-C++, or could itself call something that can throw even
1671 in Obj-C. */
1672 TREE_NOTHROW (umsg_decl) = 0;
1673 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1674 TREE_NOTHROW (umsg_stret_decl) = 0;
1675 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1677 /* id objc_msgSend_Fast (id, SEL, ...)
1678 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1679 #ifdef OFFS_MSGSEND_FAST
1680 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1681 type, 0, NOT_BUILT_IN,
1682 NULL, NULL_TREE);
1683 TREE_NOTHROW (umsg_fast_decl) = 0;
1684 DECL_ATTRIBUTES (umsg_fast_decl)
1685 = tree_cons (get_identifier ("hard_coded_address"),
1686 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1687 NULL_TREE);
1688 #else
1689 /* No direct dispatch available. */
1690 umsg_fast_decl = umsg_decl;
1691 #endif
1693 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1694 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1695 type
1696 = build_function_type (objc_object_type,
1697 tree_cons (NULL_TREE, objc_super_type,
1698 tree_cons (NULL_TREE, objc_selector_type,
1699 NULL_TREE)));
1700 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1701 type, 0, NOT_BUILT_IN,
1702 NULL, NULL_TREE);
1703 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1704 type, 0, NOT_BUILT_IN, 0,
1705 NULL_TREE);
1706 TREE_NOTHROW (umsg_super_decl) = 0;
1707 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1709 else
1711 /* GNU runtime messenger entry points. */
1713 /* typedef id (*IMP)(id, SEL, ...); */
1714 tree IMP_type
1715 = build_pointer_type
1716 (build_function_type (objc_object_type,
1717 tree_cons (NULL_TREE, objc_object_type,
1718 tree_cons (NULL_TREE, objc_selector_type,
1719 NULL_TREE))));
1721 /* IMP objc_msg_lookup (id, SEL); */
1722 type
1723 = build_function_type (IMP_type,
1724 tree_cons (NULL_TREE, objc_object_type,
1725 tree_cons (NULL_TREE, objc_selector_type,
1726 OBJC_VOID_AT_END)));
1727 umsg_decl = add_builtin_function (TAG_MSGSEND,
1728 type, 0, NOT_BUILT_IN,
1729 NULL, NULL_TREE);
1730 TREE_NOTHROW (umsg_decl) = 0;
1732 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1733 type
1734 = build_function_type (IMP_type,
1735 tree_cons (NULL_TREE, objc_super_type,
1736 tree_cons (NULL_TREE, objc_selector_type,
1737 OBJC_VOID_AT_END)));
1738 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1739 type, 0, NOT_BUILT_IN,
1740 NULL, NULL_TREE);
1741 TREE_NOTHROW (umsg_super_decl) = 0;
1743 /* The following GNU runtime entry point is called to initialize
1744 each module:
1746 __objc_exec_class (void *); */
1747 type
1748 = build_function_type (void_type_node,
1749 tree_cons (NULL_TREE, ptr_type_node,
1750 OBJC_VOID_AT_END));
1751 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1752 type, 0, NOT_BUILT_IN,
1753 NULL, NULL_TREE);
1756 /* id objc_getClass (const char *); */
1758 type = build_function_type (objc_object_type,
1759 tree_cons (NULL_TREE,
1760 const_string_type_node,
1761 OBJC_VOID_AT_END));
1763 objc_get_class_decl
1764 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1765 NULL, NULL_TREE);
1767 /* id objc_getMetaClass (const char *); */
1769 objc_get_meta_class_decl
1770 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1772 build_class_template ();
1773 build_super_template ();
1774 build_protocol_template ();
1775 build_category_template ();
1776 build_objc_exception_stuff ();
1778 if (flag_next_runtime)
1779 build_next_objc_exception_stuff ();
1781 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1783 if (! flag_next_runtime)
1784 build_selector_table_decl ();
1786 /* Forward declare constant_string_id and constant_string_type. */
1787 if (!constant_string_class_name)
1788 constant_string_class_name = default_constant_string_class_name;
1790 constant_string_id = get_identifier (constant_string_class_name);
1791 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1793 /* Pre-build the following entities - for speed/convenience. */
1794 self_id = get_identifier ("self");
1795 ucmd_id = get_identifier ("_cmd");
1797 #ifdef OBJCPLUS
1798 pop_lang_context ();
1799 #endif
1801 write_symbols = save_write_symbols;
1802 debug_hooks = save_hooks;
1805 /* Ensure that the ivar list for NSConstantString/NXConstantString
1806 (or whatever was specified via `-fconstant-string-class')
1807 contains fields at least as large as the following three, so that
1808 the runtime can stomp on them with confidence:
1810 struct STRING_OBJECT_CLASS_NAME
1812 Object isa;
1813 char *cString;
1814 unsigned int length;
1815 }; */
1817 static int
1818 check_string_class_template (void)
1820 tree field_decl = objc_get_class_ivars (constant_string_id);
1822 #define AT_LEAST_AS_LARGE_AS(F, T) \
1823 (F && TREE_CODE (F) == FIELD_DECL \
1824 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1825 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1827 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1828 return 0;
1830 field_decl = TREE_CHAIN (field_decl);
1831 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1832 return 0;
1834 field_decl = TREE_CHAIN (field_decl);
1835 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1837 #undef AT_LEAST_AS_LARGE_AS
1840 /* Avoid calling `check_string_class_template ()' more than once. */
1841 static GTY(()) int string_layout_checked;
1843 /* Construct an internal string layout to be used as a template for
1844 creating NSConstantString/NXConstantString instances. */
1846 static tree
1847 objc_build_internal_const_str_type (void)
1849 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1850 tree fields = build_decl (input_location,
1851 FIELD_DECL, NULL_TREE, ptr_type_node);
1852 tree field = build_decl (input_location,
1853 FIELD_DECL, NULL_TREE, ptr_type_node);
1855 TREE_CHAIN (field) = fields; fields = field;
1856 field = build_decl (input_location,
1857 FIELD_DECL, NULL_TREE, unsigned_type_node);
1858 TREE_CHAIN (field) = fields; fields = field;
1859 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1860 reverse order! */
1861 finish_builtin_struct (type, "__builtin_ObjCString",
1862 fields, NULL_TREE);
1864 return type;
1867 /* Custom build_string which sets TREE_TYPE! */
1869 static tree
1870 my_build_string (int len, const char *str)
1872 return fix_string_type (build_string (len, str));
1875 /* Build a string with contents STR and length LEN and convert it to a
1876 pointer. */
1878 static tree
1879 my_build_string_pointer (int len, const char *str)
1881 tree string = my_build_string (len, str);
1882 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1883 return build1 (ADDR_EXPR, ptrtype, string);
1886 static hashval_t
1887 string_hash (const void *ptr)
1889 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1890 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1891 int i, len = TREE_STRING_LENGTH (str);
1892 hashval_t h = len;
1894 for (i = 0; i < len; i++)
1895 h = ((h * 613) + p[i]);
1897 return h;
1900 static int
1901 string_eq (const void *ptr1, const void *ptr2)
1903 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1904 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1905 int len1 = TREE_STRING_LENGTH (str1);
1907 return (len1 == TREE_STRING_LENGTH (str2)
1908 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1909 len1));
1912 /* Given a chain of STRING_CST's, build a static instance of
1913 NXConstantString which points at the concatenation of those
1914 strings. We place the string object in the __string_objects
1915 section of the __OBJC segment. The Objective-C runtime will
1916 initialize the isa pointers of the string objects to point at the
1917 NXConstantString class object. */
1919 tree
1920 objc_build_string_object (tree string)
1922 tree initlist, constructor, constant_string_class;
1923 int length;
1924 tree fields, addr;
1925 struct string_descriptor *desc, key;
1926 void **loc;
1928 /* Prep the string argument. */
1929 string = fix_string_type (string);
1930 TREE_SET_CODE (string, STRING_CST);
1931 length = TREE_STRING_LENGTH (string) - 1;
1933 /* Check whether the string class being used actually exists and has the
1934 correct ivar layout. */
1935 if (!string_layout_checked)
1937 string_layout_checked = -1;
1938 constant_string_class = lookup_interface (constant_string_id);
1939 internal_const_str_type = objc_build_internal_const_str_type ();
1941 if (!constant_string_class
1942 || !(constant_string_type
1943 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1944 error ("cannot find interface declaration for %qE",
1945 constant_string_id);
1946 /* The NSConstantString/NXConstantString ivar layout is now known. */
1947 else if (!check_string_class_template ())
1948 error ("interface %qE does not have valid constant string layout",
1949 constant_string_id);
1950 /* For the NeXT runtime, we can generate a literal reference
1951 to the string class, don't need to run a constructor. */
1952 else if (flag_next_runtime && !setup_string_decl ())
1953 error ("cannot find reference tag for class %qE",
1954 constant_string_id);
1955 else
1957 string_layout_checked = 1; /* Success! */
1958 add_class_reference (constant_string_id);
1962 if (string_layout_checked == -1)
1963 return error_mark_node;
1965 /* Perhaps we already constructed a constant string just like this one? */
1966 key.literal = string;
1967 loc = htab_find_slot (string_htab, &key, INSERT);
1968 desc = (struct string_descriptor *) *loc;
1970 if (!desc)
1972 tree var;
1973 *loc = desc = GGC_NEW (struct string_descriptor);
1974 desc->literal = string;
1976 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1977 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1978 fields = TYPE_FIELDS (internal_const_str_type);
1979 initlist
1980 = build_tree_list (fields,
1981 flag_next_runtime
1982 ? build_unary_op (input_location,
1983 ADDR_EXPR, string_class_decl, 0)
1984 : build_int_cst (NULL_TREE, 0));
1985 fields = TREE_CHAIN (fields);
1986 initlist = tree_cons (fields, build_unary_op (input_location,
1987 ADDR_EXPR, string, 1),
1988 initlist);
1989 fields = TREE_CHAIN (fields);
1990 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1991 initlist);
1992 constructor = objc_build_constructor (internal_const_str_type,
1993 nreverse (initlist));
1995 if (!flag_next_runtime)
1996 constructor
1997 = objc_add_static_instance (constructor, constant_string_type);
1998 else
2000 var = build_decl (input_location,
2001 CONST_DECL, NULL, TREE_TYPE (constructor));
2002 DECL_INITIAL (var) = constructor;
2003 TREE_STATIC (var) = 1;
2004 pushdecl_top_level (var);
2005 constructor = var;
2007 desc->constructor = constructor;
2010 addr = convert (build_pointer_type (constant_string_type),
2011 build_unary_op (input_location,
2012 ADDR_EXPR, desc->constructor, 1));
2014 return addr;
2017 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2019 static GTY(()) int num_static_inst;
2021 static tree
2022 objc_add_static_instance (tree constructor, tree class_decl)
2024 tree *chain, decl;
2025 char buf[256];
2027 /* Find the list of static instances for the CLASS_DECL. Create one if
2028 not found. */
2029 for (chain = &objc_static_instances;
2030 *chain && TREE_VALUE (*chain) != class_decl;
2031 chain = &TREE_CHAIN (*chain));
2032 if (!*chain)
2034 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2035 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2038 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2039 decl = build_decl (input_location,
2040 VAR_DECL, get_identifier (buf), class_decl);
2041 DECL_COMMON (decl) = 1;
2042 TREE_STATIC (decl) = 1;
2043 DECL_ARTIFICIAL (decl) = 1;
2044 TREE_USED (decl) = 1;
2045 DECL_INITIAL (decl) = constructor;
2047 /* We may be writing something else just now.
2048 Postpone till end of input. */
2049 DECL_DEFER_OUTPUT (decl) = 1;
2050 pushdecl_top_level (decl);
2051 rest_of_decl_compilation (decl, 1, 0);
2053 /* Add the DECL to the head of this CLASS' list. */
2054 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2056 return decl;
2059 /* Build a static constant CONSTRUCTOR
2060 with type TYPE and elements ELTS. */
2062 static tree
2063 objc_build_constructor (tree type, tree elts)
2065 tree constructor = build_constructor_from_list (type, elts);
2067 TREE_CONSTANT (constructor) = 1;
2068 TREE_STATIC (constructor) = 1;
2069 TREE_READONLY (constructor) = 1;
2071 #ifdef OBJCPLUS
2072 /* Adjust for impedance mismatch. We should figure out how to build
2073 CONSTRUCTORs that consistently please both the C and C++ gods. */
2074 if (!TREE_PURPOSE (elts))
2075 TREE_TYPE (constructor) = init_list_type_node;
2076 #endif
2078 return constructor;
2081 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2083 /* Predefine the following data type:
2085 struct _objc_symtab
2087 long sel_ref_cnt;
2088 SEL *refs;
2089 short cls_def_cnt;
2090 short cat_def_cnt;
2091 void *defs[cls_def_cnt + cat_def_cnt];
2092 }; */
2094 static void
2095 build_objc_symtab_template (void)
2097 tree field_decl, field_decl_chain;
2099 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2101 /* long sel_ref_cnt; */
2102 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2103 field_decl_chain = field_decl;
2105 /* SEL *refs; */
2106 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2107 "refs");
2108 chainon (field_decl_chain, field_decl);
2110 /* short cls_def_cnt; */
2111 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2112 chainon (field_decl_chain, field_decl);
2114 /* short cat_def_cnt; */
2115 field_decl = create_field_decl (short_integer_type_node,
2116 "cat_def_cnt");
2117 chainon (field_decl_chain, field_decl);
2119 if (imp_count || cat_count || !flag_next_runtime)
2121 /* void *defs[imp_count + cat_count (+ 1)]; */
2122 /* NB: The index is one less than the size of the array. */
2123 int index = imp_count + cat_count
2124 + (flag_next_runtime? -1: 0);
2125 field_decl = create_field_decl
2126 (build_array_type
2127 (ptr_type_node,
2128 build_index_type (build_int_cst (NULL_TREE, index))),
2129 "defs");
2130 chainon (field_decl_chain, field_decl);
2133 objc_finish_struct (objc_symtab_template, field_decl_chain);
2136 /* Create the initial value for the `defs' field of _objc_symtab.
2137 This is a CONSTRUCTOR. */
2139 static tree
2140 init_def_list (tree type)
2142 tree expr, initlist = NULL_TREE;
2143 struct imp_entry *impent;
2145 if (imp_count)
2146 for (impent = imp_list; impent; impent = impent->next)
2148 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2150 expr = build_unary_op (input_location,
2151 ADDR_EXPR, impent->class_decl, 0);
2152 initlist = tree_cons (NULL_TREE, expr, initlist);
2156 if (cat_count)
2157 for (impent = imp_list; impent; impent = impent->next)
2159 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2161 expr = build_unary_op (input_location,
2162 ADDR_EXPR, impent->class_decl, 0);
2163 initlist = tree_cons (NULL_TREE, expr, initlist);
2167 if (!flag_next_runtime)
2169 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2170 tree expr;
2172 if (static_instances_decl)
2173 expr = build_unary_op (input_location,
2174 ADDR_EXPR, static_instances_decl, 0);
2175 else
2176 expr = build_int_cst (NULL_TREE, 0);
2178 initlist = tree_cons (NULL_TREE, expr, initlist);
2181 return objc_build_constructor (type, nreverse (initlist));
2184 /* Construct the initial value for all of _objc_symtab. */
2186 static tree
2187 init_objc_symtab (tree type)
2189 tree initlist;
2191 /* sel_ref_cnt = { ..., 5, ... } */
2193 initlist = build_tree_list (NULL_TREE,
2194 build_int_cst (long_integer_type_node, 0));
2196 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2198 if (flag_next_runtime || ! sel_ref_chain)
2199 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2200 else
2201 initlist
2202 = tree_cons (NULL_TREE,
2203 convert (build_pointer_type (objc_selector_type),
2204 build_unary_op (input_location, ADDR_EXPR,
2205 UOBJC_SELECTOR_TABLE_decl, 1)),
2206 initlist);
2208 /* cls_def_cnt = { ..., 5, ... } */
2210 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2212 /* cat_def_cnt = { ..., 5, ... } */
2214 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2216 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2218 if (imp_count || cat_count || !flag_next_runtime)
2221 tree field = TYPE_FIELDS (type);
2222 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2224 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2225 initlist);
2228 return objc_build_constructor (type, nreverse (initlist));
2231 /* Generate forward declarations for metadata such as
2232 'OBJC_CLASS_...'. */
2234 static tree
2235 build_metadata_decl (const char *name, tree type)
2237 tree decl;
2239 /* struct TYPE NAME_<name>; */
2240 decl = start_var_decl (type, synth_id_with_class_suffix
2241 (name,
2242 objc_implementation_context));
2244 return decl;
2247 /* Push forward-declarations of all the categories so that
2248 init_def_list can use them in a CONSTRUCTOR. */
2250 static void
2251 forward_declare_categories (void)
2253 struct imp_entry *impent;
2254 tree sav = objc_implementation_context;
2256 for (impent = imp_list; impent; impent = impent->next)
2258 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2260 /* Set an invisible arg to synth_id_with_class_suffix. */
2261 objc_implementation_context = impent->imp_context;
2262 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2263 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2264 objc_category_template);
2267 objc_implementation_context = sav;
2270 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2271 and initialized appropriately. */
2273 static void
2274 generate_objc_symtab_decl (void)
2276 /* forward declare categories */
2277 if (cat_count)
2278 forward_declare_categories ();
2280 build_objc_symtab_template ();
2281 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2282 finish_var_decl (UOBJC_SYMBOLS_decl,
2283 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2286 static tree
2287 init_module_descriptor (tree type)
2289 tree initlist, expr;
2291 /* version = { 1, ... } */
2293 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2294 initlist = build_tree_list (NULL_TREE, expr);
2296 /* size = { ..., sizeof (struct _objc_module), ... } */
2298 expr = convert (long_integer_type_node,
2299 size_in_bytes (objc_module_template));
2300 initlist = tree_cons (NULL_TREE, expr, initlist);
2302 /* Don't provide any file name for security reasons. */
2303 /* name = { ..., "", ... } */
2305 expr = add_objc_string (get_identifier (""), class_names);
2306 initlist = tree_cons (NULL_TREE, expr, initlist);
2308 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2310 if (UOBJC_SYMBOLS_decl)
2311 expr = build_unary_op (input_location,
2312 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2313 else
2314 expr = build_int_cst (NULL_TREE, 0);
2315 initlist = tree_cons (NULL_TREE, expr, initlist);
2317 return objc_build_constructor (type, nreverse (initlist));
2320 /* Write out the data structures to describe Objective C classes defined.
2322 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2324 static void
2325 build_module_descriptor (void)
2327 tree field_decl, field_decl_chain;
2329 #ifdef OBJCPLUS
2330 push_lang_context (lang_name_c); /* extern "C" */
2331 #endif
2333 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2335 /* long version; */
2336 field_decl = create_field_decl (long_integer_type_node, "version");
2337 field_decl_chain = field_decl;
2339 /* long size; */
2340 field_decl = create_field_decl (long_integer_type_node, "size");
2341 chainon (field_decl_chain, field_decl);
2343 /* char *name; */
2344 field_decl = create_field_decl (string_type_node, "name");
2345 chainon (field_decl_chain, field_decl);
2347 /* struct _objc_symtab *symtab; */
2348 field_decl
2349 = create_field_decl (build_pointer_type
2350 (xref_tag (RECORD_TYPE,
2351 get_identifier (UTAG_SYMTAB))),
2352 "symtab");
2353 chainon (field_decl_chain, field_decl);
2355 objc_finish_struct (objc_module_template, field_decl_chain);
2357 /* Create an instance of "_objc_module". */
2358 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2359 finish_var_decl (UOBJC_MODULES_decl,
2360 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2362 #ifdef OBJCPLUS
2363 pop_lang_context ();
2364 #endif
2367 /* The GNU runtime requires us to provide a static initializer function
2368 for each module:
2370 static void __objc_gnu_init (void) {
2371 __objc_exec_class (&L_OBJC_MODULES);
2372 } */
2374 static void
2375 build_module_initializer_routine (void)
2377 tree body;
2379 #ifdef OBJCPLUS
2380 push_lang_context (lang_name_c); /* extern "C" */
2381 #endif
2383 objc_push_parm (build_decl (input_location,
2384 PARM_DECL, NULL_TREE, void_type_node));
2385 objc_start_function (get_identifier (TAG_GNUINIT),
2386 build_function_type (void_type_node,
2387 OBJC_VOID_AT_END),
2388 NULL_TREE, objc_get_parm_info (0));
2390 body = c_begin_compound_stmt (true);
2391 add_stmt (build_function_call
2392 (input_location,
2393 execclass_decl,
2394 build_tree_list
2395 (NULL_TREE,
2396 build_unary_op (input_location, ADDR_EXPR,
2397 UOBJC_MODULES_decl, 0))));
2398 add_stmt (c_end_compound_stmt (input_location, body, true));
2400 TREE_PUBLIC (current_function_decl) = 0;
2402 #ifndef OBJCPLUS
2403 /* For Objective-C++, we will need to call __objc_gnu_init
2404 from objc_generate_static_init_call() below. */
2405 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2406 #endif
2408 GNU_INIT_decl = current_function_decl;
2409 finish_function ();
2411 #ifdef OBJCPLUS
2412 pop_lang_context ();
2413 #endif
2416 #ifdef OBJCPLUS
2417 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2418 to be called by the module initializer routine. */
2421 objc_static_init_needed_p (void)
2423 return (GNU_INIT_decl != NULL_TREE);
2426 /* Generate a call to the __objc_gnu_init initializer function. */
2428 tree
2429 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2431 add_stmt (build_stmt (input_location, EXPR_STMT,
2432 build_function_call (input_location,
2433 GNU_INIT_decl, NULL_TREE)));
2435 return ctors;
2437 #endif /* OBJCPLUS */
2439 /* Return the DECL of the string IDENT in the SECTION. */
2441 static tree
2442 get_objc_string_decl (tree ident, enum string_section section)
2444 tree chain;
2446 if (section == class_names)
2447 chain = class_names_chain;
2448 else if (section == meth_var_names)
2449 chain = meth_var_names_chain;
2450 else if (section == meth_var_types)
2451 chain = meth_var_types_chain;
2452 else
2453 abort ();
2455 for (; chain != 0; chain = TREE_CHAIN (chain))
2456 if (TREE_VALUE (chain) == ident)
2457 return (TREE_PURPOSE (chain));
2459 abort ();
2460 return NULL_TREE;
2463 /* Output references to all statically allocated objects. Return the DECL
2464 for the array built. */
2466 static void
2467 generate_static_references (void)
2469 tree decls = NULL_TREE, expr = NULL_TREE;
2470 tree class_name, klass, decl, initlist;
2471 tree cl_chain, in_chain, type
2472 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2473 int num_inst, num_class;
2474 char buf[256];
2476 if (flag_next_runtime)
2477 abort ();
2479 for (cl_chain = objc_static_instances, num_class = 0;
2480 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2482 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2483 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2485 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2486 decl = start_var_decl (type, buf);
2488 /* Output {class_name, ...}. */
2489 klass = TREE_VALUE (cl_chain);
2490 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2491 initlist = build_tree_list (NULL_TREE,
2492 build_unary_op (input_location,
2493 ADDR_EXPR, class_name, 1));
2495 /* Output {..., instance, ...}. */
2496 for (in_chain = TREE_PURPOSE (cl_chain);
2497 in_chain; in_chain = TREE_CHAIN (in_chain))
2499 expr = build_unary_op (input_location,
2500 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2501 initlist = tree_cons (NULL_TREE, expr, initlist);
2504 /* Output {..., NULL}. */
2505 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2507 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2508 finish_var_decl (decl, expr);
2509 decls
2510 = tree_cons (NULL_TREE, build_unary_op (input_location,
2511 ADDR_EXPR, decl, 1), decls);
2514 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2515 expr = objc_build_constructor (type, nreverse (decls));
2516 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2517 finish_var_decl (static_instances_decl, expr);
2520 static GTY(()) int selector_reference_idx;
2522 static tree
2523 build_selector_reference_decl (void)
2525 tree decl;
2526 char buf[256];
2528 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2529 decl = start_var_decl (objc_selector_type, buf);
2531 return decl;
2534 static void
2535 build_selector_table_decl (void)
2537 tree temp;
2539 if (flag_typed_selectors)
2541 build_selector_template ();
2542 temp = build_array_type (objc_selector_template, NULL_TREE);
2544 else
2545 temp = build_array_type (objc_selector_type, NULL_TREE);
2547 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2550 /* Just a handy wrapper for add_objc_string. */
2552 static tree
2553 build_selector (tree ident)
2555 return convert (objc_selector_type,
2556 add_objc_string (ident, meth_var_names));
2559 static void
2560 build_selector_translation_table (void)
2562 tree chain, initlist = NULL_TREE;
2563 int offset = 0;
2564 tree decl = NULL_TREE;
2566 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2568 tree expr;
2570 if (warn_selector && objc_implementation_context)
2572 tree method_chain;
2573 bool found = false;
2574 for (method_chain = meth_var_names_chain;
2575 method_chain;
2576 method_chain = TREE_CHAIN (method_chain))
2578 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2580 found = true;
2581 break;
2584 if (!found)
2586 location_t loc;
2587 if (flag_next_runtime && TREE_PURPOSE (chain))
2588 loc = DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2589 else
2590 loc = input_location;
2591 warning_at (loc, 0, "creating selector for nonexistent method %qE",
2592 TREE_VALUE (chain));
2596 expr = build_selector (TREE_VALUE (chain));
2597 /* add one for the '\0' character */
2598 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2600 if (flag_next_runtime)
2602 decl = TREE_PURPOSE (chain);
2603 finish_var_decl (decl, expr);
2605 else
2607 if (flag_typed_selectors)
2609 tree eltlist = NULL_TREE;
2610 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2611 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2612 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2613 expr = objc_build_constructor (objc_selector_template,
2614 nreverse (eltlist));
2617 initlist = tree_cons (NULL_TREE, expr, initlist);
2621 if (! flag_next_runtime)
2623 /* Cause the selector table (previously forward-declared)
2624 to be actually output. */
2625 initlist = tree_cons (NULL_TREE,
2626 flag_typed_selectors
2627 ? objc_build_constructor
2628 (objc_selector_template,
2629 tree_cons (NULL_TREE,
2630 build_int_cst (NULL_TREE, 0),
2631 tree_cons (NULL_TREE,
2632 build_int_cst (NULL_TREE, 0),
2633 NULL_TREE)))
2634 : build_int_cst (NULL_TREE, 0), initlist);
2635 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2636 nreverse (initlist));
2637 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2641 static tree
2642 get_proto_encoding (tree proto)
2644 tree encoding;
2645 if (proto)
2647 if (! METHOD_ENCODING (proto))
2649 encoding = encode_method_prototype (proto);
2650 METHOD_ENCODING (proto) = encoding;
2652 else
2653 encoding = METHOD_ENCODING (proto);
2655 return add_objc_string (encoding, meth_var_types);
2657 else
2658 return build_int_cst (NULL_TREE, 0);
2661 /* sel_ref_chain is a list whose "value" fields will be instances of
2662 identifier_node that represent the selector. LOC is the location of
2663 the @selector. */
2665 static tree
2666 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
2668 tree *chain = &sel_ref_chain;
2669 tree expr;
2670 int index = 0;
2672 while (*chain)
2674 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2675 goto return_at_index;
2677 index++;
2678 chain = &TREE_CHAIN (*chain);
2681 *chain = tree_cons (prototype, ident, NULL_TREE);
2683 return_at_index:
2684 expr = build_unary_op (loc, ADDR_EXPR,
2685 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2686 build_int_cst (NULL_TREE, index)),
2688 return convert (objc_selector_type, expr);
2691 static tree
2692 build_selector_reference (location_t loc, tree ident)
2694 tree *chain = &sel_ref_chain;
2695 tree expr;
2696 int index = 0;
2698 while (*chain)
2700 if (TREE_VALUE (*chain) == ident)
2701 return (flag_next_runtime
2702 ? TREE_PURPOSE (*chain)
2703 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2704 build_int_cst (NULL_TREE, index)));
2706 index++;
2707 chain = &TREE_CHAIN (*chain);
2710 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2712 *chain = tree_cons (expr, ident, NULL_TREE);
2714 return (flag_next_runtime
2715 ? expr
2716 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2717 build_int_cst (NULL_TREE, index)));
2720 static GTY(()) int class_reference_idx;
2722 static tree
2723 build_class_reference_decl (void)
2725 tree decl;
2726 char buf[256];
2728 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2729 decl = start_var_decl (objc_class_type, buf);
2731 return decl;
2734 /* Create a class reference, but don't create a variable to reference
2735 it. */
2737 static void
2738 add_class_reference (tree ident)
2740 tree chain;
2742 if ((chain = cls_ref_chain))
2744 tree tail;
2747 if (ident == TREE_VALUE (chain))
2748 return;
2750 tail = chain;
2751 chain = TREE_CHAIN (chain);
2753 while (chain);
2755 /* Append to the end of the list */
2756 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2758 else
2759 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2762 /* Get a class reference, creating it if necessary. Also create the
2763 reference variable. */
2765 tree
2766 objc_get_class_reference (tree ident)
2768 tree orig_ident = (DECL_P (ident)
2769 ? DECL_NAME (ident)
2770 : TYPE_P (ident)
2771 ? OBJC_TYPE_NAME (ident)
2772 : ident);
2773 bool local_scope = false;
2775 #ifdef OBJCPLUS
2776 if (processing_template_decl)
2777 /* Must wait until template instantiation time. */
2778 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2779 #endif
2781 if (TREE_CODE (ident) == TYPE_DECL)
2782 ident = (DECL_ORIGINAL_TYPE (ident)
2783 ? DECL_ORIGINAL_TYPE (ident)
2784 : TREE_TYPE (ident));
2786 #ifdef OBJCPLUS
2787 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2788 && TYPE_CONTEXT (ident) != global_namespace)
2789 local_scope = true;
2790 #endif
2792 if (local_scope || !(ident = objc_is_class_name (ident)))
2794 error ("%qE is not an Objective-C class name or alias",
2795 orig_ident);
2796 return error_mark_node;
2799 if (flag_next_runtime && !flag_zero_link)
2801 tree *chain;
2802 tree decl;
2804 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2805 if (TREE_VALUE (*chain) == ident)
2807 if (! TREE_PURPOSE (*chain))
2808 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2810 return TREE_PURPOSE (*chain);
2813 decl = build_class_reference_decl ();
2814 *chain = tree_cons (decl, ident, NULL_TREE);
2815 return decl;
2817 else
2819 tree params;
2821 add_class_reference (ident);
2823 params = build_tree_list (NULL_TREE,
2824 my_build_string_pointer
2825 (IDENTIFIER_LENGTH (ident) + 1,
2826 IDENTIFIER_POINTER (ident)));
2828 assemble_external (objc_get_class_decl);
2829 return build_function_call (input_location, objc_get_class_decl, params);
2833 /* For each string section we have a chain which maps identifier nodes
2834 to decls for the strings. */
2836 static tree
2837 add_objc_string (tree ident, enum string_section section)
2839 tree *chain, decl, type, string_expr;
2841 if (section == class_names)
2842 chain = &class_names_chain;
2843 else if (section == meth_var_names)
2844 chain = &meth_var_names_chain;
2845 else if (section == meth_var_types)
2846 chain = &meth_var_types_chain;
2847 else
2848 abort ();
2850 while (*chain)
2852 if (TREE_VALUE (*chain) == ident)
2853 return convert (string_type_node,
2854 build_unary_op (input_location,
2855 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2857 chain = &TREE_CHAIN (*chain);
2860 decl = build_objc_string_decl (section);
2862 type = build_array_type
2863 (char_type_node,
2864 build_index_type
2865 (build_int_cst (NULL_TREE,
2866 IDENTIFIER_LENGTH (ident))));
2867 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2868 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2869 IDENTIFIER_POINTER (ident));
2870 finish_var_decl (decl, string_expr);
2872 *chain = tree_cons (decl, ident, NULL_TREE);
2874 return convert (string_type_node, build_unary_op (input_location,
2875 ADDR_EXPR, decl, 1));
2878 static GTY(()) int class_names_idx;
2879 static GTY(()) int meth_var_names_idx;
2880 static GTY(()) int meth_var_types_idx;
2882 static tree
2883 build_objc_string_decl (enum string_section section)
2885 tree decl, ident;
2886 char buf[256];
2888 if (section == class_names)
2889 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2890 else if (section == meth_var_names)
2891 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2892 else if (section == meth_var_types)
2893 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2895 ident = get_identifier (buf);
2897 decl = build_decl (input_location,
2898 VAR_DECL, ident, build_array_type (char_type_node, 0));
2899 DECL_EXTERNAL (decl) = 1;
2900 TREE_PUBLIC (decl) = 0;
2901 TREE_USED (decl) = 1;
2902 TREE_CONSTANT (decl) = 1;
2903 DECL_CONTEXT (decl) = 0;
2904 DECL_ARTIFICIAL (decl) = 1;
2905 #ifdef OBJCPLUS
2906 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2907 #endif
2909 make_decl_rtl (decl);
2910 pushdecl_top_level (decl);
2912 return decl;
2916 void
2917 objc_declare_alias (tree alias_ident, tree class_ident)
2919 tree underlying_class;
2921 #ifdef OBJCPLUS
2922 if (current_namespace != global_namespace) {
2923 error ("Objective-C declarations may only appear in global scope");
2925 #endif /* OBJCPLUS */
2927 if (!(underlying_class = objc_is_class_name (class_ident)))
2928 warning (0, "cannot find class %qE", class_ident);
2929 else if (objc_is_class_name (alias_ident))
2930 warning (0, "class %qE already exists", alias_ident);
2931 else
2933 /* Implement @compatibility_alias as a typedef. */
2934 #ifdef OBJCPLUS
2935 push_lang_context (lang_name_c); /* extern "C" */
2936 #endif
2937 lang_hooks.decls.pushdecl (build_decl
2938 (input_location,
2939 TYPE_DECL,
2940 alias_ident,
2941 xref_tag (RECORD_TYPE, underlying_class)));
2942 #ifdef OBJCPLUS
2943 pop_lang_context ();
2944 #endif
2945 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2949 void
2950 objc_declare_class (tree ident_list)
2952 tree list;
2953 #ifdef OBJCPLUS
2954 if (current_namespace != global_namespace) {
2955 error ("Objective-C declarations may only appear in global scope");
2957 #endif /* OBJCPLUS */
2959 for (list = ident_list; list; list = TREE_CHAIN (list))
2961 tree ident = TREE_VALUE (list);
2963 if (! objc_is_class_name (ident))
2965 tree record = lookup_name (ident), type = record;
2967 if (record)
2969 if (TREE_CODE (record) == TYPE_DECL)
2970 type = DECL_ORIGINAL_TYPE (record);
2972 if (!TYPE_HAS_OBJC_INFO (type)
2973 || !TYPE_OBJC_INTERFACE (type))
2975 error ("%qE redeclared as different kind of symbol",
2976 ident);
2977 error ("previous declaration of %q+D",
2978 record);
2982 record = xref_tag (RECORD_TYPE, ident);
2983 INIT_TYPE_OBJC_INFO (record);
2984 TYPE_OBJC_INTERFACE (record) = ident;
2985 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2990 tree
2991 objc_is_class_name (tree ident)
2993 tree chain;
2995 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2996 && identifier_global_value (ident))
2997 ident = identifier_global_value (ident);
2998 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2999 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3001 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3002 ident = OBJC_TYPE_NAME (ident);
3003 #ifdef OBJCPLUS
3004 if (ident && TREE_CODE (ident) == TYPE_DECL)
3005 ident = DECL_NAME (ident);
3006 #endif
3007 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3008 return NULL_TREE;
3010 if (lookup_interface (ident))
3011 return ident;
3013 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3015 if (ident == TREE_VALUE (chain))
3016 return ident;
3019 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3021 if (ident == TREE_VALUE (chain))
3022 return TREE_PURPOSE (chain);
3025 return 0;
3028 /* Check whether TYPE is either 'id' or 'Class'. */
3030 tree
3031 objc_is_id (tree type)
3033 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3034 && identifier_global_value (type))
3035 type = identifier_global_value (type);
3037 if (type && TREE_CODE (type) == TYPE_DECL)
3038 type = TREE_TYPE (type);
3040 /* NB: This function may be called before the ObjC front-end has
3041 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3042 return (objc_object_type && type
3043 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3044 ? type
3045 : NULL_TREE);
3048 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3049 class instance. This is needed by other parts of the compiler to
3050 handle ObjC types gracefully. */
3052 tree
3053 objc_is_object_ptr (tree type)
3055 tree ret;
3057 type = TYPE_MAIN_VARIANT (type);
3058 if (!POINTER_TYPE_P (type))
3059 return 0;
3061 ret = objc_is_id (type);
3062 if (!ret)
3063 ret = objc_is_class_name (TREE_TYPE (type));
3065 return ret;
3068 static int
3069 objc_is_gcable_type (tree type, int or_strong_p)
3071 tree name;
3073 if (!TYPE_P (type))
3074 return 0;
3075 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3076 return 1;
3077 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3078 return 1;
3079 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3080 return 0;
3081 type = TREE_TYPE (type);
3082 if (TREE_CODE (type) != RECORD_TYPE)
3083 return 0;
3084 name = TYPE_NAME (type);
3085 return (objc_is_class_name (name) != NULL_TREE);
3088 static tree
3089 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3091 if (expr == oldexpr)
3092 return newexpr;
3094 switch (TREE_CODE (expr))
3096 case COMPONENT_REF:
3097 return objc_build_component_ref
3098 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3099 oldexpr,
3100 newexpr),
3101 DECL_NAME (TREE_OPERAND (expr, 1)));
3102 case ARRAY_REF:
3103 return build_array_ref (input_location,
3104 objc_substitute_decl (TREE_OPERAND (expr, 0),
3105 oldexpr,
3106 newexpr),
3107 TREE_OPERAND (expr, 1));
3108 case INDIRECT_REF:
3109 return build_indirect_ref (input_location,
3110 objc_substitute_decl (TREE_OPERAND (expr, 0),
3111 oldexpr,
3112 newexpr), "->");
3113 default:
3114 return expr;
3118 static tree
3119 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3121 tree func_params;
3122 /* The LHS parameter contains the expression 'outervar->memberspec';
3123 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3124 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3126 tree offs
3127 = objc_substitute_decl
3128 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3129 tree func
3130 = (flag_objc_direct_dispatch
3131 ? objc_assign_ivar_fast_decl
3132 : objc_assign_ivar_decl);
3134 offs = convert (integer_type_node, build_unary_op (input_location,
3135 ADDR_EXPR, offs, 0));
3136 offs = fold (offs);
3137 func_params = tree_cons (NULL_TREE,
3138 convert (objc_object_type, rhs),
3139 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3140 tree_cons (NULL_TREE, offs,
3141 NULL_TREE)));
3143 assemble_external (func);
3144 return build_function_call (input_location, func, func_params);
3147 static tree
3148 objc_build_global_assignment (tree lhs, tree rhs)
3150 tree func_params = tree_cons (NULL_TREE,
3151 convert (objc_object_type, rhs),
3152 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3153 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3154 NULL_TREE));
3156 assemble_external (objc_assign_global_decl);
3157 return build_function_call (input_location,
3158 objc_assign_global_decl, func_params);
3161 static tree
3162 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3164 tree func_params = tree_cons (NULL_TREE,
3165 convert (objc_object_type, rhs),
3166 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3167 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3168 NULL_TREE));
3170 assemble_external (objc_assign_strong_cast_decl);
3171 return build_function_call (input_location,
3172 objc_assign_strong_cast_decl, func_params);
3175 static int
3176 objc_is_gcable_p (tree expr)
3178 return (TREE_CODE (expr) == COMPONENT_REF
3179 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3180 : TREE_CODE (expr) == ARRAY_REF
3181 ? (objc_is_gcable_p (TREE_TYPE (expr))
3182 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3183 : TREE_CODE (expr) == ARRAY_TYPE
3184 ? objc_is_gcable_p (TREE_TYPE (expr))
3185 : TYPE_P (expr)
3186 ? objc_is_gcable_type (expr, 1)
3187 : (objc_is_gcable_p (TREE_TYPE (expr))
3188 || (DECL_P (expr)
3189 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3192 static int
3193 objc_is_ivar_reference_p (tree expr)
3195 return (TREE_CODE (expr) == ARRAY_REF
3196 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3197 : TREE_CODE (expr) == COMPONENT_REF
3198 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3199 : 0);
3202 static int
3203 objc_is_global_reference_p (tree expr)
3205 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3206 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3207 : DECL_P (expr)
3208 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3209 : 0);
3212 tree
3213 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3215 tree result = NULL_TREE, outer;
3216 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3218 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3219 will have been transformed to the form '*(type *)&expr'. */
3220 if (TREE_CODE (lhs) == INDIRECT_REF)
3222 outer = TREE_OPERAND (lhs, 0);
3224 while (!strong_cast_p
3225 && (CONVERT_EXPR_P (outer)
3226 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3228 tree lhstype = TREE_TYPE (outer);
3230 /* Descend down the cast chain, and record the first objc_gc
3231 attribute found. */
3232 if (POINTER_TYPE_P (lhstype))
3234 tree attr
3235 = lookup_attribute ("objc_gc",
3236 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3238 if (attr)
3239 strong_cast_p = 1;
3242 outer = TREE_OPERAND (outer, 0);
3246 /* If we have a __strong cast, it trumps all else. */
3247 if (strong_cast_p)
3249 if (modifycode != NOP_EXPR)
3250 goto invalid_pointer_arithmetic;
3252 if (warn_assign_intercept)
3253 warning (0, "strong-cast assignment has been intercepted");
3255 result = objc_build_strong_cast_assignment (lhs, rhs);
3257 goto exit_point;
3260 /* the lhs must be of a suitable type, regardless of its underlying
3261 structure. */
3262 if (!objc_is_gcable_p (lhs))
3263 goto exit_point;
3265 outer = lhs;
3267 while (outer
3268 && (TREE_CODE (outer) == COMPONENT_REF
3269 || TREE_CODE (outer) == ARRAY_REF))
3270 outer = TREE_OPERAND (outer, 0);
3272 if (TREE_CODE (outer) == INDIRECT_REF)
3274 outer = TREE_OPERAND (outer, 0);
3275 indirect_p = 1;
3278 outer_gc_p = objc_is_gcable_p (outer);
3280 /* Handle ivar assignments. */
3281 if (objc_is_ivar_reference_p (lhs))
3283 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3284 doesn't cut it here), the best we can do here is suggest a cast. */
3285 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3287 /* We may still be able to use the global write barrier... */
3288 if (!indirect_p && objc_is_global_reference_p (outer))
3289 goto global_reference;
3291 suggest_cast:
3292 if (modifycode == NOP_EXPR)
3294 if (warn_assign_intercept)
3295 warning (0, "strong-cast may possibly be needed");
3298 goto exit_point;
3301 if (modifycode != NOP_EXPR)
3302 goto invalid_pointer_arithmetic;
3304 if (warn_assign_intercept)
3305 warning (0, "instance variable assignment has been intercepted");
3307 result = objc_build_ivar_assignment (outer, lhs, rhs);
3309 goto exit_point;
3312 /* Likewise, intercept assignment to global/static variables if their type is
3313 GC-marked. */
3314 if (objc_is_global_reference_p (outer))
3316 if (indirect_p)
3317 goto suggest_cast;
3319 global_reference:
3320 if (modifycode != NOP_EXPR)
3322 invalid_pointer_arithmetic:
3323 if (outer_gc_p)
3324 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3326 goto exit_point;
3329 if (warn_assign_intercept)
3330 warning (0, "global/static variable assignment has been intercepted");
3332 result = objc_build_global_assignment (lhs, rhs);
3335 /* In all other cases, fall back to the normal mechanism. */
3336 exit_point:
3337 return result;
3340 struct GTY(()) interface_tuple {
3341 tree id;
3342 tree class_name;
3345 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3347 static hashval_t
3348 hash_interface (const void *p)
3350 const struct interface_tuple *d = (const struct interface_tuple *) p;
3351 return IDENTIFIER_HASH_VALUE (d->id);
3354 static int
3355 eq_interface (const void *p1, const void *p2)
3357 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3358 return d->id == p2;
3361 static tree
3362 lookup_interface (tree ident)
3364 #ifdef OBJCPLUS
3365 if (ident && TREE_CODE (ident) == TYPE_DECL)
3366 ident = DECL_NAME (ident);
3367 #endif
3369 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3370 return NULL_TREE;
3373 struct interface_tuple **slot;
3374 tree i = NULL_TREE;
3376 if (interface_htab)
3378 slot = (struct interface_tuple **)
3379 htab_find_slot_with_hash (interface_htab, ident,
3380 IDENTIFIER_HASH_VALUE (ident),
3381 NO_INSERT);
3382 if (slot && *slot)
3383 i = (*slot)->class_name;
3385 return i;
3389 /* Implement @defs (<classname>) within struct bodies. */
3391 tree
3392 objc_get_class_ivars (tree class_name)
3394 tree interface = lookup_interface (class_name);
3396 if (interface)
3397 return get_class_ivars (interface, true);
3399 error ("cannot find interface declaration for %qE",
3400 class_name);
3402 return error_mark_node;
3405 /* Used by: build_private_template, continue_class,
3406 and for @defs constructs. */
3408 static tree
3409 get_class_ivars (tree interface, bool inherited)
3411 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3413 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3414 by the current class (i.e., they do not include super-class ivars).
3415 However, the CLASS_IVARS list will be side-effected by a call to
3416 finish_struct(), which will fill in field offsets. */
3417 if (!CLASS_IVARS (interface))
3418 CLASS_IVARS (interface) = ivar_chain;
3420 if (!inherited)
3421 return ivar_chain;
3423 while (CLASS_SUPER_NAME (interface))
3425 /* Prepend super-class ivars. */
3426 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3427 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3428 ivar_chain);
3431 return ivar_chain;
3434 static tree
3435 objc_create_temporary_var (tree type)
3437 tree decl;
3439 decl = build_decl (input_location,
3440 VAR_DECL, NULL_TREE, type);
3441 TREE_USED (decl) = 1;
3442 DECL_ARTIFICIAL (decl) = 1;
3443 DECL_IGNORED_P (decl) = 1;
3444 DECL_CONTEXT (decl) = current_function_decl;
3446 return decl;
3449 /* Exception handling constructs. We begin by having the parser do most
3450 of the work and passing us blocks. What we do next depends on whether
3451 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3452 We abstract all of this in a handful of appropriately named routines. */
3454 /* Stack of open try blocks. */
3456 struct objc_try_context
3458 struct objc_try_context *outer;
3460 /* Statements (or statement lists) as processed by the parser. */
3461 tree try_body;
3462 tree finally_body;
3464 /* Some file position locations. */
3465 location_t try_locus;
3466 location_t end_try_locus;
3467 location_t end_catch_locus;
3468 location_t finally_locus;
3469 location_t end_finally_locus;
3471 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3472 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3473 tree catch_list;
3475 /* The CATCH_EXPR of an open @catch clause. */
3476 tree current_catch;
3478 /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer. */
3479 tree caught_decl;
3480 tree stack_decl;
3481 tree rethrow_decl;
3484 static struct objc_try_context *cur_try_context;
3486 static GTY(()) tree objc_eh_personality_decl;
3488 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3489 that represents TYPE. For Objective-C, this is just the class name. */
3490 /* ??? Isn't there a class object or some such? Is it easy to get? */
3492 #ifndef OBJCPLUS
3493 tree
3494 objc_eh_runtime_type (tree type)
3496 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3499 tree
3500 objc_eh_personality (void)
3502 if (!flag_objc_sjlj_exceptions
3503 && !objc_eh_personality_decl)
3504 objc_eh_personality_decl
3505 = build_personality_function (USING_SJLJ_EXCEPTIONS
3506 ? "__gnu_objc_personality_sj0"
3507 : "__gnu_objc_personality_v0");
3509 return objc_eh_personality_decl;
3511 #endif
3513 /* Build __builtin_eh_pointer, or the moral equivalent. In the case
3514 of Darwin, we'll arrange for it to be initialized (and associated
3515 with a binding) later. */
3517 static tree
3518 objc_build_exc_ptr (void)
3520 if (flag_objc_sjlj_exceptions)
3522 tree var = cur_try_context->caught_decl;
3523 if (!var)
3525 var = objc_create_temporary_var (objc_object_type);
3526 cur_try_context->caught_decl = var;
3528 return var;
3530 else
3532 tree t;
3533 t = built_in_decls[BUILT_IN_EH_POINTER];
3534 t = build_call_expr (t, 1, integer_zero_node);
3535 return fold_convert (objc_object_type, t);
3539 /* Build "objc_exception_try_exit(&_stack)". */
3541 static tree
3542 next_sjlj_build_try_exit (void)
3544 tree t;
3545 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3546 t = tree_cons (NULL, t, NULL);
3547 t = build_function_call (input_location,
3548 objc_exception_try_exit_decl, t);
3549 return t;
3552 /* Build
3553 objc_exception_try_enter (&_stack);
3554 if (_setjmp(&_stack.buf))
3556 else
3558 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3559 empty, ready for the caller to fill them in. */
3561 static tree
3562 next_sjlj_build_enter_and_setjmp (void)
3564 tree t, enter, sj, cond;
3566 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3567 t = tree_cons (NULL, t, NULL);
3568 enter = build_function_call (input_location,
3569 objc_exception_try_enter_decl, t);
3571 t = objc_build_component_ref (cur_try_context->stack_decl,
3572 get_identifier ("buf"));
3573 t = build_fold_addr_expr_loc (input_location, t);
3574 #ifdef OBJCPLUS
3575 /* Convert _setjmp argument to type that is expected. */
3576 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3577 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3578 else
3579 t = convert (ptr_type_node, t);
3580 #else
3581 t = convert (ptr_type_node, t);
3582 #endif
3583 t = tree_cons (NULL, t, NULL);
3584 sj = build_function_call (input_location,
3585 objc_setjmp_decl, t);
3587 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3588 cond = c_common_truthvalue_conversion (input_location, cond);
3590 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3593 /* Build:
3595 DECL = objc_exception_extract(&_stack); */
3597 static tree
3598 next_sjlj_build_exc_extract (tree decl)
3600 tree t;
3602 t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3603 t = tree_cons (NULL, t, NULL);
3604 t = build_function_call (input_location,
3605 objc_exception_extract_decl, t);
3606 t = convert (TREE_TYPE (decl), t);
3607 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3609 return t;
3612 /* Build
3613 if (objc_exception_match(obj_get_class(TYPE), _caught)
3614 BODY
3615 else if (...)
3617 else
3619 _rethrow = _caught;
3620 objc_exception_try_exit(&_stack);
3622 from the sequence of CATCH_EXPRs in the current try context. */
3624 static tree
3625 next_sjlj_build_catch_list (void)
3627 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3628 tree catch_seq, t;
3629 tree *last = &catch_seq;
3630 bool saw_id = false;
3632 for (; !tsi_end_p (i); tsi_next (&i))
3634 tree stmt = tsi_stmt (i);
3635 tree type = CATCH_TYPES (stmt);
3636 tree body = CATCH_BODY (stmt);
3638 if (type == NULL)
3640 *last = body;
3641 saw_id = true;
3642 break;
3644 else
3646 tree args, cond;
3648 if (type == error_mark_node)
3649 cond = error_mark_node;
3650 else
3652 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3653 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3654 args = tree_cons (NULL, t, args);
3655 t = build_function_call (input_location,
3656 objc_exception_match_decl, args);
3657 cond = c_common_truthvalue_conversion (input_location, t);
3659 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3660 SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
3662 *last = t;
3663 last = &COND_EXPR_ELSE (t);
3667 if (!saw_id)
3669 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3670 cur_try_context->caught_decl);
3671 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3672 append_to_statement_list (t, last);
3674 t = next_sjlj_build_try_exit ();
3675 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3676 append_to_statement_list (t, last);
3679 return catch_seq;
3682 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3683 exception handling. We aim to build:
3686 struct _objc_exception_data _stack;
3687 id _rethrow = 0;
3690 objc_exception_try_enter (&_stack);
3691 if (_setjmp(&_stack.buf))
3693 id _caught = objc_exception_extract(&_stack);
3694 objc_exception_try_enter (&_stack);
3695 if (_setjmp(&_stack.buf))
3696 _rethrow = objc_exception_extract(&_stack);
3697 else
3698 CATCH-LIST
3700 else
3701 TRY-BLOCK
3703 finally
3705 if (!_rethrow)
3706 objc_exception_try_exit(&_stack);
3707 FINALLY-BLOCK
3708 if (_rethrow)
3709 objc_exception_throw(_rethrow);
3713 If CATCH-LIST is empty, we can omit all of the block containing
3714 "_caught" except for the setting of _rethrow. Note the use of
3715 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3716 but handles goto and other exits from the block. */
3718 static tree
3719 next_sjlj_build_try_catch_finally (void)
3721 tree rethrow_decl, stack_decl, t;
3722 tree catch_seq, try_fin, bind;
3724 /* Create the declarations involved. */
3725 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3726 stack_decl = objc_create_temporary_var (t);
3727 cur_try_context->stack_decl = stack_decl;
3729 rethrow_decl = objc_create_temporary_var (objc_object_type);
3730 cur_try_context->rethrow_decl = rethrow_decl;
3731 TREE_CHAIN (rethrow_decl) = stack_decl;
3733 /* Build the outermost variable binding level. */
3734 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3735 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3736 TREE_SIDE_EFFECTS (bind) = 1;
3738 /* Initialize rethrow_decl. */
3739 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3740 convert (objc_object_type, null_pointer_node));
3741 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3742 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3744 /* Build the outermost TRY_FINALLY_EXPR. */
3745 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3746 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3747 TREE_SIDE_EFFECTS (try_fin) = 1;
3748 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3750 /* Create the complete catch sequence. */
3751 if (cur_try_context->catch_list)
3753 tree caught_decl = objc_build_exc_ptr ();
3754 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
3755 TREE_SIDE_EFFECTS (catch_seq) = 1;
3757 t = next_sjlj_build_exc_extract (caught_decl);
3758 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3760 t = next_sjlj_build_enter_and_setjmp ();
3761 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3762 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3763 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3765 else
3766 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3767 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3769 /* Build the main register-and-try if statement. */
3770 t = next_sjlj_build_enter_and_setjmp ();
3771 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3772 COND_EXPR_THEN (t) = catch_seq;
3773 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3774 TREE_OPERAND (try_fin, 0) = t;
3776 /* Build the complete FINALLY statement list. */
3777 t = next_sjlj_build_try_exit ();
3778 t = build_stmt (input_location, COND_EXPR,
3779 c_common_truthvalue_conversion
3780 (input_location, rethrow_decl),
3781 NULL, t);
3782 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3783 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3785 append_to_statement_list (cur_try_context->finally_body,
3786 &TREE_OPERAND (try_fin, 1));
3788 t = tree_cons (NULL, rethrow_decl, NULL);
3789 t = build_function_call (input_location,
3790 objc_exception_throw_decl, t);
3791 t = build_stmt (input_location, COND_EXPR,
3792 c_common_truthvalue_conversion (input_location,
3793 rethrow_decl),
3794 t, NULL);
3795 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3796 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3798 return bind;
3801 /* Called just after parsing the @try and its associated BODY. We now
3802 must prepare for the tricky bits -- handling the catches and finally. */
3804 void
3805 objc_begin_try_stmt (location_t try_locus, tree body)
3807 struct objc_try_context *c = XCNEW (struct objc_try_context);
3808 c->outer = cur_try_context;
3809 c->try_body = body;
3810 c->try_locus = try_locus;
3811 c->end_try_locus = input_location;
3812 cur_try_context = c;
3814 if (flag_objc_sjlj_exceptions)
3816 /* On Darwin, ObjC exceptions require a sufficiently recent
3817 version of the runtime, so the user must ask for them explicitly. */
3818 if (!flag_objc_exceptions)
3819 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3820 "exception syntax");
3823 if (flag_objc_sjlj_exceptions)
3824 objc_mark_locals_volatile (NULL);
3827 /* Called just after parsing "@catch (parm)". Open a binding level,
3828 enter DECL into the binding level, and initialize it. Leave the
3829 binding level open while the body of the compound statement is parsed. */
3831 void
3832 objc_begin_catch_clause (tree decl)
3834 tree compound, type, t;
3836 /* Begin a new scope that the entire catch clause will live in. */
3837 compound = c_begin_compound_stmt (true);
3839 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3840 decl = build_decl (input_location,
3841 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3842 lang_hooks.decls.pushdecl (decl);
3844 /* Since a decl is required here by syntax, don't warn if its unused. */
3845 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3846 be what the previous objc implementation did. */
3847 TREE_USED (decl) = 1;
3849 /* Verify that the type of the catch is valid. It must be a pointer
3850 to an Objective-C class, or "id" (which is catch-all). */
3851 type = TREE_TYPE (decl);
3853 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3854 type = NULL;
3855 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3857 error ("@catch parameter is not a known Objective-C class type");
3858 type = error_mark_node;
3860 else if (cur_try_context->catch_list)
3862 /* Examine previous @catch clauses and see if we've already
3863 caught the type in question. */
3864 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3865 for (; !tsi_end_p (i); tsi_next (&i))
3867 tree stmt = tsi_stmt (i);
3868 t = CATCH_TYPES (stmt);
3869 if (t == error_mark_node)
3870 continue;
3871 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3873 warning (0, "exception of type %<%T%> will be caught",
3874 TREE_TYPE (type));
3875 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
3876 TREE_TYPE (t ? t : objc_object_type));
3877 break;
3882 /* Record the data for the catch in the try context so that we can
3883 finalize it later. */
3884 t = build_stmt (input_location, CATCH_EXPR, type, compound);
3885 cur_try_context->current_catch = t;
3887 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3888 t = objc_build_exc_ptr ();
3889 t = convert (TREE_TYPE (decl), t);
3890 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3891 add_stmt (t);
3894 /* Called just after parsing the closing brace of a @catch clause. Close
3895 the open binding level, and record a CATCH_EXPR for it. */
3897 void
3898 objc_finish_catch_clause (void)
3900 tree c = cur_try_context->current_catch;
3901 cur_try_context->current_catch = NULL;
3902 cur_try_context->end_catch_locus = input_location;
3904 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
3905 append_to_statement_list (c, &cur_try_context->catch_list);
3908 /* Called after parsing a @finally clause and its associated BODY.
3909 Record the body for later placement. */
3911 void
3912 objc_build_finally_clause (location_t finally_locus, tree body)
3914 cur_try_context->finally_body = body;
3915 cur_try_context->finally_locus = finally_locus;
3916 cur_try_context->end_finally_locus = input_location;
3919 /* Called to finalize a @try construct. */
3921 tree
3922 objc_finish_try_stmt (void)
3924 struct objc_try_context *c = cur_try_context;
3925 tree stmt;
3927 if (c->catch_list == NULL && c->finally_body == NULL)
3928 error ("%<@try%> without %<@catch%> or %<@finally%>");
3930 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3931 if (flag_objc_sjlj_exceptions)
3933 bool save = in_late_binary_op;
3934 in_late_binary_op = true;
3935 if (!cur_try_context->finally_body)
3937 cur_try_context->finally_locus = input_location;
3938 cur_try_context->end_finally_locus = input_location;
3940 stmt = next_sjlj_build_try_catch_finally ();
3941 in_late_binary_op = save;
3943 else
3945 /* Otherwise, nest the CATCH inside a FINALLY. */
3946 stmt = c->try_body;
3947 if (c->catch_list)
3949 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
3950 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3952 if (c->finally_body)
3954 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
3955 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3958 add_stmt (stmt);
3960 cur_try_context = c->outer;
3961 free (c);
3962 return stmt;
3965 tree
3966 objc_build_throw_stmt (location_t loc, tree throw_expr)
3968 tree args;
3970 if (flag_objc_sjlj_exceptions)
3972 /* On Darwin, ObjC exceptions require a sufficiently recent
3973 version of the runtime, so the user must ask for them explicitly. */
3974 if (!flag_objc_exceptions)
3975 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3976 "exception syntax");
3979 if (throw_expr == NULL)
3981 /* If we're not inside a @catch block, there is no "current
3982 exception" to be rethrown. */
3983 if (cur_try_context == NULL
3984 || cur_try_context->current_catch == NULL)
3986 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
3987 return NULL_TREE;
3990 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3991 value that we get from the runtime. */
3992 throw_expr = objc_build_exc_ptr ();
3995 /* A throw is just a call to the runtime throw function with the
3996 object as a parameter. */
3997 args = tree_cons (NULL, throw_expr, NULL);
3998 return add_stmt (build_function_call (loc,
3999 objc_exception_throw_decl, args));
4002 tree
4003 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4005 tree args, call;
4007 /* First lock the mutex. */
4008 mutex = save_expr (mutex);
4009 args = tree_cons (NULL, mutex, NULL);
4010 call = build_function_call (input_location,
4011 objc_sync_enter_decl, args);
4012 SET_EXPR_LOCATION (call, start_locus);
4013 add_stmt (call);
4015 /* Build the mutex unlock. */
4016 args = tree_cons (NULL, mutex, NULL);
4017 call = build_function_call (input_location,
4018 objc_sync_exit_decl, args);
4019 SET_EXPR_LOCATION (call, input_location);
4021 /* Put the that and the body in a TRY_FINALLY. */
4022 objc_begin_try_stmt (start_locus, body);
4023 objc_build_finally_clause (input_location, call);
4024 return objc_finish_try_stmt ();
4028 /* Predefine the following data type:
4030 struct _objc_exception_data
4032 int buf[OBJC_JBLEN];
4033 void *pointers[4];
4034 }; */
4036 /* The following yuckiness should prevent users from having to #include
4037 <setjmp.h> in their code... */
4039 /* Define to a harmless positive value so the below code doesn't die. */
4040 #ifndef OBJC_JBLEN
4041 #define OBJC_JBLEN 18
4042 #endif
4044 static void
4045 build_next_objc_exception_stuff (void)
4047 tree field_decl, field_decl_chain, index, temp_type;
4049 objc_exception_data_template
4050 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4052 /* int buf[OBJC_JBLEN]; */
4054 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
4055 field_decl = create_field_decl (build_array_type (integer_type_node, index),
4056 "buf");
4057 field_decl_chain = field_decl;
4059 /* void *pointers[4]; */
4061 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
4062 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
4063 "pointers");
4064 chainon (field_decl_chain, field_decl);
4066 objc_finish_struct (objc_exception_data_template, field_decl_chain);
4068 /* int _setjmp(...); */
4069 /* If the user includes <setjmp.h>, this shall be superseded by
4070 'int _setjmp(jmp_buf);' */
4071 temp_type = build_function_type (integer_type_node, NULL_TREE);
4072 objc_setjmp_decl
4073 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4075 /* id objc_exception_extract(struct _objc_exception_data *); */
4076 temp_type
4077 = build_function_type (objc_object_type,
4078 tree_cons (NULL_TREE,
4079 build_pointer_type (objc_exception_data_template),
4080 OBJC_VOID_AT_END));
4081 objc_exception_extract_decl
4082 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4083 NULL_TREE);
4084 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4085 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4086 temp_type
4087 = build_function_type (void_type_node,
4088 tree_cons (NULL_TREE,
4089 build_pointer_type (objc_exception_data_template),
4090 OBJC_VOID_AT_END));
4091 objc_exception_try_enter_decl
4092 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4093 NULL_TREE);
4094 objc_exception_try_exit_decl
4095 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4096 NULL_TREE);
4098 /* int objc_exception_match(id, id); */
4099 temp_type
4100 = build_function_type (integer_type_node,
4101 tree_cons (NULL_TREE, objc_object_type,
4102 tree_cons (NULL_TREE, objc_object_type,
4103 OBJC_VOID_AT_END)));
4104 objc_exception_match_decl
4105 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4106 NULL_TREE);
4108 /* id objc_assign_ivar (id, id, unsigned int); */
4109 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4110 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4111 temp_type
4112 = build_function_type (objc_object_type,
4113 tree_cons
4114 (NULL_TREE, objc_object_type,
4115 tree_cons (NULL_TREE, objc_object_type,
4116 tree_cons (NULL_TREE,
4117 unsigned_type_node,
4118 OBJC_VOID_AT_END))));
4119 objc_assign_ivar_decl
4120 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4121 NULL, NULL_TREE);
4122 #ifdef OFFS_ASSIGNIVAR_FAST
4123 objc_assign_ivar_fast_decl
4124 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4125 NOT_BUILT_IN, NULL, NULL_TREE);
4126 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4127 = tree_cons (get_identifier ("hard_coded_address"),
4128 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4129 NULL_TREE);
4130 #else
4131 /* Default to slower ivar method. */
4132 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4133 #endif
4135 /* id objc_assign_global (id, id *); */
4136 /* id objc_assign_strongCast (id, id *); */
4137 temp_type = build_function_type (objc_object_type,
4138 tree_cons (NULL_TREE, objc_object_type,
4139 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4140 OBJC_VOID_AT_END)));
4141 objc_assign_global_decl
4142 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4143 NULL_TREE);
4144 objc_assign_strong_cast_decl
4145 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4146 NULL_TREE);
4149 static void
4150 build_objc_exception_stuff (void)
4152 tree noreturn_list, nothrow_list, temp_type;
4154 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4155 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4157 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4158 /* void objc_sync_enter(id); */
4159 /* void objc_sync_exit(id); */
4160 temp_type = build_function_type (void_type_node,
4161 tree_cons (NULL_TREE, objc_object_type,
4162 OBJC_VOID_AT_END));
4163 objc_exception_throw_decl
4164 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4165 noreturn_list);
4166 objc_sync_enter_decl
4167 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4168 NULL, nothrow_list);
4169 objc_sync_exit_decl
4170 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4171 NULL, nothrow_list);
4174 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4175 name as the class:
4177 struct <classname> {
4178 struct _objc_class *isa;
4180 }; */
4182 static void
4183 build_private_template (tree klass)
4185 if (!CLASS_STATIC_TEMPLATE (klass))
4187 tree record = objc_build_struct (klass,
4188 get_class_ivars (klass, false),
4189 CLASS_SUPER_NAME (klass));
4191 /* Set the TREE_USED bit for this struct, so that stab generator
4192 can emit stabs for this struct type. */
4193 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4194 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4198 /* Begin code generation for protocols... */
4200 /* struct _objc_protocol {
4201 struct _objc_class *isa;
4202 char *protocol_name;
4203 struct _objc_protocol **protocol_list;
4204 struct _objc__method_prototype_list *instance_methods;
4205 struct _objc__method_prototype_list *class_methods;
4206 }; */
4208 static void
4209 build_protocol_template (void)
4211 tree field_decl, field_decl_chain;
4213 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4215 /* struct _objc_class *isa; */
4216 field_decl = create_field_decl (build_pointer_type
4217 (xref_tag (RECORD_TYPE,
4218 get_identifier (UTAG_CLASS))),
4219 "isa");
4220 field_decl_chain = field_decl;
4222 /* char *protocol_name; */
4223 field_decl = create_field_decl (string_type_node, "protocol_name");
4224 chainon (field_decl_chain, field_decl);
4226 /* struct _objc_protocol **protocol_list; */
4227 field_decl = create_field_decl (build_pointer_type
4228 (build_pointer_type
4229 (objc_protocol_template)),
4230 "protocol_list");
4231 chainon (field_decl_chain, field_decl);
4233 /* struct _objc__method_prototype_list *instance_methods; */
4234 field_decl = create_field_decl (objc_method_proto_list_ptr,
4235 "instance_methods");
4236 chainon (field_decl_chain, field_decl);
4238 /* struct _objc__method_prototype_list *class_methods; */
4239 field_decl = create_field_decl (objc_method_proto_list_ptr,
4240 "class_methods");
4241 chainon (field_decl_chain, field_decl);
4243 objc_finish_struct (objc_protocol_template, field_decl_chain);
4246 static tree
4247 build_descriptor_table_initializer (tree type, tree entries)
4249 tree initlist = NULL_TREE;
4253 tree eltlist = NULL_TREE;
4255 eltlist
4256 = tree_cons (NULL_TREE,
4257 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4258 eltlist
4259 = tree_cons (NULL_TREE,
4260 add_objc_string (METHOD_ENCODING (entries),
4261 meth_var_types),
4262 eltlist);
4264 initlist
4265 = tree_cons (NULL_TREE,
4266 objc_build_constructor (type, nreverse (eltlist)),
4267 initlist);
4269 entries = TREE_CHAIN (entries);
4271 while (entries);
4273 return objc_build_constructor (build_array_type (type, 0),
4274 nreverse (initlist));
4277 /* struct objc_method_prototype_list {
4278 int count;
4279 struct objc_method_prototype {
4280 SEL name;
4281 char *types;
4282 } list[1];
4283 }; */
4285 static tree
4286 build_method_prototype_list_template (tree list_type, int size)
4288 tree objc_ivar_list_record;
4289 tree field_decl, field_decl_chain;
4291 /* Generate an unnamed struct definition. */
4293 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4295 /* int method_count; */
4296 field_decl = create_field_decl (integer_type_node, "method_count");
4297 field_decl_chain = field_decl;
4299 /* struct objc_method method_list[]; */
4300 field_decl = create_field_decl (build_array_type
4301 (list_type,
4302 build_index_type
4303 (build_int_cst (NULL_TREE, size - 1))),
4304 "method_list");
4305 chainon (field_decl_chain, field_decl);
4307 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
4309 return objc_ivar_list_record;
4312 static tree
4313 build_method_prototype_template (void)
4315 tree proto_record;
4316 tree field_decl, field_decl_chain;
4318 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4320 /* SEL _cmd; */
4321 field_decl = create_field_decl (objc_selector_type, "_cmd");
4322 field_decl_chain = field_decl;
4324 /* char *method_types; */
4325 field_decl = create_field_decl (string_type_node, "method_types");
4326 chainon (field_decl_chain, field_decl);
4328 objc_finish_struct (proto_record, field_decl_chain);
4330 return proto_record;
4333 static tree
4334 objc_method_parm_type (tree type)
4336 type = TREE_VALUE (TREE_TYPE (type));
4337 if (TREE_CODE (type) == TYPE_DECL)
4338 type = TREE_TYPE (type);
4339 return type;
4342 static int
4343 objc_encoded_type_size (tree type)
4345 int sz = int_size_in_bytes (type);
4347 /* Make all integer and enum types at least as large
4348 as an int. */
4349 if (sz > 0 && INTEGRAL_TYPE_P (type))
4350 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4351 /* Treat arrays as pointers, since that's how they're
4352 passed in. */
4353 else if (TREE_CODE (type) == ARRAY_TYPE)
4354 sz = int_size_in_bytes (ptr_type_node);
4355 return sz;
4358 static tree
4359 encode_method_prototype (tree method_decl)
4361 tree parms;
4362 int parm_offset, i;
4363 char buf[40];
4364 tree result;
4366 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4367 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4369 /* Encode return type. */
4370 encode_type (objc_method_parm_type (method_decl),
4371 obstack_object_size (&util_obstack),
4372 OBJC_ENCODE_INLINE_DEFS);
4374 /* Stack size. */
4375 /* The first two arguments (self and _cmd) are pointers; account for
4376 their size. */
4377 i = int_size_in_bytes (ptr_type_node);
4378 parm_offset = 2 * i;
4379 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4380 parms = TREE_CHAIN (parms))
4382 tree type = objc_method_parm_type (parms);
4383 int sz = objc_encoded_type_size (type);
4385 /* If a type size is not known, bail out. */
4386 if (sz < 0)
4388 error ("type %q+D does not have a known size",
4389 type);
4390 /* Pretend that the encoding succeeded; the compilation will
4391 fail nevertheless. */
4392 goto finish_encoding;
4394 parm_offset += sz;
4397 sprintf (buf, "%d@0:%d", parm_offset, i);
4398 obstack_grow (&util_obstack, buf, strlen (buf));
4400 /* Argument types. */
4401 parm_offset = 2 * i;
4402 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4403 parms = TREE_CHAIN (parms))
4405 tree type = objc_method_parm_type (parms);
4407 /* Process argument qualifiers for user supplied arguments. */
4408 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4410 /* Type. */
4411 encode_type (type, obstack_object_size (&util_obstack),
4412 OBJC_ENCODE_INLINE_DEFS);
4414 /* Compute offset. */
4415 sprintf (buf, "%d", parm_offset);
4416 parm_offset += objc_encoded_type_size (type);
4418 obstack_grow (&util_obstack, buf, strlen (buf));
4421 finish_encoding:
4422 obstack_1grow (&util_obstack, '\0');
4423 result = get_identifier (XOBFINISH (&util_obstack, char *));
4424 obstack_free (&util_obstack, util_firstobj);
4425 return result;
4428 static tree
4429 generate_descriptor_table (tree type, const char *name, int size, tree list,
4430 tree proto)
4432 tree decl, initlist;
4434 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4436 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4437 initlist = tree_cons (NULL_TREE, list, initlist);
4439 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4441 return decl;
4444 static void
4445 generate_method_descriptors (tree protocol)
4447 tree initlist, chain, method_list_template;
4448 int size;
4450 if (!objc_method_prototype_template)
4451 objc_method_prototype_template = build_method_prototype_template ();
4453 chain = PROTOCOL_CLS_METHODS (protocol);
4454 if (chain)
4456 size = list_length (chain);
4458 method_list_template
4459 = build_method_prototype_list_template (objc_method_prototype_template,
4460 size);
4462 initlist
4463 = build_descriptor_table_initializer (objc_method_prototype_template,
4464 chain);
4466 UOBJC_CLASS_METHODS_decl
4467 = generate_descriptor_table (method_list_template,
4468 "_OBJC_PROTOCOL_CLASS_METHODS",
4469 size, initlist, protocol);
4471 else
4472 UOBJC_CLASS_METHODS_decl = 0;
4474 chain = PROTOCOL_NST_METHODS (protocol);
4475 if (chain)
4477 size = list_length (chain);
4479 method_list_template
4480 = build_method_prototype_list_template (objc_method_prototype_template,
4481 size);
4482 initlist
4483 = build_descriptor_table_initializer (objc_method_prototype_template,
4484 chain);
4486 UOBJC_INSTANCE_METHODS_decl
4487 = generate_descriptor_table (method_list_template,
4488 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4489 size, initlist, protocol);
4491 else
4492 UOBJC_INSTANCE_METHODS_decl = 0;
4495 static void
4496 generate_protocol_references (tree plist)
4498 tree lproto;
4500 /* Forward declare protocols referenced. */
4501 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4503 tree proto = TREE_VALUE (lproto);
4505 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4506 && PROTOCOL_NAME (proto))
4508 if (! PROTOCOL_FORWARD_DECL (proto))
4509 build_protocol_reference (proto);
4511 if (PROTOCOL_LIST (proto))
4512 generate_protocol_references (PROTOCOL_LIST (proto));
4517 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4518 current class. */
4519 #ifdef OBJCPLUS
4520 static void
4521 objc_generate_cxx_ctor_or_dtor (bool dtor)
4523 tree fn, body, compound_stmt, ivar;
4525 /* - (id) .cxx_construct { ... return self; } */
4526 /* - (void) .cxx_construct { ... } */
4528 objc_set_method_type (MINUS_EXPR);
4529 objc_start_method_definition
4530 (objc_build_method_signature (build_tree_list (NULL_TREE,
4531 dtor
4532 ? void_type_node
4533 : objc_object_type),
4534 get_identifier (dtor
4535 ? TAG_CXX_DESTRUCT
4536 : TAG_CXX_CONSTRUCT),
4537 make_node (TREE_LIST),
4538 false));
4539 body = begin_function_body ();
4540 compound_stmt = begin_compound_stmt (0);
4542 ivar = CLASS_IVARS (implementation_template);
4543 /* Destroy ivars in reverse order. */
4544 if (dtor)
4545 ivar = nreverse (copy_list (ivar));
4547 for (; ivar; ivar = TREE_CHAIN (ivar))
4549 if (TREE_CODE (ivar) == FIELD_DECL)
4551 tree type = TREE_TYPE (ivar);
4553 /* Call the ivar's default constructor or destructor. Do not
4554 call the destructor unless a corresponding constructor call
4555 has also been made (or is not needed). */
4556 if (MAYBE_CLASS_TYPE_P (type)
4557 && (dtor
4558 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4559 && (!TYPE_NEEDS_CONSTRUCTING (type)
4560 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4561 : (TYPE_NEEDS_CONSTRUCTING (type)
4562 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4563 finish_expr_stmt
4564 (build_special_member_call
4565 (build_ivar_reference (DECL_NAME (ivar)),
4566 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4567 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
4571 /* The constructor returns 'self'. */
4572 if (!dtor)
4573 finish_return_stmt (self_decl);
4575 finish_compound_stmt (compound_stmt);
4576 finish_function_body (body);
4577 fn = current_function_decl;
4578 finish_function ();
4579 objc_finish_method_definition (fn);
4582 /* The following routine will examine the current @interface for any
4583 non-POD C++ ivars requiring non-trivial construction and/or
4584 destruction, and then synthesize special '- .cxx_construct' and/or
4585 '- .cxx_destruct' methods which will run the appropriate
4586 construction or destruction code. Note that ivars inherited from
4587 super-classes are _not_ considered. */
4588 static void
4589 objc_generate_cxx_cdtors (void)
4591 bool need_ctor = false, need_dtor = false;
4592 tree ivar;
4594 /* We do not want to do this for categories, since they do not have
4595 their own ivars. */
4597 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4598 return;
4600 /* First, determine if we even need a constructor and/or destructor. */
4602 for (ivar = CLASS_IVARS (implementation_template); ivar;
4603 ivar = TREE_CHAIN (ivar))
4605 if (TREE_CODE (ivar) == FIELD_DECL)
4607 tree type = TREE_TYPE (ivar);
4609 if (MAYBE_CLASS_TYPE_P (type))
4611 if (TYPE_NEEDS_CONSTRUCTING (type)
4612 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4613 /* NB: If a default constructor is not available, we will not
4614 be able to initialize this ivar; the add_instance_variable()
4615 routine will already have warned about this. */
4616 need_ctor = true;
4618 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4619 && (!TYPE_NEEDS_CONSTRUCTING (type)
4620 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4621 /* NB: If a default constructor is not available, we will not
4622 call the destructor either, for symmetry. */
4623 need_dtor = true;
4628 /* Generate '- .cxx_construct' if needed. */
4630 if (need_ctor)
4631 objc_generate_cxx_ctor_or_dtor (false);
4633 /* Generate '- .cxx_destruct' if needed. */
4635 if (need_dtor)
4636 objc_generate_cxx_ctor_or_dtor (true);
4638 /* The 'imp_list' variable points at an imp_entry record for the current
4639 @implementation. Record the existence of '- .cxx_construct' and/or
4640 '- .cxx_destruct' methods therein; it will be included in the
4641 metadata for the class. */
4642 if (flag_next_runtime)
4643 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4645 #endif
4647 /* For each protocol which was referenced either from a @protocol()
4648 expression, or because a class/category implements it (then a
4649 pointer to the protocol is stored in the struct describing the
4650 class/category), we create a statically allocated instance of the
4651 Protocol class. The code is written in such a way as to generate
4652 as few Protocol objects as possible; we generate a unique Protocol
4653 instance for each protocol, and we don't generate a Protocol
4654 instance if the protocol is never referenced (either from a
4655 @protocol() or from a class/category implementation). These
4656 statically allocated objects can be referred to via the static
4657 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4659 The statically allocated Protocol objects that we generate here
4660 need to be fixed up at runtime in order to be used: the 'isa'
4661 pointer of the objects need to be set up to point to the 'Protocol'
4662 class, as known at runtime.
4664 The NeXT runtime fixes up all protocols at program startup time,
4665 before main() is entered. It uses a low-level trick to look up all
4666 those symbols, then loops on them and fixes them up.
4668 The GNU runtime as well fixes up all protocols before user code
4669 from the module is executed; it requires pointers to those symbols
4670 to be put in the objc_symtab (which is then passed as argument to
4671 the function __objc_exec_class() which the compiler sets up to be
4672 executed automatically when the module is loaded); setup of those
4673 Protocol objects happen in two ways in the GNU runtime: all
4674 Protocol objects referred to by a class or category implementation
4675 are fixed up when the class/category is loaded; all Protocol
4676 objects referred to by a @protocol() expression are added by the
4677 compiler to the list of statically allocated instances to fixup
4678 (the same list holding the statically allocated constant string
4679 objects). Because, as explained above, the compiler generates as
4680 few Protocol objects as possible, some Protocol object might end up
4681 being referenced multiple times when compiled with the GNU runtime,
4682 and end up being fixed up multiple times at runtime initialization.
4683 But that doesn't hurt, it's just a little inefficient. */
4685 static void
4686 generate_protocols (void)
4688 tree p, encoding;
4689 tree decl;
4690 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4692 /* If a protocol was directly referenced, pull in indirect references. */
4693 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4694 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4695 generate_protocol_references (PROTOCOL_LIST (p));
4697 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4699 tree nst_methods = PROTOCOL_NST_METHODS (p);
4700 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4702 /* If protocol wasn't referenced, don't generate any code. */
4703 decl = PROTOCOL_FORWARD_DECL (p);
4705 if (!decl)
4706 continue;
4708 /* Make sure we link in the Protocol class. */
4709 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4711 while (nst_methods)
4713 if (! METHOD_ENCODING (nst_methods))
4715 encoding = encode_method_prototype (nst_methods);
4716 METHOD_ENCODING (nst_methods) = encoding;
4718 nst_methods = TREE_CHAIN (nst_methods);
4721 while (cls_methods)
4723 if (! METHOD_ENCODING (cls_methods))
4725 encoding = encode_method_prototype (cls_methods);
4726 METHOD_ENCODING (cls_methods) = encoding;
4729 cls_methods = TREE_CHAIN (cls_methods);
4731 generate_method_descriptors (p);
4733 if (PROTOCOL_LIST (p))
4734 refs_decl = generate_protocol_list (p);
4735 else
4736 refs_decl = 0;
4738 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4739 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4741 if (refs_decl)
4742 refs_expr = convert (build_pointer_type (build_pointer_type
4743 (objc_protocol_template)),
4744 build_unary_op (input_location,
4745 ADDR_EXPR, refs_decl, 0));
4746 else
4747 refs_expr = build_int_cst (NULL_TREE, 0);
4749 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4750 by generate_method_descriptors, which is called above. */
4751 initlist = build_protocol_initializer (TREE_TYPE (decl),
4752 protocol_name_expr, refs_expr,
4753 UOBJC_INSTANCE_METHODS_decl,
4754 UOBJC_CLASS_METHODS_decl);
4755 finish_var_decl (decl, initlist);
4759 static tree
4760 build_protocol_initializer (tree type, tree protocol_name,
4761 tree protocol_list, tree instance_methods,
4762 tree class_methods)
4764 tree initlist = NULL_TREE, expr;
4765 tree cast_type = build_pointer_type
4766 (xref_tag (RECORD_TYPE,
4767 get_identifier (UTAG_CLASS)));
4769 /* Filling the "isa" in with one allows the runtime system to
4770 detect that the version change...should remove before final release. */
4772 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4773 initlist = tree_cons (NULL_TREE, expr, initlist);
4774 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4775 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4777 if (!instance_methods)
4778 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4779 else
4781 expr = convert (objc_method_proto_list_ptr,
4782 build_unary_op (input_location,
4783 ADDR_EXPR, instance_methods, 0));
4784 initlist = tree_cons (NULL_TREE, expr, initlist);
4787 if (!class_methods)
4788 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4789 else
4791 expr = convert (objc_method_proto_list_ptr,
4792 build_unary_op (input_location,
4793 ADDR_EXPR, class_methods, 0));
4794 initlist = tree_cons (NULL_TREE, expr, initlist);
4797 return objc_build_constructor (type, nreverse (initlist));
4800 /* struct _objc_category {
4801 char *category_name;
4802 char *class_name;
4803 struct _objc_method_list *instance_methods;
4804 struct _objc_method_list *class_methods;
4805 struct _objc_protocol_list *protocols;
4806 }; */
4808 static void
4809 build_category_template (void)
4811 tree field_decl, field_decl_chain;
4813 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
4815 /* char *category_name; */
4816 field_decl = create_field_decl (string_type_node, "category_name");
4817 field_decl_chain = field_decl;
4819 /* char *class_name; */
4820 field_decl = create_field_decl (string_type_node, "class_name");
4821 chainon (field_decl_chain, field_decl);
4823 /* struct _objc_method_list *instance_methods; */
4824 field_decl = create_field_decl (objc_method_list_ptr,
4825 "instance_methods");
4826 chainon (field_decl_chain, field_decl);
4828 /* struct _objc_method_list *class_methods; */
4829 field_decl = create_field_decl (objc_method_list_ptr,
4830 "class_methods");
4831 chainon (field_decl_chain, field_decl);
4833 /* struct _objc_protocol **protocol_list; */
4834 field_decl = create_field_decl (build_pointer_type
4835 (build_pointer_type
4836 (objc_protocol_template)),
4837 "protocol_list");
4838 chainon (field_decl_chain, field_decl);
4840 objc_finish_struct (objc_category_template, field_decl_chain);
4843 /* struct _objc_selector {
4844 SEL sel_id;
4845 char *sel_type;
4846 }; */
4848 static void
4849 build_selector_template (void)
4851 tree field_decl, field_decl_chain;
4853 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
4855 /* SEL sel_id; */
4856 field_decl = create_field_decl (objc_selector_type, "sel_id");
4857 field_decl_chain = field_decl;
4859 /* char *sel_type; */
4860 field_decl = create_field_decl (string_type_node, "sel_type");
4861 chainon (field_decl_chain, field_decl);
4863 objc_finish_struct (objc_selector_template, field_decl_chain);
4866 /* struct _objc_class {
4867 struct _objc_class *isa;
4868 struct _objc_class *super_class;
4869 char *name;
4870 long version;
4871 long info;
4872 long instance_size;
4873 struct _objc_ivar_list *ivars;
4874 struct _objc_method_list *methods;
4875 #ifdef __NEXT_RUNTIME__
4876 struct objc_cache *cache;
4877 #else
4878 struct sarray *dtable;
4879 struct _objc_class *subclass_list;
4880 struct _objc_class *sibling_class;
4881 #endif
4882 struct _objc_protocol_list *protocols;
4883 #ifdef __NEXT_RUNTIME__
4884 void *sel_id;
4885 #endif
4886 void *gc_object_type;
4887 }; */
4889 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4890 the NeXT/Apple runtime; still, the compiler must generate them to
4891 maintain backward binary compatibility (and to allow for future
4892 expansion). */
4894 static void
4895 build_class_template (void)
4897 tree field_decl, field_decl_chain;
4899 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
4901 /* struct _objc_class *isa; */
4902 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4903 "isa");
4904 field_decl_chain = field_decl;
4906 /* struct _objc_class *super_class; */
4907 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4908 "super_class");
4909 chainon (field_decl_chain, field_decl);
4911 /* char *name; */
4912 field_decl = create_field_decl (string_type_node, "name");
4913 chainon (field_decl_chain, field_decl);
4915 /* long version; */
4916 field_decl = create_field_decl (long_integer_type_node, "version");
4917 chainon (field_decl_chain, field_decl);
4919 /* long info; */
4920 field_decl = create_field_decl (long_integer_type_node, "info");
4921 chainon (field_decl_chain, field_decl);
4923 /* long instance_size; */
4924 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4925 chainon (field_decl_chain, field_decl);
4927 /* struct _objc_ivar_list *ivars; */
4928 field_decl = create_field_decl (objc_ivar_list_ptr,
4929 "ivars");
4930 chainon (field_decl_chain, field_decl);
4932 /* struct _objc_method_list *methods; */
4933 field_decl = create_field_decl (objc_method_list_ptr,
4934 "methods");
4935 chainon (field_decl_chain, field_decl);
4937 if (flag_next_runtime)
4939 /* struct objc_cache *cache; */
4940 field_decl = create_field_decl (build_pointer_type
4941 (xref_tag (RECORD_TYPE,
4942 get_identifier
4943 ("objc_cache"))),
4944 "cache");
4945 chainon (field_decl_chain, field_decl);
4947 else
4949 /* struct sarray *dtable; */
4950 field_decl = create_field_decl (build_pointer_type
4951 (xref_tag (RECORD_TYPE,
4952 get_identifier
4953 ("sarray"))),
4954 "dtable");
4955 chainon (field_decl_chain, field_decl);
4957 /* struct objc_class *subclass_list; */
4958 field_decl = create_field_decl (build_pointer_type
4959 (objc_class_template),
4960 "subclass_list");
4961 chainon (field_decl_chain, field_decl);
4963 /* struct objc_class *sibling_class; */
4964 field_decl = create_field_decl (build_pointer_type
4965 (objc_class_template),
4966 "sibling_class");
4967 chainon (field_decl_chain, field_decl);
4970 /* struct _objc_protocol **protocol_list; */
4971 field_decl = create_field_decl (build_pointer_type
4972 (build_pointer_type
4973 (xref_tag (RECORD_TYPE,
4974 get_identifier
4975 (UTAG_PROTOCOL)))),
4976 "protocol_list");
4977 chainon (field_decl_chain, field_decl);
4979 if (flag_next_runtime)
4981 /* void *sel_id; */
4982 field_decl = create_field_decl (build_pointer_type (void_type_node),
4983 "sel_id");
4984 chainon (field_decl_chain, field_decl);
4987 /* void *gc_object_type; */
4988 field_decl = create_field_decl (build_pointer_type (void_type_node),
4989 "gc_object_type");
4990 chainon (field_decl_chain, field_decl);
4992 objc_finish_struct (objc_class_template, field_decl_chain);
4995 /* Generate appropriate forward declarations for an implementation. */
4997 static void
4998 synth_forward_declarations (void)
5000 tree an_id;
5002 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5003 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5004 objc_class_template);
5006 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5007 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5008 objc_class_template);
5010 /* Pre-build the following entities - for speed/convenience. */
5012 an_id = get_identifier ("super_class");
5013 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5014 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5017 static void
5018 error_with_ivar (const char *message, tree decl)
5020 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5021 message, identifier_to_locale (gen_declaration (decl)));
5025 static void
5026 check_ivars (tree inter, tree imp)
5028 tree intdecls = CLASS_RAW_IVARS (inter);
5029 tree impdecls = CLASS_RAW_IVARS (imp);
5031 while (1)
5033 tree t1, t2;
5035 #ifdef OBJCPLUS
5036 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5037 intdecls = TREE_CHAIN (intdecls);
5038 #endif
5039 if (intdecls == 0 && impdecls == 0)
5040 break;
5041 if (intdecls == 0 || impdecls == 0)
5043 error ("inconsistent instance variable specification");
5044 break;
5047 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5049 if (!comptypes (t1, t2)
5050 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5051 DECL_INITIAL (impdecls)))
5053 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5055 error_with_ivar ("conflicting instance variable type",
5056 impdecls);
5057 error_with_ivar ("previous declaration of",
5058 intdecls);
5060 else /* both the type and the name don't match */
5062 error ("inconsistent instance variable specification");
5063 break;
5067 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5069 error_with_ivar ("conflicting instance variable name",
5070 impdecls);
5071 error_with_ivar ("previous declaration of",
5072 intdecls);
5075 intdecls = TREE_CHAIN (intdecls);
5076 impdecls = TREE_CHAIN (impdecls);
5080 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5081 This needs to be done just once per compilation. */
5083 /* struct _objc_super {
5084 struct _objc_object *self;
5085 struct _objc_class *super_class;
5086 }; */
5088 static void
5089 build_super_template (void)
5091 tree field_decl, field_decl_chain;
5093 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5095 /* struct _objc_object *self; */
5096 field_decl = create_field_decl (objc_object_type, "self");
5097 field_decl_chain = field_decl;
5099 /* struct _objc_class *super_class; */
5100 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5101 "super_class");
5102 chainon (field_decl_chain, field_decl);
5104 objc_finish_struct (objc_super_template, field_decl_chain);
5107 /* struct _objc_ivar {
5108 char *ivar_name;
5109 char *ivar_type;
5110 int ivar_offset;
5111 }; */
5113 static tree
5114 build_ivar_template (void)
5116 tree objc_ivar_id, objc_ivar_record;
5117 tree field_decl, field_decl_chain;
5119 objc_ivar_id = get_identifier (UTAG_IVAR);
5120 objc_ivar_record = objc_start_struct (objc_ivar_id);
5122 /* char *ivar_name; */
5123 field_decl = create_field_decl (string_type_node, "ivar_name");
5124 field_decl_chain = field_decl;
5126 /* char *ivar_type; */
5127 field_decl = create_field_decl (string_type_node, "ivar_type");
5128 chainon (field_decl_chain, field_decl);
5130 /* int ivar_offset; */
5131 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5132 chainon (field_decl_chain, field_decl);
5134 objc_finish_struct (objc_ivar_record, field_decl_chain);
5136 return objc_ivar_record;
5139 /* struct {
5140 int ivar_count;
5141 struct objc_ivar ivar_list[ivar_count];
5142 }; */
5144 static tree
5145 build_ivar_list_template (tree list_type, int size)
5147 tree objc_ivar_list_record;
5148 tree field_decl, field_decl_chain;
5150 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5152 /* int ivar_count; */
5153 field_decl = create_field_decl (integer_type_node, "ivar_count");
5154 field_decl_chain = field_decl;
5156 /* struct objc_ivar ivar_list[]; */
5157 field_decl = create_field_decl (build_array_type
5158 (list_type,
5159 build_index_type
5160 (build_int_cst (NULL_TREE, size - 1))),
5161 "ivar_list");
5162 chainon (field_decl_chain, field_decl);
5164 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5166 return objc_ivar_list_record;
5169 /* struct {
5170 struct _objc__method_prototype_list *method_next;
5171 int method_count;
5172 struct objc_method method_list[method_count];
5173 }; */
5175 static tree
5176 build_method_list_template (tree list_type, int size)
5178 tree objc_ivar_list_record;
5179 tree field_decl, field_decl_chain;
5181 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5183 /* struct _objc__method_prototype_list *method_next; */
5184 field_decl = create_field_decl (objc_method_proto_list_ptr,
5185 "method_next");
5186 field_decl_chain = field_decl;
5188 /* int method_count; */
5189 field_decl = create_field_decl (integer_type_node, "method_count");
5190 chainon (field_decl_chain, field_decl);
5192 /* struct objc_method method_list[]; */
5193 field_decl = create_field_decl (build_array_type
5194 (list_type,
5195 build_index_type
5196 (build_int_cst (NULL_TREE, size - 1))),
5197 "method_list");
5198 chainon (field_decl_chain, field_decl);
5200 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5202 return objc_ivar_list_record;
5205 static tree
5206 build_ivar_list_initializer (tree type, tree field_decl)
5208 tree initlist = NULL_TREE;
5212 tree ivar = NULL_TREE;
5214 /* Set name. */
5215 if (DECL_NAME (field_decl))
5216 ivar = tree_cons (NULL_TREE,
5217 add_objc_string (DECL_NAME (field_decl),
5218 meth_var_names),
5219 ivar);
5220 else
5221 /* Unnamed bit-field ivar (yuck). */
5222 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5224 /* Set type. */
5225 encode_field_decl (field_decl,
5226 obstack_object_size (&util_obstack),
5227 OBJC_ENCODE_DONT_INLINE_DEFS);
5229 /* Null terminate string. */
5230 obstack_1grow (&util_obstack, 0);
5231 ivar
5232 = tree_cons
5233 (NULL_TREE,
5234 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5235 meth_var_types),
5236 ivar);
5237 obstack_free (&util_obstack, util_firstobj);
5239 /* Set offset. */
5240 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5241 initlist = tree_cons (NULL_TREE,
5242 objc_build_constructor (type, nreverse (ivar)),
5243 initlist);
5245 field_decl = TREE_CHAIN (field_decl);
5246 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5248 while (field_decl);
5250 return objc_build_constructor (build_array_type (type, 0),
5251 nreverse (initlist));
5254 static tree
5255 generate_ivars_list (tree type, const char *name, int size, tree list)
5257 tree decl, initlist;
5259 decl = start_var_decl (type, synth_id_with_class_suffix
5260 (name, objc_implementation_context));
5262 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5263 initlist = tree_cons (NULL_TREE, list, initlist);
5265 finish_var_decl (decl,
5266 objc_build_constructor (TREE_TYPE (decl),
5267 nreverse (initlist)));
5269 return decl;
5272 /* Count only the fields occurring in T. */
5274 static int
5275 ivar_list_length (tree t)
5277 int count = 0;
5279 for (; t; t = TREE_CHAIN (t))
5280 if (TREE_CODE (t) == FIELD_DECL)
5281 ++count;
5283 return count;
5286 static void
5287 generate_ivar_lists (void)
5289 tree initlist, ivar_list_template, chain;
5290 int size;
5292 generating_instance_variables = 1;
5294 if (!objc_ivar_template)
5295 objc_ivar_template = build_ivar_template ();
5297 /* Only generate class variables for the root of the inheritance
5298 hierarchy since these will be the same for every class. */
5300 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5301 && (chain = TYPE_FIELDS (objc_class_template)))
5303 size = ivar_list_length (chain);
5305 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5306 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5308 UOBJC_CLASS_VARIABLES_decl
5309 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5310 size, initlist);
5312 else
5313 UOBJC_CLASS_VARIABLES_decl = 0;
5315 chain = CLASS_IVARS (implementation_template);
5316 if (chain)
5318 size = ivar_list_length (chain);
5319 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5320 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5322 UOBJC_INSTANCE_VARIABLES_decl
5323 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5324 size, initlist);
5326 else
5327 UOBJC_INSTANCE_VARIABLES_decl = 0;
5329 generating_instance_variables = 0;
5332 static tree
5333 build_dispatch_table_initializer (tree type, tree entries)
5335 tree initlist = NULL_TREE;
5339 tree elemlist = NULL_TREE;
5341 elemlist = tree_cons (NULL_TREE,
5342 build_selector (METHOD_SEL_NAME (entries)),
5343 NULL_TREE);
5345 /* Generate the method encoding if we don't have one already. */
5346 if (! METHOD_ENCODING (entries))
5347 METHOD_ENCODING (entries) =
5348 encode_method_prototype (entries);
5350 elemlist = tree_cons (NULL_TREE,
5351 add_objc_string (METHOD_ENCODING (entries),
5352 meth_var_types),
5353 elemlist);
5355 elemlist
5356 = tree_cons (NULL_TREE,
5357 convert (ptr_type_node,
5358 build_unary_op (input_location, ADDR_EXPR,
5359 METHOD_DEFINITION (entries), 1)),
5360 elemlist);
5362 initlist = tree_cons (NULL_TREE,
5363 objc_build_constructor (type, nreverse (elemlist)),
5364 initlist);
5366 entries = TREE_CHAIN (entries);
5368 while (entries);
5370 return objc_build_constructor (build_array_type (type, 0),
5371 nreverse (initlist));
5374 /* To accomplish method prototyping without generating all kinds of
5375 inane warnings, the definition of the dispatch table entries were
5376 changed from:
5378 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5380 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5382 static tree
5383 build_method_template (void)
5385 tree _SLT_record;
5386 tree field_decl, field_decl_chain;
5388 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5390 /* SEL _cmd; */
5391 field_decl = create_field_decl (objc_selector_type, "_cmd");
5392 field_decl_chain = field_decl;
5394 /* char *method_types; */
5395 field_decl = create_field_decl (string_type_node, "method_types");
5396 chainon (field_decl_chain, field_decl);
5398 /* void *_imp; */
5399 field_decl = create_field_decl (build_pointer_type (void_type_node),
5400 "_imp");
5401 chainon (field_decl_chain, field_decl);
5403 objc_finish_struct (_SLT_record, field_decl_chain);
5405 return _SLT_record;
5409 static tree
5410 generate_dispatch_table (tree type, const char *name, int size, tree list)
5412 tree decl, initlist;
5414 decl = start_var_decl (type, synth_id_with_class_suffix
5415 (name, objc_implementation_context));
5417 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5418 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5419 initlist = tree_cons (NULL_TREE, list, initlist);
5421 finish_var_decl (decl,
5422 objc_build_constructor (TREE_TYPE (decl),
5423 nreverse (initlist)));
5425 return decl;
5428 static void
5429 mark_referenced_methods (void)
5431 struct imp_entry *impent;
5432 tree chain;
5434 for (impent = imp_list; impent; impent = impent->next)
5436 chain = CLASS_CLS_METHODS (impent->imp_context);
5437 while (chain)
5439 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5440 chain = TREE_CHAIN (chain);
5443 chain = CLASS_NST_METHODS (impent->imp_context);
5444 while (chain)
5446 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5447 chain = TREE_CHAIN (chain);
5452 static void
5453 generate_dispatch_tables (void)
5455 tree initlist, chain, method_list_template;
5456 int size;
5458 if (!objc_method_template)
5459 objc_method_template = build_method_template ();
5461 chain = CLASS_CLS_METHODS (objc_implementation_context);
5462 if (chain)
5464 size = list_length (chain);
5466 method_list_template
5467 = build_method_list_template (objc_method_template, size);
5468 initlist
5469 = build_dispatch_table_initializer (objc_method_template, chain);
5471 UOBJC_CLASS_METHODS_decl
5472 = generate_dispatch_table (method_list_template,
5473 ((TREE_CODE (objc_implementation_context)
5474 == CLASS_IMPLEMENTATION_TYPE)
5475 ? "_OBJC_CLASS_METHODS"
5476 : "_OBJC_CATEGORY_CLASS_METHODS"),
5477 size, initlist);
5479 else
5480 UOBJC_CLASS_METHODS_decl = 0;
5482 chain = CLASS_NST_METHODS (objc_implementation_context);
5483 if (chain)
5485 size = list_length (chain);
5487 method_list_template
5488 = build_method_list_template (objc_method_template, size);
5489 initlist
5490 = build_dispatch_table_initializer (objc_method_template, chain);
5492 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5493 UOBJC_INSTANCE_METHODS_decl
5494 = generate_dispatch_table (method_list_template,
5495 "_OBJC_INSTANCE_METHODS",
5496 size, initlist);
5497 else
5498 /* We have a category. */
5499 UOBJC_INSTANCE_METHODS_decl
5500 = generate_dispatch_table (method_list_template,
5501 "_OBJC_CATEGORY_INSTANCE_METHODS",
5502 size, initlist);
5504 else
5505 UOBJC_INSTANCE_METHODS_decl = 0;
5508 static tree
5509 generate_protocol_list (tree i_or_p)
5511 tree initlist;
5512 tree refs_decl, lproto, e, plist;
5513 int size = 0;
5514 const char *ref_name;
5516 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5517 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5518 plist = CLASS_PROTOCOL_LIST (i_or_p);
5519 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5520 plist = PROTOCOL_LIST (i_or_p);
5521 else
5522 abort ();
5524 /* Compute size. */
5525 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5526 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5527 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5528 size++;
5530 /* Build initializer. */
5531 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5532 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5533 initlist = tree_cons (NULL_TREE, e, initlist);
5535 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5537 tree pval = TREE_VALUE (lproto);
5539 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5540 && PROTOCOL_FORWARD_DECL (pval))
5542 e = build_unary_op (input_location, ADDR_EXPR,
5543 PROTOCOL_FORWARD_DECL (pval), 0);
5544 initlist = tree_cons (NULL_TREE, e, initlist);
5548 /* static struct objc_protocol *refs[n]; */
5550 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5551 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5552 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5553 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5554 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5555 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5556 else
5557 abort ();
5559 refs_decl = start_var_decl
5560 (build_array_type
5561 (build_pointer_type (objc_protocol_template),
5562 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5563 ref_name);
5565 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5566 nreverse (initlist)));
5568 return refs_decl;
5571 static tree
5572 build_category_initializer (tree type, tree cat_name, tree class_name,
5573 tree instance_methods, tree class_methods,
5574 tree protocol_list)
5576 tree initlist = NULL_TREE, expr;
5578 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5579 initlist = tree_cons (NULL_TREE, class_name, initlist);
5581 if (!instance_methods)
5582 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5583 else
5585 expr = convert (objc_method_list_ptr,
5586 build_unary_op (input_location, ADDR_EXPR,
5587 instance_methods, 0));
5588 initlist = tree_cons (NULL_TREE, expr, initlist);
5590 if (!class_methods)
5591 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5592 else
5594 expr = convert (objc_method_list_ptr,
5595 build_unary_op (input_location, ADDR_EXPR,
5596 class_methods, 0));
5597 initlist = tree_cons (NULL_TREE, expr, initlist);
5600 /* protocol_list = */
5601 if (!protocol_list)
5602 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5603 else
5605 expr = convert (build_pointer_type
5606 (build_pointer_type
5607 (objc_protocol_template)),
5608 build_unary_op (input_location, ADDR_EXPR,
5609 protocol_list, 0));
5610 initlist = tree_cons (NULL_TREE, expr, initlist);
5613 return objc_build_constructor (type, nreverse (initlist));
5616 /* struct _objc_class {
5617 struct objc_class *isa;
5618 struct objc_class *super_class;
5619 char *name;
5620 long version;
5621 long info;
5622 long instance_size;
5623 struct objc_ivar_list *ivars;
5624 struct objc_method_list *methods;
5625 if (flag_next_runtime)
5626 struct objc_cache *cache;
5627 else {
5628 struct sarray *dtable;
5629 struct objc_class *subclass_list;
5630 struct objc_class *sibling_class;
5632 struct objc_protocol_list *protocols;
5633 if (flag_next_runtime)
5634 void *sel_id;
5635 void *gc_object_type;
5636 }; */
5638 static tree
5639 build_shared_structure_initializer (tree type, tree isa, tree super,
5640 tree name, tree size, int status,
5641 tree dispatch_table, tree ivar_list,
5642 tree protocol_list)
5644 tree initlist = NULL_TREE, expr;
5646 /* isa = */
5647 initlist = tree_cons (NULL_TREE, isa, initlist);
5649 /* super_class = */
5650 initlist = tree_cons (NULL_TREE, super, initlist);
5652 /* name = */
5653 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5655 /* version = */
5656 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5657 initlist);
5659 /* info = */
5660 initlist = tree_cons (NULL_TREE,
5661 build_int_cst (long_integer_type_node, status),
5662 initlist);
5664 /* instance_size = */
5665 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5666 initlist);
5668 /* objc_ivar_list = */
5669 if (!ivar_list)
5670 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5671 else
5673 expr = convert (objc_ivar_list_ptr,
5674 build_unary_op (input_location, ADDR_EXPR,
5675 ivar_list, 0));
5676 initlist = tree_cons (NULL_TREE, expr, initlist);
5679 /* objc_method_list = */
5680 if (!dispatch_table)
5681 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5682 else
5684 expr = convert (objc_method_list_ptr,
5685 build_unary_op (input_location, ADDR_EXPR,
5686 dispatch_table, 0));
5687 initlist = tree_cons (NULL_TREE, expr, initlist);
5690 if (flag_next_runtime)
5691 /* method_cache = */
5692 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5693 else
5695 /* dtable = */
5696 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5698 /* subclass_list = */
5699 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5701 /* sibling_class = */
5702 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5705 /* protocol_list = */
5706 if (! protocol_list)
5707 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5708 else
5710 expr = convert (build_pointer_type
5711 (build_pointer_type
5712 (objc_protocol_template)),
5713 build_unary_op (input_location, ADDR_EXPR,
5714 protocol_list, 0));
5715 initlist = tree_cons (NULL_TREE, expr, initlist);
5718 if (flag_next_runtime)
5719 /* sel_id = NULL */
5720 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5722 /* gc_object_type = NULL */
5723 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5725 return objc_build_constructor (type, nreverse (initlist));
5728 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5730 static inline tree
5731 lookup_category (tree klass, tree cat_name)
5733 tree category = CLASS_CATEGORY_LIST (klass);
5735 while (category && CLASS_SUPER_NAME (category) != cat_name)
5736 category = CLASS_CATEGORY_LIST (category);
5737 return category;
5740 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5742 static void
5743 generate_category (tree cat)
5745 tree decl;
5746 tree initlist, cat_name_expr, class_name_expr;
5747 tree protocol_decl, category;
5749 add_class_reference (CLASS_NAME (cat));
5750 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5752 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5754 category = lookup_category (implementation_template,
5755 CLASS_SUPER_NAME (cat));
5757 if (category && CLASS_PROTOCOL_LIST (category))
5759 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5760 protocol_decl = generate_protocol_list (category);
5762 else
5763 protocol_decl = 0;
5765 decl = start_var_decl (objc_category_template,
5766 synth_id_with_class_suffix
5767 ("_OBJC_CATEGORY", objc_implementation_context));
5769 initlist = build_category_initializer (TREE_TYPE (decl),
5770 cat_name_expr, class_name_expr,
5771 UOBJC_INSTANCE_METHODS_decl,
5772 UOBJC_CLASS_METHODS_decl,
5773 protocol_decl);
5775 finish_var_decl (decl, initlist);
5778 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5779 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5781 static void
5782 generate_shared_structures (int cls_flags)
5784 tree sc_spec, decl_specs, decl;
5785 tree name_expr, super_expr, root_expr;
5786 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5787 tree cast_type, initlist, protocol_decl;
5789 my_super_id = CLASS_SUPER_NAME (implementation_template);
5790 if (my_super_id)
5792 add_class_reference (my_super_id);
5794 /* Compute "my_root_id" - this is required for code generation.
5795 the "isa" for all meta class structures points to the root of
5796 the inheritance hierarchy (e.g. "__Object")... */
5797 my_root_id = my_super_id;
5800 tree my_root_int = lookup_interface (my_root_id);
5802 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5803 my_root_id = CLASS_SUPER_NAME (my_root_int);
5804 else
5805 break;
5807 while (1);
5809 else
5810 /* No super class. */
5811 my_root_id = CLASS_NAME (implementation_template);
5813 cast_type = build_pointer_type (objc_class_template);
5814 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5815 class_names);
5817 /* Install class `isa' and `super' pointers at runtime. */
5818 if (my_super_id)
5820 super_expr = add_objc_string (my_super_id, class_names);
5821 super_expr = build_c_cast (input_location,
5822 cast_type, super_expr); /* cast! */
5824 else
5825 super_expr = build_int_cst (NULL_TREE, 0);
5827 root_expr = add_objc_string (my_root_id, class_names);
5828 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
5830 if (CLASS_PROTOCOL_LIST (implementation_template))
5832 generate_protocol_references
5833 (CLASS_PROTOCOL_LIST (implementation_template));
5834 protocol_decl = generate_protocol_list (implementation_template);
5836 else
5837 protocol_decl = 0;
5839 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5841 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5842 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5844 decl = start_var_decl (objc_class_template,
5845 IDENTIFIER_POINTER
5846 (DECL_NAME (UOBJC_METACLASS_decl)));
5848 initlist
5849 = build_shared_structure_initializer
5850 (TREE_TYPE (decl),
5851 root_expr, super_expr, name_expr,
5852 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5853 2 /*CLS_META*/,
5854 UOBJC_CLASS_METHODS_decl,
5855 UOBJC_CLASS_VARIABLES_decl,
5856 protocol_decl);
5858 finish_var_decl (decl, initlist);
5860 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5862 decl = start_var_decl (objc_class_template,
5863 IDENTIFIER_POINTER
5864 (DECL_NAME (UOBJC_CLASS_decl)));
5866 initlist
5867 = build_shared_structure_initializer
5868 (TREE_TYPE (decl),
5869 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5870 super_expr, name_expr,
5871 convert (integer_type_node,
5872 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5873 (implementation_template))),
5874 1 /*CLS_FACTORY*/ | cls_flags,
5875 UOBJC_INSTANCE_METHODS_decl,
5876 UOBJC_INSTANCE_VARIABLES_decl,
5877 protocol_decl);
5879 finish_var_decl (decl, initlist);
5883 static const char *
5884 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5886 static char string[BUFSIZE];
5888 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5889 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5891 sprintf (string, "%s_%s", preamble,
5892 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5894 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5895 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5897 /* We have a category. */
5898 const char *const class_name
5899 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5900 const char *const class_super_name
5901 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5902 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5904 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5906 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5907 sprintf (string, "%s_%s", preamble, protocol_name);
5909 else
5910 abort ();
5912 return string;
5915 /* If type is empty or only type qualifiers are present, add default
5916 type of id (otherwise grokdeclarator will default to int). */
5918 static tree
5919 adjust_type_for_id_default (tree type)
5921 if (!type)
5922 type = make_node (TREE_LIST);
5924 if (!TREE_VALUE (type))
5925 TREE_VALUE (type) = objc_object_type;
5926 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5927 && TYPED_OBJECT (TREE_VALUE (type)))
5928 error ("can not use an object as parameter to a method");
5930 return type;
5933 /* Usage:
5934 keyworddecl:
5935 selector ':' '(' typename ')' identifier
5937 Purpose:
5938 Transform an Objective-C keyword argument into
5939 the C equivalent parameter declarator.
5941 In: key_name, an "identifier_node" (optional).
5942 arg_type, a "tree_list" (optional).
5943 arg_name, an "identifier_node".
5945 Note: It would be really nice to strongly type the preceding
5946 arguments in the function prototype; however, then I
5947 could not use the "accessor" macros defined in "tree.h".
5949 Out: an instance of "keyword_decl". */
5951 tree
5952 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5954 tree keyword_decl;
5956 /* If no type is specified, default to "id". */
5957 arg_type = adjust_type_for_id_default (arg_type);
5959 keyword_decl = make_node (KEYWORD_DECL);
5961 TREE_TYPE (keyword_decl) = arg_type;
5962 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5963 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5965 return keyword_decl;
5968 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5970 static tree
5971 build_keyword_selector (tree selector)
5973 int len = 0;
5974 tree key_chain, key_name;
5975 char *buf;
5977 /* Scan the selector to see how much space we'll need. */
5978 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5980 if (TREE_CODE (selector) == KEYWORD_DECL)
5981 key_name = KEYWORD_KEY_NAME (key_chain);
5982 else if (TREE_CODE (selector) == TREE_LIST)
5983 key_name = TREE_PURPOSE (key_chain);
5984 else
5985 abort ();
5987 if (key_name)
5988 len += IDENTIFIER_LENGTH (key_name) + 1;
5989 else
5990 /* Just a ':' arg. */
5991 len++;
5994 buf = (char *) alloca (len + 1);
5995 /* Start the buffer out as an empty string. */
5996 buf[0] = '\0';
5998 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
6000 if (TREE_CODE (selector) == KEYWORD_DECL)
6001 key_name = KEYWORD_KEY_NAME (key_chain);
6002 else if (TREE_CODE (selector) == TREE_LIST)
6004 key_name = TREE_PURPOSE (key_chain);
6005 /* The keyword decl chain will later be used as a function argument
6006 chain. Unhook the selector itself so as to not confuse other
6007 parts of the compiler. */
6008 TREE_PURPOSE (key_chain) = NULL_TREE;
6010 else
6011 abort ();
6013 if (key_name)
6014 strcat (buf, IDENTIFIER_POINTER (key_name));
6015 strcat (buf, ":");
6018 return get_identifier (buf);
6021 /* Used for declarations and definitions. */
6023 static tree
6024 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6025 tree add_args, bool ellipsis)
6027 tree method_decl;
6029 /* If no type is specified, default to "id". */
6030 ret_type = adjust_type_for_id_default (ret_type);
6032 method_decl = make_node (code);
6033 TREE_TYPE (method_decl) = ret_type;
6035 /* If we have a keyword selector, create an identifier_node that
6036 represents the full selector name (`:' included)... */
6037 if (TREE_CODE (selector) == KEYWORD_DECL)
6039 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6040 METHOD_SEL_ARGS (method_decl) = selector;
6041 METHOD_ADD_ARGS (method_decl) = add_args;
6042 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6044 else
6046 METHOD_SEL_NAME (method_decl) = selector;
6047 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6048 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6051 return method_decl;
6054 #define METHOD_DEF 0
6055 #define METHOD_REF 1
6057 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6058 an argument list for method METH. CONTEXT is either METHOD_DEF or
6059 METHOD_REF, saying whether we are trying to define a method or call
6060 one. SUPERFLAG says this is for a send to super; this makes a
6061 difference for the NeXT calling sequence in which the lookup and
6062 the method call are done together. If METH is null, user-defined
6063 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6065 static tree
6066 get_arg_type_list (tree meth, int context, int superflag)
6068 tree arglist, akey;
6070 /* Receiver type. */
6071 if (flag_next_runtime && superflag)
6072 arglist = build_tree_list (NULL_TREE, objc_super_type);
6073 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6074 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6075 else
6076 arglist = build_tree_list (NULL_TREE, objc_object_type);
6078 /* Selector type - will eventually change to `int'. */
6079 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6081 /* No actual method prototype given -- assume that remaining arguments
6082 are `...'. */
6083 if (!meth)
6084 return arglist;
6086 /* Build a list of argument types. */
6087 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6089 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6091 /* Decay arrays and functions into pointers. */
6092 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6093 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6094 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6095 arg_type = build_pointer_type (arg_type);
6097 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6100 if (METHOD_ADD_ARGS (meth))
6102 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6103 akey; akey = TREE_CHAIN (akey))
6105 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6107 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6110 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6111 goto lack_of_ellipsis;
6113 else
6115 lack_of_ellipsis:
6116 chainon (arglist, OBJC_VOID_AT_END);
6119 return arglist;
6122 static tree
6123 check_duplicates (hash hsh, int methods, int is_class)
6125 tree meth = NULL_TREE;
6127 if (hsh)
6129 meth = hsh->key;
6131 if (hsh->list)
6133 /* We have two or more methods with the same name but
6134 different types. */
6135 attr loop;
6137 /* But just how different are those types? If
6138 -Wno-strict-selector-match is specified, we shall not
6139 complain if the differences are solely among types with
6140 identical size and alignment. */
6141 if (!warn_strict_selector_match)
6143 for (loop = hsh->list; loop; loop = loop->next)
6144 if (!comp_proto_with_proto (meth, loop->value, 0))
6145 goto issue_warning;
6147 return meth;
6150 issue_warning:
6151 if (methods)
6153 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6155 warning_at (input_location, 0,
6156 "multiple methods named %<%c%E%> found",
6157 (is_class ? '+' : '-'),
6158 METHOD_SEL_NAME (meth));
6159 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6160 (type ? '-' : '+'),
6161 identifier_to_locale (gen_method_decl (meth)));
6163 else
6165 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6167 warning_at (input_location, 0,
6168 "multiple selectors named %<%c%E%> found",
6169 (is_class ? '+' : '-'),
6170 METHOD_SEL_NAME (meth));
6171 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6172 (type ? '-' : '+'),
6173 identifier_to_locale (gen_method_decl (meth)));
6176 for (loop = hsh->list; loop; loop = loop->next)
6178 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6180 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6181 (type ? '-' : '+'),
6182 identifier_to_locale (gen_method_decl (loop->value)));
6186 return meth;
6189 /* If RECEIVER is a class reference, return the identifier node for
6190 the referenced class. RECEIVER is created by objc_get_class_reference,
6191 so we check the exact form created depending on which runtimes are
6192 used. */
6194 static tree
6195 receiver_is_class_object (tree receiver, int self, int super)
6197 tree chain, exp, arg;
6199 /* The receiver is 'self' or 'super' in the context of a class method. */
6200 if (objc_method_context
6201 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6202 && (self || super))
6203 return (super
6204 ? CLASS_SUPER_NAME (implementation_template)
6205 : CLASS_NAME (implementation_template));
6207 if (flag_next_runtime)
6209 /* The receiver is a variable created by
6210 build_class_reference_decl. */
6211 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6212 /* Look up the identifier. */
6213 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6214 if (TREE_PURPOSE (chain) == receiver)
6215 return TREE_VALUE (chain);
6218 /* The receiver is a function call that returns an id. Check if
6219 it is a call to objc_getClass, if so, pick up the class name. */
6220 if (TREE_CODE (receiver) == CALL_EXPR
6221 && (exp = CALL_EXPR_FN (receiver))
6222 && TREE_CODE (exp) == ADDR_EXPR
6223 && (exp = TREE_OPERAND (exp, 0))
6224 && TREE_CODE (exp) == FUNCTION_DECL
6225 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6226 prototypes for objc_get_class(). Thankfully, they seem to share the
6227 same function type. */
6228 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6229 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6230 /* We have a call to objc_get_class/objc_getClass! */
6231 && (arg = CALL_EXPR_ARG (receiver, 0)))
6233 STRIP_NOPS (arg);
6234 if (TREE_CODE (arg) == ADDR_EXPR
6235 && (arg = TREE_OPERAND (arg, 0))
6236 && TREE_CODE (arg) == STRING_CST)
6237 /* Finally, we have the class name. */
6238 return get_identifier (TREE_STRING_POINTER (arg));
6240 return 0;
6243 /* If we are currently building a message expr, this holds
6244 the identifier of the selector of the message. This is
6245 used when printing warnings about argument mismatches. */
6247 static tree current_objc_message_selector = 0;
6249 tree
6250 objc_message_selector (void)
6252 return current_objc_message_selector;
6255 /* Construct an expression for sending a message.
6256 MESS has the object to send to in TREE_PURPOSE
6257 and the argument list (including selector) in TREE_VALUE.
6259 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6260 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6262 tree
6263 objc_build_message_expr (tree mess)
6265 tree receiver = TREE_PURPOSE (mess);
6266 location_t loc;
6267 tree sel_name;
6268 #ifdef OBJCPLUS
6269 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6270 #else
6271 tree args = TREE_VALUE (mess);
6272 #endif
6273 tree method_params = NULL_TREE;
6275 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6276 return error_mark_node;
6278 if (CAN_HAVE_LOCATION_P (receiver))
6279 loc = EXPR_LOCATION (receiver);
6280 else
6281 loc = input_location;
6283 /* Obtain the full selector name. */
6284 if (TREE_CODE (args) == IDENTIFIER_NODE)
6285 /* A unary selector. */
6286 sel_name = args;
6287 else if (TREE_CODE (args) == TREE_LIST)
6288 sel_name = build_keyword_selector (args);
6289 else
6290 abort ();
6292 /* Build the parameter list to give to the method. */
6293 if (TREE_CODE (args) == TREE_LIST)
6294 #ifdef OBJCPLUS
6295 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6296 #else
6298 tree chain = args, prev = NULL_TREE;
6300 /* We have a keyword selector--check for comma expressions. */
6301 while (chain)
6303 tree element = TREE_VALUE (chain);
6305 /* We have a comma expression, must collapse... */
6306 if (TREE_CODE (element) == TREE_LIST)
6308 if (prev)
6309 TREE_CHAIN (prev) = element;
6310 else
6311 args = element;
6313 prev = chain;
6314 chain = TREE_CHAIN (chain);
6316 method_params = args;
6318 #endif
6320 #ifdef OBJCPLUS
6321 if (processing_template_decl)
6322 /* Must wait until template instantiation time. */
6323 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6324 method_params);
6325 #endif
6327 return objc_finish_message_expr (receiver, sel_name, method_params);
6330 /* Look up method SEL_NAME that would be suitable for receiver
6331 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6332 nonzero), and report on any duplicates. */
6334 static tree
6335 lookup_method_in_hash_lists (tree sel_name, int is_class)
6337 hash method_prototype = NULL;
6339 if (!is_class)
6340 method_prototype = hash_lookup (nst_method_hash_list,
6341 sel_name);
6343 if (!method_prototype)
6345 method_prototype = hash_lookup (cls_method_hash_list,
6346 sel_name);
6347 is_class = 1;
6350 return check_duplicates (method_prototype, 1, is_class);
6353 /* The 'objc_finish_message_expr' routine is called from within
6354 'objc_build_message_expr' for non-template functions. In the case of
6355 C++ template functions, it is called from 'build_expr_from_tree'
6356 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6358 tree
6359 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6361 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6362 tree selector, retval, class_tree;
6363 int self, super, have_cast;
6365 /* Extract the receiver of the message, as well as its type
6366 (where the latter may take the form of a cast or be inferred
6367 from the implementation context). */
6368 rtype = receiver;
6369 while (TREE_CODE (rtype) == COMPOUND_EXPR
6370 || TREE_CODE (rtype) == MODIFY_EXPR
6371 || CONVERT_EXPR_P (rtype)
6372 || TREE_CODE (rtype) == COMPONENT_REF)
6373 rtype = TREE_OPERAND (rtype, 0);
6374 self = (rtype == self_decl);
6375 super = (rtype == UOBJC_SUPER_decl);
6376 rtype = TREE_TYPE (receiver);
6377 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6378 || (TREE_CODE (receiver) == COMPOUND_EXPR
6379 && !IS_SUPER (rtype)));
6381 /* If we are calling [super dealloc], reset our warning flag. */
6382 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6383 should_call_super_dealloc = 0;
6385 /* If the receiver is a class object, retrieve the corresponding
6386 @interface, if one exists. */
6387 class_tree = receiver_is_class_object (receiver, self, super);
6389 /* Now determine the receiver type (if an explicit cast has not been
6390 provided). */
6391 if (!have_cast)
6393 if (class_tree)
6394 rtype = lookup_interface (class_tree);
6395 /* Handle `self' and `super'. */
6396 else if (super)
6398 if (!CLASS_SUPER_NAME (implementation_template))
6400 error ("no super class declared in @interface for %qE",
6401 CLASS_NAME (implementation_template));
6402 return error_mark_node;
6404 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6406 else if (self)
6407 rtype = lookup_interface (CLASS_NAME (implementation_template));
6410 /* If receiver is of type `id' or `Class' (or if the @interface for a
6411 class is not visible), we shall be satisfied with the existence of
6412 any instance or class method. */
6413 if (objc_is_id (rtype))
6415 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6416 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6417 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6418 : NULL_TREE);
6419 rtype = NULL_TREE;
6421 if (rprotos)
6423 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6424 in protocols themselves for the method prototype. */
6425 method_prototype
6426 = lookup_method_in_protocol_list (rprotos, sel_name,
6427 class_tree != NULL_TREE);
6429 /* If messaging 'Class <Proto>' but did not find a class method
6430 prototype, search for an instance method instead, and warn
6431 about having done so. */
6432 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6434 method_prototype
6435 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6437 if (method_prototype)
6438 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
6439 sel_name, sel_name);
6443 else if (rtype)
6445 tree orig_rtype = rtype, saved_rtype;
6447 if (TREE_CODE (rtype) == POINTER_TYPE)
6448 rtype = TREE_TYPE (rtype);
6449 /* Traverse typedef aliases */
6450 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6451 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6452 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6453 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6454 saved_rtype = rtype;
6455 if (TYPED_OBJECT (rtype))
6457 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6458 rtype = TYPE_OBJC_INTERFACE (rtype);
6460 /* If we could not find an @interface declaration, we must have
6461 only seen a @class declaration; so, we cannot say anything
6462 more intelligent about which methods the receiver will
6463 understand. */
6464 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6465 rtype = NULL_TREE;
6466 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6467 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6469 /* We have a valid ObjC class name. Look up the method name
6470 in the published @interface for the class (and its
6471 superclasses). */
6472 method_prototype
6473 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6475 /* If the method was not found in the @interface, it may still
6476 exist locally as part of the @implementation. */
6477 if (!method_prototype && objc_implementation_context
6478 && CLASS_NAME (objc_implementation_context)
6479 == OBJC_TYPE_NAME (rtype))
6480 method_prototype
6481 = lookup_method
6482 ((class_tree
6483 ? CLASS_CLS_METHODS (objc_implementation_context)
6484 : CLASS_NST_METHODS (objc_implementation_context)),
6485 sel_name);
6487 /* If we haven't found a candidate method by now, try looking for
6488 it in the protocol list. */
6489 if (!method_prototype && rprotos)
6490 method_prototype
6491 = lookup_method_in_protocol_list (rprotos, sel_name,
6492 class_tree != NULL_TREE);
6494 else
6496 warning (0, "invalid receiver type %qs",
6497 identifier_to_locale (gen_type_name (orig_rtype)));
6498 /* After issuing the "invalid receiver" warning, perform method
6499 lookup as if we were messaging 'id'. */
6500 rtype = rprotos = NULL_TREE;
6505 /* For 'id' or 'Class' receivers, search in the global hash table
6506 as a last resort. For all receivers, warn if protocol searches
6507 have failed. */
6508 if (!method_prototype)
6510 if (rprotos)
6511 warning (0, "%<%c%E%> not found in protocol(s)",
6512 (class_tree ? '+' : '-'),
6513 sel_name);
6515 if (!rtype)
6516 method_prototype
6517 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6520 if (!method_prototype)
6522 static bool warn_missing_methods = false;
6524 if (rtype)
6525 warning (0, "%qE may not respond to %<%c%E%>",
6526 OBJC_TYPE_NAME (rtype),
6527 (class_tree ? '+' : '-'),
6528 sel_name);
6529 /* If we are messaging an 'id' or 'Class' object and made it here,
6530 then we have failed to find _any_ instance or class method,
6531 respectively. */
6532 else
6533 warning (0, "no %<%c%E%> method found",
6534 (class_tree ? '+' : '-'),
6535 sel_name);
6537 if (!warn_missing_methods)
6539 warning_at (input_location,
6540 0, "(Messages without a matching method signature");
6541 warning_at (input_location,
6542 0, "will be assumed to return %<id%> and accept");
6543 warning_at (input_location,
6544 0, "%<...%> as arguments.)");
6545 warn_missing_methods = true;
6549 /* Save the selector name for printing error messages. */
6550 current_objc_message_selector = sel_name;
6552 /* Build the parameters list for looking up the method.
6553 These are the object itself and the selector. */
6555 if (flag_typed_selectors)
6556 selector = build_typed_selector_reference (input_location,
6557 sel_name, method_prototype);
6558 else
6559 selector = build_selector_reference (input_location, sel_name);
6561 retval = build_objc_method_call (input_location, super, method_prototype,
6562 receiver,
6563 selector, method_params);
6565 current_objc_message_selector = 0;
6567 return retval;
6570 /* Build a tree expression to send OBJECT the operation SELECTOR,
6571 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6572 assuming the method has prototype METHOD_PROTOTYPE.
6573 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6574 LOC is the location of the expression to build.
6575 Use METHOD_PARAMS as list of args to pass to the method.
6576 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6578 static tree
6579 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
6580 tree lookup_object, tree selector,
6581 tree method_params)
6583 tree sender = (super_flag ? umsg_super_decl :
6584 (!flag_next_runtime || flag_nil_receivers
6585 ? (flag_objc_direct_dispatch
6586 ? umsg_fast_decl
6587 : umsg_decl)
6588 : umsg_nonnil_decl));
6589 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6591 /* If a prototype for the method to be called exists, then cast
6592 the sender's return type and arguments to match that of the method.
6593 Otherwise, leave sender as is. */
6594 tree ret_type
6595 = (method_prototype
6596 ? TREE_VALUE (TREE_TYPE (method_prototype))
6597 : objc_object_type);
6598 tree sender_cast
6599 = build_pointer_type
6600 (build_function_type
6601 (ret_type,
6602 get_arg_type_list
6603 (method_prototype, METHOD_REF, super_flag)));
6604 tree method, t;
6606 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
6608 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6609 lookup_object = save_expr (lookup_object);
6611 if (flag_next_runtime)
6613 /* If we are returning a struct in memory, and the address
6614 of that memory location is passed as a hidden first
6615 argument, then change which messenger entry point this
6616 expr will call. NB: Note that sender_cast remains
6617 unchanged (it already has a struct return type). */
6618 if (!targetm.calls.struct_value_rtx (0, 0)
6619 && (TREE_CODE (ret_type) == RECORD_TYPE
6620 || TREE_CODE (ret_type) == UNION_TYPE)
6621 && targetm.calls.return_in_memory (ret_type, 0))
6622 sender = (super_flag ? umsg_super_stret_decl :
6623 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6625 method_params = tree_cons (NULL_TREE, lookup_object,
6626 tree_cons (NULL_TREE, selector,
6627 method_params));
6628 method = build_fold_addr_expr_loc (input_location, sender);
6630 else
6632 /* This is the portable (GNU) way. */
6633 tree object;
6635 /* First, call the lookup function to get a pointer to the method,
6636 then cast the pointer, then call it with the method arguments. */
6638 object = (super_flag ? self_decl : lookup_object);
6640 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6641 t = tree_cons (NULL_TREE, lookup_object, t);
6642 method = build_function_call (loc, sender, t);
6644 /* Pass the object to the method. */
6645 method_params = tree_cons (NULL_TREE, object,
6646 tree_cons (NULL_TREE, selector,
6647 method_params));
6650 /* ??? Selector is not at this point something we can use inside
6651 the compiler itself. Set it to garbage for the nonce. */
6652 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6653 return build_function_call (loc,
6654 t, method_params);
6657 static void
6658 build_protocol_reference (tree p)
6660 tree decl;
6661 const char *proto_name;
6663 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6665 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6666 decl = start_var_decl (objc_protocol_template, proto_name);
6668 PROTOCOL_FORWARD_DECL (p) = decl;
6671 /* This function is called by the parser when (and only when) a
6672 @protocol() expression is found, in order to compile it. */
6673 tree
6674 objc_build_protocol_expr (tree protoname)
6676 tree expr;
6677 tree p = lookup_protocol (protoname);
6679 if (!p)
6681 error ("cannot find protocol declaration for %qE",
6682 protoname);
6683 return error_mark_node;
6686 if (!PROTOCOL_FORWARD_DECL (p))
6687 build_protocol_reference (p);
6689 expr = build_unary_op (input_location,
6690 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6692 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6693 if we have it, rather than converting it here. */
6694 expr = convert (objc_protocol_type, expr);
6696 /* The @protocol() expression is being compiled into a pointer to a
6697 statically allocated instance of the Protocol class. To become
6698 usable at runtime, the 'isa' pointer of the instance need to be
6699 fixed up at runtime by the runtime library, to point to the
6700 actual 'Protocol' class. */
6702 /* For the GNU runtime, put the static Protocol instance in the list
6703 of statically allocated instances, so that we make sure that its
6704 'isa' pointer is fixed up at runtime by the GNU runtime library
6705 to point to the Protocol class (at runtime, when loading the
6706 module, the GNU runtime library loops on the statically allocated
6707 instances (as found in the defs field in objc_symtab) and fixups
6708 all the 'isa' pointers of those objects). */
6709 if (! flag_next_runtime)
6711 /* This type is a struct containing the fields of a Protocol
6712 object. (Cfr. objc_protocol_type instead is the type of a pointer
6713 to such a struct). */
6714 tree protocol_struct_type = xref_tag
6715 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6716 tree *chain;
6718 /* Look for the list of Protocol statically allocated instances
6719 to fixup at runtime. Create a new list to hold Protocol
6720 statically allocated instances, if the list is not found. At
6721 present there is only another list, holding NSConstantString
6722 static instances to be fixed up at runtime. */
6723 for (chain = &objc_static_instances;
6724 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6725 chain = &TREE_CHAIN (*chain));
6726 if (!*chain)
6728 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6729 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6730 class_names);
6733 /* Add this statically allocated instance to the Protocol list. */
6734 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6735 PROTOCOL_FORWARD_DECL (p),
6736 TREE_PURPOSE (*chain));
6740 return expr;
6743 /* This function is called by the parser when a @selector() expression
6744 is found, in order to compile it. It is only called by the parser
6745 and only to compile a @selector(). LOC is the location of the
6746 @selector. */
6747 tree
6748 objc_build_selector_expr (location_t loc, tree selnamelist)
6750 tree selname;
6752 /* Obtain the full selector name. */
6753 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6754 /* A unary selector. */
6755 selname = selnamelist;
6756 else if (TREE_CODE (selnamelist) == TREE_LIST)
6757 selname = build_keyword_selector (selnamelist);
6758 else
6759 abort ();
6761 /* If we are required to check @selector() expressions as they
6762 are found, check that the selector has been declared. */
6763 if (warn_undeclared_selector)
6765 /* Look the selector up in the list of all known class and
6766 instance methods (up to this line) to check that the selector
6767 exists. */
6768 hash hsh;
6770 /* First try with instance methods. */
6771 hsh = hash_lookup (nst_method_hash_list, selname);
6773 /* If not found, try with class methods. */
6774 if (!hsh)
6776 hsh = hash_lookup (cls_method_hash_list, selname);
6779 /* If still not found, print out a warning. */
6780 if (!hsh)
6782 warning (0, "undeclared selector %qE", selname);
6787 if (flag_typed_selectors)
6788 return build_typed_selector_reference (loc, selname, 0);
6789 else
6790 return build_selector_reference (loc, selname);
6793 tree
6794 objc_build_encode_expr (tree type)
6796 tree result;
6797 const char *string;
6799 encode_type (type, obstack_object_size (&util_obstack),
6800 OBJC_ENCODE_INLINE_DEFS);
6801 obstack_1grow (&util_obstack, 0); /* null terminate string */
6802 string = XOBFINISH (&util_obstack, const char *);
6804 /* Synthesize a string that represents the encoded struct/union. */
6805 result = my_build_string (strlen (string) + 1, string);
6806 obstack_free (&util_obstack, util_firstobj);
6807 return result;
6810 static tree
6811 build_ivar_reference (tree id)
6813 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6815 /* Historically, a class method that produced objects (factory
6816 method) would assign `self' to the instance that it
6817 allocated. This would effectively turn the class method into
6818 an instance method. Following this assignment, the instance
6819 variables could be accessed. That practice, while safe,
6820 violates the simple rule that a class method should not refer
6821 to an instance variable. It's better to catch the cases
6822 where this is done unknowingly than to support the above
6823 paradigm. */
6824 warning (0, "instance variable %qE accessed in class method",
6825 id);
6826 self_decl = convert (objc_instance_type, self_decl); /* cast */
6829 return objc_build_component_ref (build_indirect_ref (input_location,
6830 self_decl, "->"), id);
6833 /* Compute a hash value for a given method SEL_NAME. */
6835 static size_t
6836 hash_func (tree sel_name)
6838 const unsigned char *s
6839 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6840 size_t h = 0;
6842 while (*s)
6843 h = h * 67 + *s++ - 113;
6844 return h;
6847 static void
6848 hash_init (void)
6850 nst_method_hash_list
6851 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6852 cls_method_hash_list
6853 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6855 /* Initialize the hash table used to hold the constant string objects. */
6856 string_htab = htab_create_ggc (31, string_hash,
6857 string_eq, NULL);
6859 /* Initialize the hash table used to hold EH-volatilized types. */
6860 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6861 volatilized_eq, NULL);
6864 /* WARNING!!!! hash_enter is called with a method, and will peek
6865 inside to find its selector! But hash_lookup is given a selector
6866 directly, and looks for the selector that's inside the found
6867 entry's key (method) for comparison. */
6869 static void
6870 hash_enter (hash *hashlist, tree method)
6872 hash obj;
6873 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6875 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6876 obj->list = 0;
6877 obj->next = hashlist[slot];
6878 obj->key = method;
6880 hashlist[slot] = obj; /* append to front */
6883 static hash
6884 hash_lookup (hash *hashlist, tree sel_name)
6886 hash target;
6888 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6890 while (target)
6892 if (sel_name == METHOD_SEL_NAME (target->key))
6893 return target;
6895 target = target->next;
6897 return 0;
6900 static void
6901 hash_add_attr (hash entry, tree value)
6903 attr obj;
6905 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6906 obj->next = entry->list;
6907 obj->value = value;
6909 entry->list = obj; /* append to front */
6912 static tree
6913 lookup_method (tree mchain, tree method)
6915 tree key;
6917 if (TREE_CODE (method) == IDENTIFIER_NODE)
6918 key = method;
6919 else
6920 key = METHOD_SEL_NAME (method);
6922 while (mchain)
6924 if (METHOD_SEL_NAME (mchain) == key)
6925 return mchain;
6927 mchain = TREE_CHAIN (mchain);
6929 return NULL_TREE;
6932 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6933 in INTERFACE, along with any categories and protocols attached thereto.
6934 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6935 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6936 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6937 be found in INTERFACE or any of its superclasses, look for an _instance_
6938 method of the same name in the root class as a last resort.
6940 If a suitable method cannot be found, return NULL_TREE. */
6942 static tree
6943 lookup_method_static (tree interface, tree ident, int flags)
6945 tree meth = NULL_TREE, root_inter = NULL_TREE;
6946 tree inter = interface;
6947 int is_class = (flags & OBJC_LOOKUP_CLASS);
6948 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6950 while (inter)
6952 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6953 tree category = inter;
6955 /* First, look up the method in the class itself. */
6956 if ((meth = lookup_method (chain, ident)))
6957 return meth;
6959 /* Failing that, look for the method in each category of the class. */
6960 while ((category = CLASS_CATEGORY_LIST (category)))
6962 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6964 /* Check directly in each category. */
6965 if ((meth = lookup_method (chain, ident)))
6966 return meth;
6968 /* Failing that, check in each category's protocols. */
6969 if (CLASS_PROTOCOL_LIST (category))
6971 if ((meth = (lookup_method_in_protocol_list
6972 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6973 return meth;
6977 /* If not found in categories, check in protocols of the main class. */
6978 if (CLASS_PROTOCOL_LIST (inter))
6980 if ((meth = (lookup_method_in_protocol_list
6981 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6982 return meth;
6985 /* If we were instructed not to look in superclasses, don't. */
6986 if (no_superclasses)
6987 return NULL_TREE;
6989 /* Failing that, climb up the inheritance hierarchy. */
6990 root_inter = inter;
6991 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6993 while (inter);
6995 /* If no class (factory) method was found, check if an _instance_
6996 method of the same name exists in the root class. This is what
6997 the Objective-C runtime will do. If an instance method was not
6998 found, return 0. */
6999 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
7002 /* Add the method to the hash list if it doesn't contain an identical
7003 method already. */
7005 static void
7006 add_method_to_hash_list (hash *hash_list, tree method)
7008 hash hsh;
7010 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7012 /* Install on a global chain. */
7013 hash_enter (hash_list, method);
7015 else
7017 /* Check types against those; if different, add to a list. */
7018 attr loop;
7019 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7020 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7021 already_there |= comp_proto_with_proto (method, loop->value, 1);
7022 if (!already_there)
7023 hash_add_attr (hsh, method);
7027 static tree
7028 objc_add_method (tree klass, tree method, int is_class)
7030 tree mth;
7032 if (!(mth = lookup_method (is_class
7033 ? CLASS_CLS_METHODS (klass)
7034 : CLASS_NST_METHODS (klass), method)))
7036 /* put method on list in reverse order */
7037 if (is_class)
7039 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
7040 CLASS_CLS_METHODS (klass) = method;
7042 else
7044 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
7045 CLASS_NST_METHODS (klass) = method;
7048 else
7050 /* When processing an @interface for a class or category, give hard
7051 errors on methods with identical selectors but differing argument
7052 and/or return types. We do not do this for @implementations, because
7053 C/C++ will do it for us (i.e., there will be duplicate function
7054 definition errors). */
7055 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7056 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7057 && !comp_proto_with_proto (method, mth, 1))
7058 error ("duplicate declaration of method %<%c%E%>",
7059 is_class ? '+' : '-',
7060 METHOD_SEL_NAME (mth));
7063 if (is_class)
7064 add_method_to_hash_list (cls_method_hash_list, method);
7065 else
7067 add_method_to_hash_list (nst_method_hash_list, method);
7069 /* Instance methods in root classes (and categories thereof)
7070 may act as class methods as a last resort. We also add
7071 instance methods listed in @protocol declarations to
7072 the class hash table, on the assumption that @protocols
7073 may be adopted by root classes or categories. */
7074 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7075 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7076 klass = lookup_interface (CLASS_NAME (klass));
7078 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7079 || !CLASS_SUPER_NAME (klass))
7080 add_method_to_hash_list (cls_method_hash_list, method);
7083 return method;
7086 static tree
7087 add_class (tree class_name, tree name)
7089 struct interface_tuple **slot;
7091 /* Put interfaces on list in reverse order. */
7092 TREE_CHAIN (class_name) = interface_chain;
7093 interface_chain = class_name;
7095 if (interface_htab == NULL)
7096 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7097 slot = (struct interface_tuple **)
7098 htab_find_slot_with_hash (interface_htab, name,
7099 IDENTIFIER_HASH_VALUE (name),
7100 INSERT);
7101 if (!*slot)
7103 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7104 (*slot)->id = name;
7106 (*slot)->class_name = class_name;
7108 return interface_chain;
7111 static void
7112 add_category (tree klass, tree category)
7114 /* Put categories on list in reverse order. */
7115 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7117 if (cat)
7119 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7120 CLASS_NAME (klass),
7121 CLASS_SUPER_NAME (category));
7123 else
7125 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7126 CLASS_CATEGORY_LIST (klass) = category;
7130 /* Called after parsing each instance variable declaration. Necessary to
7131 preserve typedefs and implement public/private...
7133 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7135 static tree
7136 add_instance_variable (tree klass, int visibility, tree field_decl)
7138 tree field_type = TREE_TYPE (field_decl);
7139 const char *ivar_name = DECL_NAME (field_decl)
7140 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7141 : _("<unnamed>");
7143 #ifdef OBJCPLUS
7144 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7146 error ("illegal reference type specified for instance variable %qs",
7147 ivar_name);
7148 /* Return class as is without adding this ivar. */
7149 return klass;
7151 #endif
7153 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7154 || TYPE_SIZE (field_type) == error_mark_node)
7155 /* 'type[0]' is allowed, but 'type[]' is not! */
7157 error ("instance variable %qs has unknown size", ivar_name);
7158 /* Return class as is without adding this ivar. */
7159 return klass;
7162 #ifdef OBJCPLUS
7163 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7164 need to either (1) warn the user about it or (2) generate suitable
7165 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7166 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7167 if (MAYBE_CLASS_TYPE_P (field_type)
7168 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7169 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7170 || TYPE_POLYMORPHIC_P (field_type)))
7172 tree type_name = OBJC_TYPE_NAME (field_type);
7174 if (flag_objc_call_cxx_cdtors)
7176 /* Since the ObjC runtime will be calling the constructors and
7177 destructors for us, the only thing we can't handle is the lack
7178 of a default constructor. */
7179 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7180 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7182 warning (0, "type %qE has no default constructor to call",
7183 type_name);
7185 /* If we cannot call a constructor, we should also avoid
7186 calling the destructor, for symmetry. */
7187 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7188 warning (0, "destructor for %qE shall not be run either",
7189 type_name);
7192 else
7194 static bool warn_cxx_ivars = false;
7196 if (TYPE_POLYMORPHIC_P (field_type))
7198 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7199 initialize them. */
7200 error ("type %qE has virtual member functions", type_name);
7201 error ("illegal aggregate type %qE specified "
7202 "for instance variable %qs",
7203 type_name, ivar_name);
7204 /* Return class as is without adding this ivar. */
7205 return klass;
7208 /* User-defined constructors and destructors are not known to Obj-C
7209 and hence will not be called. This may or may not be a problem. */
7210 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7211 warning (0, "type %qE has a user-defined constructor", type_name);
7212 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7213 warning (0, "type %qE has a user-defined destructor", type_name);
7215 if (!warn_cxx_ivars)
7217 warning (0, "C++ constructors and destructors will not "
7218 "be invoked for Objective-C fields");
7219 warn_cxx_ivars = true;
7223 #endif
7225 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7226 switch (visibility)
7228 case 0:
7229 TREE_PUBLIC (field_decl) = 0;
7230 TREE_PRIVATE (field_decl) = 0;
7231 TREE_PROTECTED (field_decl) = 1;
7232 break;
7234 case 1:
7235 TREE_PUBLIC (field_decl) = 1;
7236 TREE_PRIVATE (field_decl) = 0;
7237 TREE_PROTECTED (field_decl) = 0;
7238 break;
7240 case 2:
7241 TREE_PUBLIC (field_decl) = 0;
7242 TREE_PRIVATE (field_decl) = 1;
7243 TREE_PROTECTED (field_decl) = 0;
7244 break;
7248 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7250 return klass;
7253 static tree
7254 is_ivar (tree decl_chain, tree ident)
7256 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7257 if (DECL_NAME (decl_chain) == ident)
7258 return decl_chain;
7259 return NULL_TREE;
7262 /* True if the ivar is private and we are not in its implementation. */
7264 static int
7265 is_private (tree decl)
7267 return (TREE_PRIVATE (decl)
7268 && ! is_ivar (CLASS_IVARS (implementation_template),
7269 DECL_NAME (decl)));
7272 /* We have an instance variable reference;, check to see if it is public. */
7275 objc_is_public (tree expr, tree identifier)
7277 tree basetype, decl;
7279 #ifdef OBJCPLUS
7280 if (processing_template_decl)
7281 return 1;
7282 #endif
7284 if (TREE_TYPE (expr) == error_mark_node)
7285 return 1;
7287 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7289 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7291 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7293 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7295 if (!klass)
7297 error ("cannot find interface declaration for %qE",
7298 OBJC_TYPE_NAME (basetype));
7299 return 0;
7302 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7304 if (TREE_PUBLIC (decl))
7305 return 1;
7307 /* Important difference between the Stepstone translator:
7308 all instance variables should be public within the context
7309 of the implementation. */
7310 if (objc_implementation_context
7311 && ((TREE_CODE (objc_implementation_context)
7312 == CLASS_IMPLEMENTATION_TYPE)
7313 || (TREE_CODE (objc_implementation_context)
7314 == CATEGORY_IMPLEMENTATION_TYPE)))
7316 tree curtype = TYPE_MAIN_VARIANT
7317 (CLASS_STATIC_TEMPLATE
7318 (implementation_template));
7320 if (basetype == curtype
7321 || DERIVED_FROM_P (basetype, curtype))
7323 int priv = is_private (decl);
7325 if (priv)
7326 error ("instance variable %qE is declared private",
7327 DECL_NAME (decl));
7329 return !priv;
7333 /* The 2.95.2 compiler sometimes allowed C functions to access
7334 non-@public ivars. We will let this slide for now... */
7335 if (!objc_method_context)
7337 warning (0, "instance variable %qE is %s; "
7338 "this will be a hard error in the future",
7339 identifier,
7340 TREE_PRIVATE (decl) ? "@private" : "@protected");
7341 return 1;
7344 error ("instance variable %qE is declared %s",
7345 identifier,
7346 TREE_PRIVATE (decl) ? "private" : "protected");
7347 return 0;
7352 return 1;
7355 /* Make sure all entries in CHAIN are also in LIST. */
7357 static int
7358 check_methods (tree chain, tree list, int mtype)
7360 int first = 1;
7362 while (chain)
7364 if (!lookup_method (list, chain))
7366 if (first)
7368 if (TREE_CODE (objc_implementation_context)
7369 == CLASS_IMPLEMENTATION_TYPE)
7370 warning (0, "incomplete implementation of class %qE",
7371 CLASS_NAME (objc_implementation_context));
7372 else if (TREE_CODE (objc_implementation_context)
7373 == CATEGORY_IMPLEMENTATION_TYPE)
7374 warning (0, "incomplete implementation of category %qE",
7375 CLASS_SUPER_NAME (objc_implementation_context));
7376 first = 0;
7379 warning (0, "method definition for %<%c%E%> not found",
7380 mtype, METHOD_SEL_NAME (chain));
7383 chain = TREE_CHAIN (chain);
7386 return first;
7389 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7391 static int
7392 conforms_to_protocol (tree klass, tree protocol)
7394 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7396 tree p = CLASS_PROTOCOL_LIST (klass);
7397 while (p && TREE_VALUE (p) != protocol)
7398 p = TREE_CHAIN (p);
7400 if (!p)
7402 tree super = (CLASS_SUPER_NAME (klass)
7403 ? lookup_interface (CLASS_SUPER_NAME (klass))
7404 : NULL_TREE);
7405 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7406 if (!tmp)
7407 return 0;
7411 return 1;
7414 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7415 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7417 static int
7418 check_methods_accessible (tree chain, tree context, int mtype)
7420 int first = 1;
7421 tree list;
7422 tree base_context = context;
7424 while (chain)
7426 context = base_context;
7427 while (context)
7429 if (mtype == '+')
7430 list = CLASS_CLS_METHODS (context);
7431 else
7432 list = CLASS_NST_METHODS (context);
7434 if (lookup_method (list, chain))
7435 break;
7437 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7438 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7439 context = (CLASS_SUPER_NAME (context)
7440 ? lookup_interface (CLASS_SUPER_NAME (context))
7441 : NULL_TREE);
7443 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7444 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7445 context = (CLASS_NAME (context)
7446 ? lookup_interface (CLASS_NAME (context))
7447 : NULL_TREE);
7448 else
7449 abort ();
7452 if (context == NULL_TREE)
7454 if (first)
7456 if (TREE_CODE (objc_implementation_context)
7457 == CLASS_IMPLEMENTATION_TYPE)
7458 warning (0, "incomplete implementation of class %qE",
7459 CLASS_NAME (objc_implementation_context));
7460 else if (TREE_CODE (objc_implementation_context)
7461 == CATEGORY_IMPLEMENTATION_TYPE)
7462 warning (0, "incomplete implementation of category %qE",
7463 CLASS_SUPER_NAME (objc_implementation_context));
7464 first = 0;
7466 warning (0, "method definition for %<%c%E%> not found",
7467 mtype, METHOD_SEL_NAME (chain));
7470 chain = TREE_CHAIN (chain); /* next method... */
7472 return first;
7475 /* Check whether the current interface (accessible via
7476 'objc_implementation_context') actually implements protocol P, along
7477 with any protocols that P inherits. */
7479 static void
7480 check_protocol (tree p, const char *type, tree name)
7482 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7484 int f1, f2;
7486 /* Ensure that all protocols have bodies! */
7487 if (warn_protocol)
7489 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7490 CLASS_CLS_METHODS (objc_implementation_context),
7491 '+');
7492 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7493 CLASS_NST_METHODS (objc_implementation_context),
7494 '-');
7496 else
7498 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7499 objc_implementation_context,
7500 '+');
7501 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7502 objc_implementation_context,
7503 '-');
7506 if (!f1 || !f2)
7507 warning (0, "%s %qE does not fully implement the %qE protocol",
7508 type, name, PROTOCOL_NAME (p));
7511 /* Check protocols recursively. */
7512 if (PROTOCOL_LIST (p))
7514 tree subs = PROTOCOL_LIST (p);
7515 tree super_class =
7516 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7518 while (subs)
7520 tree sub = TREE_VALUE (subs);
7522 /* If the superclass does not conform to the protocols
7523 inherited by P, then we must! */
7524 if (!super_class || !conforms_to_protocol (super_class, sub))
7525 check_protocol (sub, type, name);
7526 subs = TREE_CHAIN (subs);
7531 /* Check whether the current interface (accessible via
7532 'objc_implementation_context') actually implements the protocols listed
7533 in PROTO_LIST. */
7535 static void
7536 check_protocols (tree proto_list, const char *type, tree name)
7538 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7540 tree p = TREE_VALUE (proto_list);
7542 check_protocol (p, type, name);
7546 /* Make sure that the class CLASS_NAME is defined
7547 CODE says which kind of thing CLASS_NAME ought to be.
7548 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7549 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7551 static tree
7552 start_class (enum tree_code code, tree class_name, tree super_name,
7553 tree protocol_list)
7555 tree klass, decl;
7557 #ifdef OBJCPLUS
7558 if (current_namespace != global_namespace) {
7559 error ("Objective-C declarations may only appear in global scope");
7561 #endif /* OBJCPLUS */
7563 if (objc_implementation_context)
7565 warning (0, "%<@end%> missing in implementation context");
7566 finish_class (objc_implementation_context);
7567 objc_ivar_chain = NULL_TREE;
7568 objc_implementation_context = NULL_TREE;
7571 klass = make_node (code);
7572 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7574 /* Check for existence of the super class, if one was specified. Note
7575 that we must have seen an @interface, not just a @class. If we
7576 are looking at a @compatibility_alias, traverse it first. */
7577 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7578 && super_name)
7580 tree super = objc_is_class_name (super_name);
7582 if (!super || !lookup_interface (super))
7584 error ("cannot find interface declaration for %qE, superclass of %qE",
7585 super ? super : super_name,
7586 class_name);
7587 super_name = NULL_TREE;
7589 else
7590 super_name = super;
7593 CLASS_NAME (klass) = class_name;
7594 CLASS_SUPER_NAME (klass) = super_name;
7595 CLASS_CLS_METHODS (klass) = NULL_TREE;
7597 if (! objc_is_class_name (class_name)
7598 && (decl = lookup_name (class_name)))
7600 error ("%qE redeclared as different kind of symbol",
7601 class_name);
7602 error ("previous declaration of %q+D",
7603 decl);
7606 if (code == CLASS_IMPLEMENTATION_TYPE)
7609 tree chain;
7611 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7612 if (TREE_VALUE (chain) == class_name)
7614 error ("reimplementation of class %qE",
7615 class_name);
7616 return error_mark_node;
7618 implemented_classes = tree_cons (NULL_TREE, class_name,
7619 implemented_classes);
7622 /* Reset for multiple classes per file. */
7623 method_slot = 0;
7625 objc_implementation_context = klass;
7627 /* Lookup the interface for this implementation. */
7629 if (!(implementation_template = lookup_interface (class_name)))
7631 warning (0, "cannot find interface declaration for %qE",
7632 class_name);
7633 add_class (implementation_template = objc_implementation_context,
7634 class_name);
7637 /* If a super class has been specified in the implementation,
7638 insure it conforms to the one specified in the interface. */
7640 if (super_name
7641 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7643 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7644 error ("conflicting super class name %qE",
7645 super_name);
7646 if (previous_name)
7647 error ("previous declaration of %qE", previous_name);
7648 else
7649 error ("previous declaration");
7652 else if (! super_name)
7654 CLASS_SUPER_NAME (objc_implementation_context)
7655 = CLASS_SUPER_NAME (implementation_template);
7659 else if (code == CLASS_INTERFACE_TYPE)
7661 if (lookup_interface (class_name))
7662 #ifdef OBJCPLUS
7663 error ("duplicate interface declaration for class %qE",
7664 #else
7665 warning (0, "duplicate interface declaration for class %qE",
7666 #endif
7667 class_name);
7668 else
7669 add_class (klass, class_name);
7671 if (protocol_list)
7672 CLASS_PROTOCOL_LIST (klass)
7673 = lookup_and_install_protocols (protocol_list);
7676 else if (code == CATEGORY_INTERFACE_TYPE)
7678 tree class_category_is_assoc_with;
7680 /* For a category, class_name is really the name of the class that
7681 the following set of methods will be associated with. We must
7682 find the interface so that can derive the objects template. */
7684 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7686 error ("cannot find interface declaration for %qE",
7687 class_name);
7688 exit (FATAL_EXIT_CODE);
7690 else
7691 add_category (class_category_is_assoc_with, klass);
7693 if (protocol_list)
7694 CLASS_PROTOCOL_LIST (klass)
7695 = lookup_and_install_protocols (protocol_list);
7698 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7700 /* Reset for multiple classes per file. */
7701 method_slot = 0;
7703 objc_implementation_context = klass;
7705 /* For a category, class_name is really the name of the class that
7706 the following set of methods will be associated with. We must
7707 find the interface so that can derive the objects template. */
7709 if (!(implementation_template = lookup_interface (class_name)))
7711 error ("cannot find interface declaration for %qE",
7712 class_name);
7713 exit (FATAL_EXIT_CODE);
7716 return klass;
7719 static tree
7720 continue_class (tree klass)
7722 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7723 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7725 struct imp_entry *imp_entry;
7727 /* Check consistency of the instance variables. */
7729 if (CLASS_RAW_IVARS (klass))
7730 check_ivars (implementation_template, klass);
7732 /* code generation */
7734 #ifdef OBJCPLUS
7735 push_lang_context (lang_name_c);
7736 #endif
7738 build_private_template (implementation_template);
7739 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7740 objc_instance_type = build_pointer_type (uprivate_record);
7742 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7744 imp_entry->next = imp_list;
7745 imp_entry->imp_context = klass;
7746 imp_entry->imp_template = implementation_template;
7748 synth_forward_declarations ();
7749 imp_entry->class_decl = UOBJC_CLASS_decl;
7750 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7751 imp_entry->has_cxx_cdtors = 0;
7753 /* Append to front and increment count. */
7754 imp_list = imp_entry;
7755 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7756 imp_count++;
7757 else
7758 cat_count++;
7760 #ifdef OBJCPLUS
7761 pop_lang_context ();
7762 #endif /* OBJCPLUS */
7764 return get_class_ivars (implementation_template, true);
7767 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7769 #ifdef OBJCPLUS
7770 push_lang_context (lang_name_c);
7771 #endif /* OBJCPLUS */
7773 build_private_template (klass);
7775 #ifdef OBJCPLUS
7776 pop_lang_context ();
7777 #endif /* OBJCPLUS */
7779 return NULL_TREE;
7782 else
7783 return error_mark_node;
7786 /* This is called once we see the "@end" in an interface/implementation. */
7788 static void
7789 finish_class (tree klass)
7791 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7793 /* All code generation is done in finish_objc. */
7795 if (implementation_template != objc_implementation_context)
7797 /* Ensure that all method listed in the interface contain bodies. */
7798 check_methods (CLASS_CLS_METHODS (implementation_template),
7799 CLASS_CLS_METHODS (objc_implementation_context), '+');
7800 check_methods (CLASS_NST_METHODS (implementation_template),
7801 CLASS_NST_METHODS (objc_implementation_context), '-');
7803 if (CLASS_PROTOCOL_LIST (implementation_template))
7804 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7805 "class",
7806 CLASS_NAME (objc_implementation_context));
7810 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7812 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7814 if (category)
7816 /* Ensure all method listed in the interface contain bodies. */
7817 check_methods (CLASS_CLS_METHODS (category),
7818 CLASS_CLS_METHODS (objc_implementation_context), '+');
7819 check_methods (CLASS_NST_METHODS (category),
7820 CLASS_NST_METHODS (objc_implementation_context), '-');
7822 if (CLASS_PROTOCOL_LIST (category))
7823 check_protocols (CLASS_PROTOCOL_LIST (category),
7824 "category",
7825 CLASS_SUPER_NAME (objc_implementation_context));
7830 static tree
7831 add_protocol (tree protocol)
7833 /* Put protocol on list in reverse order. */
7834 TREE_CHAIN (protocol) = protocol_chain;
7835 protocol_chain = protocol;
7836 return protocol_chain;
7839 static tree
7840 lookup_protocol (tree ident)
7842 tree chain;
7844 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7845 if (ident == PROTOCOL_NAME (chain))
7846 return chain;
7848 return NULL_TREE;
7851 /* This function forward declares the protocols named by NAMES. If
7852 they are already declared or defined, the function has no effect. */
7854 void
7855 objc_declare_protocols (tree names)
7857 tree list;
7859 #ifdef OBJCPLUS
7860 if (current_namespace != global_namespace) {
7861 error ("Objective-C declarations may only appear in global scope");
7863 #endif /* OBJCPLUS */
7865 for (list = names; list; list = TREE_CHAIN (list))
7867 tree name = TREE_VALUE (list);
7869 if (lookup_protocol (name) == NULL_TREE)
7871 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7873 TYPE_LANG_SLOT_1 (protocol)
7874 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7875 PROTOCOL_NAME (protocol) = name;
7876 PROTOCOL_LIST (protocol) = NULL_TREE;
7877 add_protocol (protocol);
7878 PROTOCOL_DEFINED (protocol) = 0;
7879 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7884 static tree
7885 start_protocol (enum tree_code code, tree name, tree list)
7887 tree protocol;
7889 #ifdef OBJCPLUS
7890 if (current_namespace != global_namespace) {
7891 error ("Objective-C declarations may only appear in global scope");
7893 #endif /* OBJCPLUS */
7895 protocol = lookup_protocol (name);
7897 if (!protocol)
7899 protocol = make_node (code);
7900 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7902 PROTOCOL_NAME (protocol) = name;
7903 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7904 add_protocol (protocol);
7905 PROTOCOL_DEFINED (protocol) = 1;
7906 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7908 check_protocol_recursively (protocol, list);
7910 else if (! PROTOCOL_DEFINED (protocol))
7912 PROTOCOL_DEFINED (protocol) = 1;
7913 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7915 check_protocol_recursively (protocol, list);
7917 else
7919 warning (0, "duplicate declaration for protocol %qE",
7920 name);
7922 return protocol;
7926 /* "Encode" a data type into a string, which grows in util_obstack.
7927 ??? What is the FORMAT? Someone please document this! */
7929 static void
7930 encode_type_qualifiers (tree declspecs)
7932 tree spec;
7934 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7936 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7937 obstack_1grow (&util_obstack, 'n');
7938 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7939 obstack_1grow (&util_obstack, 'N');
7940 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7941 obstack_1grow (&util_obstack, 'o');
7942 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7943 obstack_1grow (&util_obstack, 'O');
7944 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7945 obstack_1grow (&util_obstack, 'R');
7946 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7947 obstack_1grow (&util_obstack, 'V');
7951 /* Encode a pointer type. */
7953 static void
7954 encode_pointer (tree type, int curtype, int format)
7956 tree pointer_to = TREE_TYPE (type);
7958 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7960 if (OBJC_TYPE_NAME (pointer_to)
7961 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7963 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7965 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7967 obstack_1grow (&util_obstack, '@');
7968 return;
7970 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7971 && TYPE_OBJC_INTERFACE (pointer_to))
7973 if (generating_instance_variables)
7975 obstack_1grow (&util_obstack, '@');
7976 obstack_1grow (&util_obstack, '"');
7977 obstack_grow (&util_obstack, name, strlen (name));
7978 obstack_1grow (&util_obstack, '"');
7979 return;
7981 else
7983 obstack_1grow (&util_obstack, '@');
7984 return;
7987 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7989 obstack_1grow (&util_obstack, '#');
7990 return;
7992 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7994 obstack_1grow (&util_obstack, ':');
7995 return;
7999 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
8000 && TYPE_MODE (pointer_to) == QImode)
8002 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
8003 ? OBJC_TYPE_NAME (pointer_to)
8004 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
8006 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
8008 /* It appears that "r*" means "const char *" rather than
8009 "char *const". */
8010 if (TYPE_READONLY (pointer_to))
8011 obstack_1grow (&util_obstack, 'r');
8013 obstack_1grow (&util_obstack, '*');
8014 return;
8018 /* We have a type that does not get special treatment. */
8020 /* NeXT extension */
8021 obstack_1grow (&util_obstack, '^');
8022 encode_type (pointer_to, curtype, format);
8025 static void
8026 encode_array (tree type, int curtype, int format)
8028 tree an_int_cst = TYPE_SIZE (type);
8029 tree array_of = TREE_TYPE (type);
8030 char buffer[40];
8032 /* An incomplete array is treated like a pointer. */
8033 if (an_int_cst == NULL)
8035 encode_pointer (type, curtype, format);
8036 return;
8039 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
8040 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
8041 else
8042 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
8043 TREE_INT_CST_LOW (an_int_cst)
8044 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
8046 obstack_grow (&util_obstack, buffer, strlen (buffer));
8047 encode_type (array_of, curtype, format);
8048 obstack_1grow (&util_obstack, ']');
8049 return;
8052 static void
8053 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
8055 tree field = TYPE_FIELDS (type);
8057 for (; field; field = TREE_CHAIN (field))
8059 #ifdef OBJCPLUS
8060 /* C++ static members, and things that are not field at all,
8061 should not appear in the encoding. */
8062 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
8063 continue;
8064 #endif
8066 /* Recursively encode fields of embedded base classes. */
8067 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
8068 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
8070 encode_aggregate_fields (TREE_TYPE (field),
8071 pointed_to, curtype, format);
8072 continue;
8075 if (generating_instance_variables && !pointed_to)
8077 tree fname = DECL_NAME (field);
8079 obstack_1grow (&util_obstack, '"');
8081 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
8082 obstack_grow (&util_obstack,
8083 IDENTIFIER_POINTER (fname),
8084 strlen (IDENTIFIER_POINTER (fname)));
8086 obstack_1grow (&util_obstack, '"');
8089 encode_field_decl (field, curtype, format);
8093 static void
8094 encode_aggregate_within (tree type, int curtype, int format, int left,
8095 int right)
8097 tree name;
8098 /* NB: aggregates that are pointed to have slightly different encoding
8099 rules in that you never encode the names of instance variables. */
8100 int ob_size = obstack_object_size (&util_obstack);
8101 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8102 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8103 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8104 int inline_contents
8105 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8106 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8108 /* Traverse struct aliases; it is important to get the
8109 original struct and its tag name (if any). */
8110 type = TYPE_MAIN_VARIANT (type);
8111 name = OBJC_TYPE_NAME (type);
8112 /* Open parenth/bracket. */
8113 obstack_1grow (&util_obstack, left);
8115 /* Encode the struct/union tag name, or '?' if a tag was
8116 not provided. Typedef aliases do not qualify. */
8117 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8118 #ifdef OBJCPLUS
8119 /* Did this struct have a tag? */
8120 && !TYPE_WAS_ANONYMOUS (type)
8121 #endif
8123 obstack_grow (&util_obstack,
8124 IDENTIFIER_POINTER (name),
8125 strlen (IDENTIFIER_POINTER (name)));
8126 else
8127 obstack_1grow (&util_obstack, '?');
8129 /* Encode the types (and possibly names) of the inner fields,
8130 if required. */
8131 if (inline_contents)
8133 obstack_1grow (&util_obstack, '=');
8134 encode_aggregate_fields (type, pointed_to, curtype, format);
8136 /* Close parenth/bracket. */
8137 obstack_1grow (&util_obstack, right);
8140 static void
8141 encode_aggregate (tree type, int curtype, int format)
8143 enum tree_code code = TREE_CODE (type);
8145 switch (code)
8147 case RECORD_TYPE:
8149 encode_aggregate_within (type, curtype, format, '{', '}');
8150 break;
8152 case UNION_TYPE:
8154 encode_aggregate_within (type, curtype, format, '(', ')');
8155 break;
8158 case ENUMERAL_TYPE:
8159 obstack_1grow (&util_obstack, 'i');
8160 break;
8162 default:
8163 break;
8167 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8168 field type. */
8170 static void
8171 encode_next_bitfield (int width)
8173 char buffer[40];
8174 sprintf (buffer, "b%d", width);
8175 obstack_grow (&util_obstack, buffer, strlen (buffer));
8178 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8179 static void
8180 encode_type (tree type, int curtype, int format)
8182 enum tree_code code = TREE_CODE (type);
8183 char c;
8185 if (type == error_mark_node)
8186 return;
8188 if (TYPE_READONLY (type))
8189 obstack_1grow (&util_obstack, 'r');
8191 if (code == INTEGER_TYPE)
8193 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8195 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8196 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8197 case 32:
8198 if (type == long_unsigned_type_node
8199 || type == long_integer_type_node)
8200 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8201 else
8202 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8203 break;
8204 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8205 default: abort ();
8207 obstack_1grow (&util_obstack, c);
8210 else if (code == REAL_TYPE)
8212 /* Floating point types. */
8213 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8215 case 32: c = 'f'; break;
8216 case 64:
8217 case 96:
8218 case 128: c = 'd'; break;
8219 default: abort ();
8221 obstack_1grow (&util_obstack, c);
8224 else if (code == VOID_TYPE)
8225 obstack_1grow (&util_obstack, 'v');
8227 else if (code == BOOLEAN_TYPE)
8228 obstack_1grow (&util_obstack, 'B');
8230 else if (code == ARRAY_TYPE)
8231 encode_array (type, curtype, format);
8233 else if (code == POINTER_TYPE)
8234 encode_pointer (type, curtype, format);
8236 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8237 encode_aggregate (type, curtype, format);
8239 else if (code == FUNCTION_TYPE) /* '?' */
8240 obstack_1grow (&util_obstack, '?');
8242 else if (code == COMPLEX_TYPE)
8244 obstack_1grow (&util_obstack, 'j');
8245 encode_type (TREE_TYPE (type), curtype, format);
8249 static void
8250 encode_gnu_bitfield (int position, tree type, int size)
8252 enum tree_code code = TREE_CODE (type);
8253 char buffer[40];
8254 char charType = '?';
8256 if (code == INTEGER_TYPE)
8258 if (integer_zerop (TYPE_MIN_VALUE (type)))
8260 /* Unsigned integer types. */
8262 if (TYPE_MODE (type) == QImode)
8263 charType = 'C';
8264 else if (TYPE_MODE (type) == HImode)
8265 charType = 'S';
8266 else if (TYPE_MODE (type) == SImode)
8268 if (type == long_unsigned_type_node)
8269 charType = 'L';
8270 else
8271 charType = 'I';
8273 else if (TYPE_MODE (type) == DImode)
8274 charType = 'Q';
8277 else
8278 /* Signed integer types. */
8280 if (TYPE_MODE (type) == QImode)
8281 charType = 'c';
8282 else if (TYPE_MODE (type) == HImode)
8283 charType = 's';
8284 else if (TYPE_MODE (type) == SImode)
8286 if (type == long_integer_type_node)
8287 charType = 'l';
8288 else
8289 charType = 'i';
8292 else if (TYPE_MODE (type) == DImode)
8293 charType = 'q';
8296 else if (code == ENUMERAL_TYPE)
8297 charType = 'i';
8298 else
8299 abort ();
8301 sprintf (buffer, "b%d%c%d", position, charType, size);
8302 obstack_grow (&util_obstack, buffer, strlen (buffer));
8305 static void
8306 encode_field_decl (tree field_decl, int curtype, int format)
8308 tree type;
8310 #ifdef OBJCPLUS
8311 /* C++ static members, and things that are not fields at all,
8312 should not appear in the encoding. */
8313 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8314 return;
8315 #endif
8317 type = TREE_TYPE (field_decl);
8319 /* Generate the bitfield typing information, if needed. Note the difference
8320 between GNU and NeXT runtimes. */
8321 if (DECL_BIT_FIELD_TYPE (field_decl))
8323 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8325 if (flag_next_runtime)
8326 encode_next_bitfield (size);
8327 else
8328 encode_gnu_bitfield (int_bit_position (field_decl),
8329 DECL_BIT_FIELD_TYPE (field_decl), size);
8331 else
8332 encode_type (TREE_TYPE (field_decl), curtype, format);
8335 static GTY(()) tree objc_parmlist = NULL_TREE;
8337 /* Append PARM to a list of formal parameters of a method, making a necessary
8338 array-to-pointer adjustment along the way. */
8340 static void
8341 objc_push_parm (tree parm)
8343 bool relayout_needed = false;
8345 if (TREE_TYPE (parm) == error_mark_node)
8347 objc_parmlist = chainon (objc_parmlist, parm);
8348 return;
8351 /* Decay arrays and functions into pointers. */
8352 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8354 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8355 relayout_needed = true;
8357 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8359 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8360 relayout_needed = true;
8363 if (relayout_needed)
8364 relayout_decl (parm);
8367 DECL_ARG_TYPE (parm)
8368 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8370 /* Record constancy and volatility. */
8371 c_apply_type_quals_to_decl
8372 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8373 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8374 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8376 objc_parmlist = chainon (objc_parmlist, parm);
8379 /* Retrieve the formal parameter list constructed via preceding calls to
8380 objc_push_parm(). */
8382 #ifdef OBJCPLUS
8383 static tree
8384 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8385 #else
8386 static struct c_arg_info *
8387 objc_get_parm_info (int have_ellipsis)
8388 #endif
8390 #ifdef OBJCPLUS
8391 tree parm_info = objc_parmlist;
8392 objc_parmlist = NULL_TREE;
8394 return parm_info;
8395 #else
8396 tree parm_info = objc_parmlist;
8397 struct c_arg_info *arg_info;
8398 /* The C front-end requires an elaborate song and dance at
8399 this point. */
8400 push_scope ();
8401 declare_parm_level ();
8402 while (parm_info)
8404 tree next = TREE_CHAIN (parm_info);
8406 TREE_CHAIN (parm_info) = NULL_TREE;
8407 parm_info = pushdecl (parm_info);
8408 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
8409 parm_info = next;
8411 arg_info = get_parm_info (have_ellipsis);
8412 pop_scope ();
8413 objc_parmlist = NULL_TREE;
8414 return arg_info;
8415 #endif
8418 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8419 method definitions. In the case of instance methods, we can be more
8420 specific as to the type of 'self'. */
8422 static void
8423 synth_self_and_ucmd_args (void)
8425 tree self_type;
8427 if (objc_method_context
8428 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8429 self_type = objc_instance_type;
8430 else
8431 /* Really a `struct objc_class *'. However, we allow people to
8432 assign to self, which changes its type midstream. */
8433 self_type = objc_object_type;
8435 /* id self; */
8436 objc_push_parm (build_decl (input_location,
8437 PARM_DECL, self_id, self_type));
8439 /* SEL _cmd; */
8440 objc_push_parm (build_decl (input_location,
8441 PARM_DECL, ucmd_id, objc_selector_type));
8444 /* Transform an Objective-C method definition into a static C function
8445 definition, synthesizing the first two arguments, "self" and "_cmd",
8446 in the process. */
8448 static void
8449 start_method_def (tree method)
8451 tree parmlist;
8452 #ifdef OBJCPLUS
8453 tree parm_info;
8454 #else
8455 struct c_arg_info *parm_info;
8456 #endif
8457 int have_ellipsis = 0;
8459 /* If we are defining a "dealloc" method in a non-root class, we
8460 will need to check if a [super dealloc] is missing, and warn if
8461 it is. */
8462 if(CLASS_SUPER_NAME (objc_implementation_context)
8463 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8464 should_call_super_dealloc = 1;
8465 else
8466 should_call_super_dealloc = 0;
8468 /* Required to implement _msgSuper. */
8469 objc_method_context = method;
8470 UOBJC_SUPER_decl = NULL_TREE;
8472 /* Generate prototype declarations for arguments..."new-style". */
8473 synth_self_and_ucmd_args ();
8475 /* Generate argument declarations if a keyword_decl. */
8476 parmlist = METHOD_SEL_ARGS (method);
8477 while (parmlist)
8479 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8481 parm = build_decl (input_location,
8482 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8483 objc_push_parm (parm);
8484 parmlist = TREE_CHAIN (parmlist);
8487 if (METHOD_ADD_ARGS (method))
8489 tree akey;
8491 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8492 akey; akey = TREE_CHAIN (akey))
8494 objc_push_parm (TREE_VALUE (akey));
8497 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8498 have_ellipsis = 1;
8501 parm_info = objc_get_parm_info (have_ellipsis);
8503 really_start_method (objc_method_context, parm_info);
8506 /* Return 1 if TYPE1 is equivalent to TYPE2
8507 for purposes of method overloading. */
8509 static int
8510 objc_types_are_equivalent (tree type1, tree type2)
8512 if (type1 == type2)
8513 return 1;
8515 /* Strip away indirections. */
8516 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8517 && (TREE_CODE (type1) == TREE_CODE (type2)))
8518 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8519 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8520 return 0;
8522 type1 = (TYPE_HAS_OBJC_INFO (type1)
8523 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8524 : NULL_TREE);
8525 type2 = (TYPE_HAS_OBJC_INFO (type2)
8526 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8527 : NULL_TREE);
8529 if (list_length (type1) == list_length (type2))
8531 for (; type2; type2 = TREE_CHAIN (type2))
8532 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8533 return 0;
8534 return 1;
8536 return 0;
8539 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8541 static int
8542 objc_types_share_size_and_alignment (tree type1, tree type2)
8544 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8545 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8548 /* Return 1 if PROTO1 is equivalent to PROTO2
8549 for purposes of method overloading. Ordinarily, the type signatures
8550 should match up exactly, unless STRICT is zero, in which case we
8551 shall allow differences in which the size and alignment of a type
8552 is the same. */
8554 static int
8555 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8557 tree type1, type2;
8559 /* The following test is needed in case there are hashing
8560 collisions. */
8561 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8562 return 0;
8564 /* Compare return types. */
8565 type1 = TREE_VALUE (TREE_TYPE (proto1));
8566 type2 = TREE_VALUE (TREE_TYPE (proto2));
8568 if (!objc_types_are_equivalent (type1, type2)
8569 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8570 return 0;
8572 /* Compare argument types. */
8573 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8574 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8575 type1 && type2;
8576 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8578 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8579 && (strict
8580 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8581 TREE_VALUE (type2))))
8582 return 0;
8585 return (!type1 && !type2);
8588 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8589 this occurs. ObjC method dispatches are _not_ like C++ virtual
8590 member function dispatches, and we account for the difference here. */
8591 tree
8592 #ifdef OBJCPLUS
8593 objc_fold_obj_type_ref (tree ref, tree known_type)
8594 #else
8595 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8596 tree known_type ATTRIBUTE_UNUSED)
8597 #endif
8599 #ifdef OBJCPLUS
8600 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8602 /* If the receiver does not have virtual member functions, there
8603 is nothing we can (or need to) do here. */
8604 if (!v)
8605 return NULL_TREE;
8607 /* Let C++ handle C++ virtual functions. */
8608 return cp_fold_obj_type_ref (ref, known_type);
8609 #else
8610 /* For plain ObjC, we currently do not need to do anything. */
8611 return NULL_TREE;
8612 #endif
8615 static void
8616 objc_start_function (tree name, tree type, tree attrs,
8617 #ifdef OBJCPLUS
8618 tree params
8619 #else
8620 struct c_arg_info *params
8621 #endif
8624 tree fndecl = build_decl (input_location,
8625 FUNCTION_DECL, name, type);
8627 #ifdef OBJCPLUS
8628 DECL_ARGUMENTS (fndecl) = params;
8629 DECL_INITIAL (fndecl) = error_mark_node;
8630 DECL_EXTERNAL (fndecl) = 0;
8631 TREE_STATIC (fndecl) = 1;
8632 retrofit_lang_decl (fndecl);
8633 cplus_decl_attributes (&fndecl, attrs, 0);
8634 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8635 #else
8636 current_function_returns_value = 0; /* Assume, until we see it does. */
8637 current_function_returns_null = 0;
8639 decl_attributes (&fndecl, attrs, 0);
8640 announce_function (fndecl);
8641 DECL_INITIAL (fndecl) = error_mark_node;
8642 DECL_EXTERNAL (fndecl) = 0;
8643 TREE_STATIC (fndecl) = 1;
8644 current_function_decl = pushdecl (fndecl);
8645 push_scope ();
8646 declare_parm_level ();
8647 DECL_RESULT (current_function_decl)
8648 = build_decl (input_location,
8649 RESULT_DECL, NULL_TREE,
8650 TREE_TYPE (TREE_TYPE (current_function_decl)));
8651 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8652 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8653 start_fname_decls ();
8654 store_parm_decls_from (params);
8655 #endif
8657 TREE_USED (current_function_decl) = 1;
8660 /* - Generate an identifier for the function. the format is "_n_cls",
8661 where 1 <= n <= nMethods, and cls is the name the implementation we
8662 are processing.
8663 - Install the return type from the method declaration.
8664 - If we have a prototype, check for type consistency. */
8666 static void
8667 really_start_method (tree method,
8668 #ifdef OBJCPLUS
8669 tree parmlist
8670 #else
8671 struct c_arg_info *parmlist
8672 #endif
8675 tree ret_type, meth_type;
8676 tree method_id;
8677 const char *sel_name, *class_name, *cat_name;
8678 char *buf;
8680 /* Synth the storage class & assemble the return type. */
8681 ret_type = TREE_VALUE (TREE_TYPE (method));
8683 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8684 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8685 cat_name = ((TREE_CODE (objc_implementation_context)
8686 == CLASS_IMPLEMENTATION_TYPE)
8687 ? NULL
8688 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8689 method_slot++;
8691 /* Make sure this is big enough for any plausible method label. */
8692 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8693 + (cat_name ? strlen (cat_name) : 0));
8695 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8696 class_name, cat_name, sel_name, method_slot);
8698 method_id = get_identifier (buf);
8700 #ifdef OBJCPLUS
8701 /* Objective-C methods cannot be overloaded, so we don't need
8702 the type encoding appended. It looks bad anyway... */
8703 push_lang_context (lang_name_c);
8704 #endif
8706 meth_type
8707 = build_function_type (ret_type,
8708 get_arg_type_list (method, METHOD_DEF, 0));
8709 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8711 /* Set self_decl from the first argument. */
8712 self_decl = DECL_ARGUMENTS (current_function_decl);
8714 /* Suppress unused warnings. */
8715 TREE_USED (self_decl) = 1;
8716 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8717 #ifdef OBJCPLUS
8718 pop_lang_context ();
8719 #endif
8721 METHOD_DEFINITION (method) = current_function_decl;
8723 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8725 if (implementation_template != objc_implementation_context)
8727 tree proto
8728 = lookup_method_static (implementation_template,
8729 METHOD_SEL_NAME (method),
8730 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8731 | OBJC_LOOKUP_NO_SUPER));
8733 if (proto)
8735 if (!comp_proto_with_proto (method, proto, 1))
8737 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8739 warning_at (DECL_SOURCE_LOCATION (method), 0,
8740 "conflicting types for %<%c%s%>",
8741 (type ? '-' : '+'),
8742 identifier_to_locale (gen_method_decl (method)));
8743 inform (DECL_SOURCE_LOCATION (proto),
8744 "previous declaration of %<%c%s%>",
8745 (type ? '-' : '+'),
8746 identifier_to_locale (gen_method_decl (proto)));
8749 else
8751 /* We have a method @implementation even though we did not
8752 see a corresponding @interface declaration (which is allowed
8753 by Objective-C rules). Go ahead and place the method in
8754 the @interface anyway, so that message dispatch lookups
8755 will see it. */
8756 tree interface = implementation_template;
8758 if (TREE_CODE (objc_implementation_context)
8759 == CATEGORY_IMPLEMENTATION_TYPE)
8760 interface = lookup_category
8761 (interface,
8762 CLASS_SUPER_NAME (objc_implementation_context));
8764 if (interface)
8765 objc_add_method (interface, copy_node (method),
8766 TREE_CODE (method) == CLASS_METHOD_DECL);
8771 static void *UOBJC_SUPER_scope = 0;
8773 /* _n_Method (id self, SEL sel, ...)
8775 struct objc_super _S;
8776 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8777 } */
8779 static tree
8780 get_super_receiver (void)
8782 if (objc_method_context)
8784 tree super_expr, super_expr_list;
8786 if (!UOBJC_SUPER_decl)
8788 UOBJC_SUPER_decl = build_decl (input_location,
8789 VAR_DECL, get_identifier (TAG_SUPER),
8790 objc_super_template);
8791 /* This prevents `unused variable' warnings when compiling with -Wall. */
8792 TREE_USED (UOBJC_SUPER_decl) = 1;
8793 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8794 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
8795 NULL_TREE);
8796 UOBJC_SUPER_scope = objc_get_current_scope ();
8799 /* Set receiver to self. */
8800 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8801 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8802 NOP_EXPR, input_location, self_decl,
8803 NULL_TREE);
8804 super_expr_list = super_expr;
8806 /* Set class to begin searching. */
8807 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8808 get_identifier ("super_class"));
8810 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8812 /* [_cls, __cls]Super are "pre-built" in
8813 synth_forward_declarations. */
8815 super_expr = build_modify_expr (input_location, super_expr,
8816 NULL_TREE, NOP_EXPR,
8817 input_location,
8818 ((TREE_CODE (objc_method_context)
8819 == INSTANCE_METHOD_DECL)
8820 ? ucls_super_ref
8821 : uucls_super_ref),
8822 NULL_TREE);
8825 else
8826 /* We have a category. */
8828 tree super_name = CLASS_SUPER_NAME (implementation_template);
8829 tree super_class;
8831 /* Barf if super used in a category of Object. */
8832 if (!super_name)
8834 error ("no super class declared in interface for %qE",
8835 CLASS_NAME (implementation_template));
8836 return error_mark_node;
8839 if (flag_next_runtime && !flag_zero_link)
8841 super_class = objc_get_class_reference (super_name);
8842 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8843 /* If we are in a class method, we must retrieve the
8844 _metaclass_ for the current class, pointed at by
8845 the class's "isa" pointer. The following assumes that
8846 "isa" is the first ivar in a class (which it must be). */
8847 super_class
8848 = build_indirect_ref
8849 (input_location,
8850 build_c_cast (input_location,
8851 build_pointer_type (objc_class_type),
8852 super_class), "unary *");
8854 else
8856 add_class_reference (super_name);
8857 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8858 ? objc_get_class_decl : objc_get_meta_class_decl);
8859 assemble_external (super_class);
8860 super_class
8861 = build_function_call
8862 (input_location,
8863 super_class,
8864 build_tree_list
8865 (NULL_TREE,
8866 my_build_string_pointer
8867 (IDENTIFIER_LENGTH (super_name) + 1,
8868 IDENTIFIER_POINTER (super_name))));
8871 super_expr
8872 = build_modify_expr (input_location, super_expr, NULL_TREE,
8873 NOP_EXPR,
8874 input_location,
8875 build_c_cast (input_location,
8876 TREE_TYPE (super_expr),
8877 super_class),
8878 NULL_TREE);
8881 super_expr_list = build_compound_expr (input_location,
8882 super_expr_list, super_expr);
8884 super_expr = build_unary_op (input_location,
8885 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8886 super_expr_list = build_compound_expr (input_location,
8887 super_expr_list, super_expr);
8889 return super_expr_list;
8891 else
8893 error ("[super ...] must appear in a method context");
8894 return error_mark_node;
8898 /* When exiting a scope, sever links to a 'super' declaration (if any)
8899 therein contained. */
8901 void
8902 objc_clear_super_receiver (void)
8904 if (objc_method_context
8905 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8906 UOBJC_SUPER_decl = 0;
8907 UOBJC_SUPER_scope = 0;
8911 void
8912 objc_finish_method_definition (tree fndecl)
8914 /* We cannot validly inline ObjC methods, at least not without a language
8915 extension to declare that a method need not be dynamically
8916 dispatched, so suppress all thoughts of doing so. */
8917 DECL_UNINLINABLE (fndecl) = 1;
8919 #ifndef OBJCPLUS
8920 /* The C++ front-end will have called finish_function() for us. */
8921 finish_function ();
8922 #endif
8924 METHOD_ENCODING (objc_method_context)
8925 = encode_method_prototype (objc_method_context);
8927 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8928 since the optimizer may find "may be used before set" errors. */
8929 objc_method_context = NULL_TREE;
8931 if (should_call_super_dealloc)
8932 warning (0, "method possibly missing a [super dealloc] call");
8935 /* Given a tree DECL node, produce a printable description of it in the given
8936 buffer, overwriting the buffer. */
8938 static char *
8939 gen_declaration (tree decl)
8941 errbuf[0] = '\0';
8943 if (DECL_P (decl))
8945 gen_type_name_0 (TREE_TYPE (decl));
8947 if (DECL_NAME (decl))
8949 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8950 strcat (errbuf, " ");
8952 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8955 if (DECL_INITIAL (decl)
8956 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8957 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8958 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8961 return errbuf;
8964 /* Given a tree TYPE node, produce a printable description of it in the given
8965 buffer, overwriting the buffer. */
8967 static char *
8968 gen_type_name_0 (tree type)
8970 tree orig = type, proto;
8972 if (TYPE_P (type) && TYPE_NAME (type))
8973 type = TYPE_NAME (type);
8974 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8976 tree inner = TREE_TYPE (type);
8978 while (TREE_CODE (inner) == ARRAY_TYPE)
8979 inner = TREE_TYPE (inner);
8981 gen_type_name_0 (inner);
8983 if (!POINTER_TYPE_P (inner))
8984 strcat (errbuf, " ");
8986 if (POINTER_TYPE_P (type))
8987 strcat (errbuf, "*");
8988 else
8989 while (type != inner)
8991 strcat (errbuf, "[");
8993 if (TYPE_DOMAIN (type))
8995 char sz[20];
8997 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8998 (TREE_INT_CST_LOW
8999 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
9000 strcat (errbuf, sz);
9003 strcat (errbuf, "]");
9004 type = TREE_TYPE (type);
9007 goto exit_function;
9010 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
9011 type = DECL_NAME (type);
9013 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
9014 ? IDENTIFIER_POINTER (type)
9015 : "");
9017 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
9018 if (objc_is_id (orig))
9019 orig = TREE_TYPE (orig);
9021 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
9023 if (proto)
9025 strcat (errbuf, " <");
9027 while (proto) {
9028 strcat (errbuf,
9029 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
9030 proto = TREE_CHAIN (proto);
9031 strcat (errbuf, proto ? ", " : ">");
9035 exit_function:
9036 return errbuf;
9039 static char *
9040 gen_type_name (tree type)
9042 errbuf[0] = '\0';
9044 return gen_type_name_0 (type);
9047 /* Given a method tree, put a printable description into the given
9048 buffer (overwriting) and return a pointer to the buffer. */
9050 static char *
9051 gen_method_decl (tree method)
9053 tree chain;
9055 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
9056 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
9057 strcat (errbuf, ")");
9058 chain = METHOD_SEL_ARGS (method);
9060 if (chain)
9062 /* We have a chain of keyword_decls. */
9065 if (KEYWORD_KEY_NAME (chain))
9066 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
9068 strcat (errbuf, ":(");
9069 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9070 strcat (errbuf, ")");
9072 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9073 if ((chain = TREE_CHAIN (chain)))
9074 strcat (errbuf, " ");
9076 while (chain);
9078 if (METHOD_ADD_ARGS (method))
9080 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9082 /* Know we have a chain of parm_decls. */
9083 while (chain)
9085 strcat (errbuf, ", ");
9086 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9087 chain = TREE_CHAIN (chain);
9090 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9091 strcat (errbuf, ", ...");
9095 else
9096 /* We have a unary selector. */
9097 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9099 return errbuf;
9102 /* Debug info. */
9105 /* Dump an @interface declaration of the supplied class CHAIN to the
9106 supplied file FP. Used to implement the -gen-decls option (which
9107 prints out an @interface declaration of all classes compiled in
9108 this run); potentially useful for debugging the compiler too. */
9109 static void
9110 dump_interface (FILE *fp, tree chain)
9112 /* FIXME: A heap overflow here whenever a method (or ivar)
9113 declaration is so long that it doesn't fit in the buffer. The
9114 code and all the related functions should be rewritten to avoid
9115 using fixed size buffers. */
9116 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9117 tree ivar_decls = CLASS_RAW_IVARS (chain);
9118 tree nst_methods = CLASS_NST_METHODS (chain);
9119 tree cls_methods = CLASS_CLS_METHODS (chain);
9121 fprintf (fp, "\n@interface %s", my_name);
9123 /* CLASS_SUPER_NAME is used to store the superclass name for
9124 classes, and the category name for categories. */
9125 if (CLASS_SUPER_NAME (chain))
9127 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9129 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9130 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9132 fprintf (fp, " (%s)\n", name);
9134 else
9136 fprintf (fp, " : %s\n", name);
9139 else
9140 fprintf (fp, "\n");
9142 /* FIXME - the following doesn't seem to work at the moment. */
9143 if (ivar_decls)
9145 fprintf (fp, "{\n");
9148 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9149 ivar_decls = TREE_CHAIN (ivar_decls);
9151 while (ivar_decls);
9152 fprintf (fp, "}\n");
9155 while (nst_methods)
9157 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9158 nst_methods = TREE_CHAIN (nst_methods);
9161 while (cls_methods)
9163 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9164 cls_methods = TREE_CHAIN (cls_methods);
9167 fprintf (fp, "@end\n");
9170 /* Demangle function for Objective-C */
9171 static const char *
9172 objc_demangle (const char *mangled)
9174 char *demangled, *cp;
9176 if (mangled[0] == '_' &&
9177 (mangled[1] == 'i' || mangled[1] == 'c') &&
9178 mangled[2] == '_')
9180 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9181 if (mangled[1] == 'i')
9182 *cp++ = '-'; /* for instance method */
9183 else
9184 *cp++ = '+'; /* for class method */
9185 *cp++ = '['; /* opening left brace */
9186 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9187 while (*cp && *cp == '_')
9188 cp++; /* skip any initial underbars in class name */
9189 cp = strchr(cp, '_'); /* find first non-initial underbar */
9190 if (cp == NULL)
9192 free(demangled); /* not mangled name */
9193 return mangled;
9195 if (cp[1] == '_') /* easy case: no category name */
9197 *cp++ = ' '; /* replace two '_' with one ' ' */
9198 strcpy(cp, mangled + (cp - demangled) + 2);
9200 else
9202 *cp++ = '('; /* less easy case: category name */
9203 cp = strchr(cp, '_');
9204 if (cp == 0)
9206 free(demangled); /* not mangled name */
9207 return mangled;
9209 *cp++ = ')';
9210 *cp++ = ' '; /* overwriting 1st char of method name... */
9211 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9213 while (*cp && *cp == '_')
9214 cp++; /* skip any initial underbars in method name */
9215 for (; *cp; cp++)
9216 if (*cp == '_')
9217 *cp = ':'; /* replace remaining '_' with ':' */
9218 *cp++ = ']'; /* closing right brace */
9219 *cp++ = 0; /* string terminator */
9220 return demangled;
9222 else
9223 return mangled; /* not an objc mangled name */
9226 const char *
9227 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9229 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9232 static void
9233 init_objc (void)
9235 gcc_obstack_init (&util_obstack);
9236 util_firstobj = (char *) obstack_finish (&util_obstack);
9238 errbuf = XNEWVEC (char, 1024 * 10);
9239 hash_init ();
9240 synth_module_prologue ();
9243 static void
9244 finish_objc (void)
9246 struct imp_entry *impent;
9247 tree chain;
9248 /* The internally generated initializers appear to have missing braces.
9249 Don't warn about this. */
9250 int save_warn_missing_braces = warn_missing_braces;
9251 warn_missing_braces = 0;
9253 /* A missing @end may not be detected by the parser. */
9254 if (objc_implementation_context)
9256 warning (0, "%<@end%> missing in implementation context");
9257 finish_class (objc_implementation_context);
9258 objc_ivar_chain = NULL_TREE;
9259 objc_implementation_context = NULL_TREE;
9262 /* Process the static instances here because initialization of objc_symtab
9263 depends on them. */
9264 if (objc_static_instances)
9265 generate_static_references ();
9267 if (imp_list || class_names_chain
9268 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9269 generate_objc_symtab_decl ();
9271 for (impent = imp_list; impent; impent = impent->next)
9273 objc_implementation_context = impent->imp_context;
9274 implementation_template = impent->imp_template;
9276 UOBJC_CLASS_decl = impent->class_decl;
9277 UOBJC_METACLASS_decl = impent->meta_decl;
9279 /* Dump the @interface of each class as we compile it, if the
9280 -gen-decls option is in use. TODO: Dump the classes in the
9281 order they were found, rather than in reverse order as we
9282 are doing now. */
9283 if (flag_gen_declaration)
9285 dump_interface (gen_declaration_file, objc_implementation_context);
9288 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9290 /* all of the following reference the string pool... */
9291 generate_ivar_lists ();
9292 generate_dispatch_tables ();
9293 generate_shared_structures (impent->has_cxx_cdtors
9294 ? CLS_HAS_CXX_STRUCTORS
9295 : 0);
9297 else
9299 generate_dispatch_tables ();
9300 generate_category (objc_implementation_context);
9304 /* If we are using an array of selectors, we must always
9305 finish up the array decl even if no selectors were used. */
9306 if (! flag_next_runtime || sel_ref_chain)
9307 build_selector_translation_table ();
9309 if (protocol_chain)
9310 generate_protocols ();
9312 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9313 generate_objc_image_info ();
9315 /* Arrange for ObjC data structures to be initialized at run time. */
9316 if (objc_implementation_context || class_names_chain || objc_static_instances
9317 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9319 build_module_descriptor ();
9321 if (!flag_next_runtime)
9322 build_module_initializer_routine ();
9325 /* Dump the class references. This forces the appropriate classes
9326 to be linked into the executable image, preserving unix archive
9327 semantics. This can be removed when we move to a more dynamically
9328 linked environment. */
9330 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9332 handle_class_ref (chain);
9333 if (TREE_PURPOSE (chain))
9334 generate_classref_translation_entry (chain);
9337 for (impent = imp_list; impent; impent = impent->next)
9338 handle_impent (impent);
9340 if (warn_selector)
9342 int slot;
9343 hash hsh;
9345 /* Run through the selector hash tables and print a warning for any
9346 selector which has multiple methods. */
9348 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9350 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9351 check_duplicates (hsh, 0, 1);
9352 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9353 check_duplicates (hsh, 0, 1);
9357 warn_missing_braces = save_warn_missing_braces;
9360 /* Subroutines of finish_objc. */
9362 static void
9363 generate_classref_translation_entry (tree chain)
9365 tree expr, decl, type;
9367 decl = TREE_PURPOSE (chain);
9368 type = TREE_TYPE (decl);
9370 expr = add_objc_string (TREE_VALUE (chain), class_names);
9371 expr = convert (type, expr); /* cast! */
9373 /* The decl that is the one that we
9374 forward declared in build_class_reference. */
9375 finish_var_decl (decl, expr);
9376 return;
9379 static void
9380 handle_class_ref (tree chain)
9382 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9383 char *string = (char *) alloca (strlen (name) + 30);
9384 tree decl;
9385 tree exp;
9387 sprintf (string, "%sobjc_class_name_%s",
9388 (flag_next_runtime ? "." : "__"), name);
9390 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9391 if (flag_next_runtime)
9393 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9394 return;
9396 #endif
9398 /* Make a decl for this name, so we can use its address in a tree. */
9399 decl = build_decl (input_location,
9400 VAR_DECL, get_identifier (string), char_type_node);
9401 DECL_EXTERNAL (decl) = 1;
9402 TREE_PUBLIC (decl) = 1;
9404 pushdecl (decl);
9405 rest_of_decl_compilation (decl, 0, 0);
9407 /* Make a decl for the address. */
9408 sprintf (string, "%sobjc_class_ref_%s",
9409 (flag_next_runtime ? "." : "__"), name);
9410 exp = build1 (ADDR_EXPR, string_type_node, decl);
9411 decl = build_decl (input_location,
9412 VAR_DECL, get_identifier (string), string_type_node);
9413 DECL_INITIAL (decl) = exp;
9414 TREE_STATIC (decl) = 1;
9415 TREE_USED (decl) = 1;
9416 /* Force the output of the decl as this forces the reference of the class. */
9417 mark_decl_referenced (decl);
9419 pushdecl (decl);
9420 rest_of_decl_compilation (decl, 0, 0);
9423 static void
9424 handle_impent (struct imp_entry *impent)
9426 char *string;
9428 objc_implementation_context = impent->imp_context;
9429 implementation_template = impent->imp_template;
9431 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9433 const char *const class_name =
9434 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9436 string = (char *) alloca (strlen (class_name) + 30);
9438 sprintf (string, "%sobjc_class_name_%s",
9439 (flag_next_runtime ? "." : "__"), class_name);
9441 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9443 const char *const class_name =
9444 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9445 const char *const class_super_name =
9446 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9448 string = (char *) alloca (strlen (class_name)
9449 + strlen (class_super_name) + 30);
9451 /* Do the same for categories. Even though no references to
9452 these symbols are generated automatically by the compiler, it
9453 gives you a handle to pull them into an archive by hand. */
9454 sprintf (string, "*%sobjc_category_name_%s_%s",
9455 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9457 else
9458 return;
9460 #ifdef ASM_DECLARE_CLASS_REFERENCE
9461 if (flag_next_runtime)
9463 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9464 return;
9466 else
9467 #endif
9469 tree decl, init;
9471 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9472 decl = build_decl (input_location,
9473 VAR_DECL, get_identifier (string), TREE_TYPE (init));
9474 TREE_PUBLIC (decl) = 1;
9475 TREE_READONLY (decl) = 1;
9476 TREE_USED (decl) = 1;
9477 TREE_CONSTANT (decl) = 1;
9478 DECL_CONTEXT (decl) = 0;
9479 DECL_ARTIFICIAL (decl) = 1;
9480 DECL_INITIAL (decl) = init;
9481 assemble_variable (decl, 1, 0, 0);
9485 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9486 later requires that ObjC translation units participating in F&C be
9487 specially marked. The following routine accomplishes this. */
9489 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9491 static void
9492 generate_objc_image_info (void)
9494 tree decl, initlist;
9495 int flags
9496 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9497 | (flag_objc_gc ? 2 : 0));
9499 decl = start_var_decl (build_array_type
9500 (integer_type_node,
9501 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9502 "_OBJC_IMAGE_INFO");
9504 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9505 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9506 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9508 finish_var_decl (decl, initlist);
9511 /* Look up ID as an instance variable. OTHER contains the result of
9512 the C or C++ lookup, which we may want to use instead. */
9514 tree
9515 objc_lookup_ivar (tree other, tree id)
9517 tree ivar;
9519 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9520 if (!objc_method_context)
9521 return other;
9523 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9524 /* We have a message to super. */
9525 return get_super_receiver ();
9527 /* In a class method, look up an instance variable only as a last
9528 resort. */
9529 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9530 && other && other != error_mark_node)
9531 return other;
9533 /* Look up the ivar, but do not use it if it is not accessible. */
9534 ivar = is_ivar (objc_ivar_chain, id);
9536 if (!ivar || is_private (ivar))
9537 return other;
9539 /* In an instance method, a local variable (or parameter) may hide the
9540 instance variable. */
9541 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9542 && other && other != error_mark_node
9543 #ifdef OBJCPLUS
9544 && CP_DECL_CONTEXT (other) != global_namespace)
9545 #else
9546 && !DECL_FILE_SCOPE_P (other))
9547 #endif
9549 warning (0, "local declaration of %qE hides instance variable",
9550 id);
9552 return other;
9555 /* At this point, we are either in an instance method with no obscuring
9556 local definitions, or in a class method with no alternate definitions
9557 at all. */
9558 return build_ivar_reference (id);
9561 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9562 needs to be done if we are calling a function through a cast. */
9564 tree
9565 objc_rewrite_function_call (tree function, tree first_param)
9567 if (TREE_CODE (function) == NOP_EXPR
9568 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9569 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9570 == FUNCTION_DECL)
9572 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9573 TREE_OPERAND (function, 0),
9574 first_param, size_zero_node);
9577 return function;
9580 /* Look for the special case of OBJC_TYPE_REF with the address of
9581 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9582 of its cousins). */
9585 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9587 enum gimplify_status r0, r1;
9588 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9589 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9590 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9591 == FUNCTION_DECL)
9593 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9594 value of the OBJ_TYPE_REF, so force them to be emitted
9595 during subexpression evaluation rather than after the
9596 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9597 C to use direct rather than indirect calls when the
9598 object expression has a postincrement. */
9599 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9600 is_gimple_val, fb_rvalue);
9601 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9602 is_gimple_val, fb_rvalue);
9604 return MIN (r0, r1);
9607 #ifdef OBJCPLUS
9608 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9609 #else
9610 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9611 #endif
9614 #include "gt-objc-objc-act.h"