1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
116 /* Set up for use of obstacks. */
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
158 static void objc_start_function (tree, tree, tree, tree);
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
188 static tree objc_build_volatilized_type (tree);
191 static void objc_generate_cxx_cdtors (void);
194 static const char *synth_id_with_class_suffix (const char *, tree);
196 /* Hash tables to manage the global pool of method prototypes. */
198 hash *nst_method_hash_list = 0;
199 hash *cls_method_hash_list = 0;
201 static hash hash_lookup (hash *, tree);
202 static tree lookup_method (tree, tree);
203 static tree lookup_method_static (tree, tree, int);
207 class_names, /* class, category, protocol, module names */
208 meth_var_names, /* method and variable names */
209 meth_var_types /* method and variable type descriptors */
212 static tree add_objc_string (tree, enum string_section);
213 static tree build_objc_string_decl (enum string_section);
214 static void build_selector_table_decl (void);
216 /* Protocol additions. */
218 static tree lookup_protocol (tree);
219 static tree lookup_and_install_protocols (tree);
223 static void encode_type_qualifiers (tree);
224 static void encode_type (tree, int, int);
225 static void encode_field_decl (tree, int, int);
228 static void really_start_method (tree, tree);
230 static void really_start_method (tree, struct c_arg_info *);
232 static int comp_proto_with_proto (tree, tree, int);
233 static void objc_push_parm (tree);
235 static tree objc_get_parm_info (int);
237 static struct c_arg_info *objc_get_parm_info (int);
240 /* Utilities for debugging and error diagnostics. */
242 static void warn_with_method (const char *, int, tree);
243 static char *gen_type_name (tree);
244 static char *gen_type_name_0 (tree);
245 static char *gen_method_decl (tree);
246 static char *gen_declaration (tree);
248 /* Everything else. */
250 static tree create_field_decl (tree, const char *);
251 static void add_class_reference (tree);
252 static void build_protocol_template (void);
253 static tree encode_method_prototype (tree);
254 static void generate_classref_translation_entry (tree);
255 static void handle_class_ref (tree);
256 static void generate_struct_by_value_array (void)
258 static void mark_referenced_methods (void);
259 static void generate_objc_image_info (void);
261 /*** Private Interface (data) ***/
263 /* Reserved tag definitions. */
265 #define OBJECT_TYPEDEF_NAME "id"
266 #define CLASS_TYPEDEF_NAME "Class"
268 #define TAG_OBJECT "objc_object"
269 #define TAG_CLASS "objc_class"
270 #define TAG_SUPER "objc_super"
271 #define TAG_SELECTOR "objc_selector"
273 #define UTAG_CLASS "_objc_class"
274 #define UTAG_IVAR "_objc_ivar"
275 #define UTAG_IVAR_LIST "_objc_ivar_list"
276 #define UTAG_METHOD "_objc_method"
277 #define UTAG_METHOD_LIST "_objc_method_list"
278 #define UTAG_CATEGORY "_objc_category"
279 #define UTAG_MODULE "_objc_module"
280 #define UTAG_SYMTAB "_objc_symtab"
281 #define UTAG_SUPER "_objc_super"
282 #define UTAG_SELECTOR "_objc_selector"
284 #define UTAG_PROTOCOL "_objc_protocol"
285 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
286 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
288 /* Note that the string object global name is only needed for the
290 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
292 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
294 static const char *TAG_GETCLASS;
295 static const char *TAG_GETMETACLASS;
296 static const char *TAG_MSGSEND;
297 static const char *TAG_MSGSENDSUPER;
298 /* The NeXT Objective-C messenger may have two extra entry points, for use
299 when returning a structure. */
300 static const char *TAG_MSGSEND_STRET;
301 static const char *TAG_MSGSENDSUPER_STRET;
302 static const char *default_constant_string_class_name;
304 /* Runtime metadata flags. */
305 #define CLS_FACTORY 0x0001L
306 #define CLS_META 0x0002L
307 #define CLS_HAS_CXX_STRUCTORS 0x2000L
309 #define OBJC_MODIFIER_STATIC 0x00000001
310 #define OBJC_MODIFIER_FINAL 0x00000002
311 #define OBJC_MODIFIER_PUBLIC 0x00000004
312 #define OBJC_MODIFIER_PRIVATE 0x00000008
313 #define OBJC_MODIFIER_PROTECTED 0x00000010
314 #define OBJC_MODIFIER_NATIVE 0x00000020
315 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
316 #define OBJC_MODIFIER_ABSTRACT 0x00000080
317 #define OBJC_MODIFIER_VOLATILE 0x00000100
318 #define OBJC_MODIFIER_TRANSIENT 0x00000200
319 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
321 /* NeXT-specific tags. */
323 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
324 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
325 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
326 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
327 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
328 #define TAG_EXCEPTIONMATCH "objc_exception_match"
329 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
330 #define TAG_SYNCENTER "objc_sync_enter"
331 #define TAG_SYNCEXIT "objc_sync_exit"
332 #define TAG_SETJMP "_setjmp"
333 #define UTAG_EXCDATA "_objc_exception_data"
335 #define TAG_ASSIGNIVAR "objc_assign_ivar"
336 #define TAG_ASSIGNGLOBAL "objc_assign_global"
337 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
339 /* Branch entry points. All that matters here are the addresses;
340 functions with these names do not really exist in libobjc. */
342 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
343 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
345 #define TAG_CXX_CONSTRUCT ".cxx_construct"
346 #define TAG_CXX_DESTRUCT ".cxx_destruct"
348 /* GNU-specific tags. */
350 #define TAG_EXECCLASS "__objc_exec_class"
351 #define TAG_GNUINIT "__objc_gnu_init"
353 /* Flags for lookup_method_static(). */
354 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
355 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
357 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
358 tree objc_global_trees[OCTI_MAX];
360 static void handle_impent (struct imp_entry *);
362 struct imp_entry *imp_list = 0;
363 int imp_count = 0; /* `@implementation' */
364 int cat_count = 0; /* `@category' */
366 enum tree_code objc_inherit_code;
367 int objc_public_flag;
369 /* Use to generate method labels. */
370 static int method_slot = 0;
374 static char *errbuf; /* Buffer for error diagnostics */
376 /* Data imported from tree.c. */
378 extern enum debug_info_type write_symbols;
380 /* Data imported from toplev.c. */
382 extern const char *dump_base_name;
384 static int flag_typed_selectors;
386 /* Store all constructed constant strings in a hash table so that
387 they get uniqued properly. */
389 struct string_descriptor GTY(())
391 /* The literal argument . */
394 /* The resulting constant string. */
398 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
400 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
401 struct volatilized_type GTY(())
406 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
408 FILE *gen_declaration_file;
410 /* Tells "encode_pointer/encode_aggregate" whether we are generating
411 type descriptors for instance variables (as opposed to methods).
412 Type descriptors for instance variables contain more information
413 than methods (for static typing and embedded structures). */
415 static int generating_instance_variables = 0;
417 /* Some platforms pass small structures through registers versus
418 through an invisible pointer. Determine at what size structure is
419 the transition point between the two possibilities. */
422 generate_struct_by_value_array (void)
425 tree field_decl, field_decl_chain;
427 int aggregate_in_mem[32];
430 /* Presumably no platform passes 32 byte structures in a register. */
431 for (i = 1; i < 32; i++)
435 /* Create an unnamed struct that has `i' character components */
436 type = start_struct (RECORD_TYPE, NULL_TREE);
438 strcpy (buffer, "c1");
439 field_decl = create_field_decl (char_type_node,
441 field_decl_chain = field_decl;
443 for (j = 1; j < i; j++)
445 sprintf (buffer, "c%d", j + 1);
446 field_decl = create_field_decl (char_type_node,
448 chainon (field_decl_chain, field_decl);
450 finish_struct (type, field_decl_chain, NULL_TREE);
452 aggregate_in_mem[i] = aggregate_value_p (type, 0);
453 if (!aggregate_in_mem[i])
457 /* We found some structures that are returned in registers instead of memory
458 so output the necessary data. */
461 for (i = 31; i >= 0; i--)
462 if (!aggregate_in_mem[i])
464 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
466 /* The first member of the structure is always 0 because we don't handle
467 structures with 0 members */
468 printf ("static int struct_forward_array[] = {\n 0");
470 for (j = 1; j <= i; j++)
471 printf (", %d", aggregate_in_mem[j]);
482 if (cxx_init () == false)
484 if (c_objc_common_init () == false)
488 #ifndef USE_MAPPED_LOCATION
489 /* Force the line number back to 0; check_newline will have
490 raised it to 1, which will make the builtin functions appear
491 not to be built in. */
495 /* If gen_declaration desired, open the output file. */
496 if (flag_gen_declaration)
498 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
499 gen_declaration_file = fopen (dumpname, "w");
500 if (gen_declaration_file == 0)
501 fatal_error ("can't open %s: %m", dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_MSGSEND_STRET = "objc_msgSend_stret";
512 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
513 default_constant_string_class_name = "NSConstantString";
517 TAG_GETCLASS = "objc_get_class";
518 TAG_GETMETACLASS = "objc_get_meta_class";
519 TAG_MSGSEND = "objc_msg_lookup";
520 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
521 /* GNU runtime does not provide special functions to support
522 structure-returning methods. */
523 default_constant_string_class_name = "NXConstantString";
524 flag_typed_selectors = 1;
529 if (print_struct_values)
530 generate_struct_by_value_array ();
536 objc_finish_file (void)
538 mark_referenced_methods ();
541 /* We need to instantiate templates _before_ we emit ObjC metadata;
542 if we do not, some metadata (such as selectors) may go missing. */
544 instantiate_pending_templates (0);
547 /* Finalize Objective-C runtime data. No need to generate tables
548 and code if only checking syntax, or if generating a PCH file. */
549 if (!flag_syntax_only && !pch_file)
552 if (gen_declaration_file)
553 fclose (gen_declaration_file);
560 /* Return the first occurrence of a method declaration corresponding
561 to sel_name in rproto_list. Search rproto_list recursively.
562 If is_class is 0, search for instance methods, otherwise for class
565 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
571 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
573 p = TREE_VALUE (rproto);
575 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
577 if ((fnd = lookup_method (is_class
578 ? PROTOCOL_CLS_METHODS (p)
579 : PROTOCOL_NST_METHODS (p), sel_name)))
581 else if (PROTOCOL_LIST (p))
582 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
587 ; /* An identifier...if we could not find a protocol. */
598 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
602 /* Make sure the protocol is supported by the object on the rhs. */
603 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
606 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
608 p = TREE_VALUE (rproto);
610 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
615 else if (PROTOCOL_LIST (p))
616 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
625 ; /* An identifier...if we could not find a protocol. */
632 objc_start_class_interface (tree class, tree super_class, tree protos)
634 objc_interface_context
636 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
637 objc_public_flag = 0;
641 objc_start_category_interface (tree class, tree categ, tree protos)
643 objc_interface_context
644 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
646 = continue_class (objc_interface_context);
650 objc_start_protocol (tree name, tree protos)
652 objc_interface_context
653 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
657 objc_continue_interface (void)
660 = continue_class (objc_interface_context);
664 objc_finish_interface (void)
666 finish_class (objc_interface_context);
667 objc_interface_context = NULL_TREE;
671 objc_start_class_implementation (tree class, tree super_class)
673 objc_implementation_context
675 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
676 objc_public_flag = 0;
680 objc_start_category_implementation (tree class, tree categ)
682 objc_implementation_context
683 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
685 = continue_class (objc_implementation_context);
689 objc_continue_implementation (void)
692 = continue_class (objc_implementation_context);
696 objc_finish_implementation (void)
699 if (flag_objc_call_cxx_cdtors)
700 objc_generate_cxx_cdtors ();
703 if (objc_implementation_context)
705 finish_class (objc_implementation_context);
706 objc_ivar_chain = NULL_TREE;
707 objc_implementation_context = NULL_TREE;
710 warning (0, "%<@end%> must appear in an @implementation context");
714 objc_set_visibility (int visibility)
716 objc_public_flag = visibility;
720 objc_set_method_type (enum tree_code type)
722 objc_inherit_code = (type == PLUS_EXPR
724 : INSTANCE_METHOD_DECL);
728 objc_build_method_signature (tree rettype, tree selector,
729 tree optparms, bool ellipsis)
731 return build_method_decl (objc_inherit_code, rettype, selector,
736 objc_add_method_declaration (tree decl)
738 if (!objc_interface_context)
739 fatal_error ("method declaration not in @interface context");
741 objc_add_method (objc_interface_context,
743 objc_inherit_code == CLASS_METHOD_DECL);
747 objc_start_method_definition (tree decl)
749 if (!objc_implementation_context)
750 fatal_error ("method definition not in @implementation context");
752 objc_add_method (objc_implementation_context,
754 objc_inherit_code == CLASS_METHOD_DECL);
755 start_method_def (decl);
759 objc_add_instance_variable (tree decl)
761 (void) add_instance_variable (objc_ivar_context,
766 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
770 objc_is_reserved_word (tree ident)
772 unsigned char code = C_RID_CODE (ident);
774 return (OBJC_IS_AT_KEYWORD (code)
776 || code == RID_CLASS || code == RID_PUBLIC
777 || code == RID_PROTECTED || code == RID_PRIVATE
778 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
783 /* Return true if TYPE is 'id'. */
786 objc_is_object_id (tree type)
788 return OBJC_TYPE_NAME (type) == objc_object_id;
792 objc_is_class_id (tree type)
794 return OBJC_TYPE_NAME (type) == objc_class_id;
797 /* Construct a C struct with same name as CLASS, a base struct with tag
798 SUPER_NAME (if any), and FIELDS indicated. */
801 objc_build_struct (tree class, tree fields, tree super_name)
803 tree name = CLASS_NAME (class);
804 tree s = start_struct (RECORD_TYPE, name);
805 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
806 tree t, objc_info = NULL_TREE;
810 /* Prepend a packed variant of the base class into the layout. This
811 is necessary to preserve ObjC ABI compatibility. */
812 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
813 tree field = TYPE_FIELDS (super);
815 while (field && TREE_CHAIN (field)
816 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
817 field = TREE_CHAIN (field);
819 /* For ObjC ABI purposes, the "packed" size of a base class is the
820 the sum of the offset and the size (in bits) of the last field
823 = (field && TREE_CODE (field) == FIELD_DECL
824 ? size_binop (PLUS_EXPR,
825 size_binop (PLUS_EXPR,
828 convert (bitsizetype,
829 DECL_FIELD_OFFSET (field)),
830 bitsize_int (BITS_PER_UNIT)),
831 DECL_FIELD_BIT_OFFSET (field)),
833 : bitsize_zero_node);
834 DECL_SIZE_UNIT (base)
835 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
836 size_int (BITS_PER_UNIT));
837 DECL_ARTIFICIAL (base) = 1;
838 DECL_ALIGN (base) = 1;
839 DECL_FIELD_CONTEXT (base) = s;
841 DECL_FIELD_IS_BASE (base) = 1;
844 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
845 #endif /* are following the ObjC ABI here. */
846 TREE_CHAIN (base) = fields;
850 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
851 in all variants of this RECORD_TYPE to be clobbered, but it is therein
852 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
853 Hence, we must squirrel away the ObjC-specific information before calling
854 finish_struct(), and then reinstate it afterwards. */
856 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
858 = chainon (objc_info,
859 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
861 /* Point the struct at its related Objective-C class. */
862 INIT_TYPE_OBJC_INFO (s);
863 TYPE_OBJC_INTERFACE (s) = class;
865 s = finish_struct (s, fields, NULL_TREE);
867 for (t = TYPE_NEXT_VARIANT (s); t;
868 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
870 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
871 /* Replace the IDENTIFIER_NODE with an actual @interface. */
872 TYPE_OBJC_INTERFACE (t) = class;
875 /* Use TYPE_BINFO structures to point at the super class, if any. */
876 objc_xref_basetypes (s, super);
878 /* Mark this struct as a class template. */
879 CLASS_STATIC_TEMPLATE (class) = s;
884 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
885 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
888 objc_build_volatilized_type (tree type)
892 /* Check if we have not constructed the desired variant already. */
893 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
895 /* The type qualifiers must (obviously) match up. */
896 if (!TYPE_VOLATILE (t)
897 || (TYPE_READONLY (t) != TYPE_READONLY (type))
898 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
901 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
902 info, if any) must match up. */
903 if (POINTER_TYPE_P (t)
904 && (TREE_TYPE (t) != TREE_TYPE (type)))
907 /* Everything matches up! */
911 /* Ok, we could not re-use any of the pre-existing variants. Create
913 t = build_variant_type_copy (type);
914 TYPE_VOLATILE (t) = 1;
919 /* Mark DECL as being 'volatile' for purposes of Darwin
920 _setjmp()/_longjmp() exception handling. Called from
921 objc_mark_locals_volatile(). */
923 objc_volatilize_decl (tree decl)
925 /* Do not mess with variables that are 'static' or (already)
927 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
928 && (TREE_CODE (decl) == VAR_DECL
929 || TREE_CODE (decl) == PARM_DECL))
931 tree t = TREE_TYPE (decl);
932 struct volatilized_type key;
935 t = objc_build_volatilized_type (t);
937 loc = htab_find_slot (volatilized_htab, &key, INSERT);
941 *loc = ggc_alloc (sizeof (key));
942 ((struct volatilized_type *) *loc)->type = t;
945 TREE_TYPE (decl) = t;
946 TREE_THIS_VOLATILE (decl) = 1;
947 TREE_SIDE_EFFECTS (decl) = 1;
948 DECL_REGISTER (decl) = 0;
950 C_DECL_REGISTER (decl) = 0;
955 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
956 (including its categoreis and superclasses) or by object type TYP.
957 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
960 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
962 bool class_type = (cls != NULL_TREE);
968 /* Check protocols adopted by the class and its categories. */
969 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
971 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
975 /* Repeat for superclasses. */
976 cls = lookup_interface (CLASS_SUPER_NAME (cls));
979 /* Check for any protocols attached directly to the object type. */
980 if (TYPE_HAS_OBJC_INFO (typ))
982 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
988 strcpy (errbuf, class_type ? "class \'" : "type \'");
989 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
990 strcat (errbuf, "\' does not ");
991 /* NB: Types 'id' and 'Class' cannot reasonably be described as
992 "implementing" a given protocol, since they do not have an
994 strcat (errbuf, class_type ? "implement" : "conform to");
995 strcat (errbuf, " the \'");
996 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
997 strcat (errbuf, "\' protocol");
1004 /* Check if class RCLS and instance struct type RTYP conform to at least the
1005 same protocols that LCLS and LTYP conform to. */
1008 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1011 bool have_lproto = false;
1015 /* NB: We do _not_ look at categories defined for LCLS; these may or
1016 may not get loaded in, and therefore it is unreasonable to require
1017 that RCLS/RTYP must implement any of their protocols. */
1018 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1022 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1026 /* Repeat for superclasses. */
1027 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1030 /* Check for any protocols attached directly to the object type. */
1031 if (TYPE_HAS_OBJC_INFO (ltyp))
1033 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1037 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1042 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1043 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1044 away with simply checking for 'id' or 'Class' (!RCLS), since this
1045 routine will not get called in other cases. */
1046 return have_lproto || (rcls != NULL_TREE);
1049 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1050 an instance of RTYP to an instance of LTYP or to compare the two
1051 (if ARGNO is equal to -3), per ObjC type system rules. Before
1052 returning 'true', this routine may issue warnings related to, e.g.,
1053 protocol conformance. When returning 'false', the routine must
1054 produce absolutely no warnings; the C or C++ front-end will do so
1055 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1056 the routine must return 'false'.
1058 The ARGNO parameter is encoded as follows:
1059 >= 1 Parameter number (CALLEE contains function being called);
1063 -3 Comparison (LTYP and RTYP may match in either direction). */
1066 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1068 tree lcls, rcls, lproto, rproto;
1069 bool pointers_compatible;
1071 /* We must be dealing with pointer types */
1072 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1077 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1078 rtyp = TREE_TYPE (rtyp);
1080 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1082 /* Past this point, we are only interested in ObjC class instances,
1083 or 'id' or 'Class'. */
1084 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1087 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1088 && !TYPE_HAS_OBJC_INFO (ltyp))
1091 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1092 && !TYPE_HAS_OBJC_INFO (rtyp))
1095 /* Past this point, we are committed to returning 'true' to the caller.
1096 However, we can still warn about type and/or protocol mismatches. */
1098 if (TYPE_HAS_OBJC_INFO (ltyp))
1100 lcls = TYPE_OBJC_INTERFACE (ltyp);
1101 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1104 lcls = lproto = NULL_TREE;
1106 if (TYPE_HAS_OBJC_INFO (rtyp))
1108 rcls = TYPE_OBJC_INTERFACE (rtyp);
1109 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1112 rcls = rproto = NULL_TREE;
1114 /* If we could not find an @interface declaration, we must have
1115 only seen a @class declaration; for purposes of type comparison,
1116 treat it as a stand-alone (root) class. */
1118 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1121 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1124 /* If either type is an unqualified 'id', we're done. */
1125 if ((!lproto && objc_is_object_id (ltyp))
1126 || (!rproto && objc_is_object_id (rtyp)))
1129 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1131 /* If the underlying types are the same, and at most one of them has
1132 a protocol list, we do not need to issue any diagnostics. */
1133 if (pointers_compatible && (!lproto || !rproto))
1136 /* If exactly one of the types is 'Class', issue a diagnostic; any
1137 exceptions of this rule have already been handled. */
1138 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1139 pointers_compatible = false;
1140 /* Otherwise, check for inheritance relations. */
1143 if (!pointers_compatible)
1145 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1147 if (!pointers_compatible)
1148 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1150 if (!pointers_compatible && argno == -3)
1151 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1154 /* If the pointers match modulo protocols, check for protocol conformance
1156 if (pointers_compatible)
1158 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1161 if (!pointers_compatible && argno == -3)
1162 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1166 if (!pointers_compatible)
1168 /* NB: For the time being, we shall make our warnings look like their
1169 C counterparts. In the future, we may wish to make them more
1174 warning (0, "comparison of distinct Objective-C types lacks a cast");
1178 warning (0, "initialization from distinct Objective-C type");
1182 warning (0, "assignment from distinct Objective-C type");
1186 warning (0, "distinct Objective-C type in return");
1190 warning (0, "passing argument %d of %qE from distinct "
1191 "Objective-C type", argno, callee);
1199 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1200 lives in the volatilized hash table, ignore the 'volatile' bit when
1201 making the comparison. */
1204 objc_type_quals_match (tree ltyp, tree rtyp)
1206 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1207 struct volatilized_type key;
1211 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1212 lquals &= ~TYPE_QUAL_VOLATILE;
1216 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1217 rquals &= ~TYPE_QUAL_VOLATILE;
1219 return (lquals == rquals);
1223 /* Determine if CHILD is derived from PARENT. The routine assumes that
1224 both parameters are RECORD_TYPEs, and is non-reflexive. */
1227 objc_derived_from_p (tree parent, tree child)
1229 parent = TYPE_MAIN_VARIANT (parent);
1231 for (child = TYPE_MAIN_VARIANT (child);
1232 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1234 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1235 (TYPE_BINFO (child),
1238 if (child == parent)
1247 objc_build_component_ref (tree datum, tree component)
1249 /* If COMPONENT is NULL, the caller is referring to the anonymous
1250 base class field. */
1253 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1255 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1258 /* The 'build_component_ref' routine has been removed from the C++
1259 front-end, but 'finish_class_member_access_expr' seems to be
1260 a worthy substitute. */
1262 return finish_class_member_access_expr (datum, component);
1264 return build_component_ref (datum, component);
1268 /* Recursively copy inheritance information rooted at BINFO. To do this,
1269 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1272 objc_copy_binfo (tree binfo)
1274 tree btype = BINFO_TYPE (binfo);
1275 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1279 BINFO_TYPE (binfo2) = btype;
1280 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1281 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1283 /* Recursively copy base binfos of BINFO. */
1284 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1286 tree base_binfo2 = objc_copy_binfo (base_binfo);
1288 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1289 BINFO_BASE_APPEND (binfo2, base_binfo2);
1295 /* Record superclass information provided in BASETYPE for ObjC class REF.
1296 This is loosely based on cp/decl.c:xref_basetypes(). */
1299 objc_xref_basetypes (tree ref, tree basetype)
1301 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1303 TYPE_BINFO (ref) = binfo;
1304 BINFO_OFFSET (binfo) = size_zero_node;
1305 BINFO_TYPE (binfo) = ref;
1309 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1311 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1312 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1313 BINFO_BASE_APPEND (binfo, base_binfo);
1314 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1319 volatilized_hash (const void *ptr)
1321 tree typ = ((struct volatilized_type *)ptr)->type;
1323 return htab_hash_pointer(typ);
1327 volatilized_eq (const void *ptr1, const void *ptr2)
1329 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1330 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1332 return typ1 == typ2;
1335 /* Called from finish_decl. */
1338 objc_check_decl (tree decl)
1340 tree type = TREE_TYPE (decl);
1342 if (TREE_CODE (type) != RECORD_TYPE)
1344 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1345 error ("statically allocated instance of Objective-C class %qs",
1346 IDENTIFIER_POINTER (type));
1349 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1350 either name an Objective-C class, or refer to the special 'id' or 'Class'
1351 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1354 objc_get_protocol_qualified_type (tree interface, tree protocols)
1356 /* If INTERFACE is not provided, default to 'id'. */
1357 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1358 bool is_ptr = (type != NULL_TREE);
1362 type = objc_is_class_name (interface);
1365 type = xref_tag (RECORD_TYPE, type);
1372 type = build_variant_type_copy (type);
1374 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1378 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1379 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1380 type = TREE_TYPE (type);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1385 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1390 type = TYPE_POINTER_TO (type);
1392 TYPE_OBJC_INTERFACE (type)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1404 check_protocol_recursively (tree proto, tree list)
1408 for (p = list; p; p = TREE_CHAIN (p))
1410 tree pp = TREE_VALUE (p);
1412 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1413 pp = lookup_protocol (pp);
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1419 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1427 lookup_and_install_protocols (tree protocols)
1430 tree return_value = NULL_TREE;
1432 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1434 tree ident = TREE_VALUE (proto);
1435 tree p = lookup_protocol (ident);
1438 error ("cannot find protocol declaration for %qs",
1439 IDENTIFIER_POINTER (ident));
1441 return_value = chainon (return_value,
1442 build_tree_list (NULL_TREE, p));
1445 return return_value;
1448 /* Create a declaration for field NAME of a given TYPE. */
1451 create_field_decl (tree type, const char *name)
1453 return build_decl (FIELD_DECL, get_identifier (name), type);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1460 start_var_decl (tree type, const char *name)
1462 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1464 TREE_STATIC (var) = 1;
1465 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var) = 1;
1467 DECL_ARTIFICIAL (var) = 1;
1468 DECL_CONTEXT (var) = NULL_TREE;
1470 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1476 /* Finish off the variable declaration created by start_var_decl(). */
1479 finish_var_decl (tree var, tree initializer)
1481 finish_decl (var, initializer, NULL_TREE);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1492 setup_string_decl (void)
1497 /* %s in format will provide room for terminating null */
1498 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1499 + strlen (constant_string_class_name);
1500 name = xmalloc (length);
1501 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1502 constant_string_class_name);
1503 constant_string_global_id = get_identifier (name);
1504 string_class_decl = lookup_name (constant_string_global_id);
1506 return string_class_decl;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1521 synth_module_prologue (void)
1524 enum debug_info_type save_write_symbols = write_symbols;
1525 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn'r been called yet. */
1529 write_symbols = NO_DEBUG;
1530 debug_hooks = &do_nothing_debug_hooks;
1533 push_lang_context (lang_name_c); /* extern "C" */
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id = get_identifier (TAG_OBJECT);
1539 objc_class_id = get_identifier (TAG_CLASS);
1541 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1542 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1544 objc_object_type = build_pointer_type (objc_object_reference);
1545 objc_class_type = build_pointer_type (objc_class_reference);
1547 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1548 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1555 DECL_IN_SYSTEM_HEADER (type) = 1;
1556 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1559 DECL_IN_SYSTEM_HEADER (type) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1564 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1565 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime)
1571 /* `struct objc_selector *' */
1573 = build_pointer_type (xref_tag (RECORD_TYPE,
1574 get_identifier (TAG_SELECTOR)));
1576 /* `const struct objc_selector *' */
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE,
1580 get_identifier (TAG_SELECTOR)),
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1587 get_identifier (TAG_SUPER)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr = build_pointer_type
1591 (xref_tag (RECORD_TYPE,
1592 get_identifier (UTAG_METHOD_LIST)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1596 objc_ivar_list_ptr = build_pointer_type
1597 (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_IVAR_LIST)));
1600 if (flag_next_runtime)
1602 /* NB: In order to call one of the ..._stret (struct-returning)
1603 functions, the function *MUST* first be cast to a signature that
1604 corresponds to the actual ObjC method being invoked. This is
1605 what is done by the build_objc_method_call() routine below. */
1607 /* id objc_msgSend (id, SEL, ...); */
1608 /* id objc_msgSendNonNil (id, SEL, ...); */
1609 /* id objc_msgSend_stret (id, SEL, ...); */
1610 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1612 = build_function_type (objc_object_type,
1613 tree_cons (NULL_TREE, objc_object_type,
1614 tree_cons (NULL_TREE, objc_selector_type,
1616 umsg_decl = builtin_function (TAG_MSGSEND,
1617 type, 0, NOT_BUILT_IN,
1619 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1620 type, 0, NOT_BUILT_IN,
1622 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1623 type, 0, NOT_BUILT_IN,
1625 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1626 type, 0, NOT_BUILT_IN,
1629 /* id objc_msgSend_Fast (id, SEL, ...)
1630 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1631 #ifdef OFFS_MSGSEND_FAST
1632 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1633 type, 0, NOT_BUILT_IN,
1635 DECL_ATTRIBUTES (umsg_fast_decl)
1636 = tree_cons (get_identifier ("hard_coded_address"),
1637 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1640 /* No direct dispatch availible. */
1641 umsg_fast_decl = umsg_decl;
1644 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1645 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1647 = build_function_type (objc_object_type,
1648 tree_cons (NULL_TREE, objc_super_type,
1649 tree_cons (NULL_TREE, objc_selector_type,
1651 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1652 type, 0, NOT_BUILT_IN,
1654 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1655 type, 0, NOT_BUILT_IN, 0,
1660 /* GNU runtime messenger entry points. */
1662 /* typedef id (*IMP)(id, SEL, ...); */
1664 = build_pointer_type
1665 (build_function_type (objc_object_type,
1666 tree_cons (NULL_TREE, objc_object_type,
1667 tree_cons (NULL_TREE, objc_selector_type,
1670 /* IMP objc_msg_lookup (id, SEL); */
1672 = build_function_type (IMP_type,
1673 tree_cons (NULL_TREE, objc_object_type,
1674 tree_cons (NULL_TREE, objc_selector_type,
1675 OBJC_VOID_AT_END)));
1676 umsg_decl = builtin_function (TAG_MSGSEND,
1677 type, 0, NOT_BUILT_IN,
1680 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1682 = build_function_type (IMP_type,
1683 tree_cons (NULL_TREE, objc_super_type,
1684 tree_cons (NULL_TREE, objc_selector_type,
1685 OBJC_VOID_AT_END)));
1686 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1687 type, 0, NOT_BUILT_IN,
1690 /* The following GNU runtime entry point is called to initialize
1693 __objc_exec_class (void *); */
1695 = build_function_type (void_type_node,
1696 tree_cons (NULL_TREE, ptr_type_node,
1698 execclass_decl = builtin_function (TAG_EXECCLASS,
1699 type, 0, NOT_BUILT_IN,
1703 /* id objc_getClass (const char *); */
1705 type = build_function_type (objc_object_type,
1706 tree_cons (NULL_TREE,
1707 const_string_type_node,
1711 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1714 /* id objc_getMetaClass (const char *); */
1716 objc_get_meta_class_decl
1717 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1719 build_class_template ();
1720 build_super_template ();
1721 build_protocol_template ();
1722 build_category_template ();
1723 build_objc_exception_stuff ();
1725 if (flag_next_runtime)
1726 build_next_objc_exception_stuff ();
1728 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1730 if (! flag_next_runtime)
1731 build_selector_table_decl ();
1733 /* Forward declare constant_string_id and constant_string_type. */
1734 if (!constant_string_class_name)
1735 constant_string_class_name = default_constant_string_class_name;
1737 constant_string_id = get_identifier (constant_string_class_name);
1738 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1740 /* Pre-build the following entities - for speed/convenience. */
1741 self_id = get_identifier ("self");
1742 ucmd_id = get_identifier ("_cmd");
1745 pop_lang_context ();
1748 write_symbols = save_write_symbols;
1749 debug_hooks = save_hooks;
1752 /* Ensure that the ivar list for NSConstantString/NXConstantString
1753 (or whatever was specified via `-fconstant-string-class')
1754 contains fields at least as large as the following three, so that
1755 the runtime can stomp on them with confidence:
1757 struct STRING_OBJECT_CLASS_NAME
1761 unsigned int length;
1765 check_string_class_template (void)
1767 tree field_decl = objc_get_class_ivars (constant_string_id);
1769 #define AT_LEAST_AS_LARGE_AS(F, T) \
1770 (F && TREE_CODE (F) == FIELD_DECL \
1771 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1772 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1774 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1777 field_decl = TREE_CHAIN (field_decl);
1778 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1781 field_decl = TREE_CHAIN (field_decl);
1782 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1784 #undef AT_LEAST_AS_LARGE_AS
1787 /* Avoid calling `check_string_class_template ()' more than once. */
1788 static GTY(()) int string_layout_checked;
1790 /* Construct an internal string layout to be used as a template for
1791 creating NSConstantString/NXConstantString instances. */
1794 objc_build_internal_const_str_type (void)
1796 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1797 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1798 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1800 TREE_CHAIN (field) = fields; fields = field;
1801 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1802 TREE_CHAIN (field) = fields; fields = field;
1803 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1805 finish_builtin_struct (type, "__builtin_ObjCString",
1811 /* Custom build_string which sets TREE_TYPE! */
1814 my_build_string (int len, const char *str)
1816 return fix_string_type (build_string (len, str));
1819 /* Build a string with contents STR and length LEN and convert it to a
1823 my_build_string_pointer (int len, const char *str)
1825 tree string = my_build_string (len, str);
1826 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1827 return build1 (ADDR_EXPR, ptrtype, string);
1831 string_hash (const void *ptr)
1833 tree str = ((struct string_descriptor *)ptr)->literal;
1834 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1835 int i, len = TREE_STRING_LENGTH (str);
1838 for (i = 0; i < len; i++)
1839 h = ((h * 613) + p[i]);
1845 string_eq (const void *ptr1, const void *ptr2)
1847 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1848 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1849 int len1 = TREE_STRING_LENGTH (str1);
1851 return (len1 == TREE_STRING_LENGTH (str2)
1852 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1856 /* Given a chain of STRING_CST's, build a static instance of
1857 NXConstantString which points at the concatenation of those
1858 strings. We place the string object in the __string_objects
1859 section of the __OBJC segment. The Objective-C runtime will
1860 initialize the isa pointers of the string objects to point at the
1861 NXConstantString class object. */
1864 objc_build_string_object (tree string)
1866 tree initlist, constructor, constant_string_class;
1869 struct string_descriptor *desc, key;
1872 /* Prep the string argument. */
1873 string = fix_string_type (string);
1874 TREE_SET_CODE (string, STRING_CST);
1875 length = TREE_STRING_LENGTH (string) - 1;
1877 /* Check whether the string class being used actually exists and has the
1878 correct ivar layout. */
1879 if (!string_layout_checked)
1881 string_layout_checked = -1;
1882 constant_string_class = lookup_interface (constant_string_id);
1883 internal_const_str_type = objc_build_internal_const_str_type ();
1885 if (!constant_string_class
1886 || !(constant_string_type
1887 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1888 error ("cannot find interface declaration for %qs",
1889 IDENTIFIER_POINTER (constant_string_id));
1890 /* The NSConstantString/NXConstantString ivar layout is now known. */
1891 else if (!check_string_class_template ())
1892 error ("interface %qs does not have valid constant string layout",
1893 IDENTIFIER_POINTER (constant_string_id));
1894 /* For the NeXT runtime, we can generate a literal reference
1895 to the string class, don't need to run a constructor. */
1896 else if (flag_next_runtime && !setup_string_decl ())
1897 error ("cannot find reference tag for class %qs",
1898 IDENTIFIER_POINTER (constant_string_id));
1901 string_layout_checked = 1; /* Success! */
1902 add_class_reference (constant_string_id);
1906 if (string_layout_checked == -1)
1907 return error_mark_node;
1909 /* Perhaps we already constructed a constant string just like this one? */
1910 key.literal = string;
1911 loc = htab_find_slot (string_htab, &key, INSERT);
1917 *loc = desc = ggc_alloc (sizeof (*desc));
1918 desc->literal = string;
1920 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1921 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1922 fields = TYPE_FIELDS (internal_const_str_type);
1924 = build_tree_list (fields,
1926 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1927 : build_int_cst (NULL_TREE, 0));
1928 fields = TREE_CHAIN (fields);
1929 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1931 fields = TREE_CHAIN (fields);
1932 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1934 constructor = objc_build_constructor (internal_const_str_type,
1935 nreverse (initlist));
1936 TREE_INVARIANT (constructor) = true;
1938 if (!flag_next_runtime)
1940 = objc_add_static_instance (constructor, constant_string_type);
1943 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1944 DECL_INITIAL (var) = constructor;
1945 TREE_STATIC (var) = 1;
1946 pushdecl_top_level (var);
1949 desc->constructor = constructor;
1952 addr = convert (build_pointer_type (constant_string_type),
1953 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1958 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1960 static GTY(()) int num_static_inst;
1963 objc_add_static_instance (tree constructor, tree class_decl)
1968 /* Find the list of static instances for the CLASS_DECL. Create one if
1970 for (chain = &objc_static_instances;
1971 *chain && TREE_VALUE (*chain) != class_decl;
1972 chain = &TREE_CHAIN (*chain));
1975 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1976 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1979 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1980 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1981 DECL_COMMON (decl) = 1;
1982 TREE_STATIC (decl) = 1;
1983 DECL_ARTIFICIAL (decl) = 1;
1984 DECL_INITIAL (decl) = constructor;
1986 /* We may be writing something else just now.
1987 Postpone till end of input. */
1988 DECL_DEFER_OUTPUT (decl) = 1;
1989 pushdecl_top_level (decl);
1990 rest_of_decl_compilation (decl, 1, 0);
1992 /* Add the DECL to the head of this CLASS' list. */
1993 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1998 /* Build a static constant CONSTRUCTOR
1999 with type TYPE and elements ELTS. */
2002 objc_build_constructor (tree type, tree elts)
2004 tree constructor = build_constructor_from_list (type, elts);
2006 TREE_CONSTANT (constructor) = 1;
2007 TREE_STATIC (constructor) = 1;
2008 TREE_READONLY (constructor) = 1;
2011 /* Adjust for impedance mismatch. We should figure out how to build
2012 CONSTRUCTORs that consistently please both the C and C++ gods. */
2013 if (!TREE_PURPOSE (elts))
2014 TREE_TYPE (constructor) = NULL_TREE;
2015 TREE_HAS_CONSTRUCTOR (constructor) = 1;
2021 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2023 /* Predefine the following data type:
2031 void *defs[cls_def_cnt + cat_def_cnt];
2035 build_objc_symtab_template (void)
2037 tree field_decl, field_decl_chain;
2039 objc_symtab_template
2040 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2042 /* long sel_ref_cnt; */
2043 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2044 field_decl_chain = field_decl;
2047 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2049 chainon (field_decl_chain, field_decl);
2051 /* short cls_def_cnt; */
2052 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2053 chainon (field_decl_chain, field_decl);
2055 /* short cat_def_cnt; */
2056 field_decl = create_field_decl (short_integer_type_node,
2058 chainon (field_decl_chain, field_decl);
2060 if (imp_count || cat_count || !flag_next_runtime)
2062 /* void *defs[imp_count + cat_count (+ 1)]; */
2063 /* NB: The index is one less than the size of the array. */
2064 int index = imp_count + cat_count
2065 + (flag_next_runtime? -1: 0);
2066 field_decl = create_field_decl
2069 build_index_type (build_int_cst (NULL_TREE, index))),
2071 chainon (field_decl_chain, field_decl);
2074 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2077 /* Create the initial value for the `defs' field of _objc_symtab.
2078 This is a CONSTRUCTOR. */
2081 init_def_list (tree type)
2083 tree expr, initlist = NULL_TREE;
2084 struct imp_entry *impent;
2087 for (impent = imp_list; impent; impent = impent->next)
2089 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2091 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2092 initlist = tree_cons (NULL_TREE, expr, initlist);
2097 for (impent = imp_list; impent; impent = impent->next)
2099 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2101 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2102 initlist = tree_cons (NULL_TREE, expr, initlist);
2106 if (!flag_next_runtime)
2108 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2111 if (static_instances_decl)
2112 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2114 expr = build_int_cst (NULL_TREE, 0);
2116 initlist = tree_cons (NULL_TREE, expr, initlist);
2119 return objc_build_constructor (type, nreverse (initlist));
2122 /* Construct the initial value for all of _objc_symtab. */
2125 init_objc_symtab (tree type)
2129 /* sel_ref_cnt = { ..., 5, ... } */
2131 initlist = build_tree_list (NULL_TREE,
2132 build_int_cst (long_integer_type_node, 0));
2134 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2136 if (flag_next_runtime || ! sel_ref_chain)
2137 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2140 = tree_cons (NULL_TREE,
2141 convert (build_pointer_type (objc_selector_type),
2142 build_unary_op (ADDR_EXPR,
2143 UOBJC_SELECTOR_TABLE_decl, 1)),
2146 /* cls_def_cnt = { ..., 5, ... } */
2148 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2150 /* cat_def_cnt = { ..., 5, ... } */
2152 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2154 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2156 if (imp_count || cat_count || !flag_next_runtime)
2159 tree field = TYPE_FIELDS (type);
2160 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2162 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2166 return objc_build_constructor (type, nreverse (initlist));
2169 /* Generate forward declarations for metadata such as
2170 'OBJC_CLASS_...'. */
2173 build_metadata_decl (const char *name, tree type)
2177 /* struct TYPE NAME_<name>; */
2178 decl = start_var_decl (type, synth_id_with_class_suffix
2180 objc_implementation_context));
2185 /* Push forward-declarations of all the categories so that
2186 init_def_list can use them in a CONSTRUCTOR. */
2189 forward_declare_categories (void)
2191 struct imp_entry *impent;
2192 tree sav = objc_implementation_context;
2194 for (impent = imp_list; impent; impent = impent->next)
2196 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2198 /* Set an invisible arg to synth_id_with_class_suffix. */
2199 objc_implementation_context = impent->imp_context;
2200 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2201 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2202 objc_category_template);
2205 objc_implementation_context = sav;
2208 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2209 and initialized appropriately. */
2212 generate_objc_symtab_decl (void)
2214 /* forward declare categories */
2216 forward_declare_categories ();
2218 build_objc_symtab_template ();
2219 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2220 finish_var_decl (UOBJC_SYMBOLS_decl,
2221 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2225 init_module_descriptor (tree type)
2227 tree initlist, expr;
2229 /* version = { 1, ... } */
2231 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2232 initlist = build_tree_list (NULL_TREE, expr);
2234 /* size = { ..., sizeof (struct _objc_module), ... } */
2236 expr = convert (long_integer_type_node,
2237 size_in_bytes (objc_module_template));
2238 initlist = tree_cons (NULL_TREE, expr, initlist);
2240 /* name = { ..., "foo.m", ... } */
2242 expr = add_objc_string (get_identifier (input_filename), class_names);
2243 initlist = tree_cons (NULL_TREE, expr, initlist);
2245 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2247 if (UOBJC_SYMBOLS_decl)
2248 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2250 expr = build_int_cst (NULL_TREE, 0);
2251 initlist = tree_cons (NULL_TREE, expr, initlist);
2253 return objc_build_constructor (type, nreverse (initlist));
2256 /* Write out the data structures to describe Objective C classes defined.
2258 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2261 build_module_descriptor (void)
2263 tree field_decl, field_decl_chain;
2266 push_lang_context (lang_name_c); /* extern "C" */
2269 objc_module_template
2270 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2273 field_decl = create_field_decl (long_integer_type_node, "version");
2274 field_decl_chain = field_decl;
2277 field_decl = create_field_decl (long_integer_type_node, "size");
2278 chainon (field_decl_chain, field_decl);
2281 field_decl = create_field_decl (string_type_node, "name");
2282 chainon (field_decl_chain, field_decl);
2284 /* struct _objc_symtab *symtab; */
2286 = create_field_decl (build_pointer_type
2287 (xref_tag (RECORD_TYPE,
2288 get_identifier (UTAG_SYMTAB))),
2290 chainon (field_decl_chain, field_decl);
2292 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2294 /* Create an instance of "_objc_module". */
2295 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2296 finish_var_decl (UOBJC_MODULES_decl,
2297 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2300 pop_lang_context ();
2304 /* The GNU runtime requires us to provide a static initializer function
2307 static void __objc_gnu_init (void) {
2308 __objc_exec_class (&L_OBJC_MODULES);
2312 build_module_initializer_routine (void)
2317 push_lang_context (lang_name_c); /* extern "C" */
2320 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2321 objc_start_function (get_identifier (TAG_GNUINIT),
2322 build_function_type (void_type_node,
2324 NULL_TREE, objc_get_parm_info (0));
2326 body = c_begin_compound_stmt (true);
2327 add_stmt (build_function_call
2331 build_unary_op (ADDR_EXPR,
2332 UOBJC_MODULES_decl, 0))));
2333 add_stmt (c_end_compound_stmt (body, true));
2335 TREE_PUBLIC (current_function_decl) = 0;
2338 /* For Objective-C++, we will need to call __objc_gnu_init
2339 from objc_generate_static_init_call() below. */
2340 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2343 GNU_INIT_decl = current_function_decl;
2347 pop_lang_context ();
2352 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2353 to be called by the module initializer routine. */
2356 objc_static_init_needed_p (void)
2358 return (GNU_INIT_decl != NULL_TREE);
2361 /* Generate a call to the __objc_gnu_init initializer function. */
2364 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2366 add_stmt (build_stmt (EXPR_STMT,
2367 build_function_call (GNU_INIT_decl, NULL_TREE)));
2371 #endif /* OBJCPLUS */
2373 /* Return the DECL of the string IDENT in the SECTION. */
2376 get_objc_string_decl (tree ident, enum string_section section)
2380 if (section == class_names)
2381 chain = class_names_chain;
2382 else if (section == meth_var_names)
2383 chain = meth_var_names_chain;
2384 else if (section == meth_var_types)
2385 chain = meth_var_types_chain;
2389 for (; chain != 0; chain = TREE_CHAIN (chain))
2390 if (TREE_VALUE (chain) == ident)
2391 return (TREE_PURPOSE (chain));
2397 /* Output references to all statically allocated objects. Return the DECL
2398 for the array built. */
2401 generate_static_references (void)
2403 tree decls = NULL_TREE, expr = NULL_TREE;
2404 tree class_name, class, decl, initlist;
2405 tree cl_chain, in_chain, type
2406 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2407 int num_inst, num_class;
2410 if (flag_next_runtime)
2413 for (cl_chain = objc_static_instances, num_class = 0;
2414 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2416 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2417 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2419 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2420 decl = start_var_decl (type, buf);
2422 /* Output {class_name, ...}. */
2423 class = TREE_VALUE (cl_chain);
2424 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2425 initlist = build_tree_list (NULL_TREE,
2426 build_unary_op (ADDR_EXPR, class_name, 1));
2428 /* Output {..., instance, ...}. */
2429 for (in_chain = TREE_PURPOSE (cl_chain);
2430 in_chain; in_chain = TREE_CHAIN (in_chain))
2432 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2433 initlist = tree_cons (NULL_TREE, expr, initlist);
2436 /* Output {..., NULL}. */
2437 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2439 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2440 finish_var_decl (decl, expr);
2442 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2445 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2446 expr = objc_build_constructor (type, nreverse (decls));
2447 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2448 finish_var_decl (static_instances_decl, expr);
2451 static GTY(()) int selector_reference_idx;
2454 build_selector_reference_decl (void)
2459 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2460 decl = start_var_decl (objc_selector_type, buf);
2466 build_selector_table_decl (void)
2470 if (flag_typed_selectors)
2472 build_selector_template ();
2473 temp = build_array_type (objc_selector_template, NULL_TREE);
2476 temp = build_array_type (objc_selector_type, NULL_TREE);
2478 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2481 /* Just a handy wrapper for add_objc_string. */
2484 build_selector (tree ident)
2486 return convert (objc_selector_type,
2487 add_objc_string (ident, meth_var_names));
2491 build_selector_translation_table (void)
2493 tree chain, initlist = NULL_TREE;
2495 tree decl = NULL_TREE;
2497 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2501 if (warn_selector && objc_implementation_context)
2505 for (method_chain = meth_var_names_chain;
2507 method_chain = TREE_CHAIN (method_chain))
2509 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2518 if (flag_next_runtime && TREE_PURPOSE (chain))
2519 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2521 loc = &input_location;
2522 warning (0, "%Hcreating selector for nonexistent method %qE",
2523 loc, TREE_VALUE (chain));
2527 expr = build_selector (TREE_VALUE (chain));
2528 /* add one for the '\0' character */
2529 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2531 if (flag_next_runtime)
2533 decl = TREE_PURPOSE (chain);
2534 finish_var_decl (decl, expr);
2538 if (flag_typed_selectors)
2540 tree eltlist = NULL_TREE;
2541 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2542 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2543 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2544 expr = objc_build_constructor (objc_selector_template,
2545 nreverse (eltlist));
2548 initlist = tree_cons (NULL_TREE, expr, initlist);
2552 if (! flag_next_runtime)
2554 /* Cause the selector table (previously forward-declared)
2555 to be actually output. */
2556 initlist = tree_cons (NULL_TREE,
2557 flag_typed_selectors
2558 ? objc_build_constructor
2559 (objc_selector_template,
2560 tree_cons (NULL_TREE,
2561 build_int_cst (NULL_TREE, 0),
2562 tree_cons (NULL_TREE,
2563 build_int_cst (NULL_TREE, 0),
2565 : build_int_cst (NULL_TREE, 0), initlist);
2566 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2567 nreverse (initlist));
2568 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2573 get_proto_encoding (tree proto)
2578 if (! METHOD_ENCODING (proto))
2580 encoding = encode_method_prototype (proto);
2581 METHOD_ENCODING (proto) = encoding;
2584 encoding = METHOD_ENCODING (proto);
2586 return add_objc_string (encoding, meth_var_types);
2589 return build_int_cst (NULL_TREE, 0);
2592 /* sel_ref_chain is a list whose "value" fields will be instances of
2593 identifier_node that represent the selector. */
2596 build_typed_selector_reference (tree ident, tree prototype)
2598 tree *chain = &sel_ref_chain;
2604 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2605 goto return_at_index;
2608 chain = &TREE_CHAIN (*chain);
2611 *chain = tree_cons (prototype, ident, NULL_TREE);
2614 expr = build_unary_op (ADDR_EXPR,
2615 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2616 build_int_cst (NULL_TREE, index)),
2618 return convert (objc_selector_type, expr);
2622 build_selector_reference (tree ident)
2624 tree *chain = &sel_ref_chain;
2630 if (TREE_VALUE (*chain) == ident)
2631 return (flag_next_runtime
2632 ? TREE_PURPOSE (*chain)
2633 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2634 build_int_cst (NULL_TREE, index)));
2637 chain = &TREE_CHAIN (*chain);
2640 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2642 *chain = tree_cons (expr, ident, NULL_TREE);
2644 return (flag_next_runtime
2646 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2647 build_int_cst (NULL_TREE, index)));
2650 static GTY(()) int class_reference_idx;
2653 build_class_reference_decl (void)
2658 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2659 decl = start_var_decl (objc_class_type, buf);
2664 /* Create a class reference, but don't create a variable to reference
2668 add_class_reference (tree ident)
2672 if ((chain = cls_ref_chain))
2677 if (ident == TREE_VALUE (chain))
2681 chain = TREE_CHAIN (chain);
2685 /* Append to the end of the list */
2686 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2689 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2692 /* Get a class reference, creating it if necessary. Also create the
2693 reference variable. */
2696 objc_get_class_reference (tree ident)
2698 tree orig_ident = (DECL_P (ident)
2701 ? OBJC_TYPE_NAME (ident)
2703 bool local_scope = false;
2706 if (processing_template_decl)
2707 /* Must wait until template instantiation time. */
2708 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2711 if (TREE_CODE (ident) == TYPE_DECL)
2712 ident = (DECL_ORIGINAL_TYPE (ident)
2713 ? DECL_ORIGINAL_TYPE (ident)
2714 : TREE_TYPE (ident));
2717 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2718 && TYPE_CONTEXT (ident) != global_namespace)
2722 if (local_scope || !(ident = objc_is_class_name (ident)))
2724 error ("%qs is not an Objective-C class name or alias",
2725 IDENTIFIER_POINTER (orig_ident));
2726 return error_mark_node;
2729 if (flag_next_runtime && !flag_zero_link)
2734 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2735 if (TREE_VALUE (*chain) == ident)
2737 if (! TREE_PURPOSE (*chain))
2738 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2740 return TREE_PURPOSE (*chain);
2743 decl = build_class_reference_decl ();
2744 *chain = tree_cons (decl, ident, NULL_TREE);
2751 add_class_reference (ident);
2753 params = build_tree_list (NULL_TREE,
2754 my_build_string_pointer
2755 (IDENTIFIER_LENGTH (ident) + 1,
2756 IDENTIFIER_POINTER (ident)));
2758 assemble_external (objc_get_class_decl);
2759 return build_function_call (objc_get_class_decl, params);
2763 /* For each string section we have a chain which maps identifier nodes
2764 to decls for the strings. */
2767 add_objc_string (tree ident, enum string_section section)
2769 tree *chain, decl, type, string_expr;
2771 if (section == class_names)
2772 chain = &class_names_chain;
2773 else if (section == meth_var_names)
2774 chain = &meth_var_names_chain;
2775 else if (section == meth_var_types)
2776 chain = &meth_var_types_chain;
2782 if (TREE_VALUE (*chain) == ident)
2783 return convert (string_type_node,
2784 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2786 chain = &TREE_CHAIN (*chain);
2789 decl = build_objc_string_decl (section);
2791 type = build_array_type
2794 (build_int_cst (NULL_TREE,
2795 IDENTIFIER_LENGTH (ident))));
2796 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2797 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2798 IDENTIFIER_POINTER (ident));
2799 finish_var_decl (decl, string_expr);
2801 *chain = tree_cons (decl, ident, NULL_TREE);
2803 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2806 static GTY(()) int class_names_idx;
2807 static GTY(()) int meth_var_names_idx;
2808 static GTY(()) int meth_var_types_idx;
2811 build_objc_string_decl (enum string_section section)
2816 if (section == class_names)
2817 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2818 else if (section == meth_var_names)
2819 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2820 else if (section == meth_var_types)
2821 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2823 ident = get_identifier (buf);
2825 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2826 DECL_EXTERNAL (decl) = 1;
2827 TREE_PUBLIC (decl) = 0;
2828 TREE_USED (decl) = 1;
2829 TREE_CONSTANT (decl) = 1;
2830 DECL_CONTEXT (decl) = 0;
2831 DECL_ARTIFICIAL (decl) = 1;
2833 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2836 make_decl_rtl (decl);
2837 pushdecl_top_level (decl);
2844 objc_declare_alias (tree alias_ident, tree class_ident)
2846 tree underlying_class;
2849 if (current_namespace != global_namespace) {
2850 error ("Objective-C declarations may only appear in global scope");
2852 #endif /* OBJCPLUS */
2854 if (!(underlying_class = objc_is_class_name (class_ident)))
2855 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2856 else if (objc_is_class_name (alias_ident))
2857 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2860 /* Implement @compatibility_alias as a typedef. */
2862 push_lang_context (lang_name_c); /* extern "C" */
2864 lang_hooks.decls.pushdecl (build_decl
2867 xref_tag (RECORD_TYPE, underlying_class)));
2869 pop_lang_context ();
2871 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2876 objc_declare_class (tree ident_list)
2880 if (current_namespace != global_namespace) {
2881 error ("Objective-C declarations may only appear in global scope");
2883 #endif /* OBJCPLUS */
2885 for (list = ident_list; list; list = TREE_CHAIN (list))
2887 tree ident = TREE_VALUE (list);
2889 if (! objc_is_class_name (ident))
2891 tree record = lookup_name (ident), type = record;
2895 if (TREE_CODE (record) == TYPE_DECL)
2896 type = DECL_ORIGINAL_TYPE (record);
2898 if (!TYPE_HAS_OBJC_INFO (type)
2899 || !TYPE_OBJC_INTERFACE (type))
2901 error ("%qs redeclared as different kind of symbol",
2902 IDENTIFIER_POINTER (ident));
2903 error ("previous declaration of %q+D",
2908 record = xref_tag (RECORD_TYPE, ident);
2909 INIT_TYPE_OBJC_INFO (record);
2910 TYPE_OBJC_INTERFACE (record) = ident;
2911 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2917 objc_is_class_name (tree ident)
2921 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2922 && identifier_global_value (ident))
2923 ident = identifier_global_value (ident);
2924 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2925 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2927 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2928 ident = OBJC_TYPE_NAME (ident);
2930 if (ident && TREE_CODE (ident) == TYPE_DECL)
2931 ident = DECL_NAME (ident);
2933 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2936 if (lookup_interface (ident))
2939 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2941 if (ident == TREE_VALUE (chain))
2945 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2947 if (ident == TREE_VALUE (chain))
2948 return TREE_PURPOSE (chain);
2954 /* Check whether TYPE is either 'id' or 'Class'. */
2957 objc_is_id (tree type)
2959 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2960 && identifier_global_value (type))
2961 type = identifier_global_value (type);
2963 if (type && TREE_CODE (type) == TYPE_DECL)
2964 type = TREE_TYPE (type);
2966 /* NB: This function may be called before the ObjC front-end has
2967 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2968 return (objc_object_type && type
2969 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2974 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2975 class instance. This is needed by other parts of the compiler to
2976 handle ObjC types gracefully. */
2979 objc_is_object_ptr (tree type)
2983 type = TYPE_MAIN_VARIANT (type);
2984 if (!POINTER_TYPE_P (type))
2987 ret = objc_is_id (type);
2989 ret = objc_is_class_name (TREE_TYPE (type));
2995 objc_is_gcable_type (tree type, int or_strong_p)
3001 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3003 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3005 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3007 type = TREE_TYPE (type);
3008 if (TREE_CODE (type) != RECORD_TYPE)
3010 name = TYPE_NAME (type);
3011 return (objc_is_class_name (name) != NULL_TREE);
3015 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3017 if (expr == oldexpr)
3020 switch (TREE_CODE (expr))
3023 return objc_build_component_ref
3024 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3027 DECL_NAME (TREE_OPERAND (expr, 1)));
3029 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3032 TREE_OPERAND (expr, 1));
3034 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3043 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3046 /* The LHS parameter contains the expression 'outervar->memberspec';
3047 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3048 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3051 = objc_substitute_decl
3052 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3054 = (flag_objc_direct_dispatch
3055 ? objc_assign_ivar_fast_decl
3056 : objc_assign_ivar_decl);
3058 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3060 func_params = tree_cons (NULL_TREE,
3061 convert (objc_object_type, rhs),
3062 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3063 tree_cons (NULL_TREE, offs,
3066 assemble_external (func);
3067 return build_function_call (func, func_params);
3071 objc_build_global_assignment (tree lhs, tree rhs)
3073 tree func_params = tree_cons (NULL_TREE,
3074 convert (objc_object_type, rhs),
3075 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3076 build_unary_op (ADDR_EXPR, lhs, 0)),
3079 assemble_external (objc_assign_global_decl);
3080 return build_function_call (objc_assign_global_decl, func_params);
3084 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3086 tree func_params = tree_cons (NULL_TREE,
3087 convert (objc_object_type, rhs),
3088 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3089 build_unary_op (ADDR_EXPR, lhs, 0)),
3092 assemble_external (objc_assign_strong_cast_decl);
3093 return build_function_call (objc_assign_strong_cast_decl, func_params);
3097 objc_is_gcable_p (tree expr)
3099 return (TREE_CODE (expr) == COMPONENT_REF
3100 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3101 : TREE_CODE (expr) == ARRAY_REF
3102 ? (objc_is_gcable_p (TREE_TYPE (expr))
3103 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3104 : TREE_CODE (expr) == ARRAY_TYPE
3105 ? objc_is_gcable_p (TREE_TYPE (expr))
3107 ? objc_is_gcable_type (expr, 1)
3108 : (objc_is_gcable_p (TREE_TYPE (expr))
3110 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3114 objc_is_ivar_reference_p (tree expr)
3116 return (TREE_CODE (expr) == ARRAY_REF
3117 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3118 : TREE_CODE (expr) == COMPONENT_REF
3119 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3124 objc_is_global_reference_p (tree expr)
3126 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3127 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3129 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3134 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3136 tree result = NULL_TREE, outer;
3137 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3139 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3140 will have been transformed to the form '*(type *)&expr'. */
3141 if (TREE_CODE (lhs) == INDIRECT_REF)
3143 outer = TREE_OPERAND (lhs, 0);
3145 while (!strong_cast_p
3146 && (TREE_CODE (outer) == CONVERT_EXPR
3147 || TREE_CODE (outer) == NOP_EXPR
3148 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3150 tree lhstype = TREE_TYPE (outer);
3152 /* Descend down the cast chain, and record the first objc_gc
3154 if (POINTER_TYPE_P (lhstype))
3157 = lookup_attribute ("objc_gc",
3158 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3164 outer = TREE_OPERAND (outer, 0);
3168 /* If we have a __strong cast, it trumps all else. */
3171 if (modifycode != NOP_EXPR)
3172 goto invalid_pointer_arithmetic;
3174 if (warn_assign_intercept)
3175 warning (0, "strong-cast assignment has been intercepted");
3177 result = objc_build_strong_cast_assignment (lhs, rhs);
3182 /* the lhs must be of a suitable type, regardless of its underlying
3184 if (!objc_is_gcable_p (lhs))
3190 && (TREE_CODE (outer) == COMPONENT_REF
3191 || TREE_CODE (outer) == ARRAY_REF))
3192 outer = TREE_OPERAND (outer, 0);
3194 if (TREE_CODE (outer) == INDIRECT_REF)
3196 outer = TREE_OPERAND (outer, 0);
3200 outer_gc_p = objc_is_gcable_p (outer);
3202 /* Handle ivar assignments. */
3203 if (objc_is_ivar_reference_p (lhs))
3205 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3206 doesn't cut it here), the best we can do here is suggest a cast. */
3207 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3209 /* We may still be able to use the global write barrier... */
3210 if (!indirect_p && objc_is_global_reference_p (outer))
3211 goto global_reference;
3214 if (modifycode == NOP_EXPR)
3216 if (warn_assign_intercept)
3217 warning (0, "strong-cast may possibly be needed");
3223 if (modifycode != NOP_EXPR)
3224 goto invalid_pointer_arithmetic;
3226 if (warn_assign_intercept)
3227 warning (0, "instance variable assignment has been intercepted");
3229 result = objc_build_ivar_assignment (outer, lhs, rhs);
3234 /* Likewise, intercept assignment to global/static variables if their type is
3236 if (objc_is_global_reference_p (outer))
3242 if (modifycode != NOP_EXPR)
3244 invalid_pointer_arithmetic:
3246 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3251 if (warn_assign_intercept)
3252 warning (0, "global/static variable assignment has been intercepted");
3254 result = objc_build_global_assignment (lhs, rhs);
3257 /* In all other cases, fall back to the normal mechanism. */
3262 struct interface_tuple GTY(())
3268 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3271 hash_interface (const void *p)
3273 const struct interface_tuple *d = p;
3274 return htab_hash_pointer (d->id);
3278 eq_interface (const void *p1, const void *p2)
3280 const struct interface_tuple *d = p1;
3285 lookup_interface (tree ident)
3288 if (ident && TREE_CODE (ident) == TYPE_DECL)
3289 ident = DECL_NAME (ident);
3292 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3296 struct interface_tuple **slot;
3301 slot = (struct interface_tuple **)
3302 htab_find_slot_with_hash (interface_htab, ident,
3303 htab_hash_pointer (ident),
3306 i = (*slot)->class_name;
3312 /* Implement @defs (<classname>) within struct bodies. */
3315 objc_get_class_ivars (tree class_name)
3317 tree interface = lookup_interface (class_name);
3320 return get_class_ivars (interface, true);
3322 error ("cannot find interface declaration for %qs",
3323 IDENTIFIER_POINTER (class_name));
3325 return error_mark_node;
3328 /* Used by: build_private_template, continue_class,
3329 and for @defs constructs. */
3332 get_class_ivars (tree interface, bool inherited)
3334 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3336 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3337 by the current class (i.e., they do not include super-class ivars).
3338 However, the CLASS_IVARS list will be side-effected by a call to
3339 finish_struct(), which will fill in field offsets. */
3340 if (!CLASS_IVARS (interface))
3341 CLASS_IVARS (interface) = ivar_chain;
3346 while (CLASS_SUPER_NAME (interface))
3348 /* Prepend super-class ivars. */
3349 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3350 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3358 objc_create_temporary_var (tree type)
3362 decl = build_decl (VAR_DECL, NULL_TREE, type);
3363 TREE_USED (decl) = 1;
3364 DECL_ARTIFICIAL (decl) = 1;
3365 DECL_IGNORED_P (decl) = 1;
3366 DECL_CONTEXT (decl) = current_function_decl;
3371 /* Exception handling constructs. We begin by having the parser do most
3372 of the work and passing us blocks. What we do next depends on whether
3373 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3374 We abstract all of this in a handful of appropriately named routines. */
3376 /* Stack of open try blocks. */
3378 struct objc_try_context
3380 struct objc_try_context *outer;
3382 /* Statements (or statement lists) as processed by the parser. */
3386 /* Some file position locations. */
3387 location_t try_locus;
3388 location_t end_try_locus;
3389 location_t end_catch_locus;
3390 location_t finally_locus;
3391 location_t end_finally_locus;
3393 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3394 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3397 /* The CATCH_EXPR of an open @catch clause. */
3400 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3406 static struct objc_try_context *cur_try_context;
3408 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3409 that represents TYPE. For Objective-C, this is just the class name. */
3410 /* ??? Isn't there a class object or some such? Is it easy to get? */
3414 objc_eh_runtime_type (tree type)
3416 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3420 /* Initialize exception handling. */
3423 objc_init_exceptions (void)
3425 static bool done = false;
3430 if (flag_objc_sjlj_exceptions)
3432 /* On Darwin, ObjC exceptions require a sufficiently recent
3433 version of the runtime, so the user must ask for them explicitly. */
3434 if (!flag_objc_exceptions)
3435 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3436 "exception syntax");
3441 c_eh_initialized_p = true;
3442 eh_personality_libfunc
3443 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3444 ? "__gnu_objc_personality_sj0"
3445 : "__gnu_objc_personality_v0");
3446 default_init_unwind_resume_libfunc ();
3447 using_eh_for_cleanups ();
3448 lang_eh_runtime_type = objc_eh_runtime_type;
3453 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3454 we'll arrange for it to be initialized (and associated with a binding)
3458 objc_build_exc_ptr (void)
3460 if (flag_objc_sjlj_exceptions)
3462 tree var = cur_try_context->caught_decl;
3465 var = objc_create_temporary_var (objc_object_type);
3466 cur_try_context->caught_decl = var;
3471 return build (EXC_PTR_EXPR, objc_object_type);
3474 /* Build "objc_exception_try_exit(&_stack)". */
3477 next_sjlj_build_try_exit (void)
3480 t = build_fold_addr_expr (cur_try_context->stack_decl);
3481 t = tree_cons (NULL, t, NULL);
3482 t = build_function_call (objc_exception_try_exit_decl, t);
3487 objc_exception_try_enter (&_stack);
3488 if (_setjmp(&_stack.buf))
3492 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3493 empty, ready for the caller to fill them in. */
3496 next_sjlj_build_enter_and_setjmp (void)
3498 tree t, enter, sj, cond;
3500 t = build_fold_addr_expr (cur_try_context->stack_decl);
3501 t = tree_cons (NULL, t, NULL);
3502 enter = build_function_call (objc_exception_try_enter_decl, t);
3504 t = objc_build_component_ref (cur_try_context->stack_decl,
3505 get_identifier ("buf"));
3506 t = build_fold_addr_expr (t);
3508 /* Convert _setjmp argument to type that is expected. */
3509 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3510 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3512 t = convert (ptr_type_node, t);
3514 t = convert (ptr_type_node, t);
3516 t = tree_cons (NULL, t, NULL);
3517 sj = build_function_call (objc_setjmp_decl, t);
3519 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3520 cond = c_common_truthvalue_conversion (cond);
3522 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3526 DECL = objc_exception_extract(&_stack);
3530 next_sjlj_build_exc_extract (tree decl)
3534 t = build_fold_addr_expr (cur_try_context->stack_decl);
3535 t = tree_cons (NULL, t, NULL);
3536 t = build_function_call (objc_exception_extract_decl, t);
3537 t = convert (TREE_TYPE (decl), t);
3538 t = build (MODIFY_EXPR, void_type_node, decl, t);
3544 if (objc_exception_match(obj_get_class(TYPE), _caught)
3551 objc_exception_try_exit(&_stack);
3553 from the sequence of CATCH_EXPRs in the current try context. */
3556 next_sjlj_build_catch_list (void)
3558 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3560 tree *last = &catch_seq;
3561 bool saw_id = false;
3563 for (; !tsi_end_p (i); tsi_next (&i))
3565 tree stmt = tsi_stmt (i);
3566 tree type = CATCH_TYPES (stmt);
3567 tree body = CATCH_BODY (stmt);
3579 if (type == error_mark_node)
3580 cond = error_mark_node;
3583 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3584 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3585 args = tree_cons (NULL, t, args);
3586 t = build_function_call (objc_exception_match_decl, args);
3587 cond = c_common_truthvalue_conversion (t);
3589 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3590 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3593 last = &COND_EXPR_ELSE (t);
3599 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3600 cur_try_context->caught_decl);
3601 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3602 append_to_statement_list (t, last);
3604 t = next_sjlj_build_try_exit ();
3605 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3606 append_to_statement_list (t, last);
3612 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3613 exception handling. We aim to build:
3616 struct _objc_exception_data _stack;
3617 id volatile _rethrow = 0;
3620 objc_exception_try_enter (&_stack);
3621 if (_setjmp(&_stack.buf))
3623 id _caught = objc_exception_extract(&_stack);
3624 objc_exception_try_enter (&_stack);
3625 if (_setjmp(&_stack.buf))
3626 _rethrow = objc_exception_extract(&_stack);
3636 objc_exception_try_exit(&_stack);
3639 objc_exception_throw(_rethrow);
3643 If CATCH-LIST is empty, we can omit all of the block containing
3644 "_caught" except for the setting of _rethrow. Note the use of
3645 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3646 but handles goto and other exits from the block. */
3649 next_sjlj_build_try_catch_finally (void)
3651 tree rethrow_decl, stack_decl, t;
3652 tree catch_seq, try_fin, bind;
3654 /* Create the declarations involved. */
3655 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3656 stack_decl = objc_create_temporary_var (t);
3657 cur_try_context->stack_decl = stack_decl;
3659 rethrow_decl = objc_create_temporary_var (objc_object_type);
3660 cur_try_context->rethrow_decl = rethrow_decl;
3661 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3662 TREE_CHAIN (rethrow_decl) = stack_decl;
3664 /* Build the outermost variable binding level. */
3665 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3666 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3667 TREE_SIDE_EFFECTS (bind) = 1;
3669 /* Initialize rethrow_decl. */
3670 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3671 convert (objc_object_type, null_pointer_node));
3672 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3673 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3675 /* Build the outermost TRY_FINALLY_EXPR. */
3676 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3677 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3678 TREE_SIDE_EFFECTS (try_fin) = 1;
3679 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3681 /* Create the complete catch sequence. */
3682 if (cur_try_context->catch_list)
3684 tree caught_decl = objc_build_exc_ptr ();
3685 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3686 TREE_SIDE_EFFECTS (catch_seq) = 1;
3688 t = next_sjlj_build_exc_extract (caught_decl);
3689 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3691 t = next_sjlj_build_enter_and_setjmp ();
3692 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3693 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3694 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3697 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3698 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3700 /* Build the main register-and-try if statement. */
3701 t = next_sjlj_build_enter_and_setjmp ();
3702 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3703 COND_EXPR_THEN (t) = catch_seq;
3704 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3705 TREE_OPERAND (try_fin, 0) = t;
3707 /* Build the complete FINALLY statement list. */
3708 t = next_sjlj_build_try_exit ();
3709 t = build_stmt (COND_EXPR,
3710 c_common_truthvalue_conversion (rethrow_decl),
3712 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3713 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3715 append_to_statement_list (cur_try_context->finally_body,
3716 &TREE_OPERAND (try_fin, 1));
3718 t = tree_cons (NULL, rethrow_decl, NULL);
3719 t = build_function_call (objc_exception_throw_decl, t);
3720 t = build_stmt (COND_EXPR,
3721 c_common_truthvalue_conversion (rethrow_decl),
3723 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3724 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3729 /* Called just after parsing the @try and its associated BODY. We now
3730 must prepare for the tricky bits -- handling the catches and finally. */
3733 objc_begin_try_stmt (location_t try_locus, tree body)
3735 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3736 c->outer = cur_try_context;
3738 c->try_locus = try_locus;
3739 c->end_try_locus = input_location;
3740 cur_try_context = c;
3742 objc_init_exceptions ();
3744 if (flag_objc_sjlj_exceptions)
3745 objc_mark_locals_volatile (NULL);
3748 /* Called just after parsing "@catch (parm)". Open a binding level,
3749 enter DECL into the binding level, and initialize it. Leave the
3750 binding level open while the body of the compound statement is parsed. */
3753 objc_begin_catch_clause (tree decl)
3755 tree compound, type, t;
3757 /* Begin a new scope that the entire catch clause will live in. */
3758 compound = c_begin_compound_stmt (true);
3760 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3761 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3762 lang_hooks.decls.pushdecl (decl);
3764 /* Since a decl is required here by syntax, don't warn if its unused. */
3765 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3766 be what the previous objc implementation did. */
3767 TREE_USED (decl) = 1;
3769 /* Verify that the type of the catch is valid. It must be a pointer
3770 to an Objective-C class, or "id" (which is catch-all). */
3771 type = TREE_TYPE (decl);
3773 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3775 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3777 error ("@catch parameter is not a known Objective-C class type");
3778 type = error_mark_node;
3780 else if (cur_try_context->catch_list)
3782 /* Examine previous @catch clauses and see if we've already
3783 caught the type in question. */
3784 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3785 for (; !tsi_end_p (i); tsi_next (&i))
3787 tree stmt = tsi_stmt (i);
3788 t = CATCH_TYPES (stmt);
3789 if (t == error_mark_node)
3791 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3793 warning (0, "exception of type %<%T%> will be caught",
3795 warning (0, "%H by earlier handler for %<%T%>",
3796 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3802 /* Record the data for the catch in the try context so that we can
3803 finalize it later. */
3804 t = build_stmt (CATCH_EXPR, type, compound);
3805 cur_try_context->current_catch = t;
3807 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3808 t = objc_build_exc_ptr ();
3809 t = convert (TREE_TYPE (decl), t);
3810 t = build (MODIFY_EXPR, void_type_node, decl, t);
3814 /* Called just after parsing the closing brace of a @catch clause. Close
3815 the open binding level, and record a CATCH_EXPR for it. */
3818 objc_finish_catch_clause (void)
3820 tree c = cur_try_context->current_catch;
3821 cur_try_context->current_catch = NULL;
3822 cur_try_context->end_catch_locus = input_location;
3824 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3825 append_to_statement_list (c, &cur_try_context->catch_list);
3828 /* Called after parsing a @finally clause and its associated BODY.
3829 Record the body for later placement. */
3832 objc_build_finally_clause (location_t finally_locus, tree body)
3834 cur_try_context->finally_body = body;
3835 cur_try_context->finally_locus = finally_locus;
3836 cur_try_context->end_finally_locus = input_location;
3839 /* Called to finalize a @try construct. */
3842 objc_finish_try_stmt (void)
3844 struct objc_try_context *c = cur_try_context;
3847 if (c->catch_list == NULL && c->finally_body == NULL)
3848 error ("%<@try%> without %<@catch%> or %<@finally%>");
3850 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3851 if (flag_objc_sjlj_exceptions)
3853 if (!cur_try_context->finally_body)
3855 cur_try_context->finally_locus = input_location;
3856 cur_try_context->end_finally_locus = input_location;
3858 stmt = next_sjlj_build_try_catch_finally ();
3862 /* Otherwise, nest the CATCH inside a FINALLY. */
3866 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3867 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3869 if (c->finally_body)
3871 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3872 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3877 cur_try_context = c->outer;
3883 objc_build_throw_stmt (tree throw_expr)
3887 objc_init_exceptions ();
3889 if (throw_expr == NULL)
3891 /* If we're not inside a @catch block, there is no "current
3892 exception" to be rethrown. */
3893 if (cur_try_context == NULL
3894 || cur_try_context->current_catch == NULL)
3896 error ("%<@throw%> (rethrow) used outside of a @catch block");
3900 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3901 value that we get from the runtime. */
3902 throw_expr = objc_build_exc_ptr ();
3905 /* A throw is just a call to the runtime throw function with the
3906 object as a parameter. */
3907 args = tree_cons (NULL, throw_expr, NULL);
3908 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3912 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3916 /* First lock the mutex. */
3917 mutex = save_expr (mutex);
3918 args = tree_cons (NULL, mutex, NULL);
3919 call = build_function_call (objc_sync_enter_decl, args);
3920 SET_EXPR_LOCATION (call, start_locus);
3923 /* Build the mutex unlock. */
3924 args = tree_cons (NULL, mutex, NULL);
3925 call = build_function_call (objc_sync_exit_decl, args);
3926 SET_EXPR_LOCATION (call, input_location);
3928 /* Put the that and the body in a TRY_FINALLY. */
3929 objc_begin_try_stmt (start_locus, body);
3930 objc_build_finally_clause (input_location, call);
3931 return objc_finish_try_stmt ();
3935 /* Predefine the following data type:
3937 struct _objc_exception_data
3943 /* The following yuckiness should prevent users from having to #include
3944 <setjmp.h> in their code... */
3946 #ifdef TARGET_POWERPC
3947 /* snarfed from /usr/include/ppc/setjmp.h */
3948 #define _JBLEN (26 + 36 + 129 + 1)
3950 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3955 build_next_objc_exception_stuff (void)
3957 tree field_decl, field_decl_chain, index, temp_type;
3959 objc_exception_data_template
3960 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3962 /* int buf[_JBLEN]; */
3964 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3965 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3967 field_decl_chain = field_decl;
3969 /* void *pointers[4]; */
3971 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3972 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3974 chainon (field_decl_chain, field_decl);
3976 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3978 /* int _setjmp(...); */
3979 /* If the user includes <setjmp.h>, this shall be superseded by
3980 'int _setjmp(jmp_buf);' */
3981 temp_type = build_function_type (integer_type_node, NULL_TREE);
3983 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3985 /* id objc_exception_extract(struct _objc_exception_data *); */
3987 = build_function_type (objc_object_type,
3988 tree_cons (NULL_TREE,
3989 build_pointer_type (objc_exception_data_template),
3991 objc_exception_extract_decl
3992 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3993 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3994 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3996 = build_function_type (void_type_node,
3997 tree_cons (NULL_TREE,
3998 build_pointer_type (objc_exception_data_template),
4000 objc_exception_try_enter_decl
4001 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4002 objc_exception_try_exit_decl
4003 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4005 /* int objc_exception_match(id, id); */
4007 = build_function_type (integer_type_node,
4008 tree_cons (NULL_TREE, objc_object_type,
4009 tree_cons (NULL_TREE, objc_object_type,
4010 OBJC_VOID_AT_END)));
4011 objc_exception_match_decl
4012 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4014 /* id objc_assign_ivar (id, id, unsigned int); */
4015 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4016 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4018 = build_function_type (objc_object_type,
4020 (NULL_TREE, objc_object_type,
4021 tree_cons (NULL_TREE, objc_object_type,
4022 tree_cons (NULL_TREE,
4024 OBJC_VOID_AT_END))));
4025 objc_assign_ivar_decl
4026 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4028 #ifdef OFFS_ASSIGNIVAR_FAST
4029 objc_assign_ivar_fast_decl
4030 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4031 NOT_BUILT_IN, NULL, NULL_TREE);
4032 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4033 = tree_cons (get_identifier ("hard_coded_address"),
4034 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4037 /* Default to slower ivar method. */
4038 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4041 /* id objc_assign_global (id, id *); */
4042 /* id objc_assign_strongCast (id, id *); */
4043 temp_type = build_function_type (objc_object_type,
4044 tree_cons (NULL_TREE, objc_object_type,
4045 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4046 OBJC_VOID_AT_END)));
4047 objc_assign_global_decl
4048 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4049 objc_assign_strong_cast_decl
4050 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4054 build_objc_exception_stuff (void)
4056 tree noreturn_list, nothrow_list, temp_type;
4058 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4059 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4061 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4062 /* void objc_sync_enter(id); */
4063 /* void objc_sync_exit(id); */
4064 temp_type = build_function_type (void_type_node,
4065 tree_cons (NULL_TREE, objc_object_type,
4067 objc_exception_throw_decl
4068 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4070 objc_sync_enter_decl
4071 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4072 NULL, nothrow_list);
4074 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4075 NULL, nothrow_list);
4078 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4081 struct <classname> {
4082 struct _objc_class *isa;
4087 build_private_template (tree class)
4089 if (!CLASS_STATIC_TEMPLATE (class))
4091 tree record = objc_build_struct (class,
4092 get_class_ivars (class, false),
4093 CLASS_SUPER_NAME (class));
4095 /* Set the TREE_USED bit for this struct, so that stab generator
4096 can emit stabs for this struct type. */
4097 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4098 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4102 /* Begin code generation for protocols... */
4104 /* struct _objc_protocol {
4105 struct _objc_class *isa;
4106 char *protocol_name;
4107 struct _objc_protocol **protocol_list;
4108 struct _objc__method_prototype_list *instance_methods;
4109 struct _objc__method_prototype_list *class_methods;
4113 build_protocol_template (void)
4115 tree field_decl, field_decl_chain;
4117 objc_protocol_template = start_struct (RECORD_TYPE,
4118 get_identifier (UTAG_PROTOCOL));
4120 /* struct _objc_class *isa; */
4121 field_decl = create_field_decl (build_pointer_type
4122 (xref_tag (RECORD_TYPE,
4123 get_identifier (UTAG_CLASS))),
4125 field_decl_chain = field_decl;
4127 /* char *protocol_name; */
4128 field_decl = create_field_decl (string_type_node, "protocol_name");
4129 chainon (field_decl_chain, field_decl);
4131 /* struct _objc_protocol **protocol_list; */
4132 field_decl = create_field_decl (build_pointer_type
4134 (objc_protocol_template)),
4136 chainon (field_decl_chain, field_decl);
4138 /* struct _objc__method_prototype_list *instance_methods; */
4139 field_decl = create_field_decl (objc_method_proto_list_ptr,
4140 "instance_methods");
4141 chainon (field_decl_chain, field_decl);
4143 /* struct _objc__method_prototype_list *class_methods; */
4144 field_decl = create_field_decl (objc_method_proto_list_ptr,
4146 chainon (field_decl_chain, field_decl);
4148 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4152 build_descriptor_table_initializer (tree type, tree entries)
4154 tree initlist = NULL_TREE;
4158 tree eltlist = NULL_TREE;
4161 = tree_cons (NULL_TREE,
4162 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4164 = tree_cons (NULL_TREE,
4165 add_objc_string (METHOD_ENCODING (entries),
4170 = tree_cons (NULL_TREE,
4171 objc_build_constructor (type, nreverse (eltlist)),
4174 entries = TREE_CHAIN (entries);
4178 return objc_build_constructor (build_array_type (type, 0),
4179 nreverse (initlist));
4182 /* struct objc_method_prototype_list {
4184 struct objc_method_prototype {
4191 build_method_prototype_list_template (tree list_type, int size)
4193 tree objc_ivar_list_record;
4194 tree field_decl, field_decl_chain;
4196 /* Generate an unnamed struct definition. */
4198 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4200 /* int method_count; */
4201 field_decl = create_field_decl (integer_type_node, "method_count");
4202 field_decl_chain = field_decl;
4204 /* struct objc_method method_list[]; */
4205 field_decl = create_field_decl (build_array_type
4208 (build_int_cst (NULL_TREE, size - 1))),
4210 chainon (field_decl_chain, field_decl);
4212 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4214 return objc_ivar_list_record;
4218 build_method_prototype_template (void)
4221 tree field_decl, field_decl_chain;
4224 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4227 field_decl = create_field_decl (objc_selector_type, "_cmd");
4228 field_decl_chain = field_decl;
4230 /* char *method_types; */
4231 field_decl = create_field_decl (string_type_node, "method_types");
4232 chainon (field_decl_chain, field_decl);
4234 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4236 return proto_record;
4240 objc_method_parm_type (tree type)
4242 type = TREE_VALUE (TREE_TYPE (type));
4243 if (TREE_CODE (type) == TYPE_DECL)
4244 type = TREE_TYPE (type);
4249 objc_encoded_type_size (tree type)
4251 int sz = int_size_in_bytes (type);
4253 /* Make all integer and enum types at least as large
4255 if (sz > 0 && INTEGRAL_TYPE_P (type))
4256 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4257 /* Treat arrays as pointers, since that's how they're
4259 else if (TREE_CODE (type) == ARRAY_TYPE)
4260 sz = int_size_in_bytes (ptr_type_node);
4265 encode_method_prototype (tree method_decl)
4272 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4273 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4275 /* Encode return type. */
4276 encode_type (objc_method_parm_type (method_decl),
4277 obstack_object_size (&util_obstack),
4278 OBJC_ENCODE_INLINE_DEFS);
4281 /* The first two arguments (self and _cmd) are pointers; account for
4283 i = int_size_in_bytes (ptr_type_node);
4284 parm_offset = 2 * i;
4285 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4286 parms = TREE_CHAIN (parms))
4288 tree type = objc_method_parm_type (parms);
4289 int sz = objc_encoded_type_size (type);
4291 /* If a type size is not known, bail out. */
4294 error ("type %q+D does not have a known size",
4296 /* Pretend that the encoding succeeded; the compilation will
4297 fail nevertheless. */
4298 goto finish_encoding;
4303 sprintf (buf, "%d@0:%d", parm_offset, i);
4304 obstack_grow (&util_obstack, buf, strlen (buf));
4306 /* Argument types. */
4307 parm_offset = 2 * i;
4308 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4309 parms = TREE_CHAIN (parms))
4311 tree type = objc_method_parm_type (parms);
4313 /* Process argument qualifiers for user supplied arguments. */
4314 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4317 encode_type (type, obstack_object_size (&util_obstack),
4318 OBJC_ENCODE_INLINE_DEFS);
4320 /* Compute offset. */
4321 sprintf (buf, "%d", parm_offset);
4322 parm_offset += objc_encoded_type_size (type);
4324 obstack_grow (&util_obstack, buf, strlen (buf));
4328 obstack_1grow (&util_obstack, '\0');
4329 result = get_identifier (obstack_finish (&util_obstack));
4330 obstack_free (&util_obstack, util_firstobj);
4335 generate_descriptor_table (tree type, const char *name, int size, tree list,
4338 tree decl, initlist;
4340 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4342 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4343 initlist = tree_cons (NULL_TREE, list, initlist);
4345 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4351 generate_method_descriptors (tree protocol)
4353 tree initlist, chain, method_list_template;
4356 if (!objc_method_prototype_template)
4357 objc_method_prototype_template = build_method_prototype_template ();
4359 chain = PROTOCOL_CLS_METHODS (protocol);
4362 size = list_length (chain);
4364 method_list_template
4365 = build_method_prototype_list_template (objc_method_prototype_template,
4369 = build_descriptor_table_initializer (objc_method_prototype_template,
4372 UOBJC_CLASS_METHODS_decl
4373 = generate_descriptor_table (method_list_template,
4374 "_OBJC_PROTOCOL_CLASS_METHODS",
4375 size, initlist, protocol);
4378 UOBJC_CLASS_METHODS_decl = 0;
4380 chain = PROTOCOL_NST_METHODS (protocol);
4383 size = list_length (chain);
4385 method_list_template
4386 = build_method_prototype_list_template (objc_method_prototype_template,
4389 = build_descriptor_table_initializer (objc_method_prototype_template,
4392 UOBJC_INSTANCE_METHODS_decl
4393 = generate_descriptor_table (method_list_template,
4394 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4395 size, initlist, protocol);
4398 UOBJC_INSTANCE_METHODS_decl = 0;
4402 generate_protocol_references (tree plist)
4406 /* Forward declare protocols referenced. */
4407 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4409 tree proto = TREE_VALUE (lproto);
4411 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4412 && PROTOCOL_NAME (proto))
4414 if (! PROTOCOL_FORWARD_DECL (proto))
4415 build_protocol_reference (proto);
4417 if (PROTOCOL_LIST (proto))
4418 generate_protocol_references (PROTOCOL_LIST (proto));
4423 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4427 objc_generate_cxx_ctor_or_dtor (bool dtor)
4429 tree fn, body, compound_stmt, ivar;
4431 /* - (id) .cxx_construct { ... return self; } */
4432 /* - (void) .cxx_construct { ... } */
4434 objc_set_method_type (MINUS_EXPR);
4435 objc_start_method_definition
4436 (objc_build_method_signature (build_tree_list (NULL_TREE,
4439 : objc_object_type),
4440 get_identifier (dtor
4442 : TAG_CXX_CONSTRUCT),
4443 make_node (TREE_LIST),
4445 body = begin_function_body ();
4446 compound_stmt = begin_compound_stmt (0);
4448 ivar = CLASS_IVARS (implementation_template);
4449 /* Destroy ivars in reverse order. */
4451 ivar = nreverse (copy_list (ivar));
4453 for (; ivar; ivar = TREE_CHAIN (ivar))
4455 if (TREE_CODE (ivar) == FIELD_DECL)
4457 tree type = TREE_TYPE (ivar);
4459 /* Call the ivar's default constructor or destructor. Do not
4460 call the destructor unless a corresponding constructor call
4461 has also been made (or is not needed). */
4462 if (IS_AGGR_TYPE (type)
4464 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4465 && (!TYPE_NEEDS_CONSTRUCTING (type)
4466 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4467 : (TYPE_NEEDS_CONSTRUCTING (type)
4468 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4470 (build_special_member_call
4471 (build_ivar_reference (DECL_NAME (ivar)),
4472 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4473 NULL_TREE, type, LOOKUP_NORMAL));
4477 /* The constructor returns 'self'. */
4479 finish_return_stmt (self_decl);
4481 finish_compound_stmt (compound_stmt);
4482 finish_function_body (body);
4483 fn = current_function_decl;
4485 objc_finish_method_definition (fn);
4488 /* The following routine will examine the current @interface for any
4489 non-POD C++ ivars requiring non-trivial construction and/or
4490 destruction, and then synthesize special '- .cxx_construct' and/or
4491 '- .cxx_destruct' methods which will run the appropriate
4492 construction or destruction code. Note that ivars inherited from
4493 super-classes are _not_ considered. */
4495 objc_generate_cxx_cdtors (void)
4497 bool need_ctor = false, need_dtor = false;
4500 /* We do not want to do this for categories, since they do not have
4503 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4506 /* First, determine if we even need a constructor and/or destructor. */
4508 for (ivar = CLASS_IVARS (implementation_template); ivar;
4509 ivar = TREE_CHAIN (ivar))
4511 if (TREE_CODE (ivar) == FIELD_DECL)
4513 tree type = TREE_TYPE (ivar);
4515 if (IS_AGGR_TYPE (type))
4517 if (TYPE_NEEDS_CONSTRUCTING (type)
4518 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4519 /* NB: If a default constructor is not available, we will not
4520 be able to initialize this ivar; the add_instance_variable()
4521 routine will already have warned about this. */
4524 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4525 && (!TYPE_NEEDS_CONSTRUCTING (type)
4526 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4527 /* NB: If a default constructor is not available, we will not
4528 call the destructor either, for symmetry. */
4534 /* Generate '- .cxx_construct' if needed. */
4537 objc_generate_cxx_ctor_or_dtor (false);
4539 /* Generate '- .cxx_destruct' if needed. */
4542 objc_generate_cxx_ctor_or_dtor (true);
4544 /* The 'imp_list' variable points at an imp_entry record for the current
4545 @implementation. Record the existence of '- .cxx_construct' and/or
4546 '- .cxx_destruct' methods therein; it will be included in the
4547 metadata for the class. */
4548 if (flag_next_runtime)
4549 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4553 /* For each protocol which was referenced either from a @protocol()
4554 expression, or because a class/category implements it (then a
4555 pointer to the protocol is stored in the struct describing the
4556 class/category), we create a statically allocated instance of the
4557 Protocol class. The code is written in such a way as to generate
4558 as few Protocol objects as possible; we generate a unique Protocol
4559 instance for each protocol, and we don't generate a Protocol
4560 instance if the protocol is never referenced (either from a
4561 @protocol() or from a class/category implementation). These
4562 statically allocated objects can be referred to via the static
4563 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4565 The statically allocated Protocol objects that we generate here
4566 need to be fixed up at runtime in order to be used: the 'isa'
4567 pointer of the objects need to be set up to point to the 'Protocol'
4568 class, as known at runtime.
4570 The NeXT runtime fixes up all protocols at program startup time,
4571 before main() is entered. It uses a low-level trick to look up all
4572 those symbols, then loops on them and fixes them up.
4574 The GNU runtime as well fixes up all protocols before user code
4575 from the module is executed; it requires pointers to those symbols
4576 to be put in the objc_symtab (which is then passed as argument to
4577 the function __objc_exec_class() which the compiler sets up to be
4578 executed automatically when the module is loaded); setup of those
4579 Protocol objects happen in two ways in the GNU runtime: all
4580 Protocol objects referred to by a class or category implementation
4581 are fixed up when the class/category is loaded; all Protocol
4582 objects referred to by a @protocol() expression are added by the
4583 compiler to the list of statically allocated instances to fixup
4584 (the same list holding the statically allocated constant string
4585 objects). Because, as explained above, the compiler generates as
4586 few Protocol objects as possible, some Protocol object might end up
4587 being referenced multiple times when compiled with the GNU runtime,
4588 and end up being fixed up multiple times at runtime initialization.
4589 But that doesn't hurt, it's just a little inefficient. */
4592 generate_protocols (void)
4596 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4598 /* If a protocol was directly referenced, pull in indirect references. */
4599 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4600 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4601 generate_protocol_references (PROTOCOL_LIST (p));
4603 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4605 tree nst_methods = PROTOCOL_NST_METHODS (p);
4606 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4608 /* If protocol wasn't referenced, don't generate any code. */
4609 decl = PROTOCOL_FORWARD_DECL (p);
4614 /* Make sure we link in the Protocol class. */
4615 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4619 if (! METHOD_ENCODING (nst_methods))
4621 encoding = encode_method_prototype (nst_methods);
4622 METHOD_ENCODING (nst_methods) = encoding;
4624 nst_methods = TREE_CHAIN (nst_methods);
4629 if (! METHOD_ENCODING (cls_methods))
4631 encoding = encode_method_prototype (cls_methods);
4632 METHOD_ENCODING (cls_methods) = encoding;
4635 cls_methods = TREE_CHAIN (cls_methods);
4637 generate_method_descriptors (p);
4639 if (PROTOCOL_LIST (p))
4640 refs_decl = generate_protocol_list (p);
4644 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4645 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4648 refs_expr = convert (build_pointer_type (build_pointer_type
4649 (objc_protocol_template)),
4650 build_unary_op (ADDR_EXPR, refs_decl, 0));
4652 refs_expr = build_int_cst (NULL_TREE, 0);
4654 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4655 by generate_method_descriptors, which is called above. */
4656 initlist = build_protocol_initializer (TREE_TYPE (decl),
4657 protocol_name_expr, refs_expr,
4658 UOBJC_INSTANCE_METHODS_decl,
4659 UOBJC_CLASS_METHODS_decl);
4660 finish_var_decl (decl, initlist);
4665 build_protocol_initializer (tree type, tree protocol_name,
4666 tree protocol_list, tree instance_methods,
4669 tree initlist = NULL_TREE, expr;
4670 tree cast_type = build_pointer_type
4671 (xref_tag (RECORD_TYPE,
4672 get_identifier (UTAG_CLASS)));
4674 /* Filling the "isa" in with one allows the runtime system to
4675 detect that the version change...should remove before final release. */
4677 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4678 initlist = tree_cons (NULL_TREE, expr, initlist);
4679 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4680 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4682 if (!instance_methods)
4683 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4686 expr = convert (objc_method_proto_list_ptr,
4687 build_unary_op (ADDR_EXPR, instance_methods, 0));
4688 initlist = tree_cons (NULL_TREE, expr, initlist);
4692 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4695 expr = convert (objc_method_proto_list_ptr,
4696 build_unary_op (ADDR_EXPR, class_methods, 0));
4697 initlist = tree_cons (NULL_TREE, expr, initlist);
4700 return objc_build_constructor (type, nreverse (initlist));
4703 /* struct _objc_category {
4704 char *category_name;
4706 struct _objc_method_list *instance_methods;
4707 struct _objc_method_list *class_methods;
4708 struct _objc_protocol_list *protocols;
4712 build_category_template (void)
4714 tree field_decl, field_decl_chain;
4716 objc_category_template = start_struct (RECORD_TYPE,
4717 get_identifier (UTAG_CATEGORY));
4719 /* char *category_name; */
4720 field_decl = create_field_decl (string_type_node, "category_name");
4721 field_decl_chain = field_decl;
4723 /* char *class_name; */
4724 field_decl = create_field_decl (string_type_node, "class_name");
4725 chainon (field_decl_chain, field_decl);
4727 /* struct _objc_method_list *instance_methods; */
4728 field_decl = create_field_decl (objc_method_list_ptr,
4729 "instance_methods");
4730 chainon (field_decl_chain, field_decl);
4732 /* struct _objc_method_list *class_methods; */
4733 field_decl = create_field_decl (objc_method_list_ptr,
4735 chainon (field_decl_chain, field_decl);
4737 /* struct _objc_protocol **protocol_list; */
4738 field_decl = create_field_decl (build_pointer_type
4740 (objc_protocol_template)),
4742 chainon (field_decl_chain, field_decl);
4744 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4747 /* struct _objc_selector {
4753 build_selector_template (void)
4756 tree field_decl, field_decl_chain;
4758 objc_selector_template
4759 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4762 field_decl = create_field_decl (objc_selector_type, "sel_id");
4763 field_decl_chain = field_decl;
4765 /* char *sel_type; */
4766 field_decl = create_field_decl (string_type_node, "sel_type");
4767 chainon (field_decl_chain, field_decl);
4769 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4772 /* struct _objc_class {
4773 struct _objc_class *isa;
4774 struct _objc_class *super_class;
4779 struct _objc_ivar_list *ivars;
4780 struct _objc_method_list *methods;
4781 #ifdef __NEXT_RUNTIME__
4782 struct objc_cache *cache;
4784 struct sarray *dtable;
4785 struct _objc_class *subclass_list;
4786 struct _objc_class *sibling_class;
4788 struct _objc_protocol_list *protocols;
4789 #ifdef __NEXT_RUNTIME__
4792 void *gc_object_type;
4795 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4796 the NeXT/Apple runtime; still, the compiler must generate them to
4797 maintain backward binary compatibility (and to allow for future
4801 build_class_template (void)
4803 tree field_decl, field_decl_chain;
4806 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4808 /* struct _objc_class *isa; */
4809 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4811 field_decl_chain = field_decl;
4813 /* struct _objc_class *super_class; */
4814 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4816 chainon (field_decl_chain, field_decl);
4819 field_decl = create_field_decl (string_type_node, "name");
4820 chainon (field_decl_chain, field_decl);
4823 field_decl = create_field_decl (long_integer_type_node, "version");
4824 chainon (field_decl_chain, field_decl);
4827 field_decl = create_field_decl (long_integer_type_node, "info");
4828 chainon (field_decl_chain, field_decl);
4830 /* long instance_size; */
4831 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4832 chainon (field_decl_chain, field_decl);
4834 /* struct _objc_ivar_list *ivars; */
4835 field_decl = create_field_decl (objc_ivar_list_ptr,
4837 chainon (field_decl_chain, field_decl);
4839 /* struct _objc_method_list *methods; */
4840 field_decl = create_field_decl (objc_method_list_ptr,
4842 chainon (field_decl_chain, field_decl);
4844 if (flag_next_runtime)
4846 /* struct objc_cache *cache; */
4847 field_decl = create_field_decl (build_pointer_type
4848 (xref_tag (RECORD_TYPE,
4852 chainon (field_decl_chain, field_decl);
4856 /* struct sarray *dtable; */
4857 field_decl = create_field_decl (build_pointer_type
4858 (xref_tag (RECORD_TYPE,
4862 chainon (field_decl_chain, field_decl);
4864 /* struct objc_class *subclass_list; */
4865 field_decl = create_field_decl (build_pointer_type
4866 (objc_class_template),
4868 chainon (field_decl_chain, field_decl);
4870 /* struct objc_class *sibling_class; */
4871 field_decl = create_field_decl (build_pointer_type
4872 (objc_class_template),
4874 chainon (field_decl_chain, field_decl);
4877 /* struct _objc_protocol **protocol_list; */
4878 field_decl = create_field_decl (build_pointer_type
4880 (xref_tag (RECORD_TYPE,
4884 chainon (field_decl_chain, field_decl);
4886 if (flag_next_runtime)
4889 field_decl = create_field_decl (build_pointer_type (void_type_node),
4891 chainon (field_decl_chain, field_decl);
4894 /* void *gc_object_type; */
4895 field_decl = create_field_decl (build_pointer_type (void_type_node),
4897 chainon (field_decl_chain, field_decl);
4899 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4902 /* Generate appropriate forward declarations for an implementation. */
4905 synth_forward_declarations (void)
4909 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4910 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4911 objc_class_template);
4913 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4914 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4915 objc_class_template);
4917 /* Pre-build the following entities - for speed/convenience. */
4919 an_id = get_identifier ("super_class");
4920 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4921 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4925 error_with_ivar (const char *message, tree decl)
4927 error ("%J%s %qs", decl,
4928 message, gen_declaration (decl));
4933 check_ivars (tree inter, tree imp)
4935 tree intdecls = CLASS_RAW_IVARS (inter);
4936 tree impdecls = CLASS_RAW_IVARS (imp);
4943 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4944 intdecls = TREE_CHAIN (intdecls);
4946 if (intdecls == 0 && impdecls == 0)
4948 if (intdecls == 0 || impdecls == 0)
4950 error ("inconsistent instance variable specification");
4954 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4956 if (!comptypes (t1, t2)
4957 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4958 DECL_INITIAL (impdecls)))
4960 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4962 error_with_ivar ("conflicting instance variable type",
4964 error_with_ivar ("previous declaration of",
4967 else /* both the type and the name don't match */
4969 error ("inconsistent instance variable specification");
4974 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4976 error_with_ivar ("conflicting instance variable name",
4978 error_with_ivar ("previous declaration of",
4982 intdecls = TREE_CHAIN (intdecls);
4983 impdecls = TREE_CHAIN (impdecls);
4987 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4988 This needs to be done just once per compilation. */
4990 /* struct _objc_super {
4991 struct _objc_object *self;
4992 struct _objc_class *super_class;
4996 build_super_template (void)
4998 tree field_decl, field_decl_chain;
5000 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5002 /* struct _objc_object *self; */
5003 field_decl = create_field_decl (objc_object_type, "self");
5004 field_decl_chain = field_decl;
5006 /* struct _objc_class *super_class; */
5007 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5009 chainon (field_decl_chain, field_decl);
5011 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5014 /* struct _objc_ivar {
5021 build_ivar_template (void)
5023 tree objc_ivar_id, objc_ivar_record;
5024 tree field_decl, field_decl_chain;
5026 objc_ivar_id = get_identifier (UTAG_IVAR);
5027 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5029 /* char *ivar_name; */
5030 field_decl = create_field_decl (string_type_node, "ivar_name");
5031 field_decl_chain = field_decl;
5033 /* char *ivar_type; */
5034 field_decl = create_field_decl (string_type_node, "ivar_type");
5035 chainon (field_decl_chain, field_decl);
5037 /* int ivar_offset; */
5038 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5039 chainon (field_decl_chain, field_decl);
5041 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5043 return objc_ivar_record;
5048 struct objc_ivar ivar_list[ivar_count];
5052 build_ivar_list_template (tree list_type, int size)
5054 tree objc_ivar_list_record;
5055 tree field_decl, field_decl_chain;
5057 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5059 /* int ivar_count; */
5060 field_decl = create_field_decl (integer_type_node, "ivar_count");
5061 field_decl_chain = field_decl;
5063 /* struct objc_ivar ivar_list[]; */
5064 field_decl = create_field_decl (build_array_type
5067 (build_int_cst (NULL_TREE, size - 1))),
5069 chainon (field_decl_chain, field_decl);
5071 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5073 return objc_ivar_list_record;
5077 struct _objc__method_prototype_list *method_next;
5079 struct objc_method method_list[method_count];
5083 build_method_list_template (tree list_type, int size)
5085 tree objc_ivar_list_record;
5086 tree field_decl, field_decl_chain;
5088 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5090 /* struct _objc__method_prototype_list *method_next; */
5091 field_decl = create_field_decl (objc_method_proto_list_ptr,
5093 field_decl_chain = field_decl;
5095 /* int method_count; */
5096 field_decl = create_field_decl (integer_type_node, "method_count");
5097 chainon (field_decl_chain, field_decl);
5099 /* struct objc_method method_list[]; */
5100 field_decl = create_field_decl (build_array_type
5103 (build_int_cst (NULL_TREE, size - 1))),
5105 chainon (field_decl_chain, field_decl);
5107 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5109 return objc_ivar_list_record;
5113 build_ivar_list_initializer (tree type, tree field_decl)
5115 tree initlist = NULL_TREE;
5119 tree ivar = NULL_TREE;
5122 if (DECL_NAME (field_decl))
5123 ivar = tree_cons (NULL_TREE,
5124 add_objc_string (DECL_NAME (field_decl),
5128 /* Unnamed bit-field ivar (yuck). */
5129 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5132 encode_field_decl (field_decl,
5133 obstack_object_size (&util_obstack),
5134 OBJC_ENCODE_DONT_INLINE_DEFS);
5136 /* Null terminate string. */
5137 obstack_1grow (&util_obstack, 0);
5141 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5144 obstack_free (&util_obstack, util_firstobj);
5147 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5148 initlist = tree_cons (NULL_TREE,
5149 objc_build_constructor (type, nreverse (ivar)),
5152 field_decl = TREE_CHAIN (field_decl);
5153 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5157 return objc_build_constructor (build_array_type (type, 0),
5158 nreverse (initlist));
5162 generate_ivars_list (tree type, const char *name, int size, tree list)
5164 tree decl, initlist;
5166 decl = start_var_decl (type, synth_id_with_class_suffix
5167 (name, objc_implementation_context));
5169 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5170 initlist = tree_cons (NULL_TREE, list, initlist);
5172 finish_var_decl (decl,
5173 objc_build_constructor (TREE_TYPE (decl),
5174 nreverse (initlist)));
5179 /* Count only the fields occurring in T. */
5181 ivar_list_length (tree t)
5185 for (; t; t = TREE_CHAIN (t))
5186 if (TREE_CODE (t) == FIELD_DECL)
5193 generate_ivar_lists (void)
5195 tree initlist, ivar_list_template, chain;
5198 generating_instance_variables = 1;
5200 if (!objc_ivar_template)
5201 objc_ivar_template = build_ivar_template ();
5203 /* Only generate class variables for the root of the inheritance
5204 hierarchy since these will be the same for every class. */
5206 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5207 && (chain = TYPE_FIELDS (objc_class_template)))
5209 size = ivar_list_length (chain);
5211 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5212 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5214 UOBJC_CLASS_VARIABLES_decl
5215 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5219 UOBJC_CLASS_VARIABLES_decl = 0;
5221 chain = CLASS_IVARS (implementation_template);
5224 size = ivar_list_length (chain);
5225 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5226 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5228 UOBJC_INSTANCE_VARIABLES_decl
5229 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5233 UOBJC_INSTANCE_VARIABLES_decl = 0;
5235 generating_instance_variables = 0;
5239 build_dispatch_table_initializer (tree type, tree entries)
5241 tree initlist = NULL_TREE;
5245 tree elemlist = NULL_TREE;
5247 elemlist = tree_cons (NULL_TREE,
5248 build_selector (METHOD_SEL_NAME (entries)),
5251 /* Generate the method encoding if we don't have one already. */
5252 if (! METHOD_ENCODING (entries))
5253 METHOD_ENCODING (entries) =
5254 encode_method_prototype (entries);
5256 elemlist = tree_cons (NULL_TREE,
5257 add_objc_string (METHOD_ENCODING (entries),
5262 = tree_cons (NULL_TREE,
5263 convert (ptr_type_node,
5264 build_unary_op (ADDR_EXPR,
5265 METHOD_DEFINITION (entries), 1)),
5268 initlist = tree_cons (NULL_TREE,
5269 objc_build_constructor (type, nreverse (elemlist)),
5272 entries = TREE_CHAIN (entries);
5276 return objc_build_constructor (build_array_type (type, 0),
5277 nreverse (initlist));
5280 /* To accomplish method prototyping without generating all kinds of
5281 inane warnings, the definition of the dispatch table entries were
5284 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5286 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5289 build_method_template (void)
5292 tree field_decl, field_decl_chain;
5294 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5297 field_decl = create_field_decl (objc_selector_type, "_cmd");
5298 field_decl_chain = field_decl;
5300 /* char *method_types; */
5301 field_decl = create_field_decl (string_type_node, "method_types");
5302 chainon (field_decl_chain, field_decl);
5305 field_decl = create_field_decl (build_pointer_type (void_type_node),
5307 chainon (field_decl_chain, field_decl);
5309 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5316 generate_dispatch_table (tree type, const char *name, int size, tree list)
5318 tree decl, initlist;
5320 decl = start_var_decl (type, synth_id_with_class_suffix
5321 (name, objc_implementation_context));
5323 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5324 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5325 initlist = tree_cons (NULL_TREE, list, initlist);
5327 finish_var_decl (decl,
5328 objc_build_constructor (TREE_TYPE (decl),
5329 nreverse (initlist)));
5335 mark_referenced_methods (void)
5337 struct imp_entry *impent;
5340 for (impent = imp_list; impent; impent = impent->next)
5342 chain = CLASS_CLS_METHODS (impent->imp_context);
5345 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5346 chain = TREE_CHAIN (chain);
5349 chain = CLASS_NST_METHODS (impent->imp_context);
5352 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5353 chain = TREE_CHAIN (chain);
5359 generate_dispatch_tables (void)
5361 tree initlist, chain, method_list_template;
5364 if (!objc_method_template)
5365 objc_method_template = build_method_template ();
5367 chain = CLASS_CLS_METHODS (objc_implementation_context);
5370 size = list_length (chain);
5372 method_list_template
5373 = build_method_list_template (objc_method_template, size);
5375 = build_dispatch_table_initializer (objc_method_template, chain);
5377 UOBJC_CLASS_METHODS_decl
5378 = generate_dispatch_table (method_list_template,
5379 ((TREE_CODE (objc_implementation_context)
5380 == CLASS_IMPLEMENTATION_TYPE)
5381 ? "_OBJC_CLASS_METHODS"
5382 : "_OBJC_CATEGORY_CLASS_METHODS"),
5386 UOBJC_CLASS_METHODS_decl = 0;
5388 chain = CLASS_NST_METHODS (objc_implementation_context);
5391 size = list_length (chain);
5393 method_list_template
5394 = build_method_list_template (objc_method_template, size);
5396 = build_dispatch_table_initializer (objc_method_template, chain);
5398 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5399 UOBJC_INSTANCE_METHODS_decl
5400 = generate_dispatch_table (method_list_template,
5401 "_OBJC_INSTANCE_METHODS",
5404 /* We have a category. */
5405 UOBJC_INSTANCE_METHODS_decl
5406 = generate_dispatch_table (method_list_template,
5407 "_OBJC_CATEGORY_INSTANCE_METHODS",
5411 UOBJC_INSTANCE_METHODS_decl = 0;
5415 generate_protocol_list (tree i_or_p)
5418 tree refs_decl, lproto, e, plist;
5420 const char *ref_name;
5422 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5423 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5424 plist = CLASS_PROTOCOL_LIST (i_or_p);
5425 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5426 plist = PROTOCOL_LIST (i_or_p);
5431 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5432 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5433 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5436 /* Build initializer. */
5437 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5438 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5439 initlist = tree_cons (NULL_TREE, e, initlist);
5441 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5443 tree pval = TREE_VALUE (lproto);
5445 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5446 && PROTOCOL_FORWARD_DECL (pval))
5448 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5449 initlist = tree_cons (NULL_TREE, e, initlist);
5453 /* static struct objc_protocol *refs[n]; */
5455 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5456 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5457 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5458 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5459 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5460 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5464 refs_decl = start_var_decl
5466 (build_pointer_type (objc_protocol_template),
5467 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5470 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5471 nreverse (initlist)));
5477 build_category_initializer (tree type, tree cat_name, tree class_name,
5478 tree instance_methods, tree class_methods,
5481 tree initlist = NULL_TREE, expr;
5483 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5484 initlist = tree_cons (NULL_TREE, class_name, initlist);
5486 if (!instance_methods)
5487 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5490 expr = convert (objc_method_list_ptr,
5491 build_unary_op (ADDR_EXPR, instance_methods, 0));
5492 initlist = tree_cons (NULL_TREE, expr, initlist);
5495 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5498 expr = convert (objc_method_list_ptr,
5499 build_unary_op (ADDR_EXPR, class_methods, 0));
5500 initlist = tree_cons (NULL_TREE, expr, initlist);
5503 /* protocol_list = */
5505 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5508 expr = convert (build_pointer_type
5510 (objc_protocol_template)),
5511 build_unary_op (ADDR_EXPR, protocol_list, 0));
5512 initlist = tree_cons (NULL_TREE, expr, initlist);
5515 return objc_build_constructor (type, nreverse (initlist));
5518 /* struct _objc_class {
5519 struct objc_class *isa;
5520 struct objc_class *super_class;
5525 struct objc_ivar_list *ivars;
5526 struct objc_method_list *methods;
5527 if (flag_next_runtime)
5528 struct objc_cache *cache;
5530 struct sarray *dtable;
5531 struct objc_class *subclass_list;
5532 struct objc_class *sibling_class;
5534 struct objc_protocol_list *protocols;
5535 if (flag_next_runtime)
5537 void *gc_object_type;
5541 build_shared_structure_initializer (tree type, tree isa, tree super,
5542 tree name, tree size, int status,
5543 tree dispatch_table, tree ivar_list,
5546 tree initlist = NULL_TREE, expr;
5549 initlist = tree_cons (NULL_TREE, isa, initlist);
5552 initlist = tree_cons (NULL_TREE, super, initlist);
5555 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5558 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5562 initlist = tree_cons (NULL_TREE,
5563 build_int_cst (long_integer_type_node, status),
5566 /* instance_size = */
5567 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5570 /* objc_ivar_list = */
5572 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5575 expr = convert (objc_ivar_list_ptr,
5576 build_unary_op (ADDR_EXPR, ivar_list, 0));
5577 initlist = tree_cons (NULL_TREE, expr, initlist);
5580 /* objc_method_list = */
5581 if (!dispatch_table)
5582 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5585 expr = convert (objc_method_list_ptr,
5586 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5587 initlist = tree_cons (NULL_TREE, expr, initlist);
5590 if (flag_next_runtime)
5591 /* method_cache = */
5592 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5596 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5598 /* subclass_list = */
5599 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5601 /* sibling_class = */
5602 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5605 /* protocol_list = */
5606 if (! protocol_list)
5607 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5610 expr = convert (build_pointer_type
5612 (objc_protocol_template)),
5613 build_unary_op (ADDR_EXPR, protocol_list, 0));
5614 initlist = tree_cons (NULL_TREE, expr, initlist);
5617 if (flag_next_runtime)
5619 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5621 /* gc_object_type = NULL */
5622 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5624 return objc_build_constructor (type, nreverse (initlist));
5627 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5630 lookup_category (tree class, tree cat_name)
5632 tree category = CLASS_CATEGORY_LIST (class);
5634 while (category && CLASS_SUPER_NAME (category) != cat_name)
5635 category = CLASS_CATEGORY_LIST (category);
5639 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5642 generate_category (tree cat)
5645 tree initlist, cat_name_expr, class_name_expr;
5646 tree protocol_decl, category;
5648 add_class_reference (CLASS_NAME (cat));
5649 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5651 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5653 category = lookup_category (implementation_template,
5654 CLASS_SUPER_NAME (cat));
5656 if (category && CLASS_PROTOCOL_LIST (category))
5658 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5659 protocol_decl = generate_protocol_list (category);
5664 decl = start_var_decl (objc_category_template,
5665 synth_id_with_class_suffix
5666 ("_OBJC_CATEGORY", objc_implementation_context));
5668 initlist = build_category_initializer (TREE_TYPE (decl),
5669 cat_name_expr, class_name_expr,
5670 UOBJC_INSTANCE_METHODS_decl,
5671 UOBJC_CLASS_METHODS_decl,
5674 finish_var_decl (decl, initlist);
5677 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5678 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5681 generate_shared_structures (int cls_flags)
5683 tree sc_spec, decl_specs, decl;
5684 tree name_expr, super_expr, root_expr;
5685 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5686 tree cast_type, initlist, protocol_decl;
5688 my_super_id = CLASS_SUPER_NAME (implementation_template);
5691 add_class_reference (my_super_id);
5693 /* Compute "my_root_id" - this is required for code generation.
5694 the "isa" for all meta class structures points to the root of
5695 the inheritance hierarchy (e.g. "__Object")... */
5696 my_root_id = my_super_id;
5699 tree my_root_int = lookup_interface (my_root_id);
5701 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5702 my_root_id = CLASS_SUPER_NAME (my_root_int);
5709 /* No super class. */
5710 my_root_id = CLASS_NAME (implementation_template);
5712 cast_type = build_pointer_type (objc_class_template);
5713 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5716 /* Install class `isa' and `super' pointers at runtime. */
5719 super_expr = add_objc_string (my_super_id, class_names);
5720 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5723 super_expr = build_int_cst (NULL_TREE, 0);
5725 root_expr = add_objc_string (my_root_id, class_names);
5726 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5728 if (CLASS_PROTOCOL_LIST (implementation_template))
5730 generate_protocol_references
5731 (CLASS_PROTOCOL_LIST (implementation_template));
5732 protocol_decl = generate_protocol_list (implementation_template);
5737 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5739 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5740 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5742 decl = start_var_decl (objc_class_template,
5744 (DECL_NAME (UOBJC_METACLASS_decl)));
5747 = build_shared_structure_initializer
5749 root_expr, super_expr, name_expr,
5750 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5752 UOBJC_CLASS_METHODS_decl,
5753 UOBJC_CLASS_VARIABLES_decl,
5756 finish_var_decl (decl, initlist);
5758 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5760 decl = start_var_decl (objc_class_template,
5762 (DECL_NAME (UOBJC_CLASS_decl)));
5765 = build_shared_structure_initializer
5767 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5768 super_expr, name_expr,
5769 convert (integer_type_node,
5770 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5771 (implementation_template))),
5772 1 /*CLS_FACTORY*/ | cls_flags,
5773 UOBJC_INSTANCE_METHODS_decl,
5774 UOBJC_INSTANCE_VARIABLES_decl,
5777 finish_var_decl (decl, initlist);
5782 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5784 static char string[BUFSIZE];
5786 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5787 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5789 sprintf (string, "%s_%s", preamble,
5790 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5792 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5793 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5795 /* We have a category. */
5796 const char *const class_name
5797 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5798 const char *const class_super_name
5799 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5800 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5802 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5804 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5805 sprintf (string, "%s_%s", preamble, protocol_name);
5813 /* If type is empty or only type qualifiers are present, add default
5814 type of id (otherwise grokdeclarator will default to int). */
5817 adjust_type_for_id_default (tree type)
5820 type = make_node (TREE_LIST);
5822 if (!TREE_VALUE (type))
5823 TREE_VALUE (type) = objc_object_type;
5824 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5825 && TYPED_OBJECT (TREE_VALUE (type)))
5826 error ("can not use an object as parameter to a method");
5833 selector ':' '(' typename ')' identifier
5836 Transform an Objective-C keyword argument into
5837 the C equivalent parameter declarator.
5839 In: key_name, an "identifier_node" (optional).
5840 arg_type, a "tree_list" (optional).
5841 arg_name, an "identifier_node".
5843 Note: It would be really nice to strongly type the preceding
5844 arguments in the function prototype; however, then I
5845 could not use the "accessor" macros defined in "tree.h".
5847 Out: an instance of "keyword_decl". */
5850 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5854 /* If no type is specified, default to "id". */
5855 arg_type = adjust_type_for_id_default (arg_type);
5857 keyword_decl = make_node (KEYWORD_DECL);
5859 TREE_TYPE (keyword_decl) = arg_type;
5860 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5861 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5863 return keyword_decl;
5866 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5869 build_keyword_selector (tree selector)
5872 tree key_chain, key_name;
5875 /* Scan the selector to see how much space we'll need. */
5876 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5878 if (TREE_CODE (selector) == KEYWORD_DECL)
5879 key_name = KEYWORD_KEY_NAME (key_chain);
5880 else if (TREE_CODE (selector) == TREE_LIST)
5881 key_name = TREE_PURPOSE (key_chain);
5886 len += IDENTIFIER_LENGTH (key_name) + 1;
5888 /* Just a ':' arg. */
5892 buf = (char *) alloca (len + 1);
5893 /* Start the buffer out as an empty string. */
5896 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5898 if (TREE_CODE (selector) == KEYWORD_DECL)
5899 key_name = KEYWORD_KEY_NAME (key_chain);
5900 else if (TREE_CODE (selector) == TREE_LIST)
5902 key_name = TREE_PURPOSE (key_chain);
5903 /* The keyword decl chain will later be used as a function argument
5904 chain. Unhook the selector itself so as to not confuse other
5905 parts of the compiler. */
5906 TREE_PURPOSE (key_chain) = NULL_TREE;
5912 strcat (buf, IDENTIFIER_POINTER (key_name));
5916 return get_identifier (buf);
5919 /* Used for declarations and definitions. */
5922 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5923 tree add_args, bool ellipsis)
5927 /* If no type is specified, default to "id". */
5928 ret_type = adjust_type_for_id_default (ret_type);
5930 method_decl = make_node (code);
5931 TREE_TYPE (method_decl) = ret_type;
5933 /* If we have a keyword selector, create an identifier_node that
5934 represents the full selector name (`:' included)... */
5935 if (TREE_CODE (selector) == KEYWORD_DECL)
5937 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5938 METHOD_SEL_ARGS (method_decl) = selector;
5939 METHOD_ADD_ARGS (method_decl) = add_args;
5940 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5944 METHOD_SEL_NAME (method_decl) = selector;
5945 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5946 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5952 #define METHOD_DEF 0
5953 #define METHOD_REF 1
5955 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5956 an argument list for method METH. CONTEXT is either METHOD_DEF or
5957 METHOD_REF, saying whether we are trying to define a method or call
5958 one. SUPERFLAG says this is for a send to super; this makes a
5959 difference for the NeXT calling sequence in which the lookup and
5960 the method call are done together. If METH is null, user-defined
5961 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5964 get_arg_type_list (tree meth, int context, int superflag)
5968 /* Receiver type. */
5969 if (flag_next_runtime && superflag)
5970 arglist = build_tree_list (NULL_TREE, objc_super_type);
5971 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5972 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5974 arglist = build_tree_list (NULL_TREE, objc_object_type);
5976 /* Selector type - will eventually change to `int'. */
5977 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5979 /* No actual method prototype given -- assume that remaining arguments
5984 /* Build a list of argument types. */
5985 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5987 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5989 /* Decay arrays and functions into pointers. */
5990 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5991 arg_type = build_pointer_type (TREE_TYPE (arg_type));
5992 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
5993 arg_type = build_pointer_type (arg_type);
5995 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5998 if (METHOD_ADD_ARGS (meth))
6000 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6001 akey; akey = TREE_CHAIN (akey))
6003 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6005 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6008 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6009 goto lack_of_ellipsis;
6014 chainon (arglist, OBJC_VOID_AT_END);
6021 check_duplicates (hash hsh, int methods, int is_class)
6023 tree meth = NULL_TREE;
6031 /* We have two or more methods with the same name but
6035 /* But just how different are those types? If
6036 -Wno-strict-selector-match is specified, we shall not
6037 complain if the differences are solely among types with
6038 identical size and alignment. */
6039 if (!warn_strict_selector_match)
6041 for (loop = hsh->list; loop; loop = loop->next)
6042 if (!comp_proto_with_proto (meth, loop->value, 0))
6049 warning (0, "multiple %s named %<%c%s%> found",
6050 methods ? "methods" : "selectors",
6051 (is_class ? '+' : '-'),
6052 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6054 warn_with_method (methods ? "using" : "found",
6055 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6059 for (loop = hsh->list; loop; loop = loop->next)
6060 warn_with_method ("also found",
6061 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6070 /* If RECEIVER is a class reference, return the identifier node for
6071 the referenced class. RECEIVER is created by objc_get_class_reference,
6072 so we check the exact form created depending on which runtimes are
6076 receiver_is_class_object (tree receiver, int self, int super)
6078 tree chain, exp, arg;
6080 /* The receiver is 'self' or 'super' in the context of a class method. */
6081 if (objc_method_context
6082 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6085 ? CLASS_SUPER_NAME (implementation_template)
6086 : CLASS_NAME (implementation_template));
6088 if (flag_next_runtime)
6090 /* The receiver is a variable created by
6091 build_class_reference_decl. */
6092 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6093 /* Look up the identifier. */
6094 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6095 if (TREE_PURPOSE (chain) == receiver)
6096 return TREE_VALUE (chain);
6099 /* The receiver is a function call that returns an id. Check if
6100 it is a call to objc_getClass, if so, pick up the class name. */
6101 if (TREE_CODE (receiver) == CALL_EXPR
6102 && (exp = TREE_OPERAND (receiver, 0))
6103 && TREE_CODE (exp) == ADDR_EXPR
6104 && (exp = TREE_OPERAND (exp, 0))
6105 && TREE_CODE (exp) == FUNCTION_DECL
6106 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6107 prototypes for objc_get_class(). Thankfully, they seem to share the
6108 same function type. */
6109 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6110 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6111 /* We have a call to objc_get_class/objc_getClass! */
6112 && (arg = TREE_OPERAND (receiver, 1))
6113 && TREE_CODE (arg) == TREE_LIST
6114 && (arg = TREE_VALUE (arg)))
6117 if (TREE_CODE (arg) == ADDR_EXPR
6118 && (arg = TREE_OPERAND (arg, 0))
6119 && TREE_CODE (arg) == STRING_CST)
6120 /* Finally, we have the class name. */
6121 return get_identifier (TREE_STRING_POINTER (arg));
6126 /* If we are currently building a message expr, this holds
6127 the identifier of the selector of the message. This is
6128 used when printing warnings about argument mismatches. */
6130 static tree current_objc_message_selector = 0;
6133 objc_message_selector (void)
6135 return current_objc_message_selector;
6138 /* Construct an expression for sending a message.
6139 MESS has the object to send to in TREE_PURPOSE
6140 and the argument list (including selector) in TREE_VALUE.
6142 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6143 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6146 objc_build_message_expr (tree mess)
6148 tree receiver = TREE_PURPOSE (mess);
6151 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6153 tree args = TREE_VALUE (mess);
6155 tree method_params = NULL_TREE;
6157 if (TREE_CODE (receiver) == ERROR_MARK)
6158 return error_mark_node;
6160 /* Obtain the full selector name. */
6161 if (TREE_CODE (args) == IDENTIFIER_NODE)
6162 /* A unary selector. */
6164 else if (TREE_CODE (args) == TREE_LIST)
6165 sel_name = build_keyword_selector (args);
6169 /* Build the parameter list to give to the method. */
6170 if (TREE_CODE (args) == TREE_LIST)
6172 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6175 tree chain = args, prev = NULL_TREE;
6177 /* We have a keyword selector--check for comma expressions. */
6180 tree element = TREE_VALUE (chain);
6182 /* We have a comma expression, must collapse... */
6183 if (TREE_CODE (element) == TREE_LIST)
6186 TREE_CHAIN (prev) = element;
6191 chain = TREE_CHAIN (chain);
6193 method_params = args;
6198 if (processing_template_decl)
6199 /* Must wait until template instantiation time. */
6200 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6204 return objc_finish_message_expr (receiver, sel_name, method_params);
6207 /* Look up method SEL_NAME that would be suitable for receiver
6208 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6209 nonzero), and report on any duplicates. */
6212 lookup_method_in_hash_lists (tree sel_name, int is_class)
6214 hash method_prototype = NULL;
6217 method_prototype = hash_lookup (nst_method_hash_list,
6220 if (!method_prototype)
6222 method_prototype = hash_lookup (cls_method_hash_list,
6227 return check_duplicates (method_prototype, 1, is_class);
6230 /* The 'objc_finish_message_expr' routine is called from within
6231 'objc_build_message_expr' for non-template functions. In the case of
6232 C++ template functions, it is called from 'build_expr_from_tree'
6233 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6236 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6238 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6239 tree selector, retval, class_tree;
6240 int self, super, have_cast;
6242 /* Extract the receiver of the message, as well as its type
6243 (where the latter may take the form of a cast or be inferred
6244 from the implementation context). */
6246 while (TREE_CODE (rtype) == COMPOUND_EXPR
6247 || TREE_CODE (rtype) == MODIFY_EXPR
6248 || TREE_CODE (rtype) == NOP_EXPR
6249 || TREE_CODE (rtype) == CONVERT_EXPR
6250 || TREE_CODE (rtype) == COMPONENT_REF)
6251 rtype = TREE_OPERAND (rtype, 0);
6252 self = (rtype == self_decl);
6253 super = (rtype == UOBJC_SUPER_decl);
6254 rtype = TREE_TYPE (receiver);
6255 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6256 || (TREE_CODE (receiver) == COMPOUND_EXPR
6257 && !IS_SUPER (rtype)));
6259 /* If we are calling [super dealloc], reset our warning flag. */
6260 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6261 should_call_super_dealloc = 0;
6263 /* If the receiver is a class object, retrieve the corresponding
6264 @interface, if one exists. */
6265 class_tree = receiver_is_class_object (receiver, self, super);
6267 /* Now determine the receiver type (if an explicit cast has not been
6272 rtype = lookup_interface (class_tree);
6273 /* Handle `self' and `super'. */
6276 if (!CLASS_SUPER_NAME (implementation_template))
6278 error ("no super class declared in @interface for %qs",
6279 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6280 return error_mark_node;
6282 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6285 rtype = lookup_interface (CLASS_NAME (implementation_template));
6288 /* If receiver is of type `id' or `Class' (or if the @interface for a
6289 class is not visible), we shall be satisfied with the existence of
6290 any instance or class method. */
6291 if (objc_is_id (rtype))
6293 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6294 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6295 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6301 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6302 in protocols themselves for the method prototype. */
6304 = lookup_method_in_protocol_list (rprotos, sel_name,
6305 class_tree != NULL_TREE);
6307 /* If messaging 'Class <Proto>' but did not find a class method
6308 prototype, search for an instance method instead, and warn
6309 about having done so. */
6310 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6313 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6315 if (method_prototype)
6316 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6317 IDENTIFIER_POINTER (sel_name),
6318 IDENTIFIER_POINTER (sel_name));
6324 tree orig_rtype = rtype, saved_rtype;
6326 if (TREE_CODE (rtype) == POINTER_TYPE)
6327 rtype = TREE_TYPE (rtype);
6328 /* Traverse typedef aliases */
6329 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6330 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6331 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6332 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6333 saved_rtype = rtype;
6334 if (TYPED_OBJECT (rtype))
6336 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6337 rtype = TYPE_OBJC_INTERFACE (rtype);
6339 /* If we could not find an @interface declaration, we must have
6340 only seen a @class declaration; so, we cannot say anything
6341 more intelligent about which methods the receiver will
6343 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6345 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6346 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6348 /* We have a valid ObjC class name. Look up the method name
6349 in the published @interface for the class (and its
6352 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6354 /* If the method was not found in the @interface, it may still
6355 exist locally as part of the @implementation. */
6356 if (!method_prototype && objc_implementation_context
6357 && CLASS_NAME (objc_implementation_context)
6358 == OBJC_TYPE_NAME (rtype))
6362 ? CLASS_CLS_METHODS (objc_implementation_context)
6363 : CLASS_NST_METHODS (objc_implementation_context)),
6366 /* If we haven't found a candidate method by now, try looking for
6367 it in the protocol list. */
6368 if (!method_prototype && rprotos)
6370 = lookup_method_in_protocol_list (rprotos, sel_name,
6371 class_tree != NULL_TREE);
6375 warning (0, "invalid receiver type %qs",
6376 gen_type_name (orig_rtype));
6377 /* After issuing the "invalid receiver" warning, perform method
6378 lookup as if we were messaging 'id'. */
6379 rtype = rprotos = NULL_TREE;
6384 /* For 'id' or 'Class' receivers, search in the global hash table
6385 as a last resort. For all receivers, warn if protocol searches
6387 if (!method_prototype)
6390 warning (0, "%<%c%s%> not found in protocol(s)",
6391 (class_tree ? '+' : '-'),
6392 IDENTIFIER_POINTER (sel_name));
6396 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6399 if (!method_prototype)
6401 static bool warn_missing_methods = false;
6404 warning (0, "%qs may not respond to %<%c%s%>",
6405 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6406 (class_tree ? '+' : '-'),
6407 IDENTIFIER_POINTER (sel_name));
6408 /* If we are messaging an 'id' or 'Class' object and made it here,
6409 then we have failed to find _any_ instance or class method,
6412 warning (0, "no %<%c%s%> method found",
6413 (class_tree ? '+' : '-'),
6414 IDENTIFIER_POINTER (sel_name));
6416 if (!warn_missing_methods)
6418 warning (0, "(Messages without a matching method signature");
6419 warning (0, "will be assumed to return %<id%> and accept");
6420 warning (0, "%<...%> as arguments.)");
6421 warn_missing_methods = true;
6425 /* Save the selector name for printing error messages. */
6426 current_objc_message_selector = sel_name;
6428 /* Build the parameters list for looking up the method.
6429 These are the object itself and the selector. */
6431 if (flag_typed_selectors)
6432 selector = build_typed_selector_reference (sel_name, method_prototype);
6434 selector = build_selector_reference (sel_name);
6436 retval = build_objc_method_call (super, method_prototype,
6438 selector, method_params);
6440 current_objc_message_selector = 0;
6445 /* Build a tree expression to send OBJECT the operation SELECTOR,
6446 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6447 assuming the method has prototype METHOD_PROTOTYPE.
6448 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6449 Use METHOD_PARAMS as list of args to pass to the method.
6450 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6453 build_objc_method_call (int super_flag, tree method_prototype,
6454 tree lookup_object, tree selector,
6457 tree sender = (super_flag ? umsg_super_decl :
6458 (!flag_next_runtime || flag_nil_receivers
6459 ? (flag_objc_direct_dispatch
6462 : umsg_nonnil_decl));
6463 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6465 /* If a prototype for the method to be called exists, then cast
6466 the sender's return type and arguments to match that of the method.
6467 Otherwise, leave sender as is. */
6470 ? TREE_VALUE (TREE_TYPE (method_prototype))
6471 : objc_object_type);
6473 = build_pointer_type
6474 (build_function_type
6477 (method_prototype, METHOD_REF, super_flag)));
6480 lookup_object = build_c_cast (rcv_p, lookup_object);
6482 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6483 lookup_object = save_expr (lookup_object);
6485 if (flag_next_runtime)
6487 /* If we are returning a struct in memory, and the address
6488 of that memory location is passed as a hidden first
6489 argument, then change which messenger entry point this
6490 expr will call. NB: Note that sender_cast remains
6491 unchanged (it already has a struct return type). */
6492 if (!targetm.calls.struct_value_rtx (0, 0)
6493 && (TREE_CODE (ret_type) == RECORD_TYPE
6494 || TREE_CODE (ret_type) == UNION_TYPE)
6495 && targetm.calls.return_in_memory (ret_type, 0))
6496 sender = (super_flag ? umsg_super_stret_decl :
6497 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6499 method_params = tree_cons (NULL_TREE, lookup_object,
6500 tree_cons (NULL_TREE, selector,
6502 method = build_fold_addr_expr (sender);
6506 /* This is the portable (GNU) way. */
6509 /* First, call the lookup function to get a pointer to the method,
6510 then cast the pointer, then call it with the method arguments. */
6512 object = (super_flag ? self_decl : lookup_object);
6514 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6515 t = tree_cons (NULL_TREE, lookup_object, t);
6516 method = build_function_call (sender, t);
6518 /* Pass the object to the method. */
6519 method_params = tree_cons (NULL_TREE, object,
6520 tree_cons (NULL_TREE, selector,
6524 /* ??? Selector is not at this point something we can use inside
6525 the compiler itself. Set it to garbage for the nonce. */
6526 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6527 return build_function_call (t, method_params);
6531 build_protocol_reference (tree p)
6534 const char *proto_name;
6536 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6538 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6539 decl = start_var_decl (objc_protocol_template, proto_name);
6541 PROTOCOL_FORWARD_DECL (p) = decl;
6544 /* This function is called by the parser when (and only when) a
6545 @protocol() expression is found, in order to compile it. */
6547 objc_build_protocol_expr (tree protoname)
6550 tree p = lookup_protocol (protoname);
6554 error ("cannot find protocol declaration for %qs",
6555 IDENTIFIER_POINTER (protoname));
6556 return error_mark_node;
6559 if (!PROTOCOL_FORWARD_DECL (p))
6560 build_protocol_reference (p);
6562 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6564 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6565 if we have it, rather than converting it here. */
6566 expr = convert (objc_protocol_type, expr);
6568 /* The @protocol() expression is being compiled into a pointer to a
6569 statically allocated instance of the Protocol class. To become
6570 usable at runtime, the 'isa' pointer of the instance need to be
6571 fixed up at runtime by the runtime library, to point to the
6572 actual 'Protocol' class. */
6574 /* For the GNU runtime, put the static Protocol instance in the list
6575 of statically allocated instances, so that we make sure that its
6576 'isa' pointer is fixed up at runtime by the GNU runtime library
6577 to point to the Protocol class (at runtime, when loading the
6578 module, the GNU runtime library loops on the statically allocated
6579 instances (as found in the defs field in objc_symtab) and fixups
6580 all the 'isa' pointers of those objects). */
6581 if (! flag_next_runtime)
6583 /* This type is a struct containing the fields of a Protocol
6584 object. (Cfr. objc_protocol_type instead is the type of a pointer
6585 to such a struct). */
6586 tree protocol_struct_type = xref_tag
6587 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6590 /* Look for the list of Protocol statically allocated instances
6591 to fixup at runtime. Create a new list to hold Protocol
6592 statically allocated instances, if the list is not found. At
6593 present there is only another list, holding NSConstantString
6594 static instances to be fixed up at runtime. */
6595 for (chain = &objc_static_instances;
6596 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6597 chain = &TREE_CHAIN (*chain));
6600 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6601 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6605 /* Add this statically allocated instance to the Protocol list. */
6606 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6607 PROTOCOL_FORWARD_DECL (p),
6608 TREE_PURPOSE (*chain));
6615 /* This function is called by the parser when a @selector() expression
6616 is found, in order to compile it. It is only called by the parser
6617 and only to compile a @selector(). */
6619 objc_build_selector_expr (tree selnamelist)
6623 /* Obtain the full selector name. */
6624 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6625 /* A unary selector. */
6626 selname = selnamelist;
6627 else if (TREE_CODE (selnamelist) == TREE_LIST)
6628 selname = build_keyword_selector (selnamelist);
6632 /* If we are required to check @selector() expressions as they
6633 are found, check that the selector has been declared. */
6634 if (warn_undeclared_selector)
6636 /* Look the selector up in the list of all known class and
6637 instance methods (up to this line) to check that the selector
6641 /* First try with instance methods. */
6642 hsh = hash_lookup (nst_method_hash_list, selname);
6644 /* If not found, try with class methods. */
6647 hsh = hash_lookup (cls_method_hash_list, selname);
6650 /* If still not found, print out a warning. */
6653 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6658 if (flag_typed_selectors)
6659 return build_typed_selector_reference (selname, 0);
6661 return build_selector_reference (selname);
6665 objc_build_encode_expr (tree type)
6670 encode_type (type, obstack_object_size (&util_obstack),
6671 OBJC_ENCODE_INLINE_DEFS);
6672 obstack_1grow (&util_obstack, 0); /* null terminate string */
6673 string = obstack_finish (&util_obstack);
6675 /* Synthesize a string that represents the encoded struct/union. */
6676 result = my_build_string (strlen (string) + 1, string);
6677 obstack_free (&util_obstack, util_firstobj);
6682 build_ivar_reference (tree id)
6684 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6686 /* Historically, a class method that produced objects (factory
6687 method) would assign `self' to the instance that it
6688 allocated. This would effectively turn the class method into
6689 an instance method. Following this assignment, the instance
6690 variables could be accessed. That practice, while safe,
6691 violates the simple rule that a class method should not refer
6692 to an instance variable. It's better to catch the cases
6693 where this is done unknowingly than to support the above
6695 warning (0, "instance variable %qs accessed in class method",
6696 IDENTIFIER_POINTER (id));
6697 self_decl = convert (objc_instance_type, self_decl); /* cast */
6700 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6703 /* Compute a hash value for a given method SEL_NAME. */
6706 hash_func (tree sel_name)
6708 const unsigned char *s
6709 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6713 h = h * 67 + *s++ - 113;
6720 nst_method_hash_list
6721 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6722 cls_method_hash_list
6723 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6725 /* Initialize the hash table used to hold the constant string objects. */
6726 string_htab = htab_create_ggc (31, string_hash,
6729 /* Initialize the hash table used to hold EH-volatilized types. */
6730 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6731 volatilized_eq, NULL);
6734 /* WARNING!!!! hash_enter is called with a method, and will peek
6735 inside to find its selector! But hash_lookup is given a selector
6736 directly, and looks for the selector that's inside the found
6737 entry's key (method) for comparison. */
6740 hash_enter (hash *hashlist, tree method)
6743 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6745 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6747 obj->next = hashlist[slot];
6750 hashlist[slot] = obj; /* append to front */
6754 hash_lookup (hash *hashlist, tree sel_name)
6758 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6762 if (sel_name == METHOD_SEL_NAME (target->key))
6765 target = target->next;
6771 hash_add_attr (hash entry, tree value)
6775 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6776 obj->next = entry->list;
6779 entry->list = obj; /* append to front */
6783 lookup_method (tree mchain, tree method)
6787 if (TREE_CODE (method) == IDENTIFIER_NODE)
6790 key = METHOD_SEL_NAME (method);
6794 if (METHOD_SEL_NAME (mchain) == key)
6797 mchain = TREE_CHAIN (mchain);
6802 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6803 in INTERFACE, along with any categories and protocols attached thereto.
6804 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6805 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6806 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6807 be found in INTERFACE or any of its superclasses, look for an _instance_
6808 method of the same name in the root class as a last resort.
6810 If a suitable method cannot be found, return NULL_TREE. */
6813 lookup_method_static (tree interface, tree ident, int flags)
6815 tree meth = NULL_TREE, root_inter = NULL_TREE;
6816 tree inter = interface;
6817 int is_class = (flags & OBJC_LOOKUP_CLASS);
6818 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6822 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6823 tree category = inter;
6825 /* First, look up the method in the class itself. */
6826 if ((meth = lookup_method (chain, ident)))
6829 /* Failing that, look for the method in each category of the class. */
6830 while ((category = CLASS_CATEGORY_LIST (category)))
6832 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6834 /* Check directly in each category. */
6835 if ((meth = lookup_method (chain, ident)))
6838 /* Failing that, check in each category's protocols. */
6839 if (CLASS_PROTOCOL_LIST (category))
6841 if ((meth = (lookup_method_in_protocol_list
6842 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6847 /* If not found in categories, check in protocols of the main class. */
6848 if (CLASS_PROTOCOL_LIST (inter))
6850 if ((meth = (lookup_method_in_protocol_list
6851 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6855 /* If we were instructed not to look in superclasses, don't. */
6856 if (no_superclasses)
6859 /* Failing that, climb up the inheritance hierarchy. */
6861 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6865 /* If no class (factory) method was found, check if an _instance_
6866 method of the same name exists in the root class. This is what
6867 the Objective-C runtime will do. If an instance method was not
6869 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6872 /* Add the method to the hash list if it doesn't contain an identical
6875 add_method_to_hash_list (hash *hash_list, tree method)
6879 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6881 /* Install on a global chain. */
6882 hash_enter (hash_list, method);
6886 /* Check types against those; if different, add to a list. */
6888 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6889 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6890 already_there |= comp_proto_with_proto (method, loop->value, 1);
6892 hash_add_attr (hsh, method);
6897 objc_add_method (tree class, tree method, int is_class)
6901 if (!(mth = lookup_method (is_class
6902 ? CLASS_CLS_METHODS (class)
6903 : CLASS_NST_METHODS (class), method)))
6905 /* put method on list in reverse order */
6908 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6909 CLASS_CLS_METHODS (class) = method;
6913 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6914 CLASS_NST_METHODS (class) = method;
6919 /* When processing an @interface for a class or category, give hard
6920 errors on methods with identical selectors but differing argument
6921 and/or return types. We do not do this for @implementations, because
6922 C/C++ will do it for us (i.e., there will be duplicate function
6923 definition errors). */
6924 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6925 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6926 && !comp_proto_with_proto (method, mth, 1))
6927 error ("duplicate declaration of method %<%c%s%>",
6928 is_class ? '+' : '-',
6929 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6933 add_method_to_hash_list (cls_method_hash_list, method);
6936 add_method_to_hash_list (nst_method_hash_list, method);
6938 /* Instance methods in root classes (and categories thereof)
6939 may act as class methods as a last resort. We also add
6940 instance methods listed in @protocol declarations to
6941 the class hash table, on the assumption that @protocols
6942 may be adopted by root classes or categories. */
6943 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6944 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6945 class = lookup_interface (CLASS_NAME (class));
6947 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6948 || !CLASS_SUPER_NAME (class))
6949 add_method_to_hash_list (cls_method_hash_list, method);
6956 add_class (tree class_name, tree name)
6958 struct interface_tuple **slot;
6960 /* Put interfaces on list in reverse order. */
6961 TREE_CHAIN (class_name) = interface_chain;
6962 interface_chain = class_name;
6964 if (interface_htab == NULL)
6965 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6966 slot = (struct interface_tuple **)
6967 htab_find_slot_with_hash (interface_htab, name,
6968 htab_hash_pointer (name),
6972 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6975 (*slot)->class_name = class_name;
6977 return interface_chain;
6981 add_category (tree class, tree category)
6983 /* Put categories on list in reverse order. */
6984 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6988 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
6989 IDENTIFIER_POINTER (CLASS_NAME (class)),
6990 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6994 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6995 CLASS_CATEGORY_LIST (class) = category;
6999 /* Called after parsing each instance variable declaration. Necessary to
7000 preserve typedefs and implement public/private...
7002 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7005 add_instance_variable (tree class, int public, tree field_decl)
7007 tree field_type = TREE_TYPE (field_decl);
7008 const char *ivar_name = DECL_NAME (field_decl)
7009 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7013 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7015 error ("illegal reference type specified for instance variable %qs",
7017 /* Return class as is without adding this ivar. */
7022 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7023 || TYPE_SIZE (field_type) == error_mark_node)
7024 /* 'type[0]' is allowed, but 'type[]' is not! */
7026 error ("instance variable %qs has unknown size", ivar_name);
7027 /* Return class as is without adding this ivar. */
7032 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7033 need to either (1) warn the user about it or (2) generate suitable
7034 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7035 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7036 if (IS_AGGR_TYPE (field_type)
7037 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7038 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7039 || TYPE_POLYMORPHIC_P (field_type)))
7041 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7043 if (flag_objc_call_cxx_cdtors)
7045 /* Since the ObjC runtime will be calling the constructors and
7046 destructors for us, the only thing we can't handle is the lack
7047 of a default constructor. */
7048 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7049 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7051 warning (0, "type %qs has no default constructor to call",
7054 /* If we cannot call a constructor, we should also avoid
7055 calling the destructor, for symmetry. */
7056 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7057 warning (0, "destructor for %qs shall not be run either",
7063 static bool warn_cxx_ivars = false;
7065 if (TYPE_POLYMORPHIC_P (field_type))
7067 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7069 error ("type %qs has virtual member functions", type_name);
7070 error ("illegal aggregate type %qs specified "
7071 "for instance variable %qs",
7072 type_name, ivar_name);
7073 /* Return class as is without adding this ivar. */
7077 /* User-defined constructors and destructors are not known to Obj-C
7078 and hence will not be called. This may or may not be a problem. */
7079 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7080 warning (0, "type %qs has a user-defined constructor", type_name);
7081 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7082 warning (0, "type %qs has a user-defined destructor", type_name);
7084 if (!warn_cxx_ivars)
7086 warning (0, "C++ constructors and destructors will not "
7087 "be invoked for Objective-C fields");
7088 warn_cxx_ivars = true;
7094 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7098 TREE_PUBLIC (field_decl) = 0;
7099 TREE_PRIVATE (field_decl) = 0;
7100 TREE_PROTECTED (field_decl) = 1;
7104 TREE_PUBLIC (field_decl) = 1;
7105 TREE_PRIVATE (field_decl) = 0;
7106 TREE_PROTECTED (field_decl) = 0;
7110 TREE_PUBLIC (field_decl) = 0;
7111 TREE_PRIVATE (field_decl) = 1;
7112 TREE_PROTECTED (field_decl) = 0;
7117 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7123 is_ivar (tree decl_chain, tree ident)
7125 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7126 if (DECL_NAME (decl_chain) == ident)
7131 /* True if the ivar is private and we are not in its implementation. */
7134 is_private (tree decl)
7136 return (TREE_PRIVATE (decl)
7137 && ! is_ivar (CLASS_IVARS (implementation_template),
7141 /* We have an instance variable reference;, check to see if it is public. */
7144 objc_is_public (tree expr, tree identifier)
7146 tree basetype, decl;
7149 if (processing_template_decl)
7153 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7155 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7157 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7159 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7163 error ("cannot find interface declaration for %qs",
7164 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7168 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7170 if (TREE_PUBLIC (decl))
7173 /* Important difference between the Stepstone translator:
7174 all instance variables should be public within the context
7175 of the implementation. */
7176 if (objc_implementation_context
7177 && ((TREE_CODE (objc_implementation_context)
7178 == CLASS_IMPLEMENTATION_TYPE)
7179 || (TREE_CODE (objc_implementation_context)
7180 == CATEGORY_IMPLEMENTATION_TYPE)))
7182 tree curtype = TYPE_MAIN_VARIANT
7183 (CLASS_STATIC_TEMPLATE
7184 (implementation_template));
7186 if (basetype == curtype
7187 || DERIVED_FROM_P (basetype, curtype))
7189 int private = is_private (decl);
7192 error ("instance variable %qs is declared private",
7193 IDENTIFIER_POINTER (DECL_NAME (decl)));
7199 /* The 2.95.2 compiler sometimes allowed C functions to access
7200 non-@public ivars. We will let this slide for now... */
7201 if (!objc_method_context)
7203 warning (0, "instance variable %qs is %s; "
7204 "this will be a hard error in the future",
7205 IDENTIFIER_POINTER (identifier),
7206 TREE_PRIVATE (decl) ? "@private" : "@protected");
7210 error ("instance variable %qs is declared %s",
7211 IDENTIFIER_POINTER (identifier),
7212 TREE_PRIVATE (decl) ? "private" : "protected");
7221 /* Make sure all entries in CHAIN are also in LIST. */
7224 check_methods (tree chain, tree list, int mtype)
7230 if (!lookup_method (list, chain))
7234 if (TREE_CODE (objc_implementation_context)
7235 == CLASS_IMPLEMENTATION_TYPE)
7236 warning (0, "incomplete implementation of class %qs",
7237 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7238 else if (TREE_CODE (objc_implementation_context)
7239 == CATEGORY_IMPLEMENTATION_TYPE)
7240 warning (0, "incomplete implementation of category %qs",
7241 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7245 warning (0, "method definition for %<%c%s%> not found",
7246 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7249 chain = TREE_CHAIN (chain);
7255 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7258 conforms_to_protocol (tree class, tree protocol)
7260 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7262 tree p = CLASS_PROTOCOL_LIST (class);
7263 while (p && TREE_VALUE (p) != protocol)
7268 tree super = (CLASS_SUPER_NAME (class)
7269 ? lookup_interface (CLASS_SUPER_NAME (class))
7271 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7280 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7281 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7284 check_methods_accessible (tree chain, tree context, int mtype)
7288 tree base_context = context;
7292 context = base_context;
7296 list = CLASS_CLS_METHODS (context);
7298 list = CLASS_NST_METHODS (context);
7300 if (lookup_method (list, chain))
7303 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7304 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7305 context = (CLASS_SUPER_NAME (context)
7306 ? lookup_interface (CLASS_SUPER_NAME (context))
7309 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7310 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7311 context = (CLASS_NAME (context)
7312 ? lookup_interface (CLASS_NAME (context))
7318 if (context == NULL_TREE)
7322 if (TREE_CODE (objc_implementation_context)
7323 == CLASS_IMPLEMENTATION_TYPE)
7324 warning (0, "incomplete implementation of class %qs",
7326 (CLASS_NAME (objc_implementation_context)));
7327 else if (TREE_CODE (objc_implementation_context)
7328 == CATEGORY_IMPLEMENTATION_TYPE)
7329 warning (0, "incomplete implementation of category %qs",
7331 (CLASS_SUPER_NAME (objc_implementation_context)));
7334 warning (0, "method definition for %<%c%s%> not found",
7335 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7338 chain = TREE_CHAIN (chain); /* next method... */
7343 /* Check whether the current interface (accessible via
7344 'objc_implementation_context') actually implements protocol P, along
7345 with any protocols that P inherits. */
7348 check_protocol (tree p, const char *type, const char *name)
7350 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7354 /* Ensure that all protocols have bodies! */
7357 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7358 CLASS_CLS_METHODS (objc_implementation_context),
7360 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7361 CLASS_NST_METHODS (objc_implementation_context),
7366 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7367 objc_implementation_context,
7369 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7370 objc_implementation_context,
7375 warning (0, "%s %qs does not fully implement the %qs protocol",
7376 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7379 /* Check protocols recursively. */
7380 if (PROTOCOL_LIST (p))
7382 tree subs = PROTOCOL_LIST (p);
7384 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7388 tree sub = TREE_VALUE (subs);
7390 /* If the superclass does not conform to the protocols
7391 inherited by P, then we must! */
7392 if (!super_class || !conforms_to_protocol (super_class, sub))
7393 check_protocol (sub, type, name);
7394 subs = TREE_CHAIN (subs);
7399 /* Check whether the current interface (accessible via
7400 'objc_implementation_context') actually implements the protocols listed
7404 check_protocols (tree proto_list, const char *type, const char *name)
7406 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7408 tree p = TREE_VALUE (proto_list);
7410 check_protocol (p, type, name);
7414 /* Make sure that the class CLASS_NAME is defined
7415 CODE says which kind of thing CLASS_NAME ought to be.
7416 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7417 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7420 start_class (enum tree_code code, tree class_name, tree super_name,
7426 if (current_namespace != global_namespace) {
7427 error ("Objective-C declarations may only appear in global scope");
7429 #endif /* OBJCPLUS */
7431 if (objc_implementation_context)
7433 warning (0, "%<@end%> missing in implementation context");
7434 finish_class (objc_implementation_context);
7435 objc_ivar_chain = NULL_TREE;
7436 objc_implementation_context = NULL_TREE;
7439 class = make_node (code);
7440 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7442 /* Check for existence of the super class, if one was specified. Note
7443 that we must have seen an @interface, not just a @class. If we
7444 are looking at a @compatibility_alias, traverse it first. */
7445 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7448 tree super = objc_is_class_name (super_name);
7450 if (!super || !lookup_interface (super))
7452 error ("cannot find interface declaration for %qs, superclass of %qs",
7453 IDENTIFIER_POINTER (super ? super : super_name),
7454 IDENTIFIER_POINTER (class_name));
7455 super_name = NULL_TREE;
7461 CLASS_NAME (class) = class_name;
7462 CLASS_SUPER_NAME (class) = super_name;
7463 CLASS_CLS_METHODS (class) = NULL_TREE;
7465 if (! objc_is_class_name (class_name)
7466 && (decl = lookup_name (class_name)))
7468 error ("%qs redeclared as different kind of symbol",
7469 IDENTIFIER_POINTER (class_name));
7470 error ("previous declaration of %q+D",
7474 if (code == CLASS_IMPLEMENTATION_TYPE)
7479 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7480 if (TREE_VALUE (chain) == class_name)
7482 error ("reimplementation of class %qs",
7483 IDENTIFIER_POINTER (class_name));
7484 return error_mark_node;
7486 implemented_classes = tree_cons (NULL_TREE, class_name,
7487 implemented_classes);
7490 /* Reset for multiple classes per file. */
7493 objc_implementation_context = class;
7495 /* Lookup the interface for this implementation. */
7497 if (!(implementation_template = lookup_interface (class_name)))
7499 warning (0, "cannot find interface declaration for %qs",
7500 IDENTIFIER_POINTER (class_name));
7501 add_class (implementation_template = objc_implementation_context,
7505 /* If a super class has been specified in the implementation,
7506 insure it conforms to the one specified in the interface. */
7509 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7511 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7512 const char *const name =
7513 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7514 error ("conflicting super class name %qs",
7515 IDENTIFIER_POINTER (super_name));
7516 error ("previous declaration of %qs", name);
7519 else if (! super_name)
7521 CLASS_SUPER_NAME (objc_implementation_context)
7522 = CLASS_SUPER_NAME (implementation_template);
7526 else if (code == CLASS_INTERFACE_TYPE)
7528 if (lookup_interface (class_name))
7530 error ("duplicate interface declaration for class %qs",
7532 warning (0, "duplicate interface declaration for class %qs",
7534 IDENTIFIER_POINTER (class_name));
7536 add_class (class, class_name);
7539 CLASS_PROTOCOL_LIST (class)
7540 = lookup_and_install_protocols (protocol_list);
7543 else if (code == CATEGORY_INTERFACE_TYPE)
7545 tree class_category_is_assoc_with;
7547 /* For a category, class_name is really the name of the class that
7548 the following set of methods will be associated with. We must
7549 find the interface so that can derive the objects template. */
7551 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7553 error ("cannot find interface declaration for %qs",
7554 IDENTIFIER_POINTER (class_name));
7555 exit (FATAL_EXIT_CODE);
7558 add_category (class_category_is_assoc_with, class);
7561 CLASS_PROTOCOL_LIST (class)
7562 = lookup_and_install_protocols (protocol_list);
7565 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7567 /* Reset for multiple classes per file. */
7570 objc_implementation_context = class;
7572 /* For a category, class_name is really the name of the class that
7573 the following set of methods will be associated with. We must
7574 find the interface so that can derive the objects template. */
7576 if (!(implementation_template = lookup_interface (class_name)))
7578 error ("cannot find interface declaration for %qs",
7579 IDENTIFIER_POINTER (class_name));
7580 exit (FATAL_EXIT_CODE);
7587 continue_class (tree class)
7589 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7590 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7592 struct imp_entry *imp_entry;
7594 /* Check consistency of the instance variables. */
7596 if (CLASS_RAW_IVARS (class))
7597 check_ivars (implementation_template, class);
7599 /* code generation */
7602 push_lang_context (lang_name_c);
7605 build_private_template (implementation_template);
7606 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7607 objc_instance_type = build_pointer_type (uprivate_record);
7609 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7611 imp_entry->next = imp_list;
7612 imp_entry->imp_context = class;
7613 imp_entry->imp_template = implementation_template;
7615 synth_forward_declarations ();
7616 imp_entry->class_decl = UOBJC_CLASS_decl;
7617 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7618 imp_entry->has_cxx_cdtors = 0;
7620 /* Append to front and increment count. */
7621 imp_list = imp_entry;
7622 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7628 pop_lang_context ();
7629 #endif /* OBJCPLUS */
7631 return get_class_ivars (implementation_template, true);
7634 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7637 push_lang_context (lang_name_c);
7638 #endif /* OBJCPLUS */
7640 build_private_template (class);
7643 pop_lang_context ();
7644 #endif /* OBJCPLUS */
7650 return error_mark_node;
7653 /* This is called once we see the "@end" in an interface/implementation. */
7656 finish_class (tree class)
7658 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7660 /* All code generation is done in finish_objc. */
7662 if (implementation_template != objc_implementation_context)
7664 /* Ensure that all method listed in the interface contain bodies. */
7665 check_methods (CLASS_CLS_METHODS (implementation_template),
7666 CLASS_CLS_METHODS (objc_implementation_context), '+');
7667 check_methods (CLASS_NST_METHODS (implementation_template),
7668 CLASS_NST_METHODS (objc_implementation_context), '-');
7670 if (CLASS_PROTOCOL_LIST (implementation_template))
7671 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7673 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7677 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7679 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7683 /* Ensure all method listed in the interface contain bodies. */
7684 check_methods (CLASS_CLS_METHODS (category),
7685 CLASS_CLS_METHODS (objc_implementation_context), '+');
7686 check_methods (CLASS_NST_METHODS (category),
7687 CLASS_NST_METHODS (objc_implementation_context), '-');
7689 if (CLASS_PROTOCOL_LIST (category))
7690 check_protocols (CLASS_PROTOCOL_LIST (category),
7692 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7698 add_protocol (tree protocol)
7700 /* Put protocol on list in reverse order. */
7701 TREE_CHAIN (protocol) = protocol_chain;
7702 protocol_chain = protocol;
7703 return protocol_chain;
7707 lookup_protocol (tree ident)
7711 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7712 if (ident == PROTOCOL_NAME (chain))
7718 /* This function forward declares the protocols named by NAMES. If
7719 they are already declared or defined, the function has no effect. */
7722 objc_declare_protocols (tree names)
7727 if (current_namespace != global_namespace) {
7728 error ("Objective-C declarations may only appear in global scope");
7730 #endif /* OBJCPLUS */
7732 for (list = names; list; list = TREE_CHAIN (list))
7734 tree name = TREE_VALUE (list);
7736 if (lookup_protocol (name) == NULL_TREE)
7738 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7740 TYPE_LANG_SLOT_1 (protocol)
7741 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7742 PROTOCOL_NAME (protocol) = name;
7743 PROTOCOL_LIST (protocol) = NULL_TREE;
7744 add_protocol (protocol);
7745 PROTOCOL_DEFINED (protocol) = 0;
7746 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7752 start_protocol (enum tree_code code, tree name, tree list)
7757 if (current_namespace != global_namespace) {
7758 error ("Objective-C declarations may only appear in global scope");
7760 #endif /* OBJCPLUS */
7762 protocol = lookup_protocol (name);
7766 protocol = make_node (code);
7767 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7769 PROTOCOL_NAME (protocol) = name;
7770 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7771 add_protocol (protocol);
7772 PROTOCOL_DEFINED (protocol) = 1;
7773 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7775 check_protocol_recursively (protocol, list);
7777 else if (! PROTOCOL_DEFINED (protocol))
7779 PROTOCOL_DEFINED (protocol) = 1;
7780 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7782 check_protocol_recursively (protocol, list);
7786 warning (0, "duplicate declaration for protocol %qs",
7787 IDENTIFIER_POINTER (name));
7793 /* "Encode" a data type into a string, which grows in util_obstack.
7794 ??? What is the FORMAT? Someone please document this! */
7797 encode_type_qualifiers (tree declspecs)
7801 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7803 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7804 obstack_1grow (&util_obstack, 'n');
7805 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7806 obstack_1grow (&util_obstack, 'N');
7807 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7808 obstack_1grow (&util_obstack, 'o');
7809 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7810 obstack_1grow (&util_obstack, 'O');
7811 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7812 obstack_1grow (&util_obstack, 'R');
7813 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7814 obstack_1grow (&util_obstack, 'V');
7818 /* Encode a pointer type. */
7821 encode_pointer (tree type, int curtype, int format)
7823 tree pointer_to = TREE_TYPE (type);
7825 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7827 if (OBJC_TYPE_NAME (pointer_to)
7828 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7830 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7832 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7834 obstack_1grow (&util_obstack, '@');
7837 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7838 && TYPE_OBJC_INTERFACE (pointer_to))
7840 if (generating_instance_variables)
7842 obstack_1grow (&util_obstack, '@');
7843 obstack_1grow (&util_obstack, '"');
7844 obstack_grow (&util_obstack, name, strlen (name));
7845 obstack_1grow (&util_obstack, '"');
7850 obstack_1grow (&util_obstack, '@');
7854 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7856 obstack_1grow (&util_obstack, '#');
7859 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7861 obstack_1grow (&util_obstack, ':');
7866 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7867 && TYPE_MODE (pointer_to) == QImode)
7869 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7870 ? OBJC_TYPE_NAME (pointer_to)
7871 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7873 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7875 /* It appears that "r*" means "const char *" rather than
7877 if (TYPE_READONLY (pointer_to))
7878 obstack_1grow (&util_obstack, 'r');
7880 obstack_1grow (&util_obstack, '*');
7885 /* We have a type that does not get special treatment. */
7887 /* NeXT extension */
7888 obstack_1grow (&util_obstack, '^');
7889 encode_type (pointer_to, curtype, format);
7893 encode_array (tree type, int curtype, int format)
7895 tree an_int_cst = TYPE_SIZE (type);
7896 tree array_of = TREE_TYPE (type);
7899 /* An incomplete array is treated like a pointer. */
7900 if (an_int_cst == NULL)
7902 encode_pointer (type, curtype, format);
7906 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7907 (TREE_INT_CST_LOW (an_int_cst)
7908 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7910 obstack_grow (&util_obstack, buffer, strlen (buffer));
7911 encode_type (array_of, curtype, format);
7912 obstack_1grow (&util_obstack, ']');
7917 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7919 tree field = TYPE_FIELDS (type);
7921 for (; field; field = TREE_CHAIN (field))
7924 /* C++ static members, and things that are not field at all,
7925 should not appear in the encoding. */
7926 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7930 /* Recursively encode fields of embedded base classes. */
7931 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7932 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7934 encode_aggregate_fields (TREE_TYPE (field),
7935 pointed_to, curtype, format);
7939 if (generating_instance_variables && !pointed_to)
7941 tree fname = DECL_NAME (field);
7943 obstack_1grow (&util_obstack, '"');
7945 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7946 obstack_grow (&util_obstack,
7947 IDENTIFIER_POINTER (fname),
7948 strlen (IDENTIFIER_POINTER (fname)));
7950 obstack_1grow (&util_obstack, '"');
7953 encode_field_decl (field, curtype, format);
7958 encode_aggregate_within (tree type, int curtype, int format, int left,
7962 /* NB: aggregates that are pointed to have slightly different encoding
7963 rules in that you never encode the names of instance variables. */
7964 int ob_size = obstack_object_size (&util_obstack);
7965 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7966 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7967 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7969 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7970 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7972 /* Traverse struct aliases; it is important to get the
7973 original struct and its tag name (if any). */
7974 type = TYPE_MAIN_VARIANT (type);
7975 name = OBJC_TYPE_NAME (type);
7976 /* Open parenth/bracket. */
7977 obstack_1grow (&util_obstack, left);
7979 /* Encode the struct/union tag name, or '?' if a tag was
7980 not provided. Typedef aliases do not qualify. */
7981 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7983 /* Did this struct have a tag? */
7984 && !TYPE_WAS_ANONYMOUS (type)
7987 obstack_grow (&util_obstack,
7988 IDENTIFIER_POINTER (name),
7989 strlen (IDENTIFIER_POINTER (name)));
7991 obstack_1grow (&util_obstack, '?');
7993 /* Encode the types (and possibly names) of the inner fields,
7995 if (inline_contents)
7997 obstack_1grow (&util_obstack, '=');
7998 encode_aggregate_fields (type, pointed_to, curtype, format);
8000 /* Close parenth/bracket. */
8001 obstack_1grow (&util_obstack, right);
8005 encode_aggregate (tree type, int curtype, int format)
8007 enum tree_code code = TREE_CODE (type);
8013 encode_aggregate_within (type, curtype, format, '{', '}');
8018 encode_aggregate_within (type, curtype, format, '(', ')');
8023 obstack_1grow (&util_obstack, 'i');
8031 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8035 encode_next_bitfield (int width)
8038 sprintf (buffer, "b%d", width);
8039 obstack_grow (&util_obstack, buffer, strlen (buffer));
8042 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8044 encode_type (tree type, int curtype, int format)
8046 enum tree_code code = TREE_CODE (type);
8049 if (TYPE_READONLY (type))
8050 obstack_1grow (&util_obstack, 'r');
8052 if (code == INTEGER_TYPE)
8054 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8056 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8057 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8059 if (type == long_unsigned_type_node
8060 || type == long_integer_type_node)
8061 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8063 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8065 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8068 obstack_1grow (&util_obstack, c);
8071 else if (code == REAL_TYPE)
8073 /* Floating point types. */
8074 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8076 case 32: c = 'f'; break;
8079 case 128: c = 'd'; break;
8082 obstack_1grow (&util_obstack, c);
8085 else if (code == VOID_TYPE)
8086 obstack_1grow (&util_obstack, 'v');
8088 else if (code == BOOLEAN_TYPE)
8089 obstack_1grow (&util_obstack, 'B');
8091 else if (code == ARRAY_TYPE)
8092 encode_array (type, curtype, format);
8094 else if (code == POINTER_TYPE)
8095 encode_pointer (type, curtype, format);
8097 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8098 encode_aggregate (type, curtype, format);
8100 else if (code == FUNCTION_TYPE) /* '?' */
8101 obstack_1grow (&util_obstack, '?');
8105 encode_gnu_bitfield (int position, tree type, int size)
8107 enum tree_code code = TREE_CODE (type);
8109 char charType = '?';
8111 if (code == INTEGER_TYPE)
8113 if (integer_zerop (TYPE_MIN_VALUE (type)))
8115 /* Unsigned integer types. */
8117 if (TYPE_MODE (type) == QImode)
8119 else if (TYPE_MODE (type) == HImode)
8121 else if (TYPE_MODE (type) == SImode)
8123 if (type == long_unsigned_type_node)
8128 else if (TYPE_MODE (type) == DImode)
8133 /* Signed integer types. */
8135 if (TYPE_MODE (type) == QImode)
8137 else if (TYPE_MODE (type) == HImode)
8139 else if (TYPE_MODE (type) == SImode)
8141 if (type == long_integer_type_node)
8147 else if (TYPE_MODE (type) == DImode)
8151 else if (code == ENUMERAL_TYPE)
8156 sprintf (buffer, "b%d%c%d", position, charType, size);
8157 obstack_grow (&util_obstack, buffer, strlen (buffer));
8161 encode_field_decl (tree field_decl, int curtype, int format)
8166 /* C++ static members, and things that are not fields at all,
8167 should not appear in the encoding. */
8168 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8172 type = TREE_TYPE (field_decl);
8174 /* Generate the bitfield typing information, if needed. Note the difference
8175 between GNU and NeXT runtimes. */
8176 if (DECL_BIT_FIELD_TYPE (field_decl))
8178 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8180 if (flag_next_runtime)
8181 encode_next_bitfield (size);
8183 encode_gnu_bitfield (int_bit_position (field_decl),
8184 DECL_BIT_FIELD_TYPE (field_decl), size);
8187 encode_type (TREE_TYPE (field_decl), curtype, format);
8190 static GTY(()) tree objc_parmlist = NULL_TREE;
8192 /* Append PARM to a list of formal parameters of a method, making a necessary
8193 array-to-pointer adjustment along the way. */
8196 objc_push_parm (tree parm)
8198 /* Decay arrays and functions into pointers. */
8199 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8200 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8201 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8202 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8204 DECL_ARG_TYPE (parm)
8205 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8207 /* Record constancy and volatility. */
8208 c_apply_type_quals_to_decl
8209 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8210 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8211 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8213 objc_parmlist = chainon (objc_parmlist, parm);
8216 /* Retrieve the formal parameter list constructed via preceding calls to
8217 objc_push_parm(). */
8221 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8223 static struct c_arg_info *
8224 objc_get_parm_info (int have_ellipsis)
8228 tree parm_info = objc_parmlist;
8229 objc_parmlist = NULL_TREE;
8233 tree parm_info = objc_parmlist;
8234 struct c_arg_info *arg_info;
8235 /* The C front-end requires an elaborate song and dance at
8238 declare_parm_level ();
8241 tree next = TREE_CHAIN (parm_info);
8243 TREE_CHAIN (parm_info) = NULL_TREE;
8244 parm_info = pushdecl (parm_info);
8245 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8248 arg_info = get_parm_info (have_ellipsis);
8250 objc_parmlist = NULL_TREE;
8255 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8256 method definitions. In the case of instance methods, we can be more
8257 specific as to the type of 'self'. */
8260 synth_self_and_ucmd_args (void)
8264 if (objc_method_context
8265 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8266 self_type = objc_instance_type;
8268 /* Really a `struct objc_class *'. However, we allow people to
8269 assign to self, which changes its type midstream. */
8270 self_type = objc_object_type;
8273 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8276 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8279 /* Transform an Objective-C method definition into a static C function
8280 definition, synthesizing the first two arguments, "self" and "_cmd",
8284 start_method_def (tree method)
8290 struct c_arg_info *parm_info;
8292 int have_ellipsis = 0;
8294 /* If we are defining a "dealloc" method in a non-root class, we
8295 will need to check if a [super dealloc] is missing, and warn if
8297 if(CLASS_SUPER_NAME (objc_implementation_context)
8298 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8299 should_call_super_dealloc = 1;
8301 should_call_super_dealloc = 0;
8303 /* Required to implement _msgSuper. */
8304 objc_method_context = method;
8305 UOBJC_SUPER_decl = NULL_TREE;
8307 /* Generate prototype declarations for arguments..."new-style". */
8308 synth_self_and_ucmd_args ();
8310 /* Generate argument declarations if a keyword_decl. */
8311 parmlist = METHOD_SEL_ARGS (method);
8314 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8316 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8317 objc_push_parm (parm);
8318 parmlist = TREE_CHAIN (parmlist);
8321 if (METHOD_ADD_ARGS (method))
8325 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8326 akey; akey = TREE_CHAIN (akey))
8328 objc_push_parm (TREE_VALUE (akey));
8331 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8335 parm_info = objc_get_parm_info (have_ellipsis);
8337 really_start_method (objc_method_context, parm_info);
8341 warn_with_method (const char *message, int mtype, tree method)
8343 /* Add a readable method name to the warning. */
8344 warning (0, "%J%s %<%c%s%>", method,
8345 message, mtype, gen_method_decl (method));
8348 /* Return 1 if TYPE1 is equivalent to TYPE2
8349 for purposes of method overloading. */
8352 objc_types_are_equivalent (tree type1, tree type2)
8357 /* Strip away indirections. */
8358 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8359 && (TREE_CODE (type1) == TREE_CODE (type2)))
8360 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8361 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8364 type1 = (TYPE_HAS_OBJC_INFO (type1)
8365 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8367 type2 = (TYPE_HAS_OBJC_INFO (type2)
8368 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8371 if (list_length (type1) == list_length (type2))
8373 for (; type2; type2 = TREE_CHAIN (type2))
8374 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8381 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8384 objc_types_share_size_and_alignment (tree type1, tree type2)
8386 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8387 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8390 /* Return 1 if PROTO1 is equivalent to PROTO2
8391 for purposes of method overloading. Ordinarily, the type signatures
8392 should match up exactly, unless STRICT is zero, in which case we
8393 shall allow differences in which the size and alignment of a type
8397 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8401 /* The following test is needed in case there are hashing
8403 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8406 /* Compare return types. */
8407 type1 = TREE_VALUE (TREE_TYPE (proto1));
8408 type2 = TREE_VALUE (TREE_TYPE (proto2));
8410 if (!objc_types_are_equivalent (type1, type2)
8411 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8414 /* Compare argument types. */
8415 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8416 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8418 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8420 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8422 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8423 TREE_VALUE (type2))))
8427 return (!type1 && !type2);
8430 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8431 this occurs. ObjC method dispatches are _not_ like C++ virtual
8432 member function dispatches, and we account for the difference here. */
8435 objc_fold_obj_type_ref (tree ref, tree known_type)
8437 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8438 tree known_type ATTRIBUTE_UNUSED)
8442 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8444 /* If the receiver does not have virtual member functions, there
8445 is nothing we can (or need to) do here. */
8449 /* Let C++ handle C++ virtual functions. */
8450 return cp_fold_obj_type_ref (ref, known_type);
8452 /* For plain ObjC, we currently do not need to do anything. */
8458 objc_start_function (tree name, tree type, tree attrs,
8462 struct c_arg_info *params
8466 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8469 DECL_ARGUMENTS (fndecl) = params;
8470 DECL_INITIAL (fndecl) = error_mark_node;
8471 DECL_EXTERNAL (fndecl) = 0;
8472 TREE_STATIC (fndecl) = 1;
8473 retrofit_lang_decl (fndecl);
8474 cplus_decl_attributes (&fndecl, attrs, 0);
8475 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8477 struct c_label_context_se *nstack_se;
8478 struct c_label_context_vm *nstack_vm;
8479 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8480 nstack_se->labels_def = NULL;
8481 nstack_se->labels_used = NULL;
8482 nstack_se->next = label_context_stack_se;
8483 label_context_stack_se = nstack_se;
8484 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8485 nstack_vm->labels_def = NULL;
8486 nstack_vm->labels_used = NULL;
8487 nstack_vm->scope = 0;
8488 nstack_vm->next = label_context_stack_vm;
8489 label_context_stack_vm = nstack_vm;
8490 current_function_returns_value = 0; /* Assume, until we see it does. */
8491 current_function_returns_null = 0;
8493 decl_attributes (&fndecl, attrs, 0);
8494 announce_function (fndecl);
8495 DECL_INITIAL (fndecl) = error_mark_node;
8496 DECL_EXTERNAL (fndecl) = 0;
8497 TREE_STATIC (fndecl) = 1;
8498 current_function_decl = pushdecl (fndecl);
8500 declare_parm_level ();
8501 DECL_RESULT (current_function_decl)
8502 = build_decl (RESULT_DECL, NULL_TREE,
8503 TREE_TYPE (TREE_TYPE (current_function_decl)));
8504 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8505 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8506 start_fname_decls ();
8507 store_parm_decls_from (params);
8510 TREE_USED (current_function_decl) = 1;
8513 /* - Generate an identifier for the function. the format is "_n_cls",
8514 where 1 <= n <= nMethods, and cls is the name the implementation we
8516 - Install the return type from the method declaration.
8517 - If we have a prototype, check for type consistency. */
8520 really_start_method (tree method,
8524 struct c_arg_info *parmlist
8528 tree ret_type, meth_type;
8530 const char *sel_name, *class_name, *cat_name;
8533 /* Synth the storage class & assemble the return type. */
8534 ret_type = TREE_VALUE (TREE_TYPE (method));
8536 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8537 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8538 cat_name = ((TREE_CODE (objc_implementation_context)
8539 == CLASS_IMPLEMENTATION_TYPE)
8541 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8544 /* Make sure this is big enough for any plausible method label. */
8545 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8546 + (cat_name ? strlen (cat_name) : 0));
8548 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8549 class_name, cat_name, sel_name, method_slot);
8551 method_id = get_identifier (buf);
8554 /* Objective-C methods cannot be overloaded, so we don't need
8555 the type encoding appended. It looks bad anyway... */
8556 push_lang_context (lang_name_c);
8560 = build_function_type (ret_type,
8561 get_arg_type_list (method, METHOD_DEF, 0));
8562 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8564 /* Set self_decl from the first argument. */
8565 self_decl = DECL_ARGUMENTS (current_function_decl);
8567 /* Suppress unused warnings. */
8568 TREE_USED (self_decl) = 1;
8569 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8571 pop_lang_context ();
8574 METHOD_DEFINITION (method) = current_function_decl;
8576 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8578 if (implementation_template != objc_implementation_context)
8581 = lookup_method_static (implementation_template,
8582 METHOD_SEL_NAME (method),
8583 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8584 | OBJC_LOOKUP_NO_SUPER));
8588 if (!comp_proto_with_proto (method, proto, 1))
8590 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8592 warn_with_method ("conflicting types for", type, method);
8593 warn_with_method ("previous declaration of", type, proto);
8598 /* We have a method @implementation even though we did not
8599 see a corresponding @interface declaration (which is allowed
8600 by Objective-C rules). Go ahead and place the method in
8601 the @interface anyway, so that message dispatch lookups
8603 tree interface = implementation_template;
8605 if (TREE_CODE (objc_implementation_context)
8606 == CATEGORY_IMPLEMENTATION_TYPE)
8607 interface = lookup_category
8609 CLASS_SUPER_NAME (objc_implementation_context));
8612 objc_add_method (interface, copy_node (method),
8613 TREE_CODE (method) == CLASS_METHOD_DECL);
8618 static void *UOBJC_SUPER_scope = 0;
8620 /* _n_Method (id self, SEL sel, ...)
8622 struct objc_super _S;
8623 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8627 get_super_receiver (void)
8629 if (objc_method_context)
8631 tree super_expr, super_expr_list;
8633 if (!UOBJC_SUPER_decl)
8635 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8636 objc_super_template);
8637 /* This prevents `unused variable' warnings when compiling with -Wall. */
8638 TREE_USED (UOBJC_SUPER_decl) = 1;
8639 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8640 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8641 UOBJC_SUPER_scope = objc_get_current_scope ();
8644 /* Set receiver to self. */
8645 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8646 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8647 super_expr_list = super_expr;
8649 /* Set class to begin searching. */
8650 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8651 get_identifier ("super_class"));
8653 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8655 /* [_cls, __cls]Super are "pre-built" in
8656 synth_forward_declarations. */
8658 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8659 ((TREE_CODE (objc_method_context)
8660 == INSTANCE_METHOD_DECL)
8662 : uucls_super_ref));
8666 /* We have a category. */
8668 tree super_name = CLASS_SUPER_NAME (implementation_template);
8671 /* Barf if super used in a category of Object. */
8674 error ("no super class declared in interface for %qs",
8675 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8676 return error_mark_node;
8679 if (flag_next_runtime && !flag_zero_link)
8681 super_class = objc_get_class_reference (super_name);
8682 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8683 /* If we are in a class method, we must retrieve the
8684 _metaclass_ for the current class, pointed at by
8685 the class's "isa" pointer. The following assumes that
8686 "isa" is the first ivar in a class (which it must be). */
8688 = build_indirect_ref
8689 (build_c_cast (build_pointer_type (objc_class_type),
8690 super_class), "unary *");
8694 add_class_reference (super_name);
8695 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8696 ? objc_get_class_decl : objc_get_meta_class_decl);
8697 assemble_external (super_class);
8699 = build_function_call
8703 my_build_string_pointer
8704 (IDENTIFIER_LENGTH (super_name) + 1,
8705 IDENTIFIER_POINTER (super_name))));
8709 = build_modify_expr (super_expr, NOP_EXPR,
8710 build_c_cast (TREE_TYPE (super_expr),
8714 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8716 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8717 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8719 return super_expr_list;
8723 error ("[super ...] must appear in a method context");
8724 return error_mark_node;
8728 /* When exiting a scope, sever links to a 'super' declaration (if any)
8729 therein contained. */
8732 objc_clear_super_receiver (void)
8734 if (objc_method_context
8735 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8736 UOBJC_SUPER_decl = 0;
8737 UOBJC_SUPER_scope = 0;
8742 objc_finish_method_definition (tree fndecl)
8744 /* We cannot validly inline ObjC methods, at least not without a language
8745 extension to declare that a method need not be dynamically
8746 dispatched, so suppress all thoughts of doing so. */
8747 DECL_INLINE (fndecl) = 0;
8748 DECL_UNINLINABLE (fndecl) = 1;
8751 /* The C++ front-end will have called finish_function() for us. */
8755 METHOD_ENCODING (objc_method_context)
8756 = encode_method_prototype (objc_method_context);
8758 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8759 since the optimizer may find "may be used before set" errors. */
8760 objc_method_context = NULL_TREE;
8762 if (should_call_super_dealloc)
8763 warning (0, "method possibly missing a [super dealloc] call");
8768 lang_report_error_function (tree decl)
8770 if (objc_method_context)
8772 fprintf (stderr, "In method %qs\n",
8773 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8782 /* Given a tree DECL node, produce a printable description of it in the given
8783 buffer, overwriting the buffer. */
8786 gen_declaration (tree decl)
8792 gen_type_name_0 (TREE_TYPE (decl));
8794 if (DECL_NAME (decl))
8796 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8797 strcat (errbuf, " ");
8799 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8802 if (DECL_INITIAL (decl)
8803 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8804 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8805 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8811 /* Given a tree TYPE node, produce a printable description of it in the given
8812 buffer, overwriting the buffer. */
8815 gen_type_name_0 (tree type)
8817 tree orig = type, proto;
8819 if (TYPE_P (type) && TYPE_NAME (type))
8820 type = TYPE_NAME (type);
8821 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8823 tree inner = TREE_TYPE (type);
8825 while (TREE_CODE (inner) == ARRAY_TYPE)
8826 inner = TREE_TYPE (inner);
8828 gen_type_name_0 (inner);
8830 if (!POINTER_TYPE_P (inner))
8831 strcat (errbuf, " ");
8833 if (POINTER_TYPE_P (type))
8834 strcat (errbuf, "*");
8836 while (type != inner)
8838 strcat (errbuf, "[");
8840 if (TYPE_DOMAIN (type))
8844 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8846 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8847 strcat (errbuf, sz);
8850 strcat (errbuf, "]");
8851 type = TREE_TYPE (type);
8857 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8858 type = DECL_NAME (type);
8860 strcat (errbuf, IDENTIFIER_POINTER (type));
8862 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8863 if (objc_is_id (orig))
8864 orig = TREE_TYPE (orig);
8866 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8870 strcat (errbuf, " <");
8874 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8875 proto = TREE_CHAIN (proto);
8876 strcat (errbuf, proto ? ", " : ">");
8885 gen_type_name (tree type)
8889 return gen_type_name_0 (type);
8892 /* Given a method tree, put a printable description into the given
8893 buffer (overwriting) and return a pointer to the buffer. */
8896 gen_method_decl (tree method)
8900 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8901 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8902 strcat (errbuf, ")");
8903 chain = METHOD_SEL_ARGS (method);
8907 /* We have a chain of keyword_decls. */
8910 if (KEYWORD_KEY_NAME (chain))
8911 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8913 strcat (errbuf, ":(");
8914 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8915 strcat (errbuf, ")");
8917 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8918 if ((chain = TREE_CHAIN (chain)))
8919 strcat (errbuf, " ");
8923 if (METHOD_ADD_ARGS (method))
8925 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8927 /* Know we have a chain of parm_decls. */
8930 strcat (errbuf, ", ");
8931 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8932 chain = TREE_CHAIN (chain);
8935 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8936 strcat (errbuf, ", ...");
8941 /* We have a unary selector. */
8942 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8950 /* Dump an @interface declaration of the supplied class CHAIN to the
8951 supplied file FP. Used to implement the -gen-decls option (which
8952 prints out an @interface declaration of all classes compiled in
8953 this run); potentially useful for debugging the compiler too. */
8955 dump_interface (FILE *fp, tree chain)
8957 /* FIXME: A heap overflow here whenever a method (or ivar)
8958 declaration is so long that it doesn't fit in the buffer. The
8959 code and all the related functions should be rewritten to avoid
8960 using fixed size buffers. */
8961 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8962 tree ivar_decls = CLASS_RAW_IVARS (chain);
8963 tree nst_methods = CLASS_NST_METHODS (chain);
8964 tree cls_methods = CLASS_CLS_METHODS (chain);
8966 fprintf (fp, "\n@interface %s", my_name);
8968 /* CLASS_SUPER_NAME is used to store the superclass name for
8969 classes, and the category name for categories. */
8970 if (CLASS_SUPER_NAME (chain))
8972 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8974 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8975 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8977 fprintf (fp, " (%s)\n", name);
8981 fprintf (fp, " : %s\n", name);
8987 /* FIXME - the following doesn't seem to work at the moment. */
8990 fprintf (fp, "{\n");
8993 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8994 ivar_decls = TREE_CHAIN (ivar_decls);
8997 fprintf (fp, "}\n");
9002 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9003 nst_methods = TREE_CHAIN (nst_methods);
9008 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9009 cls_methods = TREE_CHAIN (cls_methods);
9012 fprintf (fp, "@end\n");
9015 /* Demangle function for Objective-C */
9017 objc_demangle (const char *mangled)
9019 char *demangled, *cp;
9021 if (mangled[0] == '_' &&
9022 (mangled[1] == 'i' || mangled[1] == 'c') &&
9025 cp = demangled = xmalloc(strlen(mangled) + 2);
9026 if (mangled[1] == 'i')
9027 *cp++ = '-'; /* for instance method */
9029 *cp++ = '+'; /* for class method */
9030 *cp++ = '['; /* opening left brace */
9031 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9032 while (*cp && *cp == '_')
9033 cp++; /* skip any initial underbars in class name */
9034 cp = strchr(cp, '_'); /* find first non-initial underbar */
9037 free(demangled); /* not mangled name */
9040 if (cp[1] == '_') /* easy case: no category name */
9042 *cp++ = ' '; /* replace two '_' with one ' ' */
9043 strcpy(cp, mangled + (cp - demangled) + 2);
9047 *cp++ = '('; /* less easy case: category name */
9048 cp = strchr(cp, '_');
9051 free(demangled); /* not mangled name */
9055 *cp++ = ' '; /* overwriting 1st char of method name... */
9056 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9058 while (*cp && *cp == '_')
9059 cp++; /* skip any initial underbars in method name */
9062 *cp = ':'; /* replace remaining '_' with ':' */
9063 *cp++ = ']'; /* closing right brace */
9064 *cp++ = 0; /* string terminator */
9068 return mangled; /* not an objc mangled name */
9072 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9074 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9080 gcc_obstack_init (&util_obstack);
9081 util_firstobj = (char *) obstack_finish (&util_obstack);
9083 errbuf = (char *) xmalloc (1024 * 10);
9085 synth_module_prologue ();
9091 struct imp_entry *impent;
9093 /* The internally generated initializers appear to have missing braces.
9094 Don't warn about this. */
9095 int save_warn_missing_braces = warn_missing_braces;
9096 warn_missing_braces = 0;
9098 /* A missing @end may not be detected by the parser. */
9099 if (objc_implementation_context)
9101 warning (0, "%<@end%> missing in implementation context");
9102 finish_class (objc_implementation_context);
9103 objc_ivar_chain = NULL_TREE;
9104 objc_implementation_context = NULL_TREE;
9107 /* Process the static instances here because initialization of objc_symtab
9109 if (objc_static_instances)
9110 generate_static_references ();
9112 if (imp_list || class_names_chain
9113 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9114 generate_objc_symtab_decl ();
9116 for (impent = imp_list; impent; impent = impent->next)
9118 objc_implementation_context = impent->imp_context;
9119 implementation_template = impent->imp_template;
9121 UOBJC_CLASS_decl = impent->class_decl;
9122 UOBJC_METACLASS_decl = impent->meta_decl;
9124 /* Dump the @interface of each class as we compile it, if the
9125 -gen-decls option is in use. TODO: Dump the classes in the
9126 order they were found, rather than in reverse order as we
9128 if (flag_gen_declaration)
9130 dump_interface (gen_declaration_file, objc_implementation_context);
9133 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9135 /* all of the following reference the string pool... */
9136 generate_ivar_lists ();
9137 generate_dispatch_tables ();
9138 generate_shared_structures (impent->has_cxx_cdtors
9139 ? CLS_HAS_CXX_STRUCTORS
9144 generate_dispatch_tables ();
9145 generate_category (objc_implementation_context);
9149 /* If we are using an array of selectors, we must always
9150 finish up the array decl even if no selectors were used. */
9151 if (! flag_next_runtime || sel_ref_chain)
9152 build_selector_translation_table ();
9155 generate_protocols ();
9157 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9158 generate_objc_image_info ();
9160 /* Arrange for ObjC data structures to be initialized at run time. */
9161 if (objc_implementation_context || class_names_chain || objc_static_instances
9162 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9164 build_module_descriptor ();
9166 if (!flag_next_runtime)
9167 build_module_initializer_routine ();
9170 /* Dump the class references. This forces the appropriate classes
9171 to be linked into the executable image, preserving unix archive
9172 semantics. This can be removed when we move to a more dynamically
9173 linked environment. */
9175 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9177 handle_class_ref (chain);
9178 if (TREE_PURPOSE (chain))
9179 generate_classref_translation_entry (chain);
9182 for (impent = imp_list; impent; impent = impent->next)
9183 handle_impent (impent);
9190 /* Run through the selector hash tables and print a warning for any
9191 selector which has multiple methods. */
9193 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9195 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9196 check_duplicates (hsh, 0, 1);
9197 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9198 check_duplicates (hsh, 0, 1);
9202 warn_missing_braces = save_warn_missing_braces;
9205 /* Subroutines of finish_objc. */
9208 generate_classref_translation_entry (tree chain)
9210 tree expr, decl, type;
9212 decl = TREE_PURPOSE (chain);
9213 type = TREE_TYPE (decl);
9215 expr = add_objc_string (TREE_VALUE (chain), class_names);
9216 expr = convert (type, expr); /* cast! */
9218 /* The decl that is the one that we
9219 forward declared in build_class_reference. */
9220 finish_var_decl (decl, expr);
9225 handle_class_ref (tree chain)
9227 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9228 char *string = (char *) alloca (strlen (name) + 30);
9232 sprintf (string, "%sobjc_class_name_%s",
9233 (flag_next_runtime ? "." : "__"), name);
9235 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9236 if (flag_next_runtime)
9238 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9243 /* Make a decl for this name, so we can use its address in a tree. */
9244 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9245 DECL_EXTERNAL (decl) = 1;
9246 TREE_PUBLIC (decl) = 1;
9249 rest_of_decl_compilation (decl, 0, 0);
9251 /* Make a decl for the address. */
9252 sprintf (string, "%sobjc_class_ref_%s",
9253 (flag_next_runtime ? "." : "__"), name);
9254 exp = build1 (ADDR_EXPR, string_type_node, decl);
9255 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9256 DECL_INITIAL (decl) = exp;
9257 TREE_STATIC (decl) = 1;
9258 TREE_USED (decl) = 1;
9259 /* Force the output of the decl as this forces the reference of the class. */
9260 mark_decl_referenced (decl);
9263 rest_of_decl_compilation (decl, 0, 0);
9267 handle_impent (struct imp_entry *impent)
9271 objc_implementation_context = impent->imp_context;
9272 implementation_template = impent->imp_template;
9274 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9276 const char *const class_name =
9277 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9279 string = (char *) alloca (strlen (class_name) + 30);
9281 sprintf (string, "%sobjc_class_name_%s",
9282 (flag_next_runtime ? "." : "__"), class_name);
9284 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9286 const char *const class_name =
9287 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9288 const char *const class_super_name =
9289 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9291 string = (char *) alloca (strlen (class_name)
9292 + strlen (class_super_name) + 30);
9294 /* Do the same for categories. Even though no references to
9295 these symbols are generated automatically by the compiler, it
9296 gives you a handle to pull them into an archive by hand. */
9297 sprintf (string, "*%sobjc_category_name_%s_%s",
9298 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9303 #ifdef ASM_DECLARE_CLASS_REFERENCE
9304 if (flag_next_runtime)
9306 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9314 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9315 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9316 TREE_PUBLIC (decl) = 1;
9317 TREE_READONLY (decl) = 1;
9318 TREE_USED (decl) = 1;
9319 TREE_CONSTANT (decl) = 1;
9320 DECL_CONTEXT (decl) = 0;
9321 DECL_ARTIFICIAL (decl) = 1;
9322 DECL_INITIAL (decl) = init;
9323 assemble_variable (decl, 1, 0, 0);
9327 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9328 later requires that ObjC translation units participating in F&C be
9329 specially marked. The following routine accomplishes this. */
9331 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9334 generate_objc_image_info (void)
9336 tree decl, initlist;
9338 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9339 | (flag_objc_gc ? 2 : 0));
9341 decl = start_var_decl (build_array_type
9343 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9344 "_OBJC_IMAGE_INFO");
9346 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9347 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9348 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9350 finish_var_decl (decl, initlist);
9353 /* Look up ID as an instance variable. OTHER contains the result of
9354 the C or C++ lookup, which we may want to use instead. */
9357 objc_lookup_ivar (tree other, tree id)
9361 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9362 if (!objc_method_context)
9365 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9366 /* We have a message to super. */
9367 return get_super_receiver ();
9369 /* In a class method, look up an instance variable only as a last
9371 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9372 && other && other != error_mark_node)
9375 /* Look up the ivar, but do not use it if it is not accessible. */
9376 ivar = is_ivar (objc_ivar_chain, id);
9378 if (!ivar || is_private (ivar))
9381 /* In an instance method, a local variable (or parameter) may hide the
9382 instance variable. */
9383 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9384 && other && other != error_mark_node
9386 && CP_DECL_CONTEXT (other) != global_namespace)
9388 && !DECL_FILE_SCOPE_P (other))
9391 warning (0, "local declaration of %qs hides instance variable",
9392 IDENTIFIER_POINTER (id));
9397 /* At this point, we are either in an instance method with no obscuring
9398 local definitions, or in a class method with no alternate definitions
9400 return build_ivar_reference (id);
9403 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9404 needs to be done if we are calling a function through a cast. */
9407 objc_rewrite_function_call (tree function, tree params)
9409 if (TREE_CODE (function) == NOP_EXPR
9410 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9411 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9414 function = build (OBJ_TYPE_REF, TREE_TYPE (function),
9415 TREE_OPERAND (function, 0),
9416 TREE_VALUE (params), size_zero_node);
9422 /* Look for the special case of OBJC_TYPE_REF with the address of
9423 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9426 enum gimplify_status
9427 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9429 enum gimplify_status r0, r1;
9430 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9431 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9432 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9435 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9436 value of the OBJ_TYPE_REF, so force them to be emitted
9437 during subexpression evaluation rather than after the
9438 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9439 C to use direct rather than indirect calls when the
9440 object expression has a postincrement. */
9441 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9442 is_gimple_val, fb_rvalue);
9443 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9444 is_gimple_val, fb_rvalue);
9446 return MIN (r0, r1);
9450 return cp_gimplify_expr (expr_p, pre_p, post_p);
9452 return c_gimplify_expr (expr_p, pre_p, post_p);
9456 /* Given a CALL expression, find the function being called. The ObjC
9457 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9460 objc_get_callee_fndecl (tree call_expr)
9462 tree addr = TREE_OPERAND (call_expr, 0);
9463 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9466 addr = OBJ_TYPE_REF_EXPR (addr);
9468 /* If the address is just `&f' for some function `f', then we know
9469 that `f' is being called. */
9470 if (TREE_CODE (addr) == ADDR_EXPR
9471 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9472 return TREE_OPERAND (addr, 0);
9477 #include "gt-objc-objc-act.h"