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 tag NAME, a base struct with tag
798 SUPER_NAME (if any), and FIELDS indicated. */
801 objc_build_struct (tree name, tree fields, tree super_name)
803 tree s = start_struct (RECORD_TYPE, name);
804 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
805 tree t, objc_info = NULL_TREE;
809 /* Prepend a packed variant of the base class into the layout. This
810 is necessary to preserve ObjC ABI compatibility. */
811 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
812 tree field = TYPE_FIELDS (super);
814 while (field && TREE_CHAIN (field)
815 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
816 field = TREE_CHAIN (field);
818 /* For ObjC ABI purposes, the "packed" size of a base class is the
819 the sum of the offset and the size (in bits) of the last field
822 = (field && TREE_CODE (field) == FIELD_DECL
823 ? size_binop (PLUS_EXPR,
824 size_binop (PLUS_EXPR,
827 convert (bitsizetype,
828 DECL_FIELD_OFFSET (field)),
829 bitsize_int (BITS_PER_UNIT)),
830 DECL_FIELD_BIT_OFFSET (field)),
832 : bitsize_zero_node);
833 DECL_SIZE_UNIT (base)
834 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
835 size_int (BITS_PER_UNIT));
836 DECL_ARTIFICIAL (base) = 1;
837 DECL_ALIGN (base) = 1;
838 DECL_FIELD_CONTEXT (base) = s;
840 DECL_FIELD_IS_BASE (base) = 1;
843 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
844 #endif /* are following the ObjC ABI here. */
845 TREE_CHAIN (base) = fields;
849 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
850 in all variants of this RECORD_TYPE to be clobbered, but it is therein
851 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
852 Hence, we must squirrel away the ObjC-specific information before calling
853 finish_struct(), and then reinstate it afterwards. */
855 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
857 = chainon (objc_info,
858 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
860 s = finish_struct (s, fields, NULL_TREE);
862 for (t = TYPE_NEXT_VARIANT (s); t;
863 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
864 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
866 /* Use TYPE_BINFO structures to point at the super class, if any. */
867 objc_xref_basetypes (s, super);
872 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
873 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
876 objc_build_volatilized_type (tree type)
880 /* Check if we have not constructed the desired variant already. */
881 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
883 /* The type qualifiers must (obviously) match up. */
884 if (!TYPE_VOLATILE (t)
885 || (TYPE_READONLY (t) != TYPE_READONLY (type))
886 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
889 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
890 info, if any) must match up. */
891 if (POINTER_TYPE_P (t)
892 && (TREE_TYPE (t) != TREE_TYPE (type)))
895 /* Everything matches up! */
899 /* Ok, we could not re-use any of the pre-existing variants. Create
901 t = build_variant_type_copy (type);
902 TYPE_VOLATILE (t) = 1;
907 /* Mark DECL as being 'volatile' for purposes of Darwin
908 _setjmp()/_longjmp() exception handling. Called from
909 objc_mark_locals_volatile(). */
911 objc_volatilize_decl (tree decl)
913 /* Do not mess with variables that are 'static' or (already)
915 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
916 && (TREE_CODE (decl) == VAR_DECL
917 || TREE_CODE (decl) == PARM_DECL))
919 tree t = TREE_TYPE (decl);
920 struct volatilized_type key;
923 t = objc_build_volatilized_type (t);
925 loc = htab_find_slot (volatilized_htab, &key, INSERT);
929 *loc = ggc_alloc (sizeof (key));
930 ((struct volatilized_type *) *loc)->type = t;
933 TREE_TYPE (decl) = t;
934 TREE_THIS_VOLATILE (decl) = 1;
935 TREE_SIDE_EFFECTS (decl) = 1;
936 DECL_REGISTER (decl) = 0;
938 C_DECL_REGISTER (decl) = 0;
943 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
944 (including its categoreis and superclasses) or by object type TYP.
945 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
948 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
950 bool class_type = (cls != NULL_TREE);
956 /* Check protocols adopted by the class and its categories. */
957 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
959 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
963 /* Repeat for superclasses. */
964 cls = lookup_interface (CLASS_SUPER_NAME (cls));
967 /* Check for any protocols attached directly to the object type. */
968 if (TYPE_HAS_OBJC_INFO (typ))
970 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
976 strcpy (errbuf, class_type ? "class \'" : "type \'");
977 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
978 strcat (errbuf, "\' does not ");
979 /* NB: Types 'id' and 'Class' cannot reasonably be described as
980 "implementing" a given protocol, since they do not have an
982 strcat (errbuf, class_type ? "implement" : "conform to");
983 strcat (errbuf, " the \'");
984 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
985 strcat (errbuf, "\' protocol");
992 /* Check if class RCLS and instance struct type RTYP conform to at least the
993 same protocols that LCLS and LTYP conform to. */
996 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
999 bool have_lproto = false;
1003 /* NB: We do _not_ look at categories defined for LCLS; these may or
1004 may not get loaded in, and therefore it is unreasonable to require
1005 that RCLS/RTYP must implement any of their protocols. */
1006 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1010 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1014 /* Repeat for superclasses. */
1015 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1018 /* Check for any protocols attached directly to the object type. */
1019 if (TYPE_HAS_OBJC_INFO (ltyp))
1021 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1025 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1030 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1031 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1032 away with simply checking for 'id' or 'Class' (!RCLS), since this
1033 routine will not get called in other cases. */
1034 return have_lproto || (rcls != NULL_TREE);
1037 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1038 an instance of RTYP to an instance of LTYP or to compare the two
1039 (if ARGNO is equal to -3), per ObjC type system rules. Before
1040 returning 'true', this routine may issue warnings related to, e.g.,
1041 protocol conformance. When returning 'false', the routine must
1042 produce absolutely no warnings; the C or C++ front-end will do so
1043 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1044 the routine must return 'false'.
1046 The ARGNO parameter is encoded as follows:
1047 >= 1 Parameter number (CALLEE contains function being called);
1051 -3 Comparison (LTYP and RTYP may match in either direction). */
1054 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1056 tree lcls, rcls, lproto, rproto;
1057 bool pointers_compatible;
1059 /* We must be dealing with pointer types */
1060 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1065 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1066 rtyp = TREE_TYPE (rtyp);
1068 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1070 /* Past this point, we are only interested in ObjC class instances,
1071 or 'id' or 'Class'. */
1072 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1075 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1076 && !TYPE_HAS_OBJC_INFO (ltyp))
1079 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1080 && !TYPE_HAS_OBJC_INFO (rtyp))
1083 /* Past this point, we are committed to returning 'true' to the caller.
1084 However, we can still warn about type and/or protocol mismatches. */
1086 if (TYPE_HAS_OBJC_INFO (ltyp))
1088 lcls = TYPE_OBJC_INTERFACE (ltyp);
1089 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1092 lcls = lproto = NULL_TREE;
1094 if (TYPE_HAS_OBJC_INFO (rtyp))
1096 rcls = TYPE_OBJC_INTERFACE (rtyp);
1097 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1100 rcls = rproto = NULL_TREE;
1102 /* If either type is an unqualified 'id', we're done. */
1103 if ((!lproto && objc_is_object_id (ltyp))
1104 || (!rproto && objc_is_object_id (rtyp)))
1107 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1109 /* If the underlying types are the same, and at most one of them has
1110 a protocol list, we do not need to issue any diagnostics. */
1111 if (pointers_compatible && (!lproto || !rproto))
1114 /* If exactly one of the types is 'Class', issue a diagnostic; any
1115 exceptions of this rule have already been handled. */
1116 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1117 pointers_compatible = false;
1118 /* Otherwise, check for inheritance relations. */
1121 if (!pointers_compatible)
1123 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1125 if (!pointers_compatible)
1126 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1128 if (!pointers_compatible && argno == -3)
1129 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1132 /* If the pointers match modulo protocols, check for protocol conformance
1134 if (pointers_compatible)
1136 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1139 if (!pointers_compatible && argno == -3)
1140 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1144 if (!pointers_compatible)
1146 /* NB: For the time being, we shall make our warnings look like their
1147 C counterparts. In the future, we may wish to make them more
1152 warning (0, "comparison of distinct Objective-C types lacks a cast");
1156 warning (0, "initialization from distinct Objective-C type");
1160 warning (0, "assignment from distinct Objective-C type");
1164 warning (0, "distinct Objective-C type in return");
1168 warning (0, "passing argument %d of %qE from distinct "
1169 "Objective-C type", argno, callee);
1177 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1178 lives in the volatilized hash table, ignore the 'volatile' bit when
1179 making the comparison. */
1182 objc_type_quals_match (tree ltyp, tree rtyp)
1184 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1185 struct volatilized_type key;
1189 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1190 lquals &= ~TYPE_QUAL_VOLATILE;
1194 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1195 rquals &= ~TYPE_QUAL_VOLATILE;
1197 return (lquals == rquals);
1201 /* Determine if CHILD is derived from PARENT. The routine assumes that
1202 both parameters are RECORD_TYPEs, and is non-reflexive. */
1205 objc_derived_from_p (tree parent, tree child)
1207 parent = TYPE_MAIN_VARIANT (parent);
1209 for (child = TYPE_MAIN_VARIANT (child);
1210 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1212 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1213 (TYPE_BINFO (child),
1216 if (child == parent)
1225 objc_build_component_ref (tree datum, tree component)
1227 /* If COMPONENT is NULL, the caller is referring to the anonymous
1228 base class field. */
1231 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1233 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1236 /* The 'build_component_ref' routine has been removed from the C++
1237 front-end, but 'finish_class_member_access_expr' seems to be
1238 a worthy substitute. */
1240 return finish_class_member_access_expr (datum, component);
1242 return build_component_ref (datum, component);
1246 /* Recursively copy inheritance information rooted at BINFO. To do this,
1247 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1250 objc_copy_binfo (tree binfo)
1252 tree btype = BINFO_TYPE (binfo);
1253 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1257 BINFO_TYPE (binfo2) = btype;
1258 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1259 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1261 /* Recursively copy base binfos of BINFO. */
1262 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1264 tree base_binfo2 = objc_copy_binfo (base_binfo);
1266 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1267 BINFO_BASE_APPEND (binfo2, base_binfo2);
1273 /* Record superclass information provided in BASETYPE for ObjC class REF.
1274 This is loosely based on cp/decl.c:xref_basetypes(). */
1277 objc_xref_basetypes (tree ref, tree basetype)
1279 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1281 TYPE_BINFO (ref) = binfo;
1282 BINFO_OFFSET (binfo) = size_zero_node;
1283 BINFO_TYPE (binfo) = ref;
1287 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1289 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1290 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1291 BINFO_BASE_APPEND (binfo, base_binfo);
1292 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1297 volatilized_hash (const void *ptr)
1299 tree typ = ((struct volatilized_type *)ptr)->type;
1301 return htab_hash_pointer(typ);
1305 volatilized_eq (const void *ptr1, const void *ptr2)
1307 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1308 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1310 return typ1 == typ2;
1313 /* Called from finish_decl. */
1316 objc_check_decl (tree decl)
1318 tree type = TREE_TYPE (decl);
1320 if (TREE_CODE (type) != RECORD_TYPE)
1322 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1323 error ("statically allocated instance of Objective-C class %qs",
1324 IDENTIFIER_POINTER (type));
1327 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1328 either name an Objective-C class, or refer to the special 'id' or 'Class'
1329 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1332 objc_get_protocol_qualified_type (tree interface, tree protocols)
1334 /* If INTERFACE is not provided, default to 'id'. */
1335 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1336 bool is_ptr = (type != NULL_TREE);
1340 type = objc_is_class_name (interface);
1343 type = xref_tag (RECORD_TYPE, type);
1350 type = build_variant_type_copy (type);
1352 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1356 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1357 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1358 type = TREE_TYPE (type);
1361 /* Look up protocols and install in lang specific list. */
1362 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1363 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1365 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1366 return the pointer to the new pointee variant. */
1368 type = TYPE_POINTER_TO (type);
1370 TYPE_OBJC_INTERFACE (type)
1371 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1377 /* Check for circular dependencies in protocols. The arguments are
1378 PROTO, the protocol to check, and LIST, a list of protocol it
1382 check_protocol_recursively (tree proto, tree list)
1386 for (p = list; p; p = TREE_CHAIN (p))
1388 tree pp = TREE_VALUE (p);
1390 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1391 pp = lookup_protocol (pp);
1394 fatal_error ("protocol %qs has circular dependency",
1395 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1397 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1401 /* Look up PROTOCOLS, and return a list of those that are found.
1402 If none are found, return NULL. */
1405 lookup_and_install_protocols (tree protocols)
1408 tree return_value = NULL_TREE;
1410 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1412 tree ident = TREE_VALUE (proto);
1413 tree p = lookup_protocol (ident);
1416 error ("cannot find protocol declaration for %qs",
1417 IDENTIFIER_POINTER (ident));
1419 return_value = chainon (return_value,
1420 build_tree_list (NULL_TREE, p));
1423 return return_value;
1426 /* Create a declaration for field NAME of a given TYPE. */
1429 create_field_decl (tree type, const char *name)
1431 return build_decl (FIELD_DECL, get_identifier (name), type);
1434 /* Create a global, static declaration for variable NAME of a given TYPE. The
1435 finish_var_decl() routine will need to be called on it afterwards. */
1438 start_var_decl (tree type, const char *name)
1440 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1442 TREE_STATIC (var) = 1;
1443 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1444 DECL_IGNORED_P (var) = 1;
1445 DECL_ARTIFICIAL (var) = 1;
1446 DECL_CONTEXT (var) = NULL_TREE;
1448 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1454 /* Finish off the variable declaration created by start_var_decl(). */
1457 finish_var_decl (tree var, tree initializer)
1459 finish_decl (var, initializer, NULL_TREE);
1460 /* Ensure that the variable actually gets output. */
1461 mark_decl_referenced (var);
1462 /* Mark the decl to avoid "defined but not used" warning. */
1463 TREE_USED (var) = 1;
1466 /* Find the decl for the constant string class reference. This is only
1467 used for the NeXT runtime. */
1470 setup_string_decl (void)
1475 /* %s in format will provide room for terminating null */
1476 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1477 + strlen (constant_string_class_name);
1478 name = xmalloc (length);
1479 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1480 constant_string_class_name);
1481 constant_string_global_id = get_identifier (name);
1482 string_class_decl = lookup_name (constant_string_global_id);
1484 return string_class_decl;
1487 /* Purpose: "play" parser, creating/installing representations
1488 of the declarations that are required by Objective-C.
1492 type_spec--------->sc_spec
1493 (tree_list) (tree_list)
1496 identifier_node identifier_node */
1499 synth_module_prologue (void)
1502 enum debug_info_type save_write_symbols = write_symbols;
1503 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1505 /* Suppress outputting debug symbols, because
1506 dbxout_init hasn'r been called yet. */
1507 write_symbols = NO_DEBUG;
1508 debug_hooks = &do_nothing_debug_hooks;
1511 push_lang_context (lang_name_c); /* extern "C" */
1514 /* The following are also defined in <objc/objc.h> and friends. */
1516 objc_object_id = get_identifier (TAG_OBJECT);
1517 objc_class_id = get_identifier (TAG_CLASS);
1519 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1520 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1522 objc_object_type = build_pointer_type (objc_object_reference);
1523 objc_class_type = build_pointer_type (objc_class_reference);
1525 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1526 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1528 /* Declare the 'id' and 'Class' typedefs. */
1530 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1533 DECL_IN_SYSTEM_HEADER (type) = 1;
1534 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1537 DECL_IN_SYSTEM_HEADER (type) = 1;
1539 /* Forward-declare '@interface Protocol'. */
1541 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1542 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1543 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1546 /* Declare type of selector-objects that represent an operation name. */
1548 if (flag_next_runtime)
1549 /* `struct objc_selector *' */
1551 = build_pointer_type (xref_tag (RECORD_TYPE,
1552 get_identifier (TAG_SELECTOR)));
1554 /* `const struct objc_selector *' */
1556 = build_pointer_type
1557 (build_qualified_type (xref_tag (RECORD_TYPE,
1558 get_identifier (TAG_SELECTOR)),
1561 /* Declare receiver type used for dispatching messages to 'super'. */
1563 /* `struct objc_super *' */
1564 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1565 get_identifier (TAG_SUPER)));
1567 /* Declare pointers to method and ivar lists. */
1568 objc_method_list_ptr = build_pointer_type
1569 (xref_tag (RECORD_TYPE,
1570 get_identifier (UTAG_METHOD_LIST)));
1571 objc_method_proto_list_ptr
1572 = build_pointer_type (xref_tag (RECORD_TYPE,
1573 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1574 objc_ivar_list_ptr = build_pointer_type
1575 (xref_tag (RECORD_TYPE,
1576 get_identifier (UTAG_IVAR_LIST)));
1578 if (flag_next_runtime)
1580 /* NB: In order to call one of the ..._stret (struct-returning)
1581 functions, the function *MUST* first be cast to a signature that
1582 corresponds to the actual ObjC method being invoked. This is
1583 what is done by the build_objc_method_call() routine below. */
1585 /* id objc_msgSend (id, SEL, ...); */
1586 /* id objc_msgSendNonNil (id, SEL, ...); */
1587 /* id objc_msgSend_stret (id, SEL, ...); */
1588 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1590 = build_function_type (objc_object_type,
1591 tree_cons (NULL_TREE, objc_object_type,
1592 tree_cons (NULL_TREE, objc_selector_type,
1594 umsg_decl = builtin_function (TAG_MSGSEND,
1595 type, 0, NOT_BUILT_IN,
1597 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1598 type, 0, NOT_BUILT_IN,
1600 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1601 type, 0, NOT_BUILT_IN,
1603 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1604 type, 0, NOT_BUILT_IN,
1607 /* id objc_msgSend_Fast (id, SEL, ...)
1608 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1609 #ifdef OFFS_MSGSEND_FAST
1610 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1611 type, 0, NOT_BUILT_IN,
1613 DECL_ATTRIBUTES (umsg_fast_decl)
1614 = tree_cons (get_identifier ("hard_coded_address"),
1615 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1618 /* No direct dispatch availible. */
1619 umsg_fast_decl = umsg_decl;
1622 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1623 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1625 = build_function_type (objc_object_type,
1626 tree_cons (NULL_TREE, objc_super_type,
1627 tree_cons (NULL_TREE, objc_selector_type,
1629 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1630 type, 0, NOT_BUILT_IN,
1632 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1633 type, 0, NOT_BUILT_IN, 0,
1638 /* GNU runtime messenger entry points. */
1640 /* typedef id (*IMP)(id, SEL, ...); */
1642 = build_pointer_type
1643 (build_function_type (objc_object_type,
1644 tree_cons (NULL_TREE, objc_object_type,
1645 tree_cons (NULL_TREE, objc_selector_type,
1648 /* IMP objc_msg_lookup (id, SEL); */
1650 = build_function_type (IMP_type,
1651 tree_cons (NULL_TREE, objc_object_type,
1652 tree_cons (NULL_TREE, objc_selector_type,
1653 OBJC_VOID_AT_END)));
1654 umsg_decl = builtin_function (TAG_MSGSEND,
1655 type, 0, NOT_BUILT_IN,
1658 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1660 = build_function_type (IMP_type,
1661 tree_cons (NULL_TREE, objc_super_type,
1662 tree_cons (NULL_TREE, objc_selector_type,
1663 OBJC_VOID_AT_END)));
1664 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1665 type, 0, NOT_BUILT_IN,
1668 /* The following GNU runtime entry point is called to initialize
1671 __objc_exec_class (void *); */
1673 = build_function_type (void_type_node,
1674 tree_cons (NULL_TREE, ptr_type_node,
1676 execclass_decl = builtin_function (TAG_EXECCLASS,
1677 type, 0, NOT_BUILT_IN,
1681 /* id objc_getClass (const char *); */
1683 type = build_function_type (objc_object_type,
1684 tree_cons (NULL_TREE,
1685 const_string_type_node,
1689 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1692 /* id objc_getMetaClass (const char *); */
1694 objc_get_meta_class_decl
1695 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1697 build_class_template ();
1698 build_super_template ();
1699 build_protocol_template ();
1700 build_category_template ();
1701 build_objc_exception_stuff ();
1703 if (flag_next_runtime)
1704 build_next_objc_exception_stuff ();
1706 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1708 if (! flag_next_runtime)
1709 build_selector_table_decl ();
1711 /* Forward declare constant_string_id and constant_string_type. */
1712 if (!constant_string_class_name)
1713 constant_string_class_name = default_constant_string_class_name;
1715 constant_string_id = get_identifier (constant_string_class_name);
1716 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1718 /* Pre-build the following entities - for speed/convenience. */
1719 self_id = get_identifier ("self");
1720 ucmd_id = get_identifier ("_cmd");
1723 pop_lang_context ();
1726 write_symbols = save_write_symbols;
1727 debug_hooks = save_hooks;
1730 /* Ensure that the ivar list for NSConstantString/NXConstantString
1731 (or whatever was specified via `-fconstant-string-class')
1732 contains fields at least as large as the following three, so that
1733 the runtime can stomp on them with confidence:
1735 struct STRING_OBJECT_CLASS_NAME
1739 unsigned int length;
1743 check_string_class_template (void)
1745 tree field_decl = objc_get_class_ivars (constant_string_id);
1747 #define AT_LEAST_AS_LARGE_AS(F, T) \
1748 (F && TREE_CODE (F) == FIELD_DECL \
1749 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1750 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1752 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1755 field_decl = TREE_CHAIN (field_decl);
1756 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1759 field_decl = TREE_CHAIN (field_decl);
1760 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1762 #undef AT_LEAST_AS_LARGE_AS
1765 /* Avoid calling `check_string_class_template ()' more than once. */
1766 static GTY(()) int string_layout_checked;
1768 /* Construct an internal string layout to be used as a template for
1769 creating NSConstantString/NXConstantString instances. */
1772 objc_build_internal_const_str_type (void)
1774 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1775 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1776 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1778 TREE_CHAIN (field) = fields; fields = field;
1779 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1780 TREE_CHAIN (field) = fields; fields = field;
1781 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1783 finish_builtin_struct (type, "__builtin_ObjCString",
1789 /* Custom build_string which sets TREE_TYPE! */
1792 my_build_string (int len, const char *str)
1794 return fix_string_type (build_string (len, str));
1797 /* Build a string with contents STR and length LEN and convert it to a
1801 my_build_string_pointer (int len, const char *str)
1803 tree string = my_build_string (len, str);
1804 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1805 return build1 (ADDR_EXPR, ptrtype, string);
1809 string_hash (const void *ptr)
1811 tree str = ((struct string_descriptor *)ptr)->literal;
1812 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1813 int i, len = TREE_STRING_LENGTH (str);
1816 for (i = 0; i < len; i++)
1817 h = ((h * 613) + p[i]);
1823 string_eq (const void *ptr1, const void *ptr2)
1825 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1826 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1827 int len1 = TREE_STRING_LENGTH (str1);
1829 return (len1 == TREE_STRING_LENGTH (str2)
1830 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1834 /* Given a chain of STRING_CST's, build a static instance of
1835 NXConstantString which points at the concatenation of those
1836 strings. We place the string object in the __string_objects
1837 section of the __OBJC segment. The Objective-C runtime will
1838 initialize the isa pointers of the string objects to point at the
1839 NXConstantString class object. */
1842 objc_build_string_object (tree string)
1844 tree initlist, constructor, constant_string_class;
1847 struct string_descriptor *desc, key;
1850 /* Prep the string argument. */
1851 string = fix_string_type (string);
1852 TREE_SET_CODE (string, STRING_CST);
1853 length = TREE_STRING_LENGTH (string) - 1;
1855 /* Check whether the string class being used actually exists and has the
1856 correct ivar layout. */
1857 if (!string_layout_checked)
1859 string_layout_checked = -1;
1860 constant_string_class = lookup_interface (constant_string_id);
1861 internal_const_str_type = objc_build_internal_const_str_type ();
1863 if (!constant_string_class
1864 || !(constant_string_type
1865 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1866 error ("cannot find interface declaration for %qs",
1867 IDENTIFIER_POINTER (constant_string_id));
1868 /* The NSConstantString/NXConstantString ivar layout is now known. */
1869 else if (!check_string_class_template ())
1870 error ("interface %qs does not have valid constant string layout",
1871 IDENTIFIER_POINTER (constant_string_id));
1872 /* For the NeXT runtime, we can generate a literal reference
1873 to the string class, don't need to run a constructor. */
1874 else if (flag_next_runtime && !setup_string_decl ())
1875 error ("cannot find reference tag for class %qs",
1876 IDENTIFIER_POINTER (constant_string_id));
1879 string_layout_checked = 1; /* Success! */
1880 add_class_reference (constant_string_id);
1884 if (string_layout_checked == -1)
1885 return error_mark_node;
1887 /* Perhaps we already constructed a constant string just like this one? */
1888 key.literal = string;
1889 loc = htab_find_slot (string_htab, &key, INSERT);
1895 *loc = desc = ggc_alloc (sizeof (*desc));
1896 desc->literal = string;
1898 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1899 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1900 fields = TYPE_FIELDS (internal_const_str_type);
1902 = build_tree_list (fields,
1904 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1905 : build_int_cst (NULL_TREE, 0));
1906 fields = TREE_CHAIN (fields);
1907 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1909 fields = TREE_CHAIN (fields);
1910 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1912 constructor = objc_build_constructor (internal_const_str_type,
1913 nreverse (initlist));
1914 TREE_INVARIANT (constructor) = true;
1916 if (!flag_next_runtime)
1918 = objc_add_static_instance (constructor, internal_const_str_type);
1921 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1922 DECL_INITIAL (var) = constructor;
1923 TREE_STATIC (var) = 1;
1924 pushdecl_top_level (var);
1927 desc->constructor = constructor;
1930 addr = convert (build_pointer_type (constant_string_type),
1931 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1936 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1938 static GTY(()) int num_static_inst;
1941 objc_add_static_instance (tree constructor, tree class_decl)
1946 /* Find the list of static instances for the CLASS_DECL. Create one if
1948 for (chain = &objc_static_instances;
1949 *chain && TREE_VALUE (*chain) != class_decl;
1950 chain = &TREE_CHAIN (*chain));
1953 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1954 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1957 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1958 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1959 DECL_COMMON (decl) = 1;
1960 TREE_STATIC (decl) = 1;
1961 DECL_ARTIFICIAL (decl) = 1;
1962 DECL_INITIAL (decl) = constructor;
1964 /* We may be writing something else just now.
1965 Postpone till end of input. */
1966 DECL_DEFER_OUTPUT (decl) = 1;
1967 pushdecl_top_level (decl);
1968 rest_of_decl_compilation (decl, 1, 0);
1970 /* Add the DECL to the head of this CLASS' list. */
1971 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1976 /* Build a static constant CONSTRUCTOR
1977 with type TYPE and elements ELTS. */
1980 objc_build_constructor (tree type, tree elts)
1982 tree constructor = build_constructor (type, elts);
1984 TREE_CONSTANT (constructor) = 1;
1985 TREE_STATIC (constructor) = 1;
1986 TREE_READONLY (constructor) = 1;
1989 /* Adjust for impedance mismatch. We should figure out how to build
1990 CONSTRUCTORs that consistently please both the C and C++ gods. */
1991 if (!TREE_PURPOSE (elts))
1992 TREE_TYPE (constructor) = NULL_TREE;
1993 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1999 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2001 /* Predefine the following data type:
2009 void *defs[cls_def_cnt + cat_def_cnt];
2013 build_objc_symtab_template (void)
2015 tree field_decl, field_decl_chain;
2017 objc_symtab_template
2018 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2020 /* long sel_ref_cnt; */
2021 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2022 field_decl_chain = field_decl;
2025 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2027 chainon (field_decl_chain, field_decl);
2029 /* short cls_def_cnt; */
2030 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2031 chainon (field_decl_chain, field_decl);
2033 /* short cat_def_cnt; */
2034 field_decl = create_field_decl (short_integer_type_node,
2036 chainon (field_decl_chain, field_decl);
2038 if (imp_count || cat_count || !flag_next_runtime)
2040 /* void *defs[imp_count + cat_count (+ 1)]; */
2041 /* NB: The index is one less than the size of the array. */
2042 int index = imp_count + cat_count
2043 + (flag_next_runtime? -1: 0);
2044 field_decl = create_field_decl
2047 build_index_type (build_int_cst (NULL_TREE, index))),
2049 chainon (field_decl_chain, field_decl);
2052 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2055 /* Create the initial value for the `defs' field of _objc_symtab.
2056 This is a CONSTRUCTOR. */
2059 init_def_list (tree type)
2061 tree expr, initlist = NULL_TREE;
2062 struct imp_entry *impent;
2065 for (impent = imp_list; impent; impent = impent->next)
2067 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2069 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2070 initlist = tree_cons (NULL_TREE, expr, initlist);
2075 for (impent = imp_list; impent; impent = impent->next)
2077 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2079 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2080 initlist = tree_cons (NULL_TREE, expr, initlist);
2084 if (!flag_next_runtime)
2086 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2089 if (static_instances_decl)
2090 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2092 expr = build_int_cst (NULL_TREE, 0);
2094 initlist = tree_cons (NULL_TREE, expr, initlist);
2097 return objc_build_constructor (type, nreverse (initlist));
2100 /* Construct the initial value for all of _objc_symtab. */
2103 init_objc_symtab (tree type)
2107 /* sel_ref_cnt = { ..., 5, ... } */
2109 initlist = build_tree_list (NULL_TREE,
2110 build_int_cst (long_integer_type_node, 0));
2112 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2114 if (flag_next_runtime || ! sel_ref_chain)
2115 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2118 = tree_cons (NULL_TREE,
2119 convert (build_pointer_type (objc_selector_type),
2120 build_unary_op (ADDR_EXPR,
2121 UOBJC_SELECTOR_TABLE_decl, 1)),
2124 /* cls_def_cnt = { ..., 5, ... } */
2126 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2128 /* cat_def_cnt = { ..., 5, ... } */
2130 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2132 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2134 if (imp_count || cat_count || !flag_next_runtime)
2137 tree field = TYPE_FIELDS (type);
2138 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2140 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2144 return objc_build_constructor (type, nreverse (initlist));
2147 /* Generate forward declarations for metadata such as
2148 'OBJC_CLASS_...'. */
2151 build_metadata_decl (const char *name, tree type)
2155 /* struct TYPE NAME_<name>; */
2156 decl = start_var_decl (type, synth_id_with_class_suffix
2158 objc_implementation_context));
2163 /* Push forward-declarations of all the categories so that
2164 init_def_list can use them in a CONSTRUCTOR. */
2167 forward_declare_categories (void)
2169 struct imp_entry *impent;
2170 tree sav = objc_implementation_context;
2172 for (impent = imp_list; impent; impent = impent->next)
2174 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2176 /* Set an invisible arg to synth_id_with_class_suffix. */
2177 objc_implementation_context = impent->imp_context;
2178 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2179 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2180 objc_category_template);
2183 objc_implementation_context = sav;
2186 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2187 and initialized appropriately. */
2190 generate_objc_symtab_decl (void)
2192 /* forward declare categories */
2194 forward_declare_categories ();
2196 build_objc_symtab_template ();
2197 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2198 finish_var_decl (UOBJC_SYMBOLS_decl,
2199 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2203 init_module_descriptor (tree type)
2205 tree initlist, expr;
2207 /* version = { 1, ... } */
2209 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2210 initlist = build_tree_list (NULL_TREE, expr);
2212 /* size = { ..., sizeof (struct _objc_module), ... } */
2214 expr = convert (long_integer_type_node,
2215 size_in_bytes (objc_module_template));
2216 initlist = tree_cons (NULL_TREE, expr, initlist);
2218 /* name = { ..., "foo.m", ... } */
2220 expr = add_objc_string (get_identifier (input_filename), class_names);
2221 initlist = tree_cons (NULL_TREE, expr, initlist);
2223 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2225 if (UOBJC_SYMBOLS_decl)
2226 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2228 expr = build_int_cst (NULL_TREE, 0);
2229 initlist = tree_cons (NULL_TREE, expr, initlist);
2231 return objc_build_constructor (type, nreverse (initlist));
2234 /* Write out the data structures to describe Objective C classes defined.
2236 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2239 build_module_descriptor (void)
2241 tree field_decl, field_decl_chain;
2244 push_lang_context (lang_name_c); /* extern "C" */
2247 objc_module_template
2248 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2251 field_decl = create_field_decl (long_integer_type_node, "version");
2252 field_decl_chain = field_decl;
2255 field_decl = create_field_decl (long_integer_type_node, "size");
2256 chainon (field_decl_chain, field_decl);
2259 field_decl = create_field_decl (string_type_node, "name");
2260 chainon (field_decl_chain, field_decl);
2262 /* struct _objc_symtab *symtab; */
2264 = create_field_decl (build_pointer_type
2265 (xref_tag (RECORD_TYPE,
2266 get_identifier (UTAG_SYMTAB))),
2268 chainon (field_decl_chain, field_decl);
2270 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2272 /* Create an instance of "_objc_module". */
2273 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2274 finish_var_decl (UOBJC_MODULES_decl,
2275 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2278 pop_lang_context ();
2282 /* The GNU runtime requires us to provide a static initializer function
2285 static void __objc_gnu_init (void) {
2286 __objc_exec_class (&L_OBJC_MODULES);
2290 build_module_initializer_routine (void)
2295 push_lang_context (lang_name_c); /* extern "C" */
2298 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2299 objc_start_function (get_identifier (TAG_GNUINIT),
2300 build_function_type (void_type_node,
2302 NULL_TREE, objc_get_parm_info (0));
2304 body = c_begin_compound_stmt (true);
2305 add_stmt (build_function_call
2309 build_unary_op (ADDR_EXPR,
2310 UOBJC_MODULES_decl, 0))));
2311 add_stmt (c_end_compound_stmt (body, true));
2313 TREE_PUBLIC (current_function_decl) = 0;
2316 /* For Objective-C++, we will need to call __objc_gnu_init
2317 from objc_generate_static_init_call() below. */
2318 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2321 GNU_INIT_decl = current_function_decl;
2325 pop_lang_context ();
2330 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2331 to be called by the module initializer routine. */
2334 objc_static_init_needed_p (void)
2336 return (GNU_INIT_decl != NULL_TREE);
2339 /* Generate a call to the __objc_gnu_init initializer function. */
2342 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2344 add_stmt (build_stmt (EXPR_STMT,
2345 build_function_call (GNU_INIT_decl, NULL_TREE)));
2349 #endif /* OBJCPLUS */
2351 /* Return the DECL of the string IDENT in the SECTION. */
2354 get_objc_string_decl (tree ident, enum string_section section)
2358 if (section == class_names)
2359 chain = class_names_chain;
2360 else if (section == meth_var_names)
2361 chain = meth_var_names_chain;
2362 else if (section == meth_var_types)
2363 chain = meth_var_types_chain;
2367 for (; chain != 0; chain = TREE_CHAIN (chain))
2368 if (TREE_VALUE (chain) == ident)
2369 return (TREE_PURPOSE (chain));
2375 /* Output references to all statically allocated objects. Return the DECL
2376 for the array built. */
2379 generate_static_references (void)
2381 tree decls = NULL_TREE, expr = NULL_TREE;
2382 tree class_name, class, decl, initlist;
2383 tree cl_chain, in_chain, type
2384 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2385 int num_inst, num_class;
2388 if (flag_next_runtime)
2391 for (cl_chain = objc_static_instances, num_class = 0;
2392 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2394 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2395 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2397 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2398 decl = start_var_decl (type, buf);
2400 /* Output {class_name, ...}. */
2401 class = TREE_VALUE (cl_chain);
2402 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2403 initlist = build_tree_list (NULL_TREE,
2404 build_unary_op (ADDR_EXPR, class_name, 1));
2406 /* Output {..., instance, ...}. */
2407 for (in_chain = TREE_PURPOSE (cl_chain);
2408 in_chain; in_chain = TREE_CHAIN (in_chain))
2410 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2411 initlist = tree_cons (NULL_TREE, expr, initlist);
2414 /* Output {..., NULL}. */
2415 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2417 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2418 finish_var_decl (decl, expr);
2420 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2423 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2424 expr = objc_build_constructor (type, nreverse (decls));
2425 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2426 finish_var_decl (static_instances_decl, expr);
2429 /* Output all strings. */
2432 generate_strings (void)
2434 tree chain, string_expr;
2435 tree string, decl, type;
2437 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2439 string = TREE_VALUE (chain);
2440 decl = TREE_PURPOSE (chain);
2441 type = build_array_type
2444 (build_int_cst (NULL_TREE,
2445 IDENTIFIER_LENGTH (string))));
2446 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2447 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2448 IDENTIFIER_POINTER (string));
2449 finish_var_decl (decl, string_expr);
2452 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2454 string = TREE_VALUE (chain);
2455 decl = TREE_PURPOSE (chain);
2456 type = build_array_type
2459 (build_int_cst (NULL_TREE,
2460 IDENTIFIER_LENGTH (string))));
2461 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2462 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2463 IDENTIFIER_POINTER (string));
2464 finish_var_decl (decl, string_expr);
2467 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2469 string = TREE_VALUE (chain);
2470 decl = TREE_PURPOSE (chain);
2471 type = build_array_type
2474 (build_int_cst (NULL_TREE,
2475 IDENTIFIER_LENGTH (string))));
2476 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2477 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2478 IDENTIFIER_POINTER (string));
2479 finish_var_decl (decl, string_expr);
2483 static GTY(()) int selector_reference_idx;
2486 build_selector_reference_decl (void)
2491 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2492 decl = start_var_decl (objc_selector_type, buf);
2498 build_selector_table_decl (void)
2502 if (flag_typed_selectors)
2504 build_selector_template ();
2505 temp = build_array_type (objc_selector_template, NULL_TREE);
2508 temp = build_array_type (objc_selector_type, NULL_TREE);
2510 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2513 /* Just a handy wrapper for add_objc_string. */
2516 build_selector (tree ident)
2518 return convert (objc_selector_type,
2519 add_objc_string (ident, meth_var_names));
2523 build_selector_translation_table (void)
2525 tree chain, initlist = NULL_TREE;
2527 tree decl = NULL_TREE;
2529 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2533 if (warn_selector && objc_implementation_context)
2537 for (method_chain = meth_var_names_chain;
2539 method_chain = TREE_CHAIN (method_chain))
2541 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2550 if (flag_next_runtime && TREE_PURPOSE (chain))
2551 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2553 loc = &input_location;
2554 warning (0, "%Hcreating selector for nonexistent method %qE",
2555 loc, TREE_VALUE (chain));
2559 expr = build_selector (TREE_VALUE (chain));
2560 /* add one for the '\0' character */
2561 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2563 if (flag_next_runtime)
2565 decl = TREE_PURPOSE (chain);
2566 finish_var_decl (decl, expr);
2570 if (flag_typed_selectors)
2572 tree eltlist = NULL_TREE;
2573 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2574 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2575 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2576 expr = objc_build_constructor (objc_selector_template,
2577 nreverse (eltlist));
2580 initlist = tree_cons (NULL_TREE, expr, initlist);
2584 if (! flag_next_runtime)
2586 /* Cause the selector table (previously forward-declared)
2587 to be actually output. */
2588 initlist = tree_cons (NULL_TREE,
2589 flag_typed_selectors
2590 ? objc_build_constructor
2591 (objc_selector_template,
2592 tree_cons (NULL_TREE,
2593 build_int_cst (NULL_TREE, 0),
2594 tree_cons (NULL_TREE,
2595 build_int_cst (NULL_TREE, 0),
2597 : build_int_cst (NULL_TREE, 0), initlist);
2598 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2599 nreverse (initlist));
2600 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2605 get_proto_encoding (tree proto)
2610 if (! METHOD_ENCODING (proto))
2612 encoding = encode_method_prototype (proto);
2613 METHOD_ENCODING (proto) = encoding;
2616 encoding = METHOD_ENCODING (proto);
2618 return add_objc_string (encoding, meth_var_types);
2621 return build_int_cst (NULL_TREE, 0);
2624 /* sel_ref_chain is a list whose "value" fields will be instances of
2625 identifier_node that represent the selector. */
2628 build_typed_selector_reference (tree ident, tree prototype)
2630 tree *chain = &sel_ref_chain;
2636 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2637 goto return_at_index;
2640 chain = &TREE_CHAIN (*chain);
2643 *chain = tree_cons (prototype, ident, NULL_TREE);
2646 expr = build_unary_op (ADDR_EXPR,
2647 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2648 build_int_cst (NULL_TREE, index)),
2650 return convert (objc_selector_type, expr);
2654 build_selector_reference (tree ident)
2656 tree *chain = &sel_ref_chain;
2662 if (TREE_VALUE (*chain) == ident)
2663 return (flag_next_runtime
2664 ? TREE_PURPOSE (*chain)
2665 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2666 build_int_cst (NULL_TREE, index)));
2669 chain = &TREE_CHAIN (*chain);
2672 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2674 *chain = tree_cons (expr, ident, NULL_TREE);
2676 return (flag_next_runtime
2678 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2679 build_int_cst (NULL_TREE, index)));
2682 static GTY(()) int class_reference_idx;
2685 build_class_reference_decl (void)
2690 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2691 decl = start_var_decl (objc_class_type, buf);
2696 /* Create a class reference, but don't create a variable to reference
2700 add_class_reference (tree ident)
2704 if ((chain = cls_ref_chain))
2709 if (ident == TREE_VALUE (chain))
2713 chain = TREE_CHAIN (chain);
2717 /* Append to the end of the list */
2718 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2721 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2724 /* Get a class reference, creating it if necessary. Also create the
2725 reference variable. */
2728 objc_get_class_reference (tree ident)
2730 tree orig_ident = (DECL_P (ident)
2733 ? OBJC_TYPE_NAME (ident)
2735 bool local_scope = false;
2738 if (processing_template_decl)
2739 /* Must wait until template instantiation time. */
2740 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2743 if (TREE_CODE (ident) == TYPE_DECL)
2744 ident = (DECL_ORIGINAL_TYPE (ident)
2745 ? DECL_ORIGINAL_TYPE (ident)
2746 : TREE_TYPE (ident));
2749 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2750 && TYPE_CONTEXT (ident) != global_namespace)
2754 if (local_scope || !(ident = objc_is_class_name (ident)))
2756 error ("%qs is not an Objective-C class name or alias",
2757 IDENTIFIER_POINTER (orig_ident));
2758 return error_mark_node;
2761 if (flag_next_runtime && !flag_zero_link)
2766 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2767 if (TREE_VALUE (*chain) == ident)
2769 if (! TREE_PURPOSE (*chain))
2770 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2772 return TREE_PURPOSE (*chain);
2775 decl = build_class_reference_decl ();
2776 *chain = tree_cons (decl, ident, NULL_TREE);
2783 add_class_reference (ident);
2785 params = build_tree_list (NULL_TREE,
2786 my_build_string_pointer
2787 (IDENTIFIER_LENGTH (ident) + 1,
2788 IDENTIFIER_POINTER (ident)));
2790 assemble_external (objc_get_class_decl);
2791 return build_function_call (objc_get_class_decl, params);
2795 /* For each string section we have a chain which maps identifier nodes
2796 to decls for the strings. */
2799 add_objc_string (tree ident, enum string_section section)
2803 if (section == class_names)
2804 chain = &class_names_chain;
2805 else if (section == meth_var_names)
2806 chain = &meth_var_names_chain;
2807 else if (section == meth_var_types)
2808 chain = &meth_var_types_chain;
2814 if (TREE_VALUE (*chain) == ident)
2815 return convert (string_type_node,
2816 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2818 chain = &TREE_CHAIN (*chain);
2821 decl = build_objc_string_decl (section);
2823 *chain = tree_cons (decl, ident, NULL_TREE);
2825 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2828 static GTY(()) int class_names_idx;
2829 static GTY(()) int meth_var_names_idx;
2830 static GTY(()) int meth_var_types_idx;
2833 build_objc_string_decl (enum string_section section)
2838 if (section == class_names)
2839 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2840 else if (section == meth_var_names)
2841 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2842 else if (section == meth_var_types)
2843 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2845 ident = get_identifier (buf);
2847 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2848 DECL_EXTERNAL (decl) = 1;
2849 TREE_PUBLIC (decl) = 0;
2850 TREE_USED (decl) = 1;
2851 TREE_CONSTANT (decl) = 1;
2852 DECL_CONTEXT (decl) = 0;
2853 DECL_ARTIFICIAL (decl) = 1;
2855 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2858 make_decl_rtl (decl);
2859 pushdecl_top_level (decl);
2866 objc_declare_alias (tree alias_ident, tree class_ident)
2868 tree underlying_class;
2871 if (current_namespace != global_namespace) {
2872 error ("Objective-C declarations may only appear in global scope");
2874 #endif /* OBJCPLUS */
2876 if (!(underlying_class = objc_is_class_name (class_ident)))
2877 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2878 else if (objc_is_class_name (alias_ident))
2879 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2882 /* Implement @compatibility_alias as a typedef. */
2884 push_lang_context (lang_name_c); /* extern "C" */
2886 lang_hooks.decls.pushdecl (build_decl
2889 xref_tag (RECORD_TYPE, underlying_class)));
2891 pop_lang_context ();
2893 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2898 objc_declare_class (tree ident_list)
2902 if (current_namespace != global_namespace) {
2903 error ("Objective-C declarations may only appear in global scope");
2905 #endif /* OBJCPLUS */
2907 for (list = ident_list; list; list = TREE_CHAIN (list))
2909 tree ident = TREE_VALUE (list);
2911 if (! objc_is_class_name (ident))
2913 tree record = lookup_name (ident), type = record;
2917 if (TREE_CODE (record) == TYPE_DECL)
2918 type = DECL_ORIGINAL_TYPE (record);
2920 if (!TYPE_HAS_OBJC_INFO (type)
2921 || !TYPE_OBJC_INTERFACE (type))
2923 error ("%qs redeclared as different kind of symbol",
2924 IDENTIFIER_POINTER (ident));
2925 error ("previous declaration of %q+D",
2930 record = xref_tag (RECORD_TYPE, ident);
2931 INIT_TYPE_OBJC_INFO (record);
2932 TYPE_OBJC_INTERFACE (record) = ident;
2933 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2939 objc_is_class_name (tree ident)
2943 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2944 && identifier_global_value (ident))
2945 ident = identifier_global_value (ident);
2946 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2947 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2949 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2950 ident = OBJC_TYPE_NAME (ident);
2952 if (ident && TREE_CODE (ident) == TYPE_DECL)
2953 ident = DECL_NAME (ident);
2955 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2958 if (lookup_interface (ident))
2961 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2963 if (ident == TREE_VALUE (chain))
2967 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2969 if (ident == TREE_VALUE (chain))
2970 return TREE_PURPOSE (chain);
2976 /* Check whether TYPE is either 'id' or 'Class'. */
2979 objc_is_id (tree type)
2981 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2982 && identifier_global_value (type))
2983 type = identifier_global_value (type);
2985 if (type && TREE_CODE (type) == TYPE_DECL)
2986 type = TREE_TYPE (type);
2988 /* NB: This function may be called before the ObjC front-end has
2989 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2990 return (objc_object_type && type
2991 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2996 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2997 class instance. This is needed by other parts of the compiler to
2998 handle ObjC types gracefully. */
3001 objc_is_object_ptr (tree type)
3005 type = TYPE_MAIN_VARIANT (type);
3006 if (!POINTER_TYPE_P (type))
3009 ret = objc_is_id (type);
3011 ret = objc_is_class_name (TREE_TYPE (type));
3017 objc_is_gcable_type (tree type, int or_strong_p)
3023 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3025 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3027 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3029 type = TREE_TYPE (type);
3030 if (TREE_CODE (type) != RECORD_TYPE)
3032 name = TYPE_NAME (type);
3033 return (objc_is_class_name (name) != NULL_TREE);
3037 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3039 if (expr == oldexpr)
3042 switch (TREE_CODE (expr))
3045 return objc_build_component_ref
3046 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3049 DECL_NAME (TREE_OPERAND (expr, 1)));
3051 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3054 TREE_OPERAND (expr, 1));
3056 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3065 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3068 /* The LHS parameter contains the expression 'outervar->memberspec';
3069 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3070 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3073 = objc_substitute_decl
3074 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3076 = (flag_objc_direct_dispatch
3077 ? objc_assign_ivar_fast_decl
3078 : objc_assign_ivar_decl);
3080 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3082 func_params = tree_cons (NULL_TREE,
3083 convert (objc_object_type, rhs),
3084 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3085 tree_cons (NULL_TREE, offs,
3088 assemble_external (func);
3089 return build_function_call (func, func_params);
3093 objc_build_global_assignment (tree lhs, tree rhs)
3095 tree func_params = tree_cons (NULL_TREE,
3096 convert (objc_object_type, rhs),
3097 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3098 build_unary_op (ADDR_EXPR, lhs, 0)),
3101 assemble_external (objc_assign_global_decl);
3102 return build_function_call (objc_assign_global_decl, func_params);
3106 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3108 tree func_params = tree_cons (NULL_TREE,
3109 convert (objc_object_type, rhs),
3110 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3111 build_unary_op (ADDR_EXPR, lhs, 0)),
3114 assemble_external (objc_assign_strong_cast_decl);
3115 return build_function_call (objc_assign_strong_cast_decl, func_params);
3119 objc_is_gcable_p (tree expr)
3121 return (TREE_CODE (expr) == COMPONENT_REF
3122 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3123 : TREE_CODE (expr) == ARRAY_REF
3124 ? (objc_is_gcable_p (TREE_TYPE (expr))
3125 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3126 : TREE_CODE (expr) == ARRAY_TYPE
3127 ? objc_is_gcable_p (TREE_TYPE (expr))
3129 ? objc_is_gcable_type (expr, 1)
3130 : (objc_is_gcable_p (TREE_TYPE (expr))
3132 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3136 objc_is_ivar_reference_p (tree expr)
3138 return (TREE_CODE (expr) == ARRAY_REF
3139 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3140 : TREE_CODE (expr) == COMPONENT_REF
3141 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3146 objc_is_global_reference_p (tree expr)
3148 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3149 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3151 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3156 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3158 tree result = NULL_TREE, outer;
3159 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3161 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3162 will have been transformed to the form '*(type *)&expr'. */
3163 if (TREE_CODE (lhs) == INDIRECT_REF)
3165 outer = TREE_OPERAND (lhs, 0);
3167 while (!strong_cast_p
3168 && (TREE_CODE (outer) == CONVERT_EXPR
3169 || TREE_CODE (outer) == NOP_EXPR
3170 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3172 tree lhstype = TREE_TYPE (outer);
3174 /* Descend down the cast chain, and record the first objc_gc
3176 if (POINTER_TYPE_P (lhstype))
3179 = lookup_attribute ("objc_gc",
3180 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3186 outer = TREE_OPERAND (outer, 0);
3190 /* If we have a __strong cast, it trumps all else. */
3193 if (modifycode != NOP_EXPR)
3194 goto invalid_pointer_arithmetic;
3196 if (warn_assign_intercept)
3197 warning (0, "strong-cast assignment has been intercepted");
3199 result = objc_build_strong_cast_assignment (lhs, rhs);
3204 /* the lhs must be of a suitable type, regardless of its underlying
3206 if (!objc_is_gcable_p (lhs))
3212 && (TREE_CODE (outer) == COMPONENT_REF
3213 || TREE_CODE (outer) == ARRAY_REF))
3214 outer = TREE_OPERAND (outer, 0);
3216 if (TREE_CODE (outer) == INDIRECT_REF)
3218 outer = TREE_OPERAND (outer, 0);
3222 outer_gc_p = objc_is_gcable_p (outer);
3224 /* Handle ivar assignments. */
3225 if (objc_is_ivar_reference_p (lhs))
3227 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3228 doesn't cut it here), the best we can do here is suggest a cast. */
3229 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3231 /* We may still be able to use the global write barrier... */
3232 if (!indirect_p && objc_is_global_reference_p (outer))
3233 goto global_reference;
3236 if (modifycode == NOP_EXPR)
3238 if (warn_assign_intercept)
3239 warning (0, "strong-cast may possibly be needed");
3245 if (modifycode != NOP_EXPR)
3246 goto invalid_pointer_arithmetic;
3248 if (warn_assign_intercept)
3249 warning (0, "instance variable assignment has been intercepted");
3251 result = objc_build_ivar_assignment (outer, lhs, rhs);
3256 /* Likewise, intercept assignment to global/static variables if their type is
3258 if (objc_is_global_reference_p (outer))
3264 if (modifycode != NOP_EXPR)
3266 invalid_pointer_arithmetic:
3268 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3273 if (warn_assign_intercept)
3274 warning (0, "global/static variable assignment has been intercepted");
3276 result = objc_build_global_assignment (lhs, rhs);
3279 /* In all other cases, fall back to the normal mechanism. */
3284 struct interface_tuple GTY(())
3290 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3293 hash_interface (const void *p)
3295 const struct interface_tuple *d = p;
3296 return htab_hash_pointer (d->id);
3300 eq_interface (const void *p1, const void *p2)
3302 const struct interface_tuple *d = p1;
3307 lookup_interface (tree ident)
3310 if (ident && TREE_CODE (ident) == TYPE_DECL)
3311 ident = DECL_NAME (ident);
3314 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3318 struct interface_tuple **slot;
3323 slot = (struct interface_tuple **)
3324 htab_find_slot_with_hash (interface_htab, ident,
3325 htab_hash_pointer (ident),
3328 i = (*slot)->class_name;
3334 /* Implement @defs (<classname>) within struct bodies. */
3337 objc_get_class_ivars (tree class_name)
3339 tree interface = lookup_interface (class_name);
3342 return get_class_ivars (interface, true);
3344 error ("cannot find interface declaration for %qs",
3345 IDENTIFIER_POINTER (class_name));
3347 return error_mark_node;
3350 /* Used by: build_private_template, continue_class,
3351 and for @defs constructs. */
3354 get_class_ivars (tree interface, bool inherited)
3356 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3358 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3359 by the current class (i.e., they do not include super-class ivars).
3360 However, the CLASS_IVARS list will be side-effected by a call to
3361 finish_struct(), which will fill in field offsets. */
3362 if (!CLASS_IVARS (interface))
3363 CLASS_IVARS (interface) = ivar_chain;
3368 while (CLASS_SUPER_NAME (interface))
3370 /* Prepend super-class ivars. */
3371 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3372 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3380 objc_create_temporary_var (tree type)
3384 decl = build_decl (VAR_DECL, NULL_TREE, type);
3385 TREE_USED (decl) = 1;
3386 DECL_ARTIFICIAL (decl) = 1;
3387 DECL_IGNORED_P (decl) = 1;
3388 DECL_CONTEXT (decl) = current_function_decl;
3393 /* Exception handling constructs. We begin by having the parser do most
3394 of the work and passing us blocks. What we do next depends on whether
3395 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3396 We abstract all of this in a handful of appropriately named routines. */
3398 /* Stack of open try blocks. */
3400 struct objc_try_context
3402 struct objc_try_context *outer;
3404 /* Statements (or statement lists) as processed by the parser. */
3408 /* Some file position locations. */
3409 location_t try_locus;
3410 location_t end_try_locus;
3411 location_t end_catch_locus;
3412 location_t finally_locus;
3413 location_t end_finally_locus;
3415 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3416 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3419 /* The CATCH_EXPR of an open @catch clause. */
3422 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3428 static struct objc_try_context *cur_try_context;
3430 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3431 that represents TYPE. For Objective-C, this is just the class name. */
3432 /* ??? Isn't there a class object or some such? Is it easy to get? */
3436 objc_eh_runtime_type (tree type)
3438 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3442 /* Initialize exception handling. */
3445 objc_init_exceptions (void)
3447 static bool done = false;
3452 if (flag_objc_sjlj_exceptions)
3454 /* On Darwin, ObjC exceptions require a sufficiently recent
3455 version of the runtime, so the user must ask for them explicitly. */
3456 if (!flag_objc_exceptions)
3457 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3458 "exception syntax");
3463 c_eh_initialized_p = true;
3464 eh_personality_libfunc
3465 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3466 ? "__gnu_objc_personality_sj0"
3467 : "__gnu_objc_personality_v0");
3468 default_init_unwind_resume_libfunc ();
3469 using_eh_for_cleanups ();
3470 lang_eh_runtime_type = objc_eh_runtime_type;
3475 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3476 we'll arrange for it to be initialized (and associated with a binding)
3480 objc_build_exc_ptr (void)
3482 if (flag_objc_sjlj_exceptions)
3484 tree var = cur_try_context->caught_decl;
3487 var = objc_create_temporary_var (objc_object_type);
3488 cur_try_context->caught_decl = var;
3493 return build (EXC_PTR_EXPR, objc_object_type);
3496 /* Build "objc_exception_try_exit(&_stack)". */
3499 next_sjlj_build_try_exit (void)
3502 t = build_fold_addr_expr (cur_try_context->stack_decl);
3503 t = tree_cons (NULL, t, NULL);
3504 t = build_function_call (objc_exception_try_exit_decl, t);
3509 objc_exception_try_enter (&_stack);
3510 if (_setjmp(&_stack.buf))
3514 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3515 empty, ready for the caller to fill them in. */
3518 next_sjlj_build_enter_and_setjmp (void)
3520 tree t, enter, sj, cond;
3522 t = build_fold_addr_expr (cur_try_context->stack_decl);
3523 t = tree_cons (NULL, t, NULL);
3524 enter = build_function_call (objc_exception_try_enter_decl, t);
3526 t = objc_build_component_ref (cur_try_context->stack_decl,
3527 get_identifier ("buf"));
3528 t = build_fold_addr_expr (t);
3530 /* Convert _setjmp argument to type that is expected. */
3531 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3532 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3534 t = convert (ptr_type_node, t);
3536 t = convert (ptr_type_node, t);
3538 t = tree_cons (NULL, t, NULL);
3539 sj = build_function_call (objc_setjmp_decl, t);
3541 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3542 cond = c_common_truthvalue_conversion (cond);
3544 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3548 DECL = objc_exception_extract(&_stack);
3552 next_sjlj_build_exc_extract (tree decl)
3556 t = build_fold_addr_expr (cur_try_context->stack_decl);
3557 t = tree_cons (NULL, t, NULL);
3558 t = build_function_call (objc_exception_extract_decl, t);
3559 t = convert (TREE_TYPE (decl), t);
3560 t = build (MODIFY_EXPR, void_type_node, decl, t);
3566 if (objc_exception_match(obj_get_class(TYPE), _caught)
3573 objc_exception_try_exit(&_stack);
3575 from the sequence of CATCH_EXPRs in the current try context. */
3578 next_sjlj_build_catch_list (void)
3580 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3582 tree *last = &catch_seq;
3583 bool saw_id = false;
3585 for (; !tsi_end_p (i); tsi_next (&i))
3587 tree stmt = tsi_stmt (i);
3588 tree type = CATCH_TYPES (stmt);
3589 tree body = CATCH_BODY (stmt);
3601 if (type == error_mark_node)
3602 cond = error_mark_node;
3605 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3606 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3607 args = tree_cons (NULL, t, args);
3608 t = build_function_call (objc_exception_match_decl, args);
3609 cond = c_common_truthvalue_conversion (t);
3611 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3612 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3615 last = &COND_EXPR_ELSE (t);
3621 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3622 cur_try_context->caught_decl);
3623 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3624 append_to_statement_list (t, last);
3626 t = next_sjlj_build_try_exit ();
3627 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3628 append_to_statement_list (t, last);
3634 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3635 exception handling. We aim to build:
3638 struct _objc_exception_data _stack;
3639 id volatile _rethrow = 0;
3642 objc_exception_try_enter (&_stack);
3643 if (_setjmp(&_stack.buf))
3645 id _caught = objc_exception_extract(&_stack);
3646 objc_exception_try_enter (&_stack);
3647 if (_setjmp(&_stack.buf))
3648 _rethrow = objc_exception_extract(&_stack);
3658 objc_exception_try_exit(&_stack);
3661 objc_exception_throw(_rethrow);
3665 If CATCH-LIST is empty, we can omit all of the block containing
3666 "_caught" except for the setting of _rethrow. Note the use of
3667 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3668 but handles goto and other exits from the block. */
3671 next_sjlj_build_try_catch_finally (void)
3673 tree rethrow_decl, stack_decl, t;
3674 tree catch_seq, try_fin, bind;
3676 /* Create the declarations involved. */
3677 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3678 stack_decl = objc_create_temporary_var (t);
3679 cur_try_context->stack_decl = stack_decl;
3681 rethrow_decl = objc_create_temporary_var (objc_object_type);
3682 cur_try_context->rethrow_decl = rethrow_decl;
3683 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3684 TREE_CHAIN (rethrow_decl) = stack_decl;
3686 /* Build the outermost variable binding level. */
3687 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3688 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3689 TREE_SIDE_EFFECTS (bind) = 1;
3691 /* Initialize rethrow_decl. */
3692 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3693 convert (objc_object_type, null_pointer_node));
3694 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3695 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3697 /* Build the outermost TRY_FINALLY_EXPR. */
3698 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3699 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3700 TREE_SIDE_EFFECTS (try_fin) = 1;
3701 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3703 /* Create the complete catch sequence. */
3704 if (cur_try_context->catch_list)
3706 tree caught_decl = objc_build_exc_ptr ();
3707 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3709 t = next_sjlj_build_exc_extract (caught_decl);
3710 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3712 t = next_sjlj_build_enter_and_setjmp ();
3713 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3714 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3715 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3718 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3719 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3721 /* Build the main register-and-try if statement. */
3722 t = next_sjlj_build_enter_and_setjmp ();
3723 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3724 COND_EXPR_THEN (t) = catch_seq;
3725 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3726 TREE_OPERAND (try_fin, 0) = t;
3728 /* Build the complete FINALLY statement list. */
3729 t = next_sjlj_build_try_exit ();
3730 t = build_stmt (COND_EXPR,
3731 c_common_truthvalue_conversion (rethrow_decl),
3733 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3734 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3736 append_to_statement_list (cur_try_context->finally_body,
3737 &TREE_OPERAND (try_fin, 1));
3739 t = tree_cons (NULL, rethrow_decl, NULL);
3740 t = build_function_call (objc_exception_throw_decl, t);
3741 t = build_stmt (COND_EXPR,
3742 c_common_truthvalue_conversion (rethrow_decl),
3744 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3745 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3750 /* Called just after parsing the @try and its associated BODY. We now
3751 must prepare for the tricky bits -- handling the catches and finally. */
3754 objc_begin_try_stmt (location_t try_locus, tree body)
3756 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3757 c->outer = cur_try_context;
3759 c->try_locus = try_locus;
3760 c->end_try_locus = input_location;
3761 cur_try_context = c;
3763 objc_init_exceptions ();
3765 if (flag_objc_sjlj_exceptions)
3766 objc_mark_locals_volatile (NULL);
3769 /* Called just after parsing "@catch (parm)". Open a binding level,
3770 enter DECL into the binding level, and initialize it. Leave the
3771 binding level open while the body of the compound statement is parsed. */
3774 objc_begin_catch_clause (tree decl)
3776 tree compound, type, t;
3778 /* Begin a new scope that the entire catch clause will live in. */
3779 compound = c_begin_compound_stmt (true);
3781 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3782 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3783 lang_hooks.decls.pushdecl (decl);
3785 /* Since a decl is required here by syntax, don't warn if its unused. */
3786 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3787 be what the previous objc implementation did. */
3788 TREE_USED (decl) = 1;
3790 /* Verify that the type of the catch is valid. It must be a pointer
3791 to an Objective-C class, or "id" (which is catch-all). */
3792 type = TREE_TYPE (decl);
3794 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3796 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3798 error ("@catch parameter is not a known Objective-C class type");
3799 type = error_mark_node;
3801 else if (cur_try_context->catch_list)
3803 /* Examine previous @catch clauses and see if we've already
3804 caught the type in question. */
3805 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3806 for (; !tsi_end_p (i); tsi_next (&i))
3808 tree stmt = tsi_stmt (i);
3809 t = CATCH_TYPES (stmt);
3810 if (t == error_mark_node)
3812 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3814 warning (0, "exception of type %<%T%> will be caught",
3816 warning (0, "%H by earlier handler for %<%T%>",
3817 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3823 /* Record the data for the catch in the try context so that we can
3824 finalize it later. */
3825 t = build_stmt (CATCH_EXPR, type, compound);
3826 cur_try_context->current_catch = t;
3828 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3829 t = objc_build_exc_ptr ();
3830 t = convert (TREE_TYPE (decl), t);
3831 t = build (MODIFY_EXPR, void_type_node, decl, t);
3835 /* Called just after parsing the closing brace of a @catch clause. Close
3836 the open binding level, and record a CATCH_EXPR for it. */
3839 objc_finish_catch_clause (void)
3841 tree c = cur_try_context->current_catch;
3842 cur_try_context->current_catch = NULL;
3843 cur_try_context->end_catch_locus = input_location;
3845 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3846 append_to_statement_list (c, &cur_try_context->catch_list);
3849 /* Called after parsing a @finally clause and its associated BODY.
3850 Record the body for later placement. */
3853 objc_build_finally_clause (location_t finally_locus, tree body)
3855 cur_try_context->finally_body = body;
3856 cur_try_context->finally_locus = finally_locus;
3857 cur_try_context->end_finally_locus = input_location;
3860 /* Called to finalize a @try construct. */
3863 objc_finish_try_stmt (void)
3865 struct objc_try_context *c = cur_try_context;
3868 if (c->catch_list == NULL && c->finally_body == NULL)
3869 error ("%<@try%> without %<@catch%> or %<@finally%>");
3871 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3872 if (flag_objc_sjlj_exceptions)
3874 if (!cur_try_context->finally_body)
3876 cur_try_context->finally_locus = input_location;
3877 cur_try_context->end_finally_locus = input_location;
3879 stmt = next_sjlj_build_try_catch_finally ();
3883 /* Otherwise, nest the CATCH inside a FINALLY. */
3887 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3888 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3890 if (c->finally_body)
3892 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3893 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3898 cur_try_context = c->outer;
3904 objc_build_throw_stmt (tree throw_expr)
3908 objc_init_exceptions ();
3910 if (throw_expr == NULL)
3912 /* If we're not inside a @catch block, there is no "current
3913 exception" to be rethrown. */
3914 if (cur_try_context == NULL
3915 || cur_try_context->current_catch == NULL)
3917 error ("%<@throw%> (rethrow) used outside of a @catch block");
3921 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3922 value that we get from the runtime. */
3923 throw_expr = objc_build_exc_ptr ();
3926 /* A throw is just a call to the runtime throw function with the
3927 object as a parameter. */
3928 args = tree_cons (NULL, throw_expr, NULL);
3929 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3933 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3937 /* First lock the mutex. */
3938 mutex = save_expr (mutex);
3939 args = tree_cons (NULL, mutex, NULL);
3940 call = build_function_call (objc_sync_enter_decl, args);
3941 SET_EXPR_LOCATION (call, start_locus);
3944 /* Build the mutex unlock. */
3945 args = tree_cons (NULL, mutex, NULL);
3946 call = build_function_call (objc_sync_exit_decl, args);
3947 SET_EXPR_LOCATION (call, input_location);
3949 /* Put the that and the body in a TRY_FINALLY. */
3950 objc_begin_try_stmt (start_locus, body);
3951 objc_build_finally_clause (input_location, call);
3952 return objc_finish_try_stmt ();
3956 /* Predefine the following data type:
3958 struct _objc_exception_data
3964 /* The following yuckiness should prevent users from having to #include
3965 <setjmp.h> in their code... */
3967 #ifdef TARGET_POWERPC
3968 /* snarfed from /usr/include/ppc/setjmp.h */
3969 #define _JBLEN (26 + 36 + 129 + 1)
3971 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3976 build_next_objc_exception_stuff (void)
3978 tree field_decl, field_decl_chain, index, temp_type;
3980 objc_exception_data_template
3981 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3983 /* int buf[_JBLEN]; */
3985 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3986 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3988 field_decl_chain = field_decl;
3990 /* void *pointers[4]; */
3992 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3993 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3995 chainon (field_decl_chain, field_decl);
3997 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3999 /* int _setjmp(...); */
4000 /* If the user includes <setjmp.h>, this shall be superseded by
4001 'int _setjmp(jmp_buf);' */
4002 temp_type = build_function_type (integer_type_node, NULL_TREE);
4004 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4006 /* id objc_exception_extract(struct _objc_exception_data *); */
4008 = build_function_type (objc_object_type,
4009 tree_cons (NULL_TREE,
4010 build_pointer_type (objc_exception_data_template),
4012 objc_exception_extract_decl
4013 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4014 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4015 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4017 = build_function_type (void_type_node,
4018 tree_cons (NULL_TREE,
4019 build_pointer_type (objc_exception_data_template),
4021 objc_exception_try_enter_decl
4022 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4023 objc_exception_try_exit_decl
4024 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4026 /* int objc_exception_match(id, id); */
4028 = build_function_type (integer_type_node,
4029 tree_cons (NULL_TREE, objc_object_type,
4030 tree_cons (NULL_TREE, objc_object_type,
4031 OBJC_VOID_AT_END)));
4032 objc_exception_match_decl
4033 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4035 /* id objc_assign_ivar (id, id, unsigned int); */
4036 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4037 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4039 = build_function_type (objc_object_type,
4041 (NULL_TREE, objc_object_type,
4042 tree_cons (NULL_TREE, objc_object_type,
4043 tree_cons (NULL_TREE,
4045 OBJC_VOID_AT_END))));
4046 objc_assign_ivar_decl
4047 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4049 #ifdef OFFS_ASSIGNIVAR_FAST
4050 objc_assign_ivar_fast_decl
4051 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4052 NOT_BUILT_IN, NULL, NULL_TREE);
4053 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4054 = tree_cons (get_identifier ("hard_coded_address"),
4055 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4058 /* Default to slower ivar method. */
4059 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4062 /* id objc_assign_global (id, id *); */
4063 /* id objc_assign_strongCast (id, id *); */
4064 temp_type = build_function_type (objc_object_type,
4065 tree_cons (NULL_TREE, objc_object_type,
4066 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4067 OBJC_VOID_AT_END)));
4068 objc_assign_global_decl
4069 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4070 objc_assign_strong_cast_decl
4071 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4075 build_objc_exception_stuff (void)
4077 tree noreturn_list, nothrow_list, temp_type;
4079 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4080 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4082 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4083 /* void objc_sync_enter(id); */
4084 /* void objc_sync_exit(id); */
4085 temp_type = build_function_type (void_type_node,
4086 tree_cons (NULL_TREE, objc_object_type,
4088 objc_exception_throw_decl
4089 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4091 objc_sync_enter_decl
4092 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4093 NULL, nothrow_list);
4095 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4096 NULL, nothrow_list);
4099 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4102 struct <classname> {
4103 struct _objc_class *isa;
4108 build_private_template (tree class)
4110 if (!CLASS_STATIC_TEMPLATE (class))
4112 tree record = objc_build_struct (CLASS_NAME (class),
4113 get_class_ivars (class, false),
4114 CLASS_SUPER_NAME (class));
4116 /* mark this record as class template - for class type checking */
4117 INIT_TYPE_OBJC_INFO (record);
4118 TYPE_OBJC_INTERFACE (record) = class;
4119 CLASS_STATIC_TEMPLATE (class) = record;
4121 /* Set the TREE_USED bit for this struct, so that stab generator
4122 can emit stabs for this struct type. */
4123 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4124 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4128 /* Begin code generation for protocols... */
4130 /* struct _objc_protocol {
4131 struct _objc_class *isa;
4132 char *protocol_name;
4133 struct _objc_protocol **protocol_list;
4134 struct _objc__method_prototype_list *instance_methods;
4135 struct _objc__method_prototype_list *class_methods;
4139 build_protocol_template (void)
4141 tree field_decl, field_decl_chain;
4143 objc_protocol_template = start_struct (RECORD_TYPE,
4144 get_identifier (UTAG_PROTOCOL));
4146 /* struct _objc_class *isa; */
4147 field_decl = create_field_decl (build_pointer_type
4148 (xref_tag (RECORD_TYPE,
4149 get_identifier (UTAG_CLASS))),
4151 field_decl_chain = field_decl;
4153 /* char *protocol_name; */
4154 field_decl = create_field_decl (string_type_node, "protocol_name");
4155 chainon (field_decl_chain, field_decl);
4157 /* struct _objc_protocol **protocol_list; */
4158 field_decl = create_field_decl (build_pointer_type
4160 (objc_protocol_template)),
4162 chainon (field_decl_chain, field_decl);
4164 /* struct _objc__method_prototype_list *instance_methods; */
4165 field_decl = create_field_decl (objc_method_proto_list_ptr,
4166 "instance_methods");
4167 chainon (field_decl_chain, field_decl);
4169 /* struct _objc__method_prototype_list *class_methods; */
4170 field_decl = create_field_decl (objc_method_proto_list_ptr,
4172 chainon (field_decl_chain, field_decl);
4174 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4178 build_descriptor_table_initializer (tree type, tree entries)
4180 tree initlist = NULL_TREE;
4184 tree eltlist = NULL_TREE;
4187 = tree_cons (NULL_TREE,
4188 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4190 = tree_cons (NULL_TREE,
4191 add_objc_string (METHOD_ENCODING (entries),
4196 = tree_cons (NULL_TREE,
4197 objc_build_constructor (type, nreverse (eltlist)),
4200 entries = TREE_CHAIN (entries);
4204 return objc_build_constructor (build_array_type (type, 0),
4205 nreverse (initlist));
4208 /* struct objc_method_prototype_list {
4210 struct objc_method_prototype {
4217 build_method_prototype_list_template (tree list_type, int size)
4219 tree objc_ivar_list_record;
4220 tree field_decl, field_decl_chain;
4222 /* Generate an unnamed struct definition. */
4224 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4226 /* int method_count; */
4227 field_decl = create_field_decl (integer_type_node, "method_count");
4228 field_decl_chain = field_decl;
4230 /* struct objc_method method_list[]; */
4231 field_decl = create_field_decl (build_array_type
4234 (build_int_cst (NULL_TREE, size - 1))),
4236 chainon (field_decl_chain, field_decl);
4238 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4240 return objc_ivar_list_record;
4244 build_method_prototype_template (void)
4247 tree field_decl, field_decl_chain;
4250 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4253 field_decl = create_field_decl (objc_selector_type, "_cmd");
4254 field_decl_chain = field_decl;
4256 /* char *method_types; */
4257 field_decl = create_field_decl (string_type_node, "method_types");
4258 chainon (field_decl_chain, field_decl);
4260 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4262 return proto_record;
4266 objc_method_parm_type (tree type)
4268 type = TREE_VALUE (TREE_TYPE (type));
4269 if (TREE_CODE (type) == TYPE_DECL)
4270 type = TREE_TYPE (type);
4275 objc_encoded_type_size (tree type)
4277 int sz = int_size_in_bytes (type);
4279 /* Make all integer and enum types at least as large
4281 if (sz > 0 && INTEGRAL_TYPE_P (type))
4282 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4283 /* Treat arrays as pointers, since that's how they're
4285 else if (TREE_CODE (type) == ARRAY_TYPE)
4286 sz = int_size_in_bytes (ptr_type_node);
4291 encode_method_prototype (tree method_decl)
4298 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4299 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4301 /* Encode return type. */
4302 encode_type (objc_method_parm_type (method_decl),
4303 obstack_object_size (&util_obstack),
4304 OBJC_ENCODE_INLINE_DEFS);
4307 /* The first two arguments (self and _cmd) are pointers; account for
4309 i = int_size_in_bytes (ptr_type_node);
4310 parm_offset = 2 * i;
4311 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4312 parms = TREE_CHAIN (parms))
4314 tree type = objc_method_parm_type (parms);
4315 int sz = objc_encoded_type_size (type);
4317 /* If a type size is not known, bail out. */
4320 error ("type %q+D does not have a known size",
4322 /* Pretend that the encoding succeeded; the compilation will
4323 fail nevertheless. */
4324 goto finish_encoding;
4329 sprintf (buf, "%d@0:%d", parm_offset, i);
4330 obstack_grow (&util_obstack, buf, strlen (buf));
4332 /* Argument types. */
4333 parm_offset = 2 * i;
4334 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4335 parms = TREE_CHAIN (parms))
4337 tree type = objc_method_parm_type (parms);
4339 /* Process argument qualifiers for user supplied arguments. */
4340 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4343 encode_type (type, obstack_object_size (&util_obstack),
4344 OBJC_ENCODE_INLINE_DEFS);
4346 /* Compute offset. */
4347 sprintf (buf, "%d", parm_offset);
4348 parm_offset += objc_encoded_type_size (type);
4350 obstack_grow (&util_obstack, buf, strlen (buf));
4354 obstack_1grow (&util_obstack, '\0');
4355 result = get_identifier (obstack_finish (&util_obstack));
4356 obstack_free (&util_obstack, util_firstobj);
4361 generate_descriptor_table (tree type, const char *name, int size, tree list,
4364 tree decl, initlist;
4366 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4368 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4369 initlist = tree_cons (NULL_TREE, list, initlist);
4371 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4377 generate_method_descriptors (tree protocol)
4379 tree initlist, chain, method_list_template;
4382 if (!objc_method_prototype_template)
4383 objc_method_prototype_template = build_method_prototype_template ();
4385 chain = PROTOCOL_CLS_METHODS (protocol);
4388 size = list_length (chain);
4390 method_list_template
4391 = build_method_prototype_list_template (objc_method_prototype_template,
4395 = build_descriptor_table_initializer (objc_method_prototype_template,
4398 UOBJC_CLASS_METHODS_decl
4399 = generate_descriptor_table (method_list_template,
4400 "_OBJC_PROTOCOL_CLASS_METHODS",
4401 size, initlist, protocol);
4404 UOBJC_CLASS_METHODS_decl = 0;
4406 chain = PROTOCOL_NST_METHODS (protocol);
4409 size = list_length (chain);
4411 method_list_template
4412 = build_method_prototype_list_template (objc_method_prototype_template,
4415 = build_descriptor_table_initializer (objc_method_prototype_template,
4418 UOBJC_INSTANCE_METHODS_decl
4419 = generate_descriptor_table (method_list_template,
4420 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4421 size, initlist, protocol);
4424 UOBJC_INSTANCE_METHODS_decl = 0;
4428 generate_protocol_references (tree plist)
4432 /* Forward declare protocols referenced. */
4433 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4435 tree proto = TREE_VALUE (lproto);
4437 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4438 && PROTOCOL_NAME (proto))
4440 if (! PROTOCOL_FORWARD_DECL (proto))
4441 build_protocol_reference (proto);
4443 if (PROTOCOL_LIST (proto))
4444 generate_protocol_references (PROTOCOL_LIST (proto));
4449 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4453 objc_generate_cxx_ctor_or_dtor (bool dtor)
4455 tree fn, body, compound_stmt, ivar;
4457 /* - (id) .cxx_construct { ... return self; } */
4458 /* - (void) .cxx_construct { ... } */
4460 objc_set_method_type (MINUS_EXPR);
4461 objc_start_method_definition
4462 (objc_build_method_signature (build_tree_list (NULL_TREE,
4465 : objc_object_type),
4466 get_identifier (dtor
4468 : TAG_CXX_CONSTRUCT),
4469 make_node (TREE_LIST),
4471 body = begin_function_body ();
4472 compound_stmt = begin_compound_stmt (0);
4474 ivar = CLASS_IVARS (implementation_template);
4475 /* Destroy ivars in reverse order. */
4477 ivar = nreverse (copy_list (ivar));
4479 for (; ivar; ivar = TREE_CHAIN (ivar))
4481 if (TREE_CODE (ivar) == FIELD_DECL)
4483 tree type = TREE_TYPE (ivar);
4485 /* Call the ivar's default constructor or destructor. Do not
4486 call the destructor unless a corresponding constructor call
4487 has also been made (or is not needed). */
4488 if (IS_AGGR_TYPE (type)
4490 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4491 && (!TYPE_NEEDS_CONSTRUCTING (type)
4492 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4493 : (TYPE_NEEDS_CONSTRUCTING (type)
4494 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4496 (build_special_member_call
4497 (build_ivar_reference (DECL_NAME (ivar)),
4498 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4499 NULL_TREE, type, LOOKUP_NORMAL));
4503 /* The constructor returns 'self'. */
4505 finish_return_stmt (self_decl);
4507 finish_compound_stmt (compound_stmt);
4508 finish_function_body (body);
4509 fn = current_function_decl;
4511 objc_finish_method_definition (fn);
4514 /* The following routine will examine the current @interface for any
4515 non-POD C++ ivars requiring non-trivial construction and/or
4516 destruction, and then synthesize special '- .cxx_construct' and/or
4517 '- .cxx_destruct' methods which will run the appropriate
4518 construction or destruction code. Note that ivars inherited from
4519 super-classes are _not_ considered. */
4521 objc_generate_cxx_cdtors (void)
4523 bool need_ctor = false, need_dtor = false;
4526 /* We do not want to do this for categories, since they do not have
4529 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4532 /* First, determine if we even need a constructor and/or destructor. */
4534 for (ivar = CLASS_IVARS (implementation_template); ivar;
4535 ivar = TREE_CHAIN (ivar))
4537 if (TREE_CODE (ivar) == FIELD_DECL)
4539 tree type = TREE_TYPE (ivar);
4541 if (IS_AGGR_TYPE (type))
4543 if (TYPE_NEEDS_CONSTRUCTING (type)
4544 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4545 /* NB: If a default constructor is not available, we will not
4546 be able to initialize this ivar; the add_instance_variable()
4547 routine will already have warned about this. */
4550 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4551 && (!TYPE_NEEDS_CONSTRUCTING (type)
4552 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4553 /* NB: If a default constructor is not available, we will not
4554 call the destructor either, for symmetry. */
4560 /* Generate '- .cxx_construct' if needed. */
4563 objc_generate_cxx_ctor_or_dtor (false);
4565 /* Generate '- .cxx_destruct' if needed. */
4568 objc_generate_cxx_ctor_or_dtor (true);
4570 /* The 'imp_list' variable points at an imp_entry record for the current
4571 @implementation. Record the existence of '- .cxx_construct' and/or
4572 '- .cxx_destruct' methods therein; it will be included in the
4573 metadata for the class. */
4574 if (flag_next_runtime)
4575 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4579 /* For each protocol which was referenced either from a @protocol()
4580 expression, or because a class/category implements it (then a
4581 pointer to the protocol is stored in the struct describing the
4582 class/category), we create a statically allocated instance of the
4583 Protocol class. The code is written in such a way as to generate
4584 as few Protocol objects as possible; we generate a unique Protocol
4585 instance for each protocol, and we don't generate a Protocol
4586 instance if the protocol is never referenced (either from a
4587 @protocol() or from a class/category implementation). These
4588 statically allocated objects can be referred to via the static
4589 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4591 The statically allocated Protocol objects that we generate here
4592 need to be fixed up at runtime in order to be used: the 'isa'
4593 pointer of the objects need to be set up to point to the 'Protocol'
4594 class, as known at runtime.
4596 The NeXT runtime fixes up all protocols at program startup time,
4597 before main() is entered. It uses a low-level trick to look up all
4598 those symbols, then loops on them and fixes them up.
4600 The GNU runtime as well fixes up all protocols before user code
4601 from the module is executed; it requires pointers to those symbols
4602 to be put in the objc_symtab (which is then passed as argument to
4603 the function __objc_exec_class() which the compiler sets up to be
4604 executed automatically when the module is loaded); setup of those
4605 Protocol objects happen in two ways in the GNU runtime: all
4606 Protocol objects referred to by a class or category implementation
4607 are fixed up when the class/category is loaded; all Protocol
4608 objects referred to by a @protocol() expression are added by the
4609 compiler to the list of statically allocated instances to fixup
4610 (the same list holding the statically allocated constant string
4611 objects). Because, as explained above, the compiler generates as
4612 few Protocol objects as possible, some Protocol object might end up
4613 being referenced multiple times when compiled with the GNU runtime,
4614 and end up being fixed up multiple times at runtime initialization.
4615 But that doesn't hurt, it's just a little inefficient. */
4618 generate_protocols (void)
4622 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4624 /* If a protocol was directly referenced, pull in indirect references. */
4625 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4626 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4627 generate_protocol_references (PROTOCOL_LIST (p));
4629 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4631 tree nst_methods = PROTOCOL_NST_METHODS (p);
4632 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4634 /* If protocol wasn't referenced, don't generate any code. */
4635 decl = PROTOCOL_FORWARD_DECL (p);
4640 /* Make sure we link in the Protocol class. */
4641 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4645 if (! METHOD_ENCODING (nst_methods))
4647 encoding = encode_method_prototype (nst_methods);
4648 METHOD_ENCODING (nst_methods) = encoding;
4650 nst_methods = TREE_CHAIN (nst_methods);
4655 if (! METHOD_ENCODING (cls_methods))
4657 encoding = encode_method_prototype (cls_methods);
4658 METHOD_ENCODING (cls_methods) = encoding;
4661 cls_methods = TREE_CHAIN (cls_methods);
4663 generate_method_descriptors (p);
4665 if (PROTOCOL_LIST (p))
4666 refs_decl = generate_protocol_list (p);
4670 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4671 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4674 refs_expr = convert (build_pointer_type (build_pointer_type
4675 (objc_protocol_template)),
4676 build_unary_op (ADDR_EXPR, refs_decl, 0));
4678 refs_expr = build_int_cst (NULL_TREE, 0);
4680 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4681 by generate_method_descriptors, which is called above. */
4682 initlist = build_protocol_initializer (TREE_TYPE (decl),
4683 protocol_name_expr, refs_expr,
4684 UOBJC_INSTANCE_METHODS_decl,
4685 UOBJC_CLASS_METHODS_decl);
4686 finish_var_decl (decl, initlist);
4691 build_protocol_initializer (tree type, tree protocol_name,
4692 tree protocol_list, tree instance_methods,
4695 tree initlist = NULL_TREE, expr;
4696 tree cast_type = build_pointer_type
4697 (xref_tag (RECORD_TYPE,
4698 get_identifier (UTAG_CLASS)));
4700 /* Filling the "isa" in with one allows the runtime system to
4701 detect that the version change...should remove before final release. */
4703 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4704 initlist = tree_cons (NULL_TREE, expr, initlist);
4705 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4706 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4708 if (!instance_methods)
4709 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4712 expr = convert (objc_method_proto_list_ptr,
4713 build_unary_op (ADDR_EXPR, instance_methods, 0));
4714 initlist = tree_cons (NULL_TREE, expr, initlist);
4718 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4721 expr = convert (objc_method_proto_list_ptr,
4722 build_unary_op (ADDR_EXPR, class_methods, 0));
4723 initlist = tree_cons (NULL_TREE, expr, initlist);
4726 return objc_build_constructor (type, nreverse (initlist));
4729 /* struct _objc_category {
4730 char *category_name;
4732 struct _objc_method_list *instance_methods;
4733 struct _objc_method_list *class_methods;
4734 struct _objc_protocol_list *protocols;
4738 build_category_template (void)
4740 tree field_decl, field_decl_chain;
4742 objc_category_template = start_struct (RECORD_TYPE,
4743 get_identifier (UTAG_CATEGORY));
4745 /* char *category_name; */
4746 field_decl = create_field_decl (string_type_node, "category_name");
4747 field_decl_chain = field_decl;
4749 /* char *class_name; */
4750 field_decl = create_field_decl (string_type_node, "class_name");
4751 chainon (field_decl_chain, field_decl);
4753 /* struct _objc_method_list *instance_methods; */
4754 field_decl = create_field_decl (objc_method_list_ptr,
4755 "instance_methods");
4756 chainon (field_decl_chain, field_decl);
4758 /* struct _objc_method_list *class_methods; */
4759 field_decl = create_field_decl (objc_method_list_ptr,
4761 chainon (field_decl_chain, field_decl);
4763 /* struct _objc_protocol **protocol_list; */
4764 field_decl = create_field_decl (build_pointer_type
4766 (objc_protocol_template)),
4768 chainon (field_decl_chain, field_decl);
4770 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4773 /* struct _objc_selector {
4779 build_selector_template (void)
4782 tree field_decl, field_decl_chain;
4784 objc_selector_template
4785 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4788 field_decl = create_field_decl (objc_selector_type, "sel_id");
4789 field_decl_chain = field_decl;
4791 /* char *sel_type; */
4792 field_decl = create_field_decl (string_type_node, "sel_type");
4793 chainon (field_decl_chain, field_decl);
4795 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4798 /* struct _objc_class {
4799 struct _objc_class *isa;
4800 struct _objc_class *super_class;
4805 struct _objc_ivar_list *ivars;
4806 struct _objc_method_list *methods;
4807 #ifdef __NEXT_RUNTIME__
4808 struct objc_cache *cache;
4810 struct sarray *dtable;
4811 struct _objc_class *subclass_list;
4812 struct _objc_class *sibling_class;
4814 struct _objc_protocol_list *protocols;
4815 #ifdef __NEXT_RUNTIME__
4818 void *gc_object_type;
4821 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4822 the NeXT/Apple runtime; still, the compiler must generate them to
4823 maintain backward binary compatibility (and to allow for future
4827 build_class_template (void)
4829 tree field_decl, field_decl_chain;
4832 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4834 /* struct _objc_class *isa; */
4835 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4837 field_decl_chain = field_decl;
4839 /* struct _objc_class *super_class; */
4840 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4842 chainon (field_decl_chain, field_decl);
4845 field_decl = create_field_decl (string_type_node, "name");
4846 chainon (field_decl_chain, field_decl);
4849 field_decl = create_field_decl (long_integer_type_node, "version");
4850 chainon (field_decl_chain, field_decl);
4853 field_decl = create_field_decl (long_integer_type_node, "info");
4854 chainon (field_decl_chain, field_decl);
4856 /* long instance_size; */
4857 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4858 chainon (field_decl_chain, field_decl);
4860 /* struct _objc_ivar_list *ivars; */
4861 field_decl = create_field_decl (objc_ivar_list_ptr,
4863 chainon (field_decl_chain, field_decl);
4865 /* struct _objc_method_list *methods; */
4866 field_decl = create_field_decl (objc_method_list_ptr,
4868 chainon (field_decl_chain, field_decl);
4870 if (flag_next_runtime)
4872 /* struct objc_cache *cache; */
4873 field_decl = create_field_decl (build_pointer_type
4874 (xref_tag (RECORD_TYPE,
4878 chainon (field_decl_chain, field_decl);
4882 /* struct sarray *dtable; */
4883 field_decl = create_field_decl (build_pointer_type
4884 (xref_tag (RECORD_TYPE,
4888 chainon (field_decl_chain, field_decl);
4890 /* struct objc_class *subclass_list; */
4891 field_decl = create_field_decl (build_pointer_type
4892 (objc_class_template),
4894 chainon (field_decl_chain, field_decl);
4896 /* struct objc_class *sibling_class; */
4897 field_decl = create_field_decl (build_pointer_type
4898 (objc_class_template),
4900 chainon (field_decl_chain, field_decl);
4903 /* struct _objc_protocol **protocol_list; */
4904 field_decl = create_field_decl (build_pointer_type
4906 (xref_tag (RECORD_TYPE,
4910 chainon (field_decl_chain, field_decl);
4912 if (flag_next_runtime)
4915 field_decl = create_field_decl (build_pointer_type (void_type_node),
4917 chainon (field_decl_chain, field_decl);
4920 /* void *gc_object_type; */
4921 field_decl = create_field_decl (build_pointer_type (void_type_node),
4923 chainon (field_decl_chain, field_decl);
4925 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4928 /* Generate appropriate forward declarations for an implementation. */
4931 synth_forward_declarations (void)
4935 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4936 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4937 objc_class_template);
4939 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4940 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4941 objc_class_template);
4943 /* Pre-build the following entities - for speed/convenience. */
4945 an_id = get_identifier ("super_class");
4946 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4947 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4951 error_with_ivar (const char *message, tree decl)
4953 error ("%J%s %qs", decl,
4954 message, gen_declaration (decl));
4959 check_ivars (tree inter, tree imp)
4961 tree intdecls = CLASS_RAW_IVARS (inter);
4962 tree impdecls = CLASS_RAW_IVARS (imp);
4969 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4970 intdecls = TREE_CHAIN (intdecls);
4972 if (intdecls == 0 && impdecls == 0)
4974 if (intdecls == 0 || impdecls == 0)
4976 error ("inconsistent instance variable specification");
4980 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4982 if (!comptypes (t1, t2)
4983 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4984 DECL_INITIAL (impdecls)))
4986 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4988 error_with_ivar ("conflicting instance variable type",
4990 error_with_ivar ("previous declaration of",
4993 else /* both the type and the name don't match */
4995 error ("inconsistent instance variable specification");
5000 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5002 error_with_ivar ("conflicting instance variable name",
5004 error_with_ivar ("previous declaration of",
5008 intdecls = TREE_CHAIN (intdecls);
5009 impdecls = TREE_CHAIN (impdecls);
5013 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5014 This needs to be done just once per compilation. */
5016 /* struct _objc_super {
5017 struct _objc_object *self;
5018 struct _objc_class *super_class;
5022 build_super_template (void)
5024 tree field_decl, field_decl_chain;
5026 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5028 /* struct _objc_object *self; */
5029 field_decl = create_field_decl (objc_object_type, "self");
5030 field_decl_chain = field_decl;
5032 /* struct _objc_class *super_class; */
5033 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5035 chainon (field_decl_chain, field_decl);
5037 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5040 /* struct _objc_ivar {
5047 build_ivar_template (void)
5049 tree objc_ivar_id, objc_ivar_record;
5050 tree field_decl, field_decl_chain;
5052 objc_ivar_id = get_identifier (UTAG_IVAR);
5053 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5055 /* char *ivar_name; */
5056 field_decl = create_field_decl (string_type_node, "ivar_name");
5057 field_decl_chain = field_decl;
5059 /* char *ivar_type; */
5060 field_decl = create_field_decl (string_type_node, "ivar_type");
5061 chainon (field_decl_chain, field_decl);
5063 /* int ivar_offset; */
5064 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5065 chainon (field_decl_chain, field_decl);
5067 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5069 return objc_ivar_record;
5074 struct objc_ivar ivar_list[ivar_count];
5078 build_ivar_list_template (tree list_type, int size)
5080 tree objc_ivar_list_record;
5081 tree field_decl, field_decl_chain;
5083 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5085 /* int ivar_count; */
5086 field_decl = create_field_decl (integer_type_node, "ivar_count");
5087 field_decl_chain = field_decl;
5089 /* struct objc_ivar ivar_list[]; */
5090 field_decl = create_field_decl (build_array_type
5093 (build_int_cst (NULL_TREE, size - 1))),
5095 chainon (field_decl_chain, field_decl);
5097 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5099 return objc_ivar_list_record;
5103 struct _objc__method_prototype_list *method_next;
5105 struct objc_method method_list[method_count];
5109 build_method_list_template (tree list_type, int size)
5111 tree objc_ivar_list_record;
5112 tree field_decl, field_decl_chain;
5114 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5116 /* struct _objc__method_prototype_list *method_next; */
5117 field_decl = create_field_decl (objc_method_proto_list_ptr,
5119 field_decl_chain = field_decl;
5121 /* int method_count; */
5122 field_decl = create_field_decl (integer_type_node, "method_count");
5123 chainon (field_decl_chain, field_decl);
5125 /* struct objc_method method_list[]; */
5126 field_decl = create_field_decl (build_array_type
5129 (build_int_cst (NULL_TREE, size - 1))),
5131 chainon (field_decl_chain, field_decl);
5133 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5135 return objc_ivar_list_record;
5139 build_ivar_list_initializer (tree type, tree field_decl)
5141 tree initlist = NULL_TREE;
5145 tree ivar = NULL_TREE;
5148 if (DECL_NAME (field_decl))
5149 ivar = tree_cons (NULL_TREE,
5150 add_objc_string (DECL_NAME (field_decl),
5154 /* Unnamed bit-field ivar (yuck). */
5155 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5158 encode_field_decl (field_decl,
5159 obstack_object_size (&util_obstack),
5160 OBJC_ENCODE_DONT_INLINE_DEFS);
5162 /* Null terminate string. */
5163 obstack_1grow (&util_obstack, 0);
5167 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5170 obstack_free (&util_obstack, util_firstobj);
5173 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5174 initlist = tree_cons (NULL_TREE,
5175 objc_build_constructor (type, nreverse (ivar)),
5178 field_decl = TREE_CHAIN (field_decl);
5179 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5183 return objc_build_constructor (build_array_type (type, 0),
5184 nreverse (initlist));
5188 generate_ivars_list (tree type, const char *name, int size, tree list)
5190 tree decl, initlist;
5192 decl = start_var_decl (type, synth_id_with_class_suffix
5193 (name, objc_implementation_context));
5195 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5196 initlist = tree_cons (NULL_TREE, list, initlist);
5198 finish_var_decl (decl,
5199 objc_build_constructor (TREE_TYPE (decl),
5200 nreverse (initlist)));
5205 /* Count only the fields occurring in T. */
5207 ivar_list_length (tree t)
5211 for (; t; t = TREE_CHAIN (t))
5212 if (TREE_CODE (t) == FIELD_DECL)
5219 generate_ivar_lists (void)
5221 tree initlist, ivar_list_template, chain;
5224 generating_instance_variables = 1;
5226 if (!objc_ivar_template)
5227 objc_ivar_template = build_ivar_template ();
5229 /* Only generate class variables for the root of the inheritance
5230 hierarchy since these will be the same for every class. */
5232 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5233 && (chain = TYPE_FIELDS (objc_class_template)))
5235 size = ivar_list_length (chain);
5237 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5238 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5240 UOBJC_CLASS_VARIABLES_decl
5241 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5245 UOBJC_CLASS_VARIABLES_decl = 0;
5247 chain = CLASS_IVARS (implementation_template);
5250 size = ivar_list_length (chain);
5251 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5252 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5254 UOBJC_INSTANCE_VARIABLES_decl
5255 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5259 UOBJC_INSTANCE_VARIABLES_decl = 0;
5261 generating_instance_variables = 0;
5265 build_dispatch_table_initializer (tree type, tree entries)
5267 tree initlist = NULL_TREE;
5271 tree elemlist = NULL_TREE;
5273 elemlist = tree_cons (NULL_TREE,
5274 build_selector (METHOD_SEL_NAME (entries)),
5277 /* Generate the method encoding if we don't have one already. */
5278 if (! METHOD_ENCODING (entries))
5279 METHOD_ENCODING (entries) =
5280 encode_method_prototype (entries);
5282 elemlist = tree_cons (NULL_TREE,
5283 add_objc_string (METHOD_ENCODING (entries),
5288 = tree_cons (NULL_TREE,
5289 convert (ptr_type_node,
5290 build_unary_op (ADDR_EXPR,
5291 METHOD_DEFINITION (entries), 1)),
5294 initlist = tree_cons (NULL_TREE,
5295 objc_build_constructor (type, nreverse (elemlist)),
5298 entries = TREE_CHAIN (entries);
5302 return objc_build_constructor (build_array_type (type, 0),
5303 nreverse (initlist));
5306 /* To accomplish method prototyping without generating all kinds of
5307 inane warnings, the definition of the dispatch table entries were
5310 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5312 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5315 build_method_template (void)
5318 tree field_decl, field_decl_chain;
5320 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5323 field_decl = create_field_decl (objc_selector_type, "_cmd");
5324 field_decl_chain = field_decl;
5326 /* char *method_types; */
5327 field_decl = create_field_decl (string_type_node, "method_types");
5328 chainon (field_decl_chain, field_decl);
5331 field_decl = create_field_decl (build_pointer_type (void_type_node),
5333 chainon (field_decl_chain, field_decl);
5335 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5342 generate_dispatch_table (tree type, const char *name, int size, tree list)
5344 tree decl, initlist;
5346 decl = start_var_decl (type, synth_id_with_class_suffix
5347 (name, objc_implementation_context));
5349 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5350 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5351 initlist = tree_cons (NULL_TREE, list, initlist);
5353 finish_var_decl (decl,
5354 objc_build_constructor (TREE_TYPE (decl),
5355 nreverse (initlist)));
5361 mark_referenced_methods (void)
5363 struct imp_entry *impent;
5366 for (impent = imp_list; impent; impent = impent->next)
5368 chain = CLASS_CLS_METHODS (impent->imp_context);
5371 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5372 chain = TREE_CHAIN (chain);
5375 chain = CLASS_NST_METHODS (impent->imp_context);
5378 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5379 chain = TREE_CHAIN (chain);
5385 generate_dispatch_tables (void)
5387 tree initlist, chain, method_list_template;
5390 if (!objc_method_template)
5391 objc_method_template = build_method_template ();
5393 chain = CLASS_CLS_METHODS (objc_implementation_context);
5396 size = list_length (chain);
5398 method_list_template
5399 = build_method_list_template (objc_method_template, size);
5401 = build_dispatch_table_initializer (objc_method_template, chain);
5403 UOBJC_CLASS_METHODS_decl
5404 = generate_dispatch_table (method_list_template,
5405 ((TREE_CODE (objc_implementation_context)
5406 == CLASS_IMPLEMENTATION_TYPE)
5407 ? "_OBJC_CLASS_METHODS"
5408 : "_OBJC_CATEGORY_CLASS_METHODS"),
5412 UOBJC_CLASS_METHODS_decl = 0;
5414 chain = CLASS_NST_METHODS (objc_implementation_context);
5417 size = list_length (chain);
5419 method_list_template
5420 = build_method_list_template (objc_method_template, size);
5422 = build_dispatch_table_initializer (objc_method_template, chain);
5424 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5425 UOBJC_INSTANCE_METHODS_decl
5426 = generate_dispatch_table (method_list_template,
5427 "_OBJC_INSTANCE_METHODS",
5430 /* We have a category. */
5431 UOBJC_INSTANCE_METHODS_decl
5432 = generate_dispatch_table (method_list_template,
5433 "_OBJC_CATEGORY_INSTANCE_METHODS",
5437 UOBJC_INSTANCE_METHODS_decl = 0;
5441 generate_protocol_list (tree i_or_p)
5444 tree refs_decl, lproto, e, plist;
5446 const char *ref_name;
5448 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5449 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5450 plist = CLASS_PROTOCOL_LIST (i_or_p);
5451 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5452 plist = PROTOCOL_LIST (i_or_p);
5457 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5458 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5459 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5462 /* Build initializer. */
5463 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5464 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5465 initlist = tree_cons (NULL_TREE, e, initlist);
5467 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5469 tree pval = TREE_VALUE (lproto);
5471 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5472 && PROTOCOL_FORWARD_DECL (pval))
5474 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5475 initlist = tree_cons (NULL_TREE, e, initlist);
5479 /* static struct objc_protocol *refs[n]; */
5481 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5482 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5483 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5484 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5485 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5486 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5490 refs_decl = start_var_decl
5492 (build_pointer_type (objc_protocol_template),
5493 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5496 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5497 nreverse (initlist)));
5503 build_category_initializer (tree type, tree cat_name, tree class_name,
5504 tree instance_methods, tree class_methods,
5507 tree initlist = NULL_TREE, expr;
5509 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5510 initlist = tree_cons (NULL_TREE, class_name, initlist);
5512 if (!instance_methods)
5513 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5516 expr = convert (objc_method_list_ptr,
5517 build_unary_op (ADDR_EXPR, instance_methods, 0));
5518 initlist = tree_cons (NULL_TREE, expr, initlist);
5521 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5524 expr = convert (objc_method_list_ptr,
5525 build_unary_op (ADDR_EXPR, class_methods, 0));
5526 initlist = tree_cons (NULL_TREE, expr, initlist);
5529 /* protocol_list = */
5531 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5534 expr = convert (build_pointer_type
5536 (objc_protocol_template)),
5537 build_unary_op (ADDR_EXPR, protocol_list, 0));
5538 initlist = tree_cons (NULL_TREE, expr, initlist);
5541 return objc_build_constructor (type, nreverse (initlist));
5544 /* struct _objc_class {
5545 struct objc_class *isa;
5546 struct objc_class *super_class;
5551 struct objc_ivar_list *ivars;
5552 struct objc_method_list *methods;
5553 if (flag_next_runtime)
5554 struct objc_cache *cache;
5556 struct sarray *dtable;
5557 struct objc_class *subclass_list;
5558 struct objc_class *sibling_class;
5560 struct objc_protocol_list *protocols;
5561 if (flag_next_runtime)
5563 void *gc_object_type;
5567 build_shared_structure_initializer (tree type, tree isa, tree super,
5568 tree name, tree size, int status,
5569 tree dispatch_table, tree ivar_list,
5572 tree initlist = NULL_TREE, expr;
5575 initlist = tree_cons (NULL_TREE, isa, initlist);
5578 initlist = tree_cons (NULL_TREE, super, initlist);
5581 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5584 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5588 initlist = tree_cons (NULL_TREE,
5589 build_int_cst (long_integer_type_node, status),
5592 /* instance_size = */
5593 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5596 /* objc_ivar_list = */
5598 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5601 expr = convert (objc_ivar_list_ptr,
5602 build_unary_op (ADDR_EXPR, ivar_list, 0));
5603 initlist = tree_cons (NULL_TREE, expr, initlist);
5606 /* objc_method_list = */
5607 if (!dispatch_table)
5608 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5611 expr = convert (objc_method_list_ptr,
5612 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5613 initlist = tree_cons (NULL_TREE, expr, initlist);
5616 if (flag_next_runtime)
5617 /* method_cache = */
5618 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5622 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5624 /* subclass_list = */
5625 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5627 /* sibling_class = */
5628 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5631 /* protocol_list = */
5632 if (! protocol_list)
5633 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5636 expr = convert (build_pointer_type
5638 (objc_protocol_template)),
5639 build_unary_op (ADDR_EXPR, protocol_list, 0));
5640 initlist = tree_cons (NULL_TREE, expr, initlist);
5643 if (flag_next_runtime)
5645 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5647 /* gc_object_type = NULL */
5648 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5650 return objc_build_constructor (type, nreverse (initlist));
5653 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5656 lookup_category (tree class, tree cat_name)
5658 tree category = CLASS_CATEGORY_LIST (class);
5660 while (category && CLASS_SUPER_NAME (category) != cat_name)
5661 category = CLASS_CATEGORY_LIST (category);
5665 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5668 generate_category (tree cat)
5671 tree initlist, cat_name_expr, class_name_expr;
5672 tree protocol_decl, category;
5674 add_class_reference (CLASS_NAME (cat));
5675 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5677 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5679 category = lookup_category (implementation_template,
5680 CLASS_SUPER_NAME (cat));
5682 if (category && CLASS_PROTOCOL_LIST (category))
5684 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5685 protocol_decl = generate_protocol_list (category);
5690 decl = start_var_decl (objc_category_template,
5691 synth_id_with_class_suffix
5692 ("_OBJC_CATEGORY", objc_implementation_context));
5694 initlist = build_category_initializer (TREE_TYPE (decl),
5695 cat_name_expr, class_name_expr,
5696 UOBJC_INSTANCE_METHODS_decl,
5697 UOBJC_CLASS_METHODS_decl,
5700 finish_var_decl (decl, initlist);
5703 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5704 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5707 generate_shared_structures (int cls_flags)
5709 tree sc_spec, decl_specs, decl;
5710 tree name_expr, super_expr, root_expr;
5711 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5712 tree cast_type, initlist, protocol_decl;
5714 my_super_id = CLASS_SUPER_NAME (implementation_template);
5717 add_class_reference (my_super_id);
5719 /* Compute "my_root_id" - this is required for code generation.
5720 the "isa" for all meta class structures points to the root of
5721 the inheritance hierarchy (e.g. "__Object")... */
5722 my_root_id = my_super_id;
5725 tree my_root_int = lookup_interface (my_root_id);
5727 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5728 my_root_id = CLASS_SUPER_NAME (my_root_int);
5735 /* No super class. */
5736 my_root_id = CLASS_NAME (implementation_template);
5738 cast_type = build_pointer_type (objc_class_template);
5739 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5742 /* Install class `isa' and `super' pointers at runtime. */
5745 super_expr = add_objc_string (my_super_id, class_names);
5746 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5749 super_expr = build_int_cst (NULL_TREE, 0);
5751 root_expr = add_objc_string (my_root_id, class_names);
5752 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5754 if (CLASS_PROTOCOL_LIST (implementation_template))
5756 generate_protocol_references
5757 (CLASS_PROTOCOL_LIST (implementation_template));
5758 protocol_decl = generate_protocol_list (implementation_template);
5763 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5765 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5766 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5768 decl = start_var_decl (objc_class_template,
5770 (DECL_NAME (UOBJC_METACLASS_decl)));
5773 = build_shared_structure_initializer
5775 root_expr, super_expr, name_expr,
5776 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5778 UOBJC_CLASS_METHODS_decl,
5779 UOBJC_CLASS_VARIABLES_decl,
5782 finish_var_decl (decl, initlist);
5784 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5786 decl = start_var_decl (objc_class_template,
5788 (DECL_NAME (UOBJC_CLASS_decl)));
5791 = build_shared_structure_initializer
5793 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5794 super_expr, name_expr,
5795 convert (integer_type_node,
5796 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5797 (implementation_template))),
5798 1 /*CLS_FACTORY*/ | cls_flags,
5799 UOBJC_INSTANCE_METHODS_decl,
5800 UOBJC_INSTANCE_VARIABLES_decl,
5803 finish_var_decl (decl, initlist);
5808 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5810 static char string[BUFSIZE];
5812 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5813 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5815 sprintf (string, "%s_%s", preamble,
5816 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5818 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5819 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5821 /* We have a category. */
5822 const char *const class_name
5823 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5824 const char *const class_super_name
5825 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5826 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5828 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5830 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5831 sprintf (string, "%s_%s", preamble, protocol_name);
5839 /* If type is empty or only type qualifiers are present, add default
5840 type of id (otherwise grokdeclarator will default to int). */
5843 adjust_type_for_id_default (tree type)
5846 type = make_node (TREE_LIST);
5848 if (!TREE_VALUE (type))
5849 TREE_VALUE (type) = objc_object_type;
5850 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5851 && TYPED_OBJECT (TREE_VALUE (type)))
5852 error ("can not use an object as parameter to a method");
5859 selector ':' '(' typename ')' identifier
5862 Transform an Objective-C keyword argument into
5863 the C equivalent parameter declarator.
5865 In: key_name, an "identifier_node" (optional).
5866 arg_type, a "tree_list" (optional).
5867 arg_name, an "identifier_node".
5869 Note: It would be really nice to strongly type the preceding
5870 arguments in the function prototype; however, then I
5871 could not use the "accessor" macros defined in "tree.h".
5873 Out: an instance of "keyword_decl". */
5876 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5880 /* If no type is specified, default to "id". */
5881 arg_type = adjust_type_for_id_default (arg_type);
5883 keyword_decl = make_node (KEYWORD_DECL);
5885 TREE_TYPE (keyword_decl) = arg_type;
5886 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5887 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5889 return keyword_decl;
5892 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5895 build_keyword_selector (tree selector)
5898 tree key_chain, key_name;
5901 /* Scan the selector to see how much space we'll need. */
5902 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5904 if (TREE_CODE (selector) == KEYWORD_DECL)
5905 key_name = KEYWORD_KEY_NAME (key_chain);
5906 else if (TREE_CODE (selector) == TREE_LIST)
5907 key_name = TREE_PURPOSE (key_chain);
5912 len += IDENTIFIER_LENGTH (key_name) + 1;
5914 /* Just a ':' arg. */
5918 buf = (char *) alloca (len + 1);
5919 /* Start the buffer out as an empty string. */
5922 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5924 if (TREE_CODE (selector) == KEYWORD_DECL)
5925 key_name = KEYWORD_KEY_NAME (key_chain);
5926 else if (TREE_CODE (selector) == TREE_LIST)
5928 key_name = TREE_PURPOSE (key_chain);
5929 /* The keyword decl chain will later be used as a function argument
5930 chain. Unhook the selector itself so as to not confuse other
5931 parts of the compiler. */
5932 TREE_PURPOSE (key_chain) = NULL_TREE;
5938 strcat (buf, IDENTIFIER_POINTER (key_name));
5942 return get_identifier (buf);
5945 /* Used for declarations and definitions. */
5948 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5949 tree add_args, bool ellipsis)
5953 /* If no type is specified, default to "id". */
5954 ret_type = adjust_type_for_id_default (ret_type);
5956 method_decl = make_node (code);
5957 TREE_TYPE (method_decl) = ret_type;
5959 /* If we have a keyword selector, create an identifier_node that
5960 represents the full selector name (`:' included)... */
5961 if (TREE_CODE (selector) == KEYWORD_DECL)
5963 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5964 METHOD_SEL_ARGS (method_decl) = selector;
5965 METHOD_ADD_ARGS (method_decl) = add_args;
5966 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5970 METHOD_SEL_NAME (method_decl) = selector;
5971 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5972 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5978 #define METHOD_DEF 0
5979 #define METHOD_REF 1
5981 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5982 an argument list for method METH. CONTEXT is either METHOD_DEF or
5983 METHOD_REF, saying whether we are trying to define a method or call
5984 one. SUPERFLAG says this is for a send to super; this makes a
5985 difference for the NeXT calling sequence in which the lookup and
5986 the method call are done together. If METH is null, user-defined
5987 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5990 get_arg_type_list (tree meth, int context, int superflag)
5994 /* Receiver type. */
5995 if (flag_next_runtime && superflag)
5996 arglist = build_tree_list (NULL_TREE, objc_super_type);
5997 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5998 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6000 arglist = build_tree_list (NULL_TREE, objc_object_type);
6002 /* Selector type - will eventually change to `int'. */
6003 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6005 /* No actual method prototype given -- assume that remaining arguments
6010 /* Build a list of argument types. */
6011 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6013 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6015 /* Decay arrays and functions into pointers. */
6016 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6017 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6018 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6019 arg_type = build_pointer_type (arg_type);
6021 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6024 if (METHOD_ADD_ARGS (meth))
6026 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6027 akey; akey = TREE_CHAIN (akey))
6029 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6031 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6034 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6035 goto lack_of_ellipsis;
6040 chainon (arglist, OBJC_VOID_AT_END);
6047 check_duplicates (hash hsh, int methods, int is_class)
6049 tree meth = NULL_TREE;
6057 /* We have two or more methods with the same name but
6061 /* But just how different are those types? If
6062 -Wno-strict-selector-match is specified, we shall not
6063 complain if the differences are solely among types with
6064 identical size and alignment. */
6065 if (!warn_strict_selector_match)
6067 for (loop = hsh->list; loop; loop = loop->next)
6068 if (!comp_proto_with_proto (meth, loop->value, 0))
6075 warning (0, "multiple %s named %<%c%s%> found",
6076 methods ? "methods" : "selectors",
6077 (is_class ? '+' : '-'),
6078 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6080 warn_with_method (methods ? "using" : "found",
6081 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6085 for (loop = hsh->list; loop; loop = loop->next)
6086 warn_with_method ("also found",
6087 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6096 /* If RECEIVER is a class reference, return the identifier node for
6097 the referenced class. RECEIVER is created by objc_get_class_reference,
6098 so we check the exact form created depending on which runtimes are
6102 receiver_is_class_object (tree receiver, int self, int super)
6104 tree chain, exp, arg;
6106 /* The receiver is 'self' or 'super' in the context of a class method. */
6107 if (objc_method_context
6108 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6111 ? CLASS_SUPER_NAME (implementation_template)
6112 : CLASS_NAME (implementation_template));
6114 if (flag_next_runtime)
6116 /* The receiver is a variable created by
6117 build_class_reference_decl. */
6118 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6119 /* Look up the identifier. */
6120 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6121 if (TREE_PURPOSE (chain) == receiver)
6122 return TREE_VALUE (chain);
6125 /* The receiver is a function call that returns an id. Check if
6126 it is a call to objc_getClass, if so, pick up the class name. */
6127 if (TREE_CODE (receiver) == CALL_EXPR
6128 && (exp = TREE_OPERAND (receiver, 0))
6129 && TREE_CODE (exp) == ADDR_EXPR
6130 && (exp = TREE_OPERAND (exp, 0))
6131 && TREE_CODE (exp) == FUNCTION_DECL
6132 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6133 prototypes for objc_get_class(). Thankfully, they seem to share the
6134 same function type. */
6135 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6136 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6137 /* We have a call to objc_get_class/objc_getClass! */
6138 && (arg = TREE_OPERAND (receiver, 1))
6139 && TREE_CODE (arg) == TREE_LIST
6140 && (arg = TREE_VALUE (arg)))
6143 if (TREE_CODE (arg) == ADDR_EXPR
6144 && (arg = TREE_OPERAND (arg, 0))
6145 && TREE_CODE (arg) == STRING_CST)
6146 /* Finally, we have the class name. */
6147 return get_identifier (TREE_STRING_POINTER (arg));
6152 /* If we are currently building a message expr, this holds
6153 the identifier of the selector of the message. This is
6154 used when printing warnings about argument mismatches. */
6156 static tree current_objc_message_selector = 0;
6159 objc_message_selector (void)
6161 return current_objc_message_selector;
6164 /* Construct an expression for sending a message.
6165 MESS has the object to send to in TREE_PURPOSE
6166 and the argument list (including selector) in TREE_VALUE.
6168 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6169 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6172 objc_build_message_expr (tree mess)
6174 tree receiver = TREE_PURPOSE (mess);
6177 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6179 tree args = TREE_VALUE (mess);
6181 tree method_params = NULL_TREE;
6183 if (TREE_CODE (receiver) == ERROR_MARK)
6184 return error_mark_node;
6186 /* Obtain the full selector name. */
6187 if (TREE_CODE (args) == IDENTIFIER_NODE)
6188 /* A unary selector. */
6190 else if (TREE_CODE (args) == TREE_LIST)
6191 sel_name = build_keyword_selector (args);
6195 /* Build the parameter list to give to the method. */
6196 if (TREE_CODE (args) == TREE_LIST)
6198 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6201 tree chain = args, prev = NULL_TREE;
6203 /* We have a keyword selector--check for comma expressions. */
6206 tree element = TREE_VALUE (chain);
6208 /* We have a comma expression, must collapse... */
6209 if (TREE_CODE (element) == TREE_LIST)
6212 TREE_CHAIN (prev) = element;
6217 chain = TREE_CHAIN (chain);
6219 method_params = args;
6224 if (processing_template_decl)
6225 /* Must wait until template instantiation time. */
6226 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6230 return objc_finish_message_expr (receiver, sel_name, method_params);
6233 /* Look up method SEL_NAME that would be suitable for receiver
6234 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6235 nonzero), and report on any duplicates. */
6238 lookup_method_in_hash_lists (tree sel_name, int is_class)
6240 hash method_prototype = NULL;
6243 method_prototype = hash_lookup (nst_method_hash_list,
6246 if (!method_prototype)
6248 method_prototype = hash_lookup (cls_method_hash_list,
6253 return check_duplicates (method_prototype, 1, is_class);
6256 /* The 'objc_finish_message_expr' routine is called from within
6257 'objc_build_message_expr' for non-template functions. In the case of
6258 C++ template functions, it is called from 'build_expr_from_tree'
6259 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6262 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6264 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6265 tree selector, retval, class_tree;
6266 int self, super, have_cast;
6268 /* Extract the receiver of the message, as well as its type
6269 (where the latter may take the form of a cast or be inferred
6270 from the implementation context). */
6272 while (TREE_CODE (rtype) == COMPOUND_EXPR
6273 || TREE_CODE (rtype) == MODIFY_EXPR
6274 || TREE_CODE (rtype) == NOP_EXPR
6275 || TREE_CODE (rtype) == CONVERT_EXPR
6276 || TREE_CODE (rtype) == COMPONENT_REF)
6277 rtype = TREE_OPERAND (rtype, 0);
6278 self = (rtype == self_decl);
6279 super = (rtype == UOBJC_SUPER_decl);
6280 rtype = TREE_TYPE (receiver);
6281 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6282 || (TREE_CODE (receiver) == COMPOUND_EXPR
6283 && !IS_SUPER (rtype)));
6285 /* If we are calling [super dealloc], reset our warning flag. */
6286 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6287 should_call_super_dealloc = 0;
6289 /* If the receiver is a class object, retrieve the corresponding
6290 @interface, if one exists. */
6291 class_tree = receiver_is_class_object (receiver, self, super);
6293 /* Now determine the receiver type (if an explicit cast has not been
6298 rtype = lookup_interface (class_tree);
6299 /* Handle `self' and `super'. */
6302 if (!CLASS_SUPER_NAME (implementation_template))
6304 error ("no super class declared in @interface for %qs",
6305 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6306 return error_mark_node;
6308 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6311 rtype = lookup_interface (CLASS_NAME (implementation_template));
6314 /* If receiver is of type `id' or `Class' (or if the @interface for a
6315 class is not visible), we shall be satisfied with the existence of
6316 any instance or class method. */
6317 if (objc_is_id (rtype))
6319 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6320 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6321 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6327 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6328 in protocols themselves for the method prototype. */
6330 = lookup_method_in_protocol_list (rprotos, sel_name,
6331 class_tree != NULL_TREE);
6333 /* If messaging 'Class <Proto>' but did not find a class method
6334 prototype, search for an instance method instead, and warn
6335 about having done so. */
6336 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6339 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6341 if (method_prototype)
6342 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6343 IDENTIFIER_POINTER (sel_name),
6344 IDENTIFIER_POINTER (sel_name));
6350 tree orig_rtype = rtype, saved_rtype;
6352 if (TREE_CODE (rtype) == POINTER_TYPE)
6353 rtype = TREE_TYPE (rtype);
6354 /* Traverse typedef aliases */
6355 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6356 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6357 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6358 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6359 saved_rtype = rtype;
6360 if (TYPED_OBJECT (rtype))
6362 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6363 rtype = TYPE_OBJC_INTERFACE (rtype);
6365 /* If we could not find an @interface declaration, we must have
6366 only seen a @class declaration; so, we cannot say anything
6367 more intelligent about which methods the receiver will
6369 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6371 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6372 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6374 /* We have a valid ObjC class name. Look up the method name
6375 in the published @interface for the class (and its
6378 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6380 /* If the method was not found in the @interface, it may still
6381 exist locally as part of the @implementation. */
6382 if (!method_prototype && objc_implementation_context
6383 && CLASS_NAME (objc_implementation_context)
6384 == OBJC_TYPE_NAME (rtype))
6388 ? CLASS_CLS_METHODS (objc_implementation_context)
6389 : CLASS_NST_METHODS (objc_implementation_context)),
6392 /* If we haven't found a candidate method by now, try looking for
6393 it in the protocol list. */
6394 if (!method_prototype && rprotos)
6396 = lookup_method_in_protocol_list (rprotos, sel_name,
6397 class_tree != NULL_TREE);
6401 warning (0, "invalid receiver type %qs",
6402 gen_type_name (orig_rtype));
6403 /* After issuing the "invalid receiver" warning, perform method
6404 lookup as if we were messaging 'id'. */
6405 rtype = rprotos = NULL_TREE;
6410 /* For 'id' or 'Class' receivers, search in the global hash table
6411 as a last resort. For all receivers, warn if protocol searches
6413 if (!method_prototype)
6416 warning (0, "%<%c%s%> not found in protocol(s)",
6417 (class_tree ? '+' : '-'),
6418 IDENTIFIER_POINTER (sel_name));
6422 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6425 if (!method_prototype)
6427 static bool warn_missing_methods = false;
6430 warning (0, "%qs may not respond to %<%c%s%>",
6431 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6432 (class_tree ? '+' : '-'),
6433 IDENTIFIER_POINTER (sel_name));
6434 /* If we are messaging an 'id' or 'Class' object and made it here,
6435 then we have failed to find _any_ instance or class method,
6438 warning (0, "no %<%c%s%> method found",
6439 (class_tree ? '+' : '-'),
6440 IDENTIFIER_POINTER (sel_name));
6442 if (!warn_missing_methods)
6444 warning (0, "(Messages without a matching method signature");
6445 warning (0, "will be assumed to return %<id%> and accept");
6446 warning (0, "%<...%> as arguments.)");
6447 warn_missing_methods = true;
6451 /* Save the selector name for printing error messages. */
6452 current_objc_message_selector = sel_name;
6454 /* Build the parameters list for looking up the method.
6455 These are the object itself and the selector. */
6457 if (flag_typed_selectors)
6458 selector = build_typed_selector_reference (sel_name, method_prototype);
6460 selector = build_selector_reference (sel_name);
6462 retval = build_objc_method_call (super, method_prototype,
6464 selector, method_params);
6466 current_objc_message_selector = 0;
6471 /* Build a tree expression to send OBJECT the operation SELECTOR,
6472 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6473 assuming the method has prototype METHOD_PROTOTYPE.
6474 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6475 Use METHOD_PARAMS as list of args to pass to the method.
6476 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6479 build_objc_method_call (int super_flag, tree method_prototype,
6480 tree lookup_object, tree selector,
6483 tree sender = (super_flag ? umsg_super_decl :
6484 (!flag_next_runtime || flag_nil_receivers
6485 ? (flag_objc_direct_dispatch
6488 : umsg_nonnil_decl));
6489 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6491 /* If a prototype for the method to be called exists, then cast
6492 the sender's return type and arguments to match that of the method.
6493 Otherwise, leave sender as is. */
6496 ? TREE_VALUE (TREE_TYPE (method_prototype))
6497 : objc_object_type);
6499 = build_pointer_type
6500 (build_function_type
6503 (method_prototype, METHOD_REF, super_flag)));
6506 lookup_object = build_c_cast (rcv_p, lookup_object);
6508 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6509 lookup_object = save_expr (lookup_object);
6511 if (flag_next_runtime)
6513 /* If we are returning a struct in memory, and the address
6514 of that memory location is passed as a hidden first
6515 argument, then change which messenger entry point this
6516 expr will call. NB: Note that sender_cast remains
6517 unchanged (it already has a struct return type). */
6518 if (!targetm.calls.struct_value_rtx (0, 0)
6519 && (TREE_CODE (ret_type) == RECORD_TYPE
6520 || TREE_CODE (ret_type) == UNION_TYPE)
6521 && targetm.calls.return_in_memory (ret_type, 0))
6522 sender = (super_flag ? umsg_super_stret_decl :
6523 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6525 method_params = tree_cons (NULL_TREE, lookup_object,
6526 tree_cons (NULL_TREE, selector,
6528 method = build_fold_addr_expr (sender);
6532 /* This is the portable (GNU) way. */
6535 /* First, call the lookup function to get a pointer to the method,
6536 then cast the pointer, then call it with the method arguments. */
6538 object = (super_flag ? self_decl : lookup_object);
6540 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6541 t = tree_cons (NULL_TREE, lookup_object, t);
6542 method = build_function_call (sender, t);
6544 /* Pass the object to the method. */
6545 method_params = tree_cons (NULL_TREE, object,
6546 tree_cons (NULL_TREE, selector,
6550 /* ??? Selector is not at this point something we can use inside
6551 the compiler itself. Set it to garbage for the nonce. */
6552 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6553 return build_function_call (t, method_params);
6557 build_protocol_reference (tree p)
6560 const char *proto_name;
6562 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6564 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6565 decl = start_var_decl (objc_protocol_template, proto_name);
6567 PROTOCOL_FORWARD_DECL (p) = decl;
6570 /* This function is called by the parser when (and only when) a
6571 @protocol() expression is found, in order to compile it. */
6573 objc_build_protocol_expr (tree protoname)
6576 tree p = lookup_protocol (protoname);
6580 error ("cannot find protocol declaration for %qs",
6581 IDENTIFIER_POINTER (protoname));
6582 return error_mark_node;
6585 if (!PROTOCOL_FORWARD_DECL (p))
6586 build_protocol_reference (p);
6588 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6590 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6591 if we have it, rather than converting it here. */
6592 expr = convert (objc_protocol_type, expr);
6594 /* The @protocol() expression is being compiled into a pointer to a
6595 statically allocated instance of the Protocol class. To become
6596 usable at runtime, the 'isa' pointer of the instance need to be
6597 fixed up at runtime by the runtime library, to point to the
6598 actual 'Protocol' class. */
6600 /* For the GNU runtime, put the static Protocol instance in the list
6601 of statically allocated instances, so that we make sure that its
6602 'isa' pointer is fixed up at runtime by the GNU runtime library
6603 to point to the Protocol class (at runtime, when loading the
6604 module, the GNU runtime library loops on the statically allocated
6605 instances (as found in the defs field in objc_symtab) and fixups
6606 all the 'isa' pointers of those objects). */
6607 if (! flag_next_runtime)
6609 /* This type is a struct containing the fields of a Protocol
6610 object. (Cfr. objc_protocol_type instead is the type of a pointer
6611 to such a struct). */
6612 tree protocol_struct_type = xref_tag
6613 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6616 /* Look for the list of Protocol statically allocated instances
6617 to fixup at runtime. Create a new list to hold Protocol
6618 statically allocated instances, if the list is not found. At
6619 present there is only another list, holding NSConstantString
6620 static instances to be fixed up at runtime. */
6621 for (chain = &objc_static_instances;
6622 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6623 chain = &TREE_CHAIN (*chain));
6626 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6627 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6631 /* Add this statically allocated instance to the Protocol list. */
6632 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6633 PROTOCOL_FORWARD_DECL (p),
6634 TREE_PURPOSE (*chain));
6641 /* This function is called by the parser when a @selector() expression
6642 is found, in order to compile it. It is only called by the parser
6643 and only to compile a @selector(). */
6645 objc_build_selector_expr (tree selnamelist)
6649 /* Obtain the full selector name. */
6650 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6651 /* A unary selector. */
6652 selname = selnamelist;
6653 else if (TREE_CODE (selnamelist) == TREE_LIST)
6654 selname = build_keyword_selector (selnamelist);
6658 /* If we are required to check @selector() expressions as they
6659 are found, check that the selector has been declared. */
6660 if (warn_undeclared_selector)
6662 /* Look the selector up in the list of all known class and
6663 instance methods (up to this line) to check that the selector
6667 /* First try with instance methods. */
6668 hsh = hash_lookup (nst_method_hash_list, selname);
6670 /* If not found, try with class methods. */
6673 hsh = hash_lookup (cls_method_hash_list, selname);
6676 /* If still not found, print out a warning. */
6679 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6684 if (flag_typed_selectors)
6685 return build_typed_selector_reference (selname, 0);
6687 return build_selector_reference (selname);
6691 objc_build_encode_expr (tree type)
6696 encode_type (type, obstack_object_size (&util_obstack),
6697 OBJC_ENCODE_INLINE_DEFS);
6698 obstack_1grow (&util_obstack, 0); /* null terminate string */
6699 string = obstack_finish (&util_obstack);
6701 /* Synthesize a string that represents the encoded struct/union. */
6702 result = my_build_string (strlen (string) + 1, string);
6703 obstack_free (&util_obstack, util_firstobj);
6708 build_ivar_reference (tree id)
6710 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6712 /* Historically, a class method that produced objects (factory
6713 method) would assign `self' to the instance that it
6714 allocated. This would effectively turn the class method into
6715 an instance method. Following this assignment, the instance
6716 variables could be accessed. That practice, while safe,
6717 violates the simple rule that a class method should not refer
6718 to an instance variable. It's better to catch the cases
6719 where this is done unknowingly than to support the above
6721 warning (0, "instance variable %qs accessed in class method",
6722 IDENTIFIER_POINTER (id));
6723 self_decl = convert (objc_instance_type, self_decl); /* cast */
6726 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6729 /* Compute a hash value for a given method SEL_NAME. */
6732 hash_func (tree sel_name)
6734 const unsigned char *s
6735 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6739 h = h * 67 + *s++ - 113;
6746 nst_method_hash_list
6747 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6748 cls_method_hash_list
6749 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6751 /* Initialize the hash table used to hold the constant string objects. */
6752 string_htab = htab_create_ggc (31, string_hash,
6755 /* Initialize the hash table used to hold EH-volatilized types. */
6756 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6757 volatilized_eq, NULL);
6760 /* WARNING!!!! hash_enter is called with a method, and will peek
6761 inside to find its selector! But hash_lookup is given a selector
6762 directly, and looks for the selector that's inside the found
6763 entry's key (method) for comparison. */
6766 hash_enter (hash *hashlist, tree method)
6769 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6771 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6773 obj->next = hashlist[slot];
6776 hashlist[slot] = obj; /* append to front */
6780 hash_lookup (hash *hashlist, tree sel_name)
6784 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6788 if (sel_name == METHOD_SEL_NAME (target->key))
6791 target = target->next;
6797 hash_add_attr (hash entry, tree value)
6801 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6802 obj->next = entry->list;
6805 entry->list = obj; /* append to front */
6809 lookup_method (tree mchain, tree method)
6813 if (TREE_CODE (method) == IDENTIFIER_NODE)
6816 key = METHOD_SEL_NAME (method);
6820 if (METHOD_SEL_NAME (mchain) == key)
6823 mchain = TREE_CHAIN (mchain);
6828 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6829 in INTERFACE, along with any categories and protocols attached thereto.
6830 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6831 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6832 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6833 be found in INTERFACE or any of its superclasses, look for an _instance_
6834 method of the same name in the root class as a last resort.
6836 If a suitable method cannot be found, return NULL_TREE. */
6839 lookup_method_static (tree interface, tree ident, int flags)
6841 tree meth = NULL_TREE, root_inter = NULL_TREE;
6842 tree inter = interface;
6843 int is_class = (flags & OBJC_LOOKUP_CLASS);
6844 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6848 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6849 tree category = inter;
6851 /* First, look up the method in the class itself. */
6852 if ((meth = lookup_method (chain, ident)))
6855 /* Failing that, look for the method in each category of the class. */
6856 while ((category = CLASS_CATEGORY_LIST (category)))
6858 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6860 /* Check directly in each category. */
6861 if ((meth = lookup_method (chain, ident)))
6864 /* Failing that, check in each category's protocols. */
6865 if (CLASS_PROTOCOL_LIST (category))
6867 if ((meth = (lookup_method_in_protocol_list
6868 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6873 /* If not found in categories, check in protocols of the main class. */
6874 if (CLASS_PROTOCOL_LIST (inter))
6876 if ((meth = (lookup_method_in_protocol_list
6877 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6881 /* If we were instructed not to look in superclasses, don't. */
6882 if (no_superclasses)
6885 /* Failing that, climb up the inheritance hierarchy. */
6887 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6891 /* If no class (factory) method was found, check if an _instance_
6892 method of the same name exists in the root class. This is what
6893 the Objective-C runtime will do. If an instance method was not
6895 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6898 /* Add the method to the hash list if it doesn't contain an identical
6901 add_method_to_hash_list (hash *hash_list, tree method)
6905 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6907 /* Install on a global chain. */
6908 hash_enter (hash_list, method);
6912 /* Check types against those; if different, add to a list. */
6914 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6915 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6916 already_there |= comp_proto_with_proto (method, loop->value, 1);
6918 hash_add_attr (hsh, method);
6923 objc_add_method (tree class, tree method, int is_class)
6927 if (!(mth = lookup_method (is_class
6928 ? CLASS_CLS_METHODS (class)
6929 : CLASS_NST_METHODS (class), method)))
6931 /* put method on list in reverse order */
6934 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6935 CLASS_CLS_METHODS (class) = method;
6939 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6940 CLASS_NST_METHODS (class) = method;
6945 /* When processing an @interface for a class or category, give hard
6946 errors on methods with identical selectors but differing argument
6947 and/or return types. We do not do this for @implementations, because
6948 C/C++ will do it for us (i.e., there will be duplicate function
6949 definition errors). */
6950 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6951 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6952 && !comp_proto_with_proto (method, mth, 1))
6953 error ("duplicate declaration of method %<%c%s%>",
6954 is_class ? '+' : '-',
6955 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6959 add_method_to_hash_list (cls_method_hash_list, method);
6962 add_method_to_hash_list (nst_method_hash_list, method);
6964 /* Instance methods in root classes (and categories thereof)
6965 may act as class methods as a last resort. We also add
6966 instance methods listed in @protocol declarations to
6967 the class hash table, on the assumption that @protocols
6968 may be adopted by root classes or categories. */
6969 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6970 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6971 class = lookup_interface (CLASS_NAME (class));
6973 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6974 || !CLASS_SUPER_NAME (class))
6975 add_method_to_hash_list (cls_method_hash_list, method);
6982 add_class (tree class_name, tree name)
6984 struct interface_tuple **slot;
6986 /* Put interfaces on list in reverse order. */
6987 TREE_CHAIN (class_name) = interface_chain;
6988 interface_chain = class_name;
6990 if (interface_htab == NULL)
6991 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6992 slot = (struct interface_tuple **)
6993 htab_find_slot_with_hash (interface_htab, name,
6994 htab_hash_pointer (name),
6998 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7001 (*slot)->class_name = class_name;
7003 return interface_chain;
7007 add_category (tree class, tree category)
7009 /* Put categories on list in reverse order. */
7010 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7014 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7015 IDENTIFIER_POINTER (CLASS_NAME (class)),
7016 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7020 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7021 CLASS_CATEGORY_LIST (class) = category;
7025 /* Called after parsing each instance variable declaration. Necessary to
7026 preserve typedefs and implement public/private...
7028 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7031 add_instance_variable (tree class, int public, tree field_decl)
7033 tree field_type = TREE_TYPE (field_decl);
7034 const char *ivar_name = DECL_NAME (field_decl)
7035 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7039 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7041 error ("illegal reference type specified for instance variable %qs",
7043 /* Return class as is without adding this ivar. */
7048 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7049 || TYPE_SIZE (field_type) == error_mark_node)
7050 /* 'type[0]' is allowed, but 'type[]' is not! */
7052 error ("instance variable %qs has unknown size", ivar_name);
7053 /* Return class as is without adding this ivar. */
7058 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7059 need to either (1) warn the user about it or (2) generate suitable
7060 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7061 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7062 if (IS_AGGR_TYPE (field_type)
7063 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7064 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7065 || TYPE_POLYMORPHIC_P (field_type)))
7067 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7069 if (flag_objc_call_cxx_cdtors)
7071 /* Since the ObjC runtime will be calling the constructors and
7072 destructors for us, the only thing we can't handle is the lack
7073 of a default constructor. */
7074 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7075 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7077 warning (0, "type %qs has no default constructor to call",
7080 /* If we cannot call a constructor, we should also avoid
7081 calling the destructor, for symmetry. */
7082 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7083 warning (0, "destructor for %qs shall not be run either",
7089 static bool warn_cxx_ivars = false;
7091 if (TYPE_POLYMORPHIC_P (field_type))
7093 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7095 error ("type %qs has virtual member functions", type_name);
7096 error ("illegal aggregate type %qs specified "
7097 "for instance variable %qs",
7098 type_name, ivar_name);
7099 /* Return class as is without adding this ivar. */
7103 /* User-defined constructors and destructors are not known to Obj-C
7104 and hence will not be called. This may or may not be a problem. */
7105 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7106 warning (0, "type %qs has a user-defined constructor", type_name);
7107 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7108 warning (0, "type %qs has a user-defined destructor", type_name);
7110 if (!warn_cxx_ivars)
7112 warning (0, "C++ constructors and destructors will not "
7113 "be invoked for Objective-C fields");
7114 warn_cxx_ivars = true;
7120 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7124 TREE_PUBLIC (field_decl) = 0;
7125 TREE_PRIVATE (field_decl) = 0;
7126 TREE_PROTECTED (field_decl) = 1;
7130 TREE_PUBLIC (field_decl) = 1;
7131 TREE_PRIVATE (field_decl) = 0;
7132 TREE_PROTECTED (field_decl) = 0;
7136 TREE_PUBLIC (field_decl) = 0;
7137 TREE_PRIVATE (field_decl) = 1;
7138 TREE_PROTECTED (field_decl) = 0;
7143 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7149 is_ivar (tree decl_chain, tree ident)
7151 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7152 if (DECL_NAME (decl_chain) == ident)
7157 /* True if the ivar is private and we are not in its implementation. */
7160 is_private (tree decl)
7162 return (TREE_PRIVATE (decl)
7163 && ! is_ivar (CLASS_IVARS (implementation_template),
7167 /* We have an instance variable reference;, check to see if it is public. */
7170 objc_is_public (tree expr, tree identifier)
7172 tree basetype, decl;
7175 if (processing_template_decl)
7179 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7181 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7183 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7185 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7189 error ("cannot find interface declaration for %qs",
7190 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7194 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7196 if (TREE_PUBLIC (decl))
7199 /* Important difference between the Stepstone translator:
7200 all instance variables should be public within the context
7201 of the implementation. */
7202 if (objc_implementation_context
7203 && ((TREE_CODE (objc_implementation_context)
7204 == CLASS_IMPLEMENTATION_TYPE)
7205 || (TREE_CODE (objc_implementation_context)
7206 == CATEGORY_IMPLEMENTATION_TYPE)))
7208 tree curtype = TYPE_MAIN_VARIANT
7209 (CLASS_STATIC_TEMPLATE
7210 (implementation_template));
7212 if (basetype == curtype
7213 || DERIVED_FROM_P (basetype, curtype))
7215 int private = is_private (decl);
7218 error ("instance variable %qs is declared private",
7219 IDENTIFIER_POINTER (DECL_NAME (decl)));
7225 /* The 2.95.2 compiler sometimes allowed C functions to access
7226 non-@public ivars. We will let this slide for now... */
7227 if (!objc_method_context)
7229 warning (0, "instance variable %qs is %s; "
7230 "this will be a hard error in the future",
7231 IDENTIFIER_POINTER (identifier),
7232 TREE_PRIVATE (decl) ? "@private" : "@protected");
7236 error ("instance variable %qs is declared %s",
7237 IDENTIFIER_POINTER (identifier),
7238 TREE_PRIVATE (decl) ? "private" : "protected");
7247 /* Make sure all entries in CHAIN are also in LIST. */
7250 check_methods (tree chain, tree list, int mtype)
7256 if (!lookup_method (list, chain))
7260 if (TREE_CODE (objc_implementation_context)
7261 == CLASS_IMPLEMENTATION_TYPE)
7262 warning (0, "incomplete implementation of class %qs",
7263 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7264 else if (TREE_CODE (objc_implementation_context)
7265 == CATEGORY_IMPLEMENTATION_TYPE)
7266 warning (0, "incomplete implementation of category %qs",
7267 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7271 warning (0, "method definition for %<%c%s%> not found",
7272 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7275 chain = TREE_CHAIN (chain);
7281 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7284 conforms_to_protocol (tree class, tree protocol)
7286 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7288 tree p = CLASS_PROTOCOL_LIST (class);
7289 while (p && TREE_VALUE (p) != protocol)
7294 tree super = (CLASS_SUPER_NAME (class)
7295 ? lookup_interface (CLASS_SUPER_NAME (class))
7297 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7306 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7307 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7310 check_methods_accessible (tree chain, tree context, int mtype)
7314 tree base_context = context;
7318 context = base_context;
7322 list = CLASS_CLS_METHODS (context);
7324 list = CLASS_NST_METHODS (context);
7326 if (lookup_method (list, chain))
7329 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7330 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7331 context = (CLASS_SUPER_NAME (context)
7332 ? lookup_interface (CLASS_SUPER_NAME (context))
7335 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7336 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7337 context = (CLASS_NAME (context)
7338 ? lookup_interface (CLASS_NAME (context))
7344 if (context == NULL_TREE)
7348 if (TREE_CODE (objc_implementation_context)
7349 == CLASS_IMPLEMENTATION_TYPE)
7350 warning (0, "incomplete implementation of class %qs",
7352 (CLASS_NAME (objc_implementation_context)));
7353 else if (TREE_CODE (objc_implementation_context)
7354 == CATEGORY_IMPLEMENTATION_TYPE)
7355 warning (0, "incomplete implementation of category %qs",
7357 (CLASS_SUPER_NAME (objc_implementation_context)));
7360 warning (0, "method definition for %<%c%s%> not found",
7361 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7364 chain = TREE_CHAIN (chain); /* next method... */
7369 /* Check whether the current interface (accessible via
7370 'objc_implementation_context') actually implements protocol P, along
7371 with any protocols that P inherits. */
7374 check_protocol (tree p, const char *type, const char *name)
7376 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7380 /* Ensure that all protocols have bodies! */
7383 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7384 CLASS_CLS_METHODS (objc_implementation_context),
7386 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7387 CLASS_NST_METHODS (objc_implementation_context),
7392 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7393 objc_implementation_context,
7395 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7396 objc_implementation_context,
7401 warning (0, "%s %qs does not fully implement the %qs protocol",
7402 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7405 /* Check protocols recursively. */
7406 if (PROTOCOL_LIST (p))
7408 tree subs = PROTOCOL_LIST (p);
7410 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7414 tree sub = TREE_VALUE (subs);
7416 /* If the superclass does not conform to the protocols
7417 inherited by P, then we must! */
7418 if (!super_class || !conforms_to_protocol (super_class, sub))
7419 check_protocol (sub, type, name);
7420 subs = TREE_CHAIN (subs);
7425 /* Check whether the current interface (accessible via
7426 'objc_implementation_context') actually implements the protocols listed
7430 check_protocols (tree proto_list, const char *type, const char *name)
7432 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7434 tree p = TREE_VALUE (proto_list);
7436 check_protocol (p, type, name);
7440 /* Make sure that the class CLASS_NAME is defined
7441 CODE says which kind of thing CLASS_NAME ought to be.
7442 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7443 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7446 start_class (enum tree_code code, tree class_name, tree super_name,
7452 if (current_namespace != global_namespace) {
7453 error ("Objective-C declarations may only appear in global scope");
7455 #endif /* OBJCPLUS */
7457 if (objc_implementation_context)
7459 warning (0, "%<@end%> missing in implementation context");
7460 finish_class (objc_implementation_context);
7461 objc_ivar_chain = NULL_TREE;
7462 objc_implementation_context = NULL_TREE;
7465 class = make_node (code);
7466 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7468 /* Check for existence of the super class, if one was specified. Note
7469 that we must have seen an @interface, not just a @class. If we
7470 are looking at a @compatibility_alias, traverse it first. */
7471 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7474 tree super = objc_is_class_name (super_name);
7476 if (!super || !lookup_interface (super))
7478 error ("cannot find interface declaration for %qs, superclass of %qs",
7479 IDENTIFIER_POINTER (super ? super : super_name),
7480 IDENTIFIER_POINTER (class_name));
7481 super_name = NULL_TREE;
7487 CLASS_NAME (class) = class_name;
7488 CLASS_SUPER_NAME (class) = super_name;
7489 CLASS_CLS_METHODS (class) = NULL_TREE;
7491 if (! objc_is_class_name (class_name)
7492 && (decl = lookup_name (class_name)))
7494 error ("%qs redeclared as different kind of symbol",
7495 IDENTIFIER_POINTER (class_name));
7496 error ("previous declaration of %q+D",
7500 if (code == CLASS_IMPLEMENTATION_TYPE)
7505 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7506 if (TREE_VALUE (chain) == class_name)
7508 error ("reimplementation of class %qs",
7509 IDENTIFIER_POINTER (class_name));
7510 return error_mark_node;
7512 implemented_classes = tree_cons (NULL_TREE, class_name,
7513 implemented_classes);
7516 /* Reset for multiple classes per file. */
7519 objc_implementation_context = class;
7521 /* Lookup the interface for this implementation. */
7523 if (!(implementation_template = lookup_interface (class_name)))
7525 warning (0, "cannot find interface declaration for %qs",
7526 IDENTIFIER_POINTER (class_name));
7527 add_class (implementation_template = objc_implementation_context,
7531 /* If a super class has been specified in the implementation,
7532 insure it conforms to the one specified in the interface. */
7535 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7537 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7538 const char *const name =
7539 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7540 error ("conflicting super class name %qs",
7541 IDENTIFIER_POINTER (super_name));
7542 error ("previous declaration of %qs", name);
7545 else if (! super_name)
7547 CLASS_SUPER_NAME (objc_implementation_context)
7548 = CLASS_SUPER_NAME (implementation_template);
7552 else if (code == CLASS_INTERFACE_TYPE)
7554 if (lookup_interface (class_name))
7556 error ("duplicate interface declaration for class %qs",
7558 warning (0, "duplicate interface declaration for class %qs",
7560 IDENTIFIER_POINTER (class_name));
7562 add_class (class, class_name);
7565 CLASS_PROTOCOL_LIST (class)
7566 = lookup_and_install_protocols (protocol_list);
7569 else if (code == CATEGORY_INTERFACE_TYPE)
7571 tree class_category_is_assoc_with;
7573 /* For a category, class_name is really the name of the class that
7574 the following set of methods will be associated with. We must
7575 find the interface so that can derive the objects template. */
7577 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7579 error ("cannot find interface declaration for %qs",
7580 IDENTIFIER_POINTER (class_name));
7581 exit (FATAL_EXIT_CODE);
7584 add_category (class_category_is_assoc_with, class);
7587 CLASS_PROTOCOL_LIST (class)
7588 = lookup_and_install_protocols (protocol_list);
7591 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7593 /* Reset for multiple classes per file. */
7596 objc_implementation_context = class;
7598 /* For a category, class_name is really the name of the class that
7599 the following set of methods will be associated with. We must
7600 find the interface so that can derive the objects template. */
7602 if (!(implementation_template = lookup_interface (class_name)))
7604 error ("cannot find interface declaration for %qs",
7605 IDENTIFIER_POINTER (class_name));
7606 exit (FATAL_EXIT_CODE);
7613 continue_class (tree class)
7615 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7616 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7618 struct imp_entry *imp_entry;
7620 /* Check consistency of the instance variables. */
7622 if (CLASS_RAW_IVARS (class))
7623 check_ivars (implementation_template, class);
7625 /* code generation */
7628 push_lang_context (lang_name_c);
7631 build_private_template (implementation_template);
7632 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7633 objc_instance_type = build_pointer_type (uprivate_record);
7635 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7637 imp_entry->next = imp_list;
7638 imp_entry->imp_context = class;
7639 imp_entry->imp_template = implementation_template;
7641 synth_forward_declarations ();
7642 imp_entry->class_decl = UOBJC_CLASS_decl;
7643 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7644 imp_entry->has_cxx_cdtors = 0;
7646 /* Append to front and increment count. */
7647 imp_list = imp_entry;
7648 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7654 pop_lang_context ();
7655 #endif /* OBJCPLUS */
7657 return get_class_ivars (implementation_template, true);
7660 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7663 push_lang_context (lang_name_c);
7664 #endif /* OBJCPLUS */
7666 build_private_template (class);
7669 pop_lang_context ();
7670 #endif /* OBJCPLUS */
7676 return error_mark_node;
7679 /* This is called once we see the "@end" in an interface/implementation. */
7682 finish_class (tree class)
7684 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7686 /* All code generation is done in finish_objc. */
7688 if (implementation_template != objc_implementation_context)
7690 /* Ensure that all method listed in the interface contain bodies. */
7691 check_methods (CLASS_CLS_METHODS (implementation_template),
7692 CLASS_CLS_METHODS (objc_implementation_context), '+');
7693 check_methods (CLASS_NST_METHODS (implementation_template),
7694 CLASS_NST_METHODS (objc_implementation_context), '-');
7696 if (CLASS_PROTOCOL_LIST (implementation_template))
7697 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7699 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7703 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7705 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7709 /* Ensure all method listed in the interface contain bodies. */
7710 check_methods (CLASS_CLS_METHODS (category),
7711 CLASS_CLS_METHODS (objc_implementation_context), '+');
7712 check_methods (CLASS_NST_METHODS (category),
7713 CLASS_NST_METHODS (objc_implementation_context), '-');
7715 if (CLASS_PROTOCOL_LIST (category))
7716 check_protocols (CLASS_PROTOCOL_LIST (category),
7718 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7724 add_protocol (tree protocol)
7726 /* Put protocol on list in reverse order. */
7727 TREE_CHAIN (protocol) = protocol_chain;
7728 protocol_chain = protocol;
7729 return protocol_chain;
7733 lookup_protocol (tree ident)
7737 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7738 if (ident == PROTOCOL_NAME (chain))
7744 /* This function forward declares the protocols named by NAMES. If
7745 they are already declared or defined, the function has no effect. */
7748 objc_declare_protocols (tree names)
7753 if (current_namespace != global_namespace) {
7754 error ("Objective-C declarations may only appear in global scope");
7756 #endif /* OBJCPLUS */
7758 for (list = names; list; list = TREE_CHAIN (list))
7760 tree name = TREE_VALUE (list);
7762 if (lookup_protocol (name) == NULL_TREE)
7764 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7766 TYPE_LANG_SLOT_1 (protocol)
7767 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7768 PROTOCOL_NAME (protocol) = name;
7769 PROTOCOL_LIST (protocol) = NULL_TREE;
7770 add_protocol (protocol);
7771 PROTOCOL_DEFINED (protocol) = 0;
7772 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7778 start_protocol (enum tree_code code, tree name, tree list)
7783 if (current_namespace != global_namespace) {
7784 error ("Objective-C declarations may only appear in global scope");
7786 #endif /* OBJCPLUS */
7788 protocol = lookup_protocol (name);
7792 protocol = make_node (code);
7793 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7795 PROTOCOL_NAME (protocol) = name;
7796 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7797 add_protocol (protocol);
7798 PROTOCOL_DEFINED (protocol) = 1;
7799 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7801 check_protocol_recursively (protocol, list);
7803 else if (! PROTOCOL_DEFINED (protocol))
7805 PROTOCOL_DEFINED (protocol) = 1;
7806 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7808 check_protocol_recursively (protocol, list);
7812 warning (0, "duplicate declaration for protocol %qs",
7813 IDENTIFIER_POINTER (name));
7819 /* "Encode" a data type into a string, which grows in util_obstack.
7820 ??? What is the FORMAT? Someone please document this! */
7823 encode_type_qualifiers (tree declspecs)
7827 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7829 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7830 obstack_1grow (&util_obstack, 'n');
7831 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7832 obstack_1grow (&util_obstack, 'N');
7833 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7834 obstack_1grow (&util_obstack, 'o');
7835 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7836 obstack_1grow (&util_obstack, 'O');
7837 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7838 obstack_1grow (&util_obstack, 'R');
7839 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7840 obstack_1grow (&util_obstack, 'V');
7844 /* Encode a pointer type. */
7847 encode_pointer (tree type, int curtype, int format)
7849 tree pointer_to = TREE_TYPE (type);
7851 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7853 if (OBJC_TYPE_NAME (pointer_to)
7854 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7856 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7858 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7860 obstack_1grow (&util_obstack, '@');
7863 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7864 && TYPE_OBJC_INTERFACE (pointer_to))
7866 if (generating_instance_variables)
7868 obstack_1grow (&util_obstack, '@');
7869 obstack_1grow (&util_obstack, '"');
7870 obstack_grow (&util_obstack, name, strlen (name));
7871 obstack_1grow (&util_obstack, '"');
7876 obstack_1grow (&util_obstack, '@');
7880 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7882 obstack_1grow (&util_obstack, '#');
7885 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7887 obstack_1grow (&util_obstack, ':');
7892 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7893 && TYPE_MODE (pointer_to) == QImode)
7895 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7896 ? OBJC_TYPE_NAME (pointer_to)
7897 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7899 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7901 /* It appears that "r*" means "const char *" rather than
7903 if (TYPE_READONLY (pointer_to))
7904 obstack_1grow (&util_obstack, 'r');
7906 obstack_1grow (&util_obstack, '*');
7911 /* We have a type that does not get special treatment. */
7913 /* NeXT extension */
7914 obstack_1grow (&util_obstack, '^');
7915 encode_type (pointer_to, curtype, format);
7919 encode_array (tree type, int curtype, int format)
7921 tree an_int_cst = TYPE_SIZE (type);
7922 tree array_of = TREE_TYPE (type);
7925 /* An incomplete array is treated like a pointer. */
7926 if (an_int_cst == NULL)
7928 encode_pointer (type, curtype, format);
7932 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7933 (TREE_INT_CST_LOW (an_int_cst)
7934 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7936 obstack_grow (&util_obstack, buffer, strlen (buffer));
7937 encode_type (array_of, curtype, format);
7938 obstack_1grow (&util_obstack, ']');
7943 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7945 tree field = TYPE_FIELDS (type);
7947 for (; field; field = TREE_CHAIN (field))
7950 /* C++ static members, and things that are not field at all,
7951 should not appear in the encoding. */
7952 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7956 /* Recursively encode fields of embedded base classes. */
7957 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7958 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7960 encode_aggregate_fields (TREE_TYPE (field),
7961 pointed_to, curtype, format);
7965 if (generating_instance_variables && !pointed_to)
7967 tree fname = DECL_NAME (field);
7969 obstack_1grow (&util_obstack, '"');
7971 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7972 obstack_grow (&util_obstack,
7973 IDENTIFIER_POINTER (fname),
7974 strlen (IDENTIFIER_POINTER (fname)));
7976 obstack_1grow (&util_obstack, '"');
7979 encode_field_decl (field, curtype, format);
7984 encode_aggregate_within (tree type, int curtype, int format, int left,
7988 /* NB: aggregates that are pointed to have slightly different encoding
7989 rules in that you never encode the names of instance variables. */
7990 int ob_size = obstack_object_size (&util_obstack);
7991 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7992 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7993 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7995 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7996 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7998 /* Traverse struct aliases; it is important to get the
7999 original struct and its tag name (if any). */
8000 type = TYPE_MAIN_VARIANT (type);
8001 name = OBJC_TYPE_NAME (type);
8002 /* Open parenth/bracket. */
8003 obstack_1grow (&util_obstack, left);
8005 /* Encode the struct/union tag name, or '?' if a tag was
8006 not provided. Typedef aliases do not qualify. */
8007 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8009 /* Did this struct have a tag? */
8010 && !TYPE_WAS_ANONYMOUS (type)
8013 obstack_grow (&util_obstack,
8014 IDENTIFIER_POINTER (name),
8015 strlen (IDENTIFIER_POINTER (name)));
8017 obstack_1grow (&util_obstack, '?');
8019 /* Encode the types (and possibly names) of the inner fields,
8021 if (inline_contents)
8023 obstack_1grow (&util_obstack, '=');
8024 encode_aggregate_fields (type, pointed_to, curtype, format);
8026 /* Close parenth/bracket. */
8027 obstack_1grow (&util_obstack, right);
8031 encode_aggregate (tree type, int curtype, int format)
8033 enum tree_code code = TREE_CODE (type);
8039 encode_aggregate_within (type, curtype, format, '{', '}');
8044 encode_aggregate_within (type, curtype, format, '(', ')');
8049 obstack_1grow (&util_obstack, 'i');
8057 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8061 encode_next_bitfield (int width)
8064 sprintf (buffer, "b%d", width);
8065 obstack_grow (&util_obstack, buffer, strlen (buffer));
8068 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8070 encode_type (tree type, int curtype, int format)
8072 enum tree_code code = TREE_CODE (type);
8075 if (TYPE_READONLY (type))
8076 obstack_1grow (&util_obstack, 'r');
8078 if (code == INTEGER_TYPE)
8080 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8082 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8083 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8085 if (type == long_unsigned_type_node
8086 || type == long_integer_type_node)
8087 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8089 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8091 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8094 obstack_1grow (&util_obstack, c);
8097 else if (code == REAL_TYPE)
8099 /* Floating point types. */
8100 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8102 case 32: c = 'f'; break;
8105 case 128: c = 'd'; break;
8108 obstack_1grow (&util_obstack, c);
8111 else if (code == VOID_TYPE)
8112 obstack_1grow (&util_obstack, 'v');
8114 else if (code == BOOLEAN_TYPE)
8115 obstack_1grow (&util_obstack, 'B');
8117 else if (code == ARRAY_TYPE)
8118 encode_array (type, curtype, format);
8120 else if (code == POINTER_TYPE)
8121 encode_pointer (type, curtype, format);
8123 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8124 encode_aggregate (type, curtype, format);
8126 else if (code == FUNCTION_TYPE) /* '?' */
8127 obstack_1grow (&util_obstack, '?');
8131 encode_gnu_bitfield (int position, tree type, int size)
8133 enum tree_code code = TREE_CODE (type);
8135 char charType = '?';
8137 if (code == INTEGER_TYPE)
8139 if (integer_zerop (TYPE_MIN_VALUE (type)))
8141 /* Unsigned integer types. */
8143 if (TYPE_MODE (type) == QImode)
8145 else if (TYPE_MODE (type) == HImode)
8147 else if (TYPE_MODE (type) == SImode)
8149 if (type == long_unsigned_type_node)
8154 else if (TYPE_MODE (type) == DImode)
8159 /* Signed integer types. */
8161 if (TYPE_MODE (type) == QImode)
8163 else if (TYPE_MODE (type) == HImode)
8165 else if (TYPE_MODE (type) == SImode)
8167 if (type == long_integer_type_node)
8173 else if (TYPE_MODE (type) == DImode)
8177 else if (code == ENUMERAL_TYPE)
8182 sprintf (buffer, "b%d%c%d", position, charType, size);
8183 obstack_grow (&util_obstack, buffer, strlen (buffer));
8187 encode_field_decl (tree field_decl, int curtype, int format)
8192 /* C++ static members, and things that are not fields at all,
8193 should not appear in the encoding. */
8194 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8198 type = TREE_TYPE (field_decl);
8200 /* Generate the bitfield typing information, if needed. Note the difference
8201 between GNU and NeXT runtimes. */
8202 if (DECL_BIT_FIELD_TYPE (field_decl))
8204 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8206 if (flag_next_runtime)
8207 encode_next_bitfield (size);
8209 encode_gnu_bitfield (int_bit_position (field_decl),
8210 DECL_BIT_FIELD_TYPE (field_decl), size);
8213 encode_type (TREE_TYPE (field_decl), curtype, format);
8216 static GTY(()) tree objc_parmlist = NULL_TREE;
8218 /* Append PARM to a list of formal parameters of a method, making a necessary
8219 array-to-pointer adjustment along the way. */
8222 objc_push_parm (tree parm)
8224 /* Decay arrays and functions into pointers. */
8225 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8226 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8227 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8228 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8230 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
8231 DECL_ARG_TYPE (parm)
8232 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8234 /* Record constancy and volatility. */
8235 c_apply_type_quals_to_decl
8236 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8237 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8238 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8240 objc_parmlist = chainon (objc_parmlist, parm);
8243 /* Retrieve the formal parameter list constructed via preceding calls to
8244 objc_push_parm(). */
8248 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8250 static struct c_arg_info *
8251 objc_get_parm_info (int have_ellipsis)
8255 tree parm_info = objc_parmlist;
8256 objc_parmlist = NULL_TREE;
8260 tree parm_info = objc_parmlist;
8261 struct c_arg_info *arg_info;
8262 /* The C front-end requires an elaborate song and dance at
8265 declare_parm_level ();
8268 tree next = TREE_CHAIN (parm_info);
8270 TREE_CHAIN (parm_info) = NULL_TREE;
8271 parm_info = pushdecl (parm_info);
8272 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8275 arg_info = get_parm_info (have_ellipsis);
8277 objc_parmlist = NULL_TREE;
8282 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8283 method definitions. In the case of instance methods, we can be more
8284 specific as to the type of 'self'. */
8287 synth_self_and_ucmd_args (void)
8291 if (objc_method_context
8292 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8293 self_type = objc_instance_type;
8295 /* Really a `struct objc_class *'. However, we allow people to
8296 assign to self, which changes its type midstream. */
8297 self_type = objc_object_type;
8300 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8303 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8306 /* Transform an Objective-C method definition into a static C function
8307 definition, synthesizing the first two arguments, "self" and "_cmd",
8311 start_method_def (tree method)
8317 struct c_arg_info *parm_info;
8319 int have_ellipsis = 0;
8321 /* If we are defining a "dealloc" method in a non-root class, we
8322 will need to check if a [super dealloc] is missing, and warn if
8324 if(CLASS_SUPER_NAME (objc_implementation_context)
8325 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8326 should_call_super_dealloc = 1;
8328 should_call_super_dealloc = 0;
8330 /* Required to implement _msgSuper. */
8331 objc_method_context = method;
8332 UOBJC_SUPER_decl = NULL_TREE;
8334 /* Generate prototype declarations for arguments..."new-style". */
8335 synth_self_and_ucmd_args ();
8337 /* Generate argument declarations if a keyword_decl. */
8338 parmlist = METHOD_SEL_ARGS (method);
8341 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8343 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8344 objc_push_parm (parm);
8345 parmlist = TREE_CHAIN (parmlist);
8348 if (METHOD_ADD_ARGS (method))
8352 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8353 akey; akey = TREE_CHAIN (akey))
8355 objc_push_parm (TREE_VALUE (akey));
8358 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8362 parm_info = objc_get_parm_info (have_ellipsis);
8364 really_start_method (objc_method_context, parm_info);
8368 warn_with_method (const char *message, int mtype, tree method)
8370 /* Add a readable method name to the warning. */
8371 warning (0, "%J%s %<%c%s%>", method,
8372 message, mtype, gen_method_decl (method));
8375 /* Return 1 if TYPE1 is equivalent to TYPE2
8376 for purposes of method overloading. */
8379 objc_types_are_equivalent (tree type1, tree type2)
8384 /* Strip away indirections. */
8385 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8386 && (TREE_CODE (type1) == TREE_CODE (type2)))
8387 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8388 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8391 type1 = (TYPE_HAS_OBJC_INFO (type1)
8392 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8394 type2 = (TYPE_HAS_OBJC_INFO (type2)
8395 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8398 if (list_length (type1) == list_length (type2))
8400 for (; type2; type2 = TREE_CHAIN (type2))
8401 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8408 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8411 objc_types_share_size_and_alignment (tree type1, tree type2)
8413 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8414 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8417 /* Return 1 if PROTO1 is equivalent to PROTO2
8418 for purposes of method overloading. Ordinarily, the type signatures
8419 should match up exactly, unless STRICT is zero, in which case we
8420 shall allow differences in which the size and alignment of a type
8424 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8428 /* The following test is needed in case there are hashing
8430 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8433 /* Compare return types. */
8434 type1 = TREE_VALUE (TREE_TYPE (proto1));
8435 type2 = TREE_VALUE (TREE_TYPE (proto2));
8437 if (!objc_types_are_equivalent (type1, type2)
8438 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8441 /* Compare argument types. */
8442 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8443 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8445 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8447 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8449 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8450 TREE_VALUE (type2))))
8454 return (!type1 && !type2);
8457 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8458 this occurs. ObjC method dispatches are _not_ like C++ virtual
8459 member function dispatches, and we account for the difference here. */
8462 objc_fold_obj_type_ref (tree ref, tree known_type)
8464 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8465 tree known_type ATTRIBUTE_UNUSED)
8469 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8471 /* If the receiver does not have virtual member functions, there
8472 is nothing we can (or need to) do here. */
8476 /* Let C++ handle C++ virtual functions. */
8477 return cp_fold_obj_type_ref (ref, known_type);
8479 /* For plain ObjC, we currently do not need to do anything. */
8485 objc_start_function (tree name, tree type, tree attrs,
8489 struct c_arg_info *params
8493 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8496 DECL_ARGUMENTS (fndecl) = params;
8497 DECL_INITIAL (fndecl) = error_mark_node;
8498 DECL_EXTERNAL (fndecl) = 0;
8499 TREE_STATIC (fndecl) = 1;
8500 retrofit_lang_decl (fndecl);
8501 cplus_decl_attributes (&fndecl, attrs, 0);
8502 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8504 struct c_label_context_se *nstack_se;
8505 struct c_label_context_vm *nstack_vm;
8506 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8507 nstack_se->labels_def = NULL;
8508 nstack_se->labels_used = NULL;
8509 nstack_se->next = label_context_stack_se;
8510 label_context_stack_se = nstack_se;
8511 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8512 nstack_vm->labels_def = NULL;
8513 nstack_vm->labels_used = NULL;
8514 nstack_vm->scope = 0;
8515 nstack_vm->next = label_context_stack_vm;
8516 label_context_stack_vm = nstack_vm;
8517 current_function_returns_value = 0; /* Assume, until we see it does. */
8518 current_function_returns_null = 0;
8520 decl_attributes (&fndecl, attrs, 0);
8521 announce_function (fndecl);
8522 DECL_INITIAL (fndecl) = error_mark_node;
8523 DECL_EXTERNAL (fndecl) = 0;
8524 TREE_STATIC (fndecl) = 1;
8525 current_function_decl = pushdecl (fndecl);
8527 declare_parm_level ();
8528 DECL_RESULT (current_function_decl)
8529 = build_decl (RESULT_DECL, NULL_TREE,
8530 TREE_TYPE (TREE_TYPE (current_function_decl)));
8531 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8532 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8533 start_fname_decls ();
8534 store_parm_decls_from (params);
8537 TREE_USED (current_function_decl) = 1;
8540 /* - Generate an identifier for the function. the format is "_n_cls",
8541 where 1 <= n <= nMethods, and cls is the name the implementation we
8543 - Install the return type from the method declaration.
8544 - If we have a prototype, check for type consistency. */
8547 really_start_method (tree method,
8551 struct c_arg_info *parmlist
8555 tree ret_type, meth_type;
8557 const char *sel_name, *class_name, *cat_name;
8560 /* Synth the storage class & assemble the return type. */
8561 ret_type = TREE_VALUE (TREE_TYPE (method));
8563 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8564 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8565 cat_name = ((TREE_CODE (objc_implementation_context)
8566 == CLASS_IMPLEMENTATION_TYPE)
8568 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8571 /* Make sure this is big enough for any plausible method label. */
8572 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8573 + (cat_name ? strlen (cat_name) : 0));
8575 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8576 class_name, cat_name, sel_name, method_slot);
8578 method_id = get_identifier (buf);
8581 /* Objective-C methods cannot be overloaded, so we don't need
8582 the type encoding appended. It looks bad anyway... */
8583 push_lang_context (lang_name_c);
8587 = build_function_type (ret_type,
8588 get_arg_type_list (method, METHOD_DEF, 0));
8589 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8591 /* Set self_decl from the first argument. */
8592 self_decl = DECL_ARGUMENTS (current_function_decl);
8594 /* Suppress unused warnings. */
8595 TREE_USED (self_decl) = 1;
8596 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8598 pop_lang_context ();
8601 METHOD_DEFINITION (method) = current_function_decl;
8603 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8605 if (implementation_template != objc_implementation_context)
8608 = lookup_method_static (implementation_template,
8609 METHOD_SEL_NAME (method),
8610 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8611 | OBJC_LOOKUP_NO_SUPER));
8615 if (!comp_proto_with_proto (method, proto, 1))
8617 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8619 warn_with_method ("conflicting types for", type, method);
8620 warn_with_method ("previous declaration of", type, proto);
8625 /* We have a method @implementation even though we did not
8626 see a corresponding @interface declaration (which is allowed
8627 by Objective-C rules). Go ahead and place the method in
8628 the @interface anyway, so that message dispatch lookups
8630 tree interface = implementation_template;
8632 if (TREE_CODE (objc_implementation_context)
8633 == CATEGORY_IMPLEMENTATION_TYPE)
8634 interface = lookup_category
8636 CLASS_SUPER_NAME (objc_implementation_context));
8639 objc_add_method (interface, copy_node (method),
8640 TREE_CODE (method) == CLASS_METHOD_DECL);
8645 static void *UOBJC_SUPER_scope = 0;
8647 /* _n_Method (id self, SEL sel, ...)
8649 struct objc_super _S;
8650 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8654 get_super_receiver (void)
8656 if (objc_method_context)
8658 tree super_expr, super_expr_list;
8660 if (!UOBJC_SUPER_decl)
8662 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8663 objc_super_template);
8664 /* This prevents `unused variable' warnings when compiling with -Wall. */
8665 TREE_USED (UOBJC_SUPER_decl) = 1;
8666 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8667 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8668 UOBJC_SUPER_scope = objc_get_current_scope ();
8671 /* Set receiver to self. */
8672 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8673 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8674 super_expr_list = super_expr;
8676 /* Set class to begin searching. */
8677 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8678 get_identifier ("super_class"));
8680 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8682 /* [_cls, __cls]Super are "pre-built" in
8683 synth_forward_declarations. */
8685 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8686 ((TREE_CODE (objc_method_context)
8687 == INSTANCE_METHOD_DECL)
8689 : uucls_super_ref));
8693 /* We have a category. */
8695 tree super_name = CLASS_SUPER_NAME (implementation_template);
8698 /* Barf if super used in a category of Object. */
8701 error ("no super class declared in interface for %qs",
8702 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8703 return error_mark_node;
8706 if (flag_next_runtime && !flag_zero_link)
8708 super_class = objc_get_class_reference (super_name);
8709 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8710 /* If we are in a class method, we must retrieve the
8711 _metaclass_ for the current class, pointed at by
8712 the class's "isa" pointer. The following assumes that
8713 "isa" is the first ivar in a class (which it must be). */
8715 = build_indirect_ref
8716 (build_c_cast (build_pointer_type (objc_class_type),
8717 super_class), "unary *");
8721 add_class_reference (super_name);
8722 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8723 ? objc_get_class_decl : objc_get_meta_class_decl);
8724 assemble_external (super_class);
8726 = build_function_call
8730 my_build_string_pointer
8731 (IDENTIFIER_LENGTH (super_name) + 1,
8732 IDENTIFIER_POINTER (super_name))));
8736 = build_modify_expr (super_expr, NOP_EXPR,
8737 build_c_cast (TREE_TYPE (super_expr),
8741 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8743 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8744 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8746 return super_expr_list;
8750 error ("[super ...] must appear in a method context");
8751 return error_mark_node;
8755 /* When exiting a scope, sever links to a 'super' declaration (if any)
8756 therein contained. */
8759 objc_clear_super_receiver (void)
8761 if (objc_method_context
8762 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8763 UOBJC_SUPER_decl = 0;
8764 UOBJC_SUPER_scope = 0;
8769 objc_finish_method_definition (tree fndecl)
8771 /* We cannot validly inline ObjC methods, at least not without a language
8772 extension to declare that a method need not be dynamically
8773 dispatched, so suppress all thoughts of doing so. */
8774 DECL_INLINE (fndecl) = 0;
8775 DECL_UNINLINABLE (fndecl) = 1;
8778 /* The C++ front-end will have called finish_function() for us. */
8782 METHOD_ENCODING (objc_method_context)
8783 = encode_method_prototype (objc_method_context);
8785 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8786 since the optimizer may find "may be used before set" errors. */
8787 objc_method_context = NULL_TREE;
8789 if (should_call_super_dealloc)
8790 warning (0, "method possibly missing a [super dealloc] call");
8795 lang_report_error_function (tree decl)
8797 if (objc_method_context)
8799 fprintf (stderr, "In method %qs\n",
8800 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8809 /* Given a tree DECL node, produce a printable description of it in the given
8810 buffer, overwriting the buffer. */
8813 gen_declaration (tree decl)
8819 gen_type_name_0 (TREE_TYPE (decl));
8821 if (DECL_NAME (decl))
8823 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8824 strcat (errbuf, " ");
8826 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8829 if (DECL_INITIAL (decl)
8830 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8831 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8832 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8838 /* Given a tree TYPE node, produce a printable description of it in the given
8839 buffer, overwriting the buffer. */
8842 gen_type_name_0 (tree type)
8844 tree orig = type, proto;
8846 if (TYPE_P (type) && TYPE_NAME (type))
8847 type = TYPE_NAME (type);
8848 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8850 tree inner = TREE_TYPE (type);
8852 while (TREE_CODE (inner) == ARRAY_TYPE)
8853 inner = TREE_TYPE (inner);
8855 gen_type_name_0 (inner);
8857 if (!POINTER_TYPE_P (inner))
8858 strcat (errbuf, " ");
8860 if (POINTER_TYPE_P (type))
8861 strcat (errbuf, "*");
8863 while (type != inner)
8865 strcat (errbuf, "[");
8867 if (TYPE_DOMAIN (type))
8871 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8873 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8874 strcat (errbuf, sz);
8877 strcat (errbuf, "]");
8878 type = TREE_TYPE (type);
8884 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8885 type = DECL_NAME (type);
8887 strcat (errbuf, IDENTIFIER_POINTER (type));
8889 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8890 if (objc_is_id (orig))
8891 orig = TREE_TYPE (orig);
8893 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8897 strcat (errbuf, " <");
8901 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8902 proto = TREE_CHAIN (proto);
8903 strcat (errbuf, proto ? ", " : ">");
8912 gen_type_name (tree type)
8916 return gen_type_name_0 (type);
8919 /* Given a method tree, put a printable description into the given
8920 buffer (overwriting) and return a pointer to the buffer. */
8923 gen_method_decl (tree method)
8927 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8928 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8929 strcat (errbuf, ")");
8930 chain = METHOD_SEL_ARGS (method);
8934 /* We have a chain of keyword_decls. */
8937 if (KEYWORD_KEY_NAME (chain))
8938 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8940 strcat (errbuf, ":(");
8941 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8942 strcat (errbuf, ")");
8944 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8945 if ((chain = TREE_CHAIN (chain)))
8946 strcat (errbuf, " ");
8950 if (METHOD_ADD_ARGS (method))
8952 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8954 /* Know we have a chain of parm_decls. */
8957 strcat (errbuf, ", ");
8958 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8959 chain = TREE_CHAIN (chain);
8962 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8963 strcat (errbuf, ", ...");
8968 /* We have a unary selector. */
8969 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8977 /* Dump an @interface declaration of the supplied class CHAIN to the
8978 supplied file FP. Used to implement the -gen-decls option (which
8979 prints out an @interface declaration of all classes compiled in
8980 this run); potentially useful for debugging the compiler too. */
8982 dump_interface (FILE *fp, tree chain)
8984 /* FIXME: A heap overflow here whenever a method (or ivar)
8985 declaration is so long that it doesn't fit in the buffer. The
8986 code and all the related functions should be rewritten to avoid
8987 using fixed size buffers. */
8988 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8989 tree ivar_decls = CLASS_RAW_IVARS (chain);
8990 tree nst_methods = CLASS_NST_METHODS (chain);
8991 tree cls_methods = CLASS_CLS_METHODS (chain);
8993 fprintf (fp, "\n@interface %s", my_name);
8995 /* CLASS_SUPER_NAME is used to store the superclass name for
8996 classes, and the category name for categories. */
8997 if (CLASS_SUPER_NAME (chain))
8999 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9001 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9002 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9004 fprintf (fp, " (%s)\n", name);
9008 fprintf (fp, " : %s\n", name);
9014 /* FIXME - the following doesn't seem to work at the moment. */
9017 fprintf (fp, "{\n");
9020 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9021 ivar_decls = TREE_CHAIN (ivar_decls);
9024 fprintf (fp, "}\n");
9029 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9030 nst_methods = TREE_CHAIN (nst_methods);
9035 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9036 cls_methods = TREE_CHAIN (cls_methods);
9039 fprintf (fp, "@end\n");
9042 /* Demangle function for Objective-C */
9044 objc_demangle (const char *mangled)
9046 char *demangled, *cp;
9048 if (mangled[0] == '_' &&
9049 (mangled[1] == 'i' || mangled[1] == 'c') &&
9052 cp = demangled = xmalloc(strlen(mangled) + 2);
9053 if (mangled[1] == 'i')
9054 *cp++ = '-'; /* for instance method */
9056 *cp++ = '+'; /* for class method */
9057 *cp++ = '['; /* opening left brace */
9058 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9059 while (*cp && *cp == '_')
9060 cp++; /* skip any initial underbars in class name */
9061 cp = strchr(cp, '_'); /* find first non-initial underbar */
9064 free(demangled); /* not mangled name */
9067 if (cp[1] == '_') /* easy case: no category name */
9069 *cp++ = ' '; /* replace two '_' with one ' ' */
9070 strcpy(cp, mangled + (cp - demangled) + 2);
9074 *cp++ = '('; /* less easy case: category name */
9075 cp = strchr(cp, '_');
9078 free(demangled); /* not mangled name */
9082 *cp++ = ' '; /* overwriting 1st char of method name... */
9083 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9085 while (*cp && *cp == '_')
9086 cp++; /* skip any initial underbars in method name */
9089 *cp = ':'; /* replace remaining '_' with ':' */
9090 *cp++ = ']'; /* closing right brace */
9091 *cp++ = 0; /* string terminator */
9095 return mangled; /* not an objc mangled name */
9099 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9101 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9107 gcc_obstack_init (&util_obstack);
9108 util_firstobj = (char *) obstack_finish (&util_obstack);
9110 errbuf = (char *) xmalloc (1024 * 10);
9112 synth_module_prologue ();
9118 struct imp_entry *impent;
9120 /* The internally generated initializers appear to have missing braces.
9121 Don't warn about this. */
9122 int save_warn_missing_braces = warn_missing_braces;
9123 warn_missing_braces = 0;
9125 /* A missing @end may not be detected by the parser. */
9126 if (objc_implementation_context)
9128 warning (0, "%<@end%> missing in implementation context");
9129 finish_class (objc_implementation_context);
9130 objc_ivar_chain = NULL_TREE;
9131 objc_implementation_context = NULL_TREE;
9134 /* Process the static instances here because initialization of objc_symtab
9136 if (objc_static_instances)
9137 generate_static_references ();
9139 if (imp_list || class_names_chain
9140 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9141 generate_objc_symtab_decl ();
9143 for (impent = imp_list; impent; impent = impent->next)
9145 objc_implementation_context = impent->imp_context;
9146 implementation_template = impent->imp_template;
9148 UOBJC_CLASS_decl = impent->class_decl;
9149 UOBJC_METACLASS_decl = impent->meta_decl;
9151 /* Dump the @interface of each class as we compile it, if the
9152 -gen-decls option is in use. TODO: Dump the classes in the
9153 order they were found, rather than in reverse order as we
9155 if (flag_gen_declaration)
9157 dump_interface (gen_declaration_file, objc_implementation_context);
9160 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9162 /* all of the following reference the string pool... */
9163 generate_ivar_lists ();
9164 generate_dispatch_tables ();
9165 generate_shared_structures (impent->has_cxx_cdtors
9166 ? CLS_HAS_CXX_STRUCTORS
9171 generate_dispatch_tables ();
9172 generate_category (objc_implementation_context);
9176 /* If we are using an array of selectors, we must always
9177 finish up the array decl even if no selectors were used. */
9178 if (! flag_next_runtime || sel_ref_chain)
9179 build_selector_translation_table ();
9182 generate_protocols ();
9184 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9185 generate_objc_image_info ();
9187 /* Arrange for ObjC data structures to be initialized at run time. */
9188 if (objc_implementation_context || class_names_chain || objc_static_instances
9189 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9191 build_module_descriptor ();
9193 if (!flag_next_runtime)
9194 build_module_initializer_routine ();
9197 /* Dump the class references. This forces the appropriate classes
9198 to be linked into the executable image, preserving unix archive
9199 semantics. This can be removed when we move to a more dynamically
9200 linked environment. */
9202 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9204 handle_class_ref (chain);
9205 if (TREE_PURPOSE (chain))
9206 generate_classref_translation_entry (chain);
9209 for (impent = imp_list; impent; impent = impent->next)
9210 handle_impent (impent);
9212 /* Dump the string table last. */
9214 generate_strings ();
9221 /* Run through the selector hash tables and print a warning for any
9222 selector which has multiple methods. */
9224 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9226 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9227 check_duplicates (hsh, 0, 1);
9228 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9229 check_duplicates (hsh, 0, 1);
9233 warn_missing_braces = save_warn_missing_braces;
9236 /* Subroutines of finish_objc. */
9239 generate_classref_translation_entry (tree chain)
9241 tree expr, decl, type;
9243 decl = TREE_PURPOSE (chain);
9244 type = TREE_TYPE (decl);
9246 expr = add_objc_string (TREE_VALUE (chain), class_names);
9247 expr = convert (type, expr); /* cast! */
9249 /* The decl that is the one that we
9250 forward declared in build_class_reference. */
9251 finish_var_decl (decl, expr);
9256 handle_class_ref (tree chain)
9258 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9259 char *string = (char *) alloca (strlen (name) + 30);
9263 sprintf (string, "%sobjc_class_name_%s",
9264 (flag_next_runtime ? "." : "__"), name);
9266 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9267 if (flag_next_runtime)
9269 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9274 /* Make a decl for this name, so we can use its address in a tree. */
9275 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9276 DECL_EXTERNAL (decl) = 1;
9277 TREE_PUBLIC (decl) = 1;
9280 rest_of_decl_compilation (decl, 0, 0);
9282 /* Make a decl for the address. */
9283 sprintf (string, "%sobjc_class_ref_%s",
9284 (flag_next_runtime ? "." : "__"), name);
9285 exp = build1 (ADDR_EXPR, string_type_node, decl);
9286 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9287 DECL_INITIAL (decl) = exp;
9288 TREE_STATIC (decl) = 1;
9289 TREE_USED (decl) = 1;
9292 rest_of_decl_compilation (decl, 0, 0);
9296 handle_impent (struct imp_entry *impent)
9300 objc_implementation_context = impent->imp_context;
9301 implementation_template = impent->imp_template;
9303 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9305 const char *const class_name =
9306 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9308 string = (char *) alloca (strlen (class_name) + 30);
9310 sprintf (string, "%sobjc_class_name_%s",
9311 (flag_next_runtime ? "." : "__"), class_name);
9313 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9315 const char *const class_name =
9316 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9317 const char *const class_super_name =
9318 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9320 string = (char *) alloca (strlen (class_name)
9321 + strlen (class_super_name) + 30);
9323 /* Do the same for categories. Even though no references to
9324 these symbols are generated automatically by the compiler, it
9325 gives you a handle to pull them into an archive by hand. */
9326 sprintf (string, "*%sobjc_category_name_%s_%s",
9327 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9332 #ifdef ASM_DECLARE_CLASS_REFERENCE
9333 if (flag_next_runtime)
9335 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9343 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9344 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9345 TREE_PUBLIC (decl) = 1;
9346 TREE_READONLY (decl) = 1;
9347 TREE_USED (decl) = 1;
9348 TREE_CONSTANT (decl) = 1;
9349 DECL_CONTEXT (decl) = 0;
9350 DECL_ARTIFICIAL (decl) = 1;
9351 DECL_INITIAL (decl) = init;
9352 assemble_variable (decl, 1, 0, 0);
9356 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9357 later requires that ObjC translation units participating in F&C be
9358 specially marked. The following routine accomplishes this. */
9360 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9363 generate_objc_image_info (void)
9365 tree decl, initlist;
9367 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9368 | (flag_objc_gc ? 2 : 0));
9370 decl = start_var_decl (build_array_type
9372 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9373 "_OBJC_IMAGE_INFO");
9375 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9376 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9377 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9379 finish_var_decl (decl, initlist);
9382 /* Look up ID as an instance variable. OTHER contains the result of
9383 the C or C++ lookup, which we may want to use instead. */
9386 objc_lookup_ivar (tree other, tree id)
9390 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9391 if (!objc_method_context)
9394 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9395 /* We have a message to super. */
9396 return get_super_receiver ();
9398 /* In a class method, look up an instance variable only as a last
9400 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9401 && other && other != error_mark_node)
9404 /* Look up the ivar, but do not use it if it is not accessible. */
9405 ivar = is_ivar (objc_ivar_chain, id);
9407 if (!ivar || is_private (ivar))
9410 /* In an instance method, a local variable (or parameter) may hide the
9411 instance variable. */
9412 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9413 && other && other != error_mark_node
9415 && CP_DECL_CONTEXT (other) != global_namespace)
9417 && !DECL_FILE_SCOPE_P (other))
9420 warning (0, "local declaration of %qs hides instance variable",
9421 IDENTIFIER_POINTER (id));
9426 /* At this point, we are either in an instance method with no obscuring
9427 local definitions, or in a class method with no alternate definitions
9429 return build_ivar_reference (id);
9432 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9433 needs to be done if we are calling a function through a cast. */
9436 objc_rewrite_function_call (tree function, tree params)
9438 if (TREE_CODE (function) == NOP_EXPR
9439 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9440 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9443 function = build (OBJ_TYPE_REF, TREE_TYPE (function),
9444 TREE_OPERAND (function, 0),
9445 TREE_VALUE (params), size_zero_node);
9451 /* Look for the special case of OBJC_TYPE_REF with the address of
9452 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9455 enum gimplify_status
9456 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9458 enum gimplify_status r0, r1;
9459 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9460 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9461 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9464 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9465 value of the OBJ_TYPE_REF, so force them to be emitted
9466 during subexpression evaluation rather than after the
9467 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9468 C to use direct rather than indirect calls when the
9469 object expression has a postincrement. */
9470 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9471 is_gimple_val, fb_rvalue);
9472 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9473 is_gimple_val, fb_rvalue);
9475 return MIN (r0, r1);
9479 return cp_gimplify_expr (expr_p, pre_p, post_p);
9481 return c_gimplify_expr (expr_p, pre_p, post_p);
9485 /* Given a CALL expression, find the function being called. The ObjC
9486 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9489 objc_get_callee_fndecl (tree call_expr)
9491 tree addr = TREE_OPERAND (call_expr, 0);
9492 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9495 addr = OBJ_TYPE_REF_EXPR (addr);
9497 /* If the address is just `&f' for some function `f', then we know
9498 that `f' is being called. */
9499 if (TREE_CODE (addr) == ADDR_EXPR
9500 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9501 return TREE_OPERAND (addr, 0);
9506 #include "gt-objc-objc-act.h"