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);
190 static void objc_generate_cxx_cdtors (void);
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
227 static void really_start_method (tree, tree);
229 static void really_start_method (tree, struct c_arg_info *);
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
234 static tree objc_get_parm_info (int);
236 static struct c_arg_info *objc_get_parm_info (int);
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
393 /* The resulting constant string. */
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
421 generate_struct_by_value_array (void)
424 tree field_decl, field_decl_chain;
426 int aggregate_in_mem[32];
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
481 if (cxx_init () == false)
483 if (c_objc_common_init () == false)
487 #ifndef USE_MAPPED_LOCATION
488 /* Force the line number back to 0; check_newline will have
489 raised it to 1, which will make the builtin functions appear
490 not to be built in. */
494 /* If gen_declaration desired, open the output file. */
495 if (flag_gen_declaration)
497 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
498 gen_declaration_file = fopen (dumpname, "w");
499 if (gen_declaration_file == 0)
500 fatal_error ("can't open %s: %m", dumpname);
504 if (flag_next_runtime)
506 TAG_GETCLASS = "objc_getClass";
507 TAG_GETMETACLASS = "objc_getMetaClass";
508 TAG_MSGSEND = "objc_msgSend";
509 TAG_MSGSENDSUPER = "objc_msgSendSuper";
510 TAG_MSGSEND_STRET = "objc_msgSend_stret";
511 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
512 default_constant_string_class_name = "NSConstantString";
516 TAG_GETCLASS = "objc_get_class";
517 TAG_GETMETACLASS = "objc_get_meta_class";
518 TAG_MSGSEND = "objc_msg_lookup";
519 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
520 /* GNU runtime does not provide special functions to support
521 structure-returning methods. */
522 default_constant_string_class_name = "NXConstantString";
523 flag_typed_selectors = 1;
528 if (print_struct_values)
529 generate_struct_by_value_array ();
535 objc_finish_file (void)
537 mark_referenced_methods ();
540 /* We need to instantiate templates _before_ we emit ObjC metadata;
541 if we do not, some metadata (such as selectors) may go missing. */
543 instantiate_pending_templates (0);
546 /* Finalize Objective-C runtime data. No need to generate tables
547 and code if only checking syntax, or if generating a PCH file. */
548 if (!flag_syntax_only && !pch_file)
551 if (gen_declaration_file)
552 fclose (gen_declaration_file);
559 /* Return the first occurrence of a method declaration corresponding
560 to sel_name in rproto_list. Search rproto_list recursively.
561 If is_class is 0, search for instance methods, otherwise for class
564 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
570 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
572 p = TREE_VALUE (rproto);
574 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
576 if ((fnd = lookup_method (is_class
577 ? PROTOCOL_CLS_METHODS (p)
578 : PROTOCOL_NST_METHODS (p), sel_name)))
580 else if (PROTOCOL_LIST (p))
581 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
586 ; /* An identifier...if we could not find a protocol. */
597 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
601 /* Make sure the protocol is supported by the object on the rhs. */
602 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
605 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
607 p = TREE_VALUE (rproto);
609 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
614 else if (PROTOCOL_LIST (p))
615 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
624 ; /* An identifier...if we could not find a protocol. */
631 objc_start_class_interface (tree class, tree super_class, tree protos)
633 objc_interface_context
635 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
636 objc_public_flag = 0;
640 objc_start_category_interface (tree class, tree categ, tree protos)
642 objc_interface_context
643 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
645 = continue_class (objc_interface_context);
649 objc_start_protocol (tree name, tree protos)
651 objc_interface_context
652 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
656 objc_continue_interface (void)
659 = continue_class (objc_interface_context);
663 objc_finish_interface (void)
665 finish_class (objc_interface_context);
666 objc_interface_context = NULL_TREE;
670 objc_start_class_implementation (tree class, tree super_class)
672 objc_implementation_context
674 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
675 objc_public_flag = 0;
679 objc_start_category_implementation (tree class, tree categ)
681 objc_implementation_context
682 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
684 = continue_class (objc_implementation_context);
688 objc_continue_implementation (void)
691 = continue_class (objc_implementation_context);
695 objc_finish_implementation (void)
698 if (flag_objc_call_cxx_cdtors)
699 objc_generate_cxx_cdtors ();
702 if (objc_implementation_context)
704 finish_class (objc_implementation_context);
705 objc_ivar_chain = NULL_TREE;
706 objc_implementation_context = NULL_TREE;
709 warning (0, "%<@end%> must appear in an @implementation context");
713 objc_set_visibility (int visibility)
715 objc_public_flag = visibility;
719 objc_set_method_type (enum tree_code type)
721 objc_inherit_code = (type == PLUS_EXPR
723 : INSTANCE_METHOD_DECL);
727 objc_build_method_signature (tree rettype, tree selector,
728 tree optparms, bool ellipsis)
730 return build_method_decl (objc_inherit_code, rettype, selector,
735 objc_add_method_declaration (tree decl)
737 if (!objc_interface_context)
738 fatal_error ("method declaration not in @interface context");
740 objc_add_method (objc_interface_context,
742 objc_inherit_code == CLASS_METHOD_DECL);
746 objc_start_method_definition (tree decl)
748 if (!objc_implementation_context)
749 fatal_error ("method definition not in @implementation context");
751 objc_add_method (objc_implementation_context,
753 objc_inherit_code == CLASS_METHOD_DECL);
754 start_method_def (decl);
758 objc_add_instance_variable (tree decl)
760 (void) add_instance_variable (objc_ivar_context,
765 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
769 objc_is_reserved_word (tree ident)
771 unsigned char code = C_RID_CODE (ident);
773 return (OBJC_IS_AT_KEYWORD (code)
775 || code == RID_CLASS || code == RID_PUBLIC
776 || code == RID_PROTECTED || code == RID_PRIVATE
777 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
782 /* Return true if TYPE is 'id'. */
785 objc_is_object_id (tree type)
787 return OBJC_TYPE_NAME (type) == objc_object_id;
791 objc_is_class_id (tree type)
793 return OBJC_TYPE_NAME (type) == objc_class_id;
796 /* Construct a C struct with tag NAME, a base struct with tag
797 SUPER_NAME (if any), and FIELDS indicated. */
800 objc_build_struct (tree name, tree fields, tree super_name)
802 tree s = start_struct (RECORD_TYPE, name);
803 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
804 tree t, objc_info = NULL_TREE;
808 /* Prepend a packed variant of the base class into the layout. This
809 is necessary to preserve ObjC ABI compatibility. */
810 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
811 tree field = TYPE_FIELDS (super);
813 while (field && TREE_CHAIN (field)
814 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
815 field = TREE_CHAIN (field);
817 /* For ObjC ABI purposes, the "packed" size of a base class is
818 the the sum of the offset and the size (in bits) of the last
819 field in the class. */
821 = (field && TREE_CODE (field) == FIELD_DECL
822 ? size_binop (PLUS_EXPR,
823 size_binop (PLUS_EXPR,
826 convert (bitsizetype,
827 DECL_FIELD_OFFSET (field)),
828 bitsize_int (BITS_PER_UNIT)),
829 DECL_FIELD_BIT_OFFSET (field)),
831 : bitsize_zero_node);
832 DECL_SIZE_UNIT (base)
833 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
834 size_int (BITS_PER_UNIT));
835 DECL_ARTIFICIAL (base) = 1;
836 DECL_ALIGN (base) = 1;
837 DECL_FIELD_CONTEXT (base) = s;
839 DECL_FIELD_IS_BASE (base) = 1;
842 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
843 #endif /* are following the ObjC ABI here. */
844 TREE_CHAIN (base) = fields;
848 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
849 in all variants of this RECORD_TYPE to be clobbered, but it is therein
850 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
851 Hence, we must squirrel away the ObjC-specific information before calling
852 finish_struct(), and then reinstate it afterwards. */
854 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
856 = chainon (objc_info,
857 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
859 s = finish_struct (s, fields, NULL_TREE);
861 for (t = TYPE_NEXT_VARIANT (s); t;
862 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
863 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
865 /* Use TYPE_BINFO structures to point at the super class, if any. */
866 objc_xref_basetypes (s, super);
871 /* Mark DECL as being 'volatile' for purposes of Darwin
872 _setjmp()/_longjmp() exception handling. Called from
873 objc_mark_locals_volatile(). */
875 objc_volatilize_decl (tree decl)
877 /* Do not mess with variables that are 'static' or (already)
879 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
880 && (TREE_CODE (decl) == VAR_DECL
881 || TREE_CODE (decl) == PARM_DECL))
883 tree t = TREE_TYPE (decl);
884 struct volatilized_type key;
887 t = build_qualified_type (t, (TYPE_QUALS (t)
888 | TYPE_QUAL_VOLATILE));
890 loc = htab_find_slot (volatilized_htab, &key, INSERT);
894 *loc = ggc_alloc (sizeof (key));
895 ((struct volatilized_type *) *loc)->type = t;
898 TREE_TYPE (decl) = t;
899 TREE_THIS_VOLATILE (decl) = 1;
900 TREE_SIDE_EFFECTS (decl) = 1;
901 DECL_REGISTER (decl) = 0;
903 C_DECL_REGISTER (decl) = 0;
908 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
909 (including its categoreis and superclasses) or by object type TYP.
910 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
913 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
915 bool class_type = (cls != NULL_TREE);
921 /* Check protocols adopted by the class and its categories. */
922 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
924 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
928 /* Repeat for superclasses. */
929 cls = lookup_interface (CLASS_SUPER_NAME (cls));
932 /* Check for any protocols attached directly to the object type. */
933 if (TYPE_HAS_OBJC_INFO (typ))
935 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
941 strcpy (errbuf, class_type ? "class \'" : "type \'");
942 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
943 strcat (errbuf, "\' does not ");
944 /* NB: Types 'id' and 'Class' cannot reasonably be described as
945 "implementing" a given protocol, since they do not have an
947 strcat (errbuf, class_type ? "implement" : "conform to");
948 strcat (errbuf, " the \'");
949 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
950 strcat (errbuf, "\' protocol");
957 /* Check if class RCLS and instance struct type RTYP conform to at least the
958 same protocols that LCLS and LTYP conform to. */
961 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
964 bool have_lproto = false;
968 /* NB: We do _not_ look at categories defined for LCLS; these may or
969 may not get loaded in, and therefore it is unreasonable to require
970 that RCLS/RTYP must implement any of their protocols. */
971 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
975 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
979 /* Repeat for superclasses. */
980 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
983 /* Check for any protocols attached directly to the object type. */
984 if (TYPE_HAS_OBJC_INFO (ltyp))
986 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
990 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
995 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
996 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
997 away with simply checking for 'id' or 'Class' (!RCLS), since this
998 routine will not get called in other cases. */
999 return have_lproto || (rcls != NULL_TREE);
1002 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1003 an instance of RTYP to an instance of LTYP or to compare the two
1004 (if ARGNO is equal to -3), per ObjC type system rules. Before
1005 returning 'true', this routine may issue warnings related to, e.g.,
1006 protocol conformance. When returning 'false', the routine must
1007 produce absolutely no warnings; the C or C++ front-end will do so
1008 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1009 the routine must return 'false'.
1011 The ARGNO parameter is encoded as follows:
1012 >= 1 Parameter number (CALLEE contains function being called);
1016 -3 Comparison (LTYP and RTYP may match in either direction). */
1019 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1021 tree lcls, rcls, lproto, rproto;
1022 bool pointers_compatible;
1024 /* We must be dealing with pointer types */
1025 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1030 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1031 rtyp = TREE_TYPE (rtyp);
1033 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1035 /* Past this point, we are only interested in ObjC class instances,
1036 or 'id' or 'Class'. */
1037 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1040 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1041 && !TYPE_HAS_OBJC_INFO (ltyp))
1044 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1045 && !TYPE_HAS_OBJC_INFO (rtyp))
1048 /* Past this point, we are committed to returning 'true' to the caller.
1049 However, we can still warn about type and/or protocol mismatches. */
1051 if (TYPE_HAS_OBJC_INFO (ltyp))
1053 lcls = TYPE_OBJC_INTERFACE (ltyp);
1054 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1057 lcls = lproto = NULL_TREE;
1059 if (TYPE_HAS_OBJC_INFO (rtyp))
1061 rcls = TYPE_OBJC_INTERFACE (rtyp);
1062 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1065 rcls = rproto = NULL_TREE;
1067 /* If either type is an unqualified 'id', we're done. */
1068 if ((!lproto && objc_is_object_id (ltyp))
1069 || (!rproto && objc_is_object_id (rtyp)))
1072 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1074 /* If the underlying types are the same, and at most one of them has
1075 a protocol list, we do not need to issue any diagnostics. */
1076 if (pointers_compatible && (!lproto || !rproto))
1079 /* If exactly one of the types is 'Class', issue a diagnostic; any
1080 exceptions of this rule have already been handled. */
1081 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1082 pointers_compatible = false;
1083 /* Otherwise, check for inheritance relations. */
1086 if (!pointers_compatible)
1088 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1090 if (!pointers_compatible)
1091 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1093 if (!pointers_compatible && argno == -3)
1094 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1097 /* If the pointers match modulo protocols, check for protocol conformance
1099 if (pointers_compatible)
1101 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1104 if (!pointers_compatible && argno == -3)
1105 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1109 if (!pointers_compatible)
1111 /* NB: For the time being, we shall make our warnings look like their
1112 C counterparts. In the future, we may wish to make them more
1117 warning (0, "comparison of distinct Objective-C types lacks a cast");
1121 warning (0, "initialization from distinct Objective-C type");
1125 warning (0, "assignment from distinct Objective-C type");
1129 warning (0, "distinct Objective-C type in return");
1133 warning (0, "passing argument %d of %qE from distinct "
1134 "Objective-C type", argno, callee);
1142 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1143 lives in the volatilized hash table, ignore the 'volatile' bit when
1144 making the comparison. */
1147 objc_type_quals_match (tree ltyp, tree rtyp)
1149 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1150 struct volatilized_type key;
1154 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1155 lquals &= ~TYPE_QUAL_VOLATILE;
1159 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1160 rquals &= ~TYPE_QUAL_VOLATILE;
1162 return (lquals == rquals);
1166 /* Determine if CHILD is derived from PARENT. The routine assumes that
1167 both parameters are RECORD_TYPEs, and is non-reflexive. */
1170 objc_derived_from_p (tree parent, tree child)
1172 parent = TYPE_MAIN_VARIANT (parent);
1174 for (child = TYPE_MAIN_VARIANT (child);
1175 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1177 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1178 (TYPE_BINFO (child),
1181 if (child == parent)
1190 objc_build_component_ref (tree datum, tree component)
1192 /* If COMPONENT is NULL, the caller is referring to the anonymous
1193 base class field. */
1196 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1198 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1201 /* The 'build_component_ref' routine has been removed from the C++
1202 front-end, but 'finish_class_member_access_expr' seems to be
1203 a worthy substitute. */
1205 return finish_class_member_access_expr (datum, component);
1207 return build_component_ref (datum, component);
1211 /* Recursively copy inheritance information rooted at BINFO. To do this,
1212 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1215 objc_copy_binfo (tree binfo)
1217 tree btype = BINFO_TYPE (binfo);
1218 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1222 BINFO_TYPE (binfo2) = btype;
1223 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1224 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1226 /* Recursively copy base binfos of BINFO. */
1227 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1229 tree base_binfo2 = objc_copy_binfo (base_binfo);
1231 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1232 BINFO_BASE_APPEND (binfo2, base_binfo2);
1238 /* Record superclass information provided in BASETYPE for ObjC class REF.
1239 This is loosely based on cp/decl.c:xref_basetypes(). */
1242 objc_xref_basetypes (tree ref, tree basetype)
1244 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1246 TYPE_BINFO (ref) = binfo;
1247 BINFO_OFFSET (binfo) = size_zero_node;
1248 BINFO_TYPE (binfo) = ref;
1252 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1254 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1255 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1256 BINFO_BASE_APPEND (binfo, base_binfo);
1257 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1262 volatilized_hash (const void *ptr)
1264 tree typ = ((struct volatilized_type *)ptr)->type;
1266 return htab_hash_pointer(typ);
1270 volatilized_eq (const void *ptr1, const void *ptr2)
1272 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1273 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1275 return typ1 == typ2;
1278 /* Called from finish_decl. */
1281 objc_check_decl (tree decl)
1283 tree type = TREE_TYPE (decl);
1285 if (TREE_CODE (type) != RECORD_TYPE)
1287 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1288 error ("statically allocated instance of Objective-C class %qs",
1289 IDENTIFIER_POINTER (type));
1292 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1293 either name an Objective-C class, or refer to the special 'id' or 'Class'
1294 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1297 objc_get_protocol_qualified_type (tree interface, tree protocols)
1299 /* If INTERFACE is not provided, default to 'id'. */
1300 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1301 bool is_ptr = (type != NULL_TREE);
1305 type = objc_is_class_name (interface);
1308 type = xref_tag (RECORD_TYPE, type);
1315 type = build_variant_type_copy (type);
1317 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1321 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1322 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1323 type = TREE_TYPE (type);
1326 /* Look up protocols and install in lang specific list. */
1327 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1328 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1330 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1331 return the pointer to the new pointee variant. */
1333 type = TYPE_POINTER_TO (type);
1335 TYPE_OBJC_INTERFACE (type)
1336 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1342 /* Check for circular dependencies in protocols. The arguments are
1343 PROTO, the protocol to check, and LIST, a list of protocol it
1347 check_protocol_recursively (tree proto, tree list)
1351 for (p = list; p; p = TREE_CHAIN (p))
1353 tree pp = TREE_VALUE (p);
1355 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1356 pp = lookup_protocol (pp);
1359 fatal_error ("protocol %qs has circular dependency",
1360 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1362 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1366 /* Look up PROTOCOLS, and return a list of those that are found.
1367 If none are found, return NULL. */
1370 lookup_and_install_protocols (tree protocols)
1373 tree return_value = NULL_TREE;
1375 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1377 tree ident = TREE_VALUE (proto);
1378 tree p = lookup_protocol (ident);
1381 error ("cannot find protocol declaration for %qs",
1382 IDENTIFIER_POINTER (ident));
1384 return_value = chainon (return_value,
1385 build_tree_list (NULL_TREE, p));
1388 return return_value;
1391 /* Create a declaration for field NAME of a given TYPE. */
1394 create_field_decl (tree type, const char *name)
1396 return build_decl (FIELD_DECL, get_identifier (name), type);
1399 /* Create a global, static declaration for variable NAME of a given TYPE. The
1400 finish_var_decl() routine will need to be called on it afterwards. */
1403 start_var_decl (tree type, const char *name)
1405 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1407 TREE_STATIC (var) = 1;
1408 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1409 DECL_IGNORED_P (var) = 1;
1410 DECL_ARTIFICIAL (var) = 1;
1411 DECL_CONTEXT (var) = NULL_TREE;
1413 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1419 /* Finish off the variable declaration created by start_var_decl(). */
1422 finish_var_decl (tree var, tree initializer)
1424 finish_decl (var, initializer, NULL_TREE);
1425 /* Ensure that the variable actually gets output. */
1426 mark_decl_referenced (var);
1427 /* Mark the decl to avoid "defined but not used" warning. */
1428 TREE_USED (var) = 1;
1431 /* Find the decl for the constant string class reference. This is only
1432 used for the NeXT runtime. */
1435 setup_string_decl (void)
1440 /* %s in format will provide room for terminating null */
1441 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1442 + strlen (constant_string_class_name);
1443 name = xmalloc (length);
1444 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1445 constant_string_class_name);
1446 constant_string_global_id = get_identifier (name);
1447 string_class_decl = lookup_name (constant_string_global_id);
1449 return string_class_decl;
1452 /* Purpose: "play" parser, creating/installing representations
1453 of the declarations that are required by Objective-C.
1457 type_spec--------->sc_spec
1458 (tree_list) (tree_list)
1461 identifier_node identifier_node */
1464 synth_module_prologue (void)
1467 enum debug_info_type save_write_symbols = write_symbols;
1468 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1470 /* Suppress outputting debug symbols, because
1471 dbxout_init hasn'r been called yet. */
1472 write_symbols = NO_DEBUG;
1473 debug_hooks = &do_nothing_debug_hooks;
1476 push_lang_context (lang_name_c); /* extern "C" */
1479 /* The following are also defined in <objc/objc.h> and friends. */
1481 objc_object_id = get_identifier (TAG_OBJECT);
1482 objc_class_id = get_identifier (TAG_CLASS);
1484 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1485 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1487 objc_object_type = build_pointer_type (objc_object_reference);
1488 objc_class_type = build_pointer_type (objc_class_reference);
1490 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1491 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1493 /* Declare the 'id' and 'Class' typedefs. */
1495 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1498 DECL_IN_SYSTEM_HEADER (type) = 1;
1499 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1502 DECL_IN_SYSTEM_HEADER (type) = 1;
1504 /* Forward-declare '@interface Protocol'. */
1506 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1507 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1508 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1511 /* Declare type of selector-objects that represent an operation name. */
1513 if (flag_next_runtime)
1514 /* `struct objc_selector *' */
1516 = build_pointer_type (xref_tag (RECORD_TYPE,
1517 get_identifier (TAG_SELECTOR)));
1519 /* `const struct objc_selector *' */
1521 = build_pointer_type
1522 (build_qualified_type (xref_tag (RECORD_TYPE,
1523 get_identifier (TAG_SELECTOR)),
1526 /* Declare receiver type used for dispatching messages to 'super'. */
1528 /* `struct objc_super *' */
1529 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1530 get_identifier (TAG_SUPER)));
1532 /* Declare pointers to method and ivar lists. */
1533 objc_method_list_ptr = build_pointer_type
1534 (xref_tag (RECORD_TYPE,
1535 get_identifier (UTAG_METHOD_LIST)));
1536 objc_method_proto_list_ptr
1537 = build_pointer_type (xref_tag (RECORD_TYPE,
1538 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1539 objc_ivar_list_ptr = build_pointer_type
1540 (xref_tag (RECORD_TYPE,
1541 get_identifier (UTAG_IVAR_LIST)));
1543 if (flag_next_runtime)
1545 /* NB: In order to call one of the ..._stret (struct-returning)
1546 functions, the function *MUST* first be cast to a signature that
1547 corresponds to the actual ObjC method being invoked. This is
1548 what is done by the build_objc_method_call() routine below. */
1550 /* id objc_msgSend (id, SEL, ...); */
1551 /* id objc_msgSendNonNil (id, SEL, ...); */
1552 /* id objc_msgSend_stret (id, SEL, ...); */
1553 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1555 = build_function_type (objc_object_type,
1556 tree_cons (NULL_TREE, objc_object_type,
1557 tree_cons (NULL_TREE, objc_selector_type,
1559 umsg_decl = builtin_function (TAG_MSGSEND,
1560 type, 0, NOT_BUILT_IN,
1562 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1563 type, 0, NOT_BUILT_IN,
1565 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1566 type, 0, NOT_BUILT_IN,
1568 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1569 type, 0, NOT_BUILT_IN,
1572 /* id objc_msgSend_Fast (id, SEL, ...)
1573 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1574 #ifdef OFFS_MSGSEND_FAST
1575 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1576 type, 0, NOT_BUILT_IN,
1578 DECL_ATTRIBUTES (umsg_fast_decl)
1579 = tree_cons (get_identifier ("hard_coded_address"),
1580 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1583 /* No direct dispatch availible. */
1584 umsg_fast_decl = umsg_decl;
1587 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1588 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1590 = build_function_type (objc_object_type,
1591 tree_cons (NULL_TREE, objc_super_type,
1592 tree_cons (NULL_TREE, objc_selector_type,
1594 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1595 type, 0, NOT_BUILT_IN,
1597 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1598 type, 0, NOT_BUILT_IN, 0,
1603 /* GNU runtime messenger entry points. */
1605 /* typedef id (*IMP)(id, SEL, ...); */
1607 = build_pointer_type
1608 (build_function_type (objc_object_type,
1609 tree_cons (NULL_TREE, objc_object_type,
1610 tree_cons (NULL_TREE, objc_selector_type,
1613 /* IMP objc_msg_lookup (id, SEL); */
1615 = build_function_type (IMP_type,
1616 tree_cons (NULL_TREE, objc_object_type,
1617 tree_cons (NULL_TREE, objc_selector_type,
1618 OBJC_VOID_AT_END)));
1619 umsg_decl = builtin_function (TAG_MSGSEND,
1620 type, 0, NOT_BUILT_IN,
1623 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1625 = build_function_type (IMP_type,
1626 tree_cons (NULL_TREE, objc_super_type,
1627 tree_cons (NULL_TREE, objc_selector_type,
1628 OBJC_VOID_AT_END)));
1629 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1630 type, 0, NOT_BUILT_IN,
1633 /* The following GNU runtime entry point is called to initialize
1636 __objc_exec_class (void *); */
1638 = build_function_type (void_type_node,
1639 tree_cons (NULL_TREE, ptr_type_node,
1641 execclass_decl = builtin_function (TAG_EXECCLASS,
1642 type, 0, NOT_BUILT_IN,
1646 /* id objc_getClass (const char *); */
1648 type = build_function_type (objc_object_type,
1649 tree_cons (NULL_TREE,
1650 const_string_type_node,
1654 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1657 /* id objc_getMetaClass (const char *); */
1659 objc_get_meta_class_decl
1660 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1662 build_class_template ();
1663 build_super_template ();
1664 build_protocol_template ();
1665 build_category_template ();
1666 build_objc_exception_stuff ();
1668 if (flag_next_runtime)
1669 build_next_objc_exception_stuff ();
1671 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1673 if (! flag_next_runtime)
1674 build_selector_table_decl ();
1676 /* Forward declare constant_string_id and constant_string_type. */
1677 if (!constant_string_class_name)
1678 constant_string_class_name = default_constant_string_class_name;
1680 constant_string_id = get_identifier (constant_string_class_name);
1681 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1683 /* Pre-build the following entities - for speed/convenience. */
1684 self_id = get_identifier ("self");
1685 ucmd_id = get_identifier ("_cmd");
1688 pop_lang_context ();
1691 write_symbols = save_write_symbols;
1692 debug_hooks = save_hooks;
1695 /* Ensure that the ivar list for NSConstantString/NXConstantString
1696 (or whatever was specified via `-fconstant-string-class')
1697 contains fields at least as large as the following three, so that
1698 the runtime can stomp on them with confidence:
1700 struct STRING_OBJECT_CLASS_NAME
1704 unsigned int length;
1708 check_string_class_template (void)
1710 tree field_decl = TYPE_FIELDS (constant_string_type);
1712 #define AT_LEAST_AS_LARGE_AS(F, T) \
1713 (F && TREE_CODE (F) == FIELD_DECL \
1714 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1715 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1717 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1720 field_decl = TREE_CHAIN (field_decl);
1721 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1724 field_decl = TREE_CHAIN (field_decl);
1725 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1727 #undef AT_LEAST_AS_LARGE_AS
1730 /* Avoid calling `check_string_class_template ()' more than once. */
1731 static GTY(()) int string_layout_checked;
1733 /* Custom build_string which sets TREE_TYPE! */
1736 my_build_string (int len, const char *str)
1738 return fix_string_type (build_string (len, str));
1741 /* Build a string with contents STR and length LEN and convert it to a
1745 my_build_string_pointer (int len, const char *str)
1747 tree string = my_build_string (len, str);
1748 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1749 return build1 (ADDR_EXPR, ptrtype, string);
1753 string_hash (const void *ptr)
1755 tree str = ((struct string_descriptor *)ptr)->literal;
1756 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1757 int i, len = TREE_STRING_LENGTH (str);
1760 for (i = 0; i < len; i++)
1761 h = ((h * 613) + p[i]);
1767 string_eq (const void *ptr1, const void *ptr2)
1769 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1770 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1771 int len1 = TREE_STRING_LENGTH (str1);
1773 return (len1 == TREE_STRING_LENGTH (str2)
1774 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1778 /* Given a chain of STRING_CST's, build a static instance of
1779 NXConstantString which points at the concatenation of those
1780 strings. We place the string object in the __string_objects
1781 section of the __OBJC segment. The Objective-C runtime will
1782 initialize the isa pointers of the string objects to point at the
1783 NXConstantString class object. */
1786 objc_build_string_object (tree string)
1788 tree initlist, constructor, constant_string_class;
1791 struct string_descriptor *desc, key;
1794 /* Prep the string argument. */
1795 string = fix_string_type (string);
1796 TREE_SET_CODE (string, STRING_CST);
1797 length = TREE_STRING_LENGTH (string) - 1;
1799 /* Check whether the string class being used actually exists and has the
1800 correct ivar layout. */
1801 if (!string_layout_checked)
1803 string_layout_checked = -1;
1804 constant_string_class = lookup_interface (constant_string_id);
1806 if (!constant_string_class
1807 || !(constant_string_type
1808 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1809 error ("cannot find interface declaration for %qs",
1810 IDENTIFIER_POINTER (constant_string_id));
1811 /* The NSConstantString/NXConstantString ivar layout is now known. */
1812 else if (!check_string_class_template ())
1813 error ("interface %qs does not have valid constant string layout",
1814 IDENTIFIER_POINTER (constant_string_id));
1815 /* For the NeXT runtime, we can generate a literal reference
1816 to the string class, don't need to run a constructor. */
1817 else if (flag_next_runtime && !setup_string_decl ())
1818 error ("cannot find reference tag for class %qs",
1819 IDENTIFIER_POINTER (constant_string_id));
1822 string_layout_checked = 1; /* Success! */
1823 add_class_reference (constant_string_id);
1827 if (string_layout_checked == -1)
1828 return error_mark_node;
1830 /* Perhaps we already constructed a constant string just like this one? */
1831 key.literal = string;
1832 loc = htab_find_slot (string_htab, &key, INSERT);
1838 *loc = desc = ggc_alloc (sizeof (*desc));
1839 desc->literal = string;
1841 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1842 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1843 fields = TYPE_FIELDS (constant_string_type);
1845 = build_tree_list (fields,
1847 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1848 : build_int_cst (NULL_TREE, 0));
1849 fields = TREE_CHAIN (fields);
1850 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1852 fields = TREE_CHAIN (fields);
1853 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1855 constructor = objc_build_constructor (constant_string_type,
1856 nreverse (initlist));
1857 TREE_INVARIANT (constructor) = true;
1859 if (!flag_next_runtime)
1861 = objc_add_static_instance (constructor, constant_string_type);
1864 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1865 DECL_INITIAL (var) = constructor;
1866 TREE_STATIC (var) = 1;
1867 pushdecl_top_level (var);
1870 desc->constructor = constructor;
1873 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1878 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1880 static GTY(()) int num_static_inst;
1883 objc_add_static_instance (tree constructor, tree class_decl)
1888 /* Find the list of static instances for the CLASS_DECL. Create one if
1890 for (chain = &objc_static_instances;
1891 *chain && TREE_VALUE (*chain) != class_decl;
1892 chain = &TREE_CHAIN (*chain));
1895 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1896 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1899 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1900 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1901 DECL_COMMON (decl) = 1;
1902 TREE_STATIC (decl) = 1;
1903 DECL_ARTIFICIAL (decl) = 1;
1904 DECL_INITIAL (decl) = constructor;
1906 /* We may be writing something else just now.
1907 Postpone till end of input. */
1908 DECL_DEFER_OUTPUT (decl) = 1;
1909 pushdecl_top_level (decl);
1910 rest_of_decl_compilation (decl, 1, 0);
1912 /* Add the DECL to the head of this CLASS' list. */
1913 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1918 /* Build a static constant CONSTRUCTOR
1919 with type TYPE and elements ELTS. */
1922 objc_build_constructor (tree type, tree elts)
1924 tree constructor = build_constructor (type, elts);
1926 TREE_CONSTANT (constructor) = 1;
1927 TREE_STATIC (constructor) = 1;
1928 TREE_READONLY (constructor) = 1;
1931 /* Adjust for impedance mismatch. We should figure out how to build
1932 CONSTRUCTORs that consistently please both the C and C++ gods. */
1933 if (!TREE_PURPOSE (elts))
1934 TREE_TYPE (constructor) = NULL_TREE;
1935 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1941 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1943 /* Predefine the following data type:
1951 void *defs[cls_def_cnt + cat_def_cnt];
1955 build_objc_symtab_template (void)
1957 tree field_decl, field_decl_chain;
1959 objc_symtab_template
1960 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1962 /* long sel_ref_cnt; */
1963 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1964 field_decl_chain = field_decl;
1967 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1969 chainon (field_decl_chain, field_decl);
1971 /* short cls_def_cnt; */
1972 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1973 chainon (field_decl_chain, field_decl);
1975 /* short cat_def_cnt; */
1976 field_decl = create_field_decl (short_integer_type_node,
1978 chainon (field_decl_chain, field_decl);
1980 if (imp_count || cat_count || !flag_next_runtime)
1982 /* void *defs[imp_count + cat_count (+ 1)]; */
1983 /* NB: The index is one less than the size of the array. */
1984 int index = imp_count + cat_count
1985 + (flag_next_runtime? -1: 0);
1986 field_decl = create_field_decl
1989 build_index_type (build_int_cst (NULL_TREE, index))),
1991 chainon (field_decl_chain, field_decl);
1994 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1997 /* Create the initial value for the `defs' field of _objc_symtab.
1998 This is a CONSTRUCTOR. */
2001 init_def_list (tree type)
2003 tree expr, initlist = NULL_TREE;
2004 struct imp_entry *impent;
2007 for (impent = imp_list; impent; impent = impent->next)
2009 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2011 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2012 initlist = tree_cons (NULL_TREE, expr, initlist);
2017 for (impent = imp_list; impent; impent = impent->next)
2019 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2021 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2022 initlist = tree_cons (NULL_TREE, expr, initlist);
2026 if (!flag_next_runtime)
2028 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2031 if (static_instances_decl)
2032 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2034 expr = build_int_cst (NULL_TREE, 0);
2036 initlist = tree_cons (NULL_TREE, expr, initlist);
2039 return objc_build_constructor (type, nreverse (initlist));
2042 /* Construct the initial value for all of _objc_symtab. */
2045 init_objc_symtab (tree type)
2049 /* sel_ref_cnt = { ..., 5, ... } */
2051 initlist = build_tree_list (NULL_TREE,
2052 build_int_cst (long_integer_type_node, 0));
2054 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2056 if (flag_next_runtime || ! sel_ref_chain)
2057 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2060 = tree_cons (NULL_TREE,
2061 convert (build_pointer_type (objc_selector_type),
2062 build_unary_op (ADDR_EXPR,
2063 UOBJC_SELECTOR_TABLE_decl, 1)),
2066 /* cls_def_cnt = { ..., 5, ... } */
2068 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2070 /* cat_def_cnt = { ..., 5, ... } */
2072 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2074 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2076 if (imp_count || cat_count || !flag_next_runtime)
2079 tree field = TYPE_FIELDS (type);
2080 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2082 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2086 return objc_build_constructor (type, nreverse (initlist));
2089 /* Generate forward declarations for metadata such as
2090 'OBJC_CLASS_...'. */
2093 build_metadata_decl (const char *name, tree type)
2097 /* struct TYPE NAME_<name>; */
2098 decl = start_var_decl (type, synth_id_with_class_suffix
2100 objc_implementation_context));
2105 /* Push forward-declarations of all the categories so that
2106 init_def_list can use them in a CONSTRUCTOR. */
2109 forward_declare_categories (void)
2111 struct imp_entry *impent;
2112 tree sav = objc_implementation_context;
2114 for (impent = imp_list; impent; impent = impent->next)
2116 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2118 /* Set an invisible arg to synth_id_with_class_suffix. */
2119 objc_implementation_context = impent->imp_context;
2120 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2121 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2122 objc_category_template);
2125 objc_implementation_context = sav;
2128 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2129 and initialized appropriately. */
2132 generate_objc_symtab_decl (void)
2134 /* forward declare categories */
2136 forward_declare_categories ();
2138 build_objc_symtab_template ();
2139 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2140 finish_var_decl (UOBJC_SYMBOLS_decl,
2141 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2145 init_module_descriptor (tree type)
2147 tree initlist, expr;
2149 /* version = { 1, ... } */
2151 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2152 initlist = build_tree_list (NULL_TREE, expr);
2154 /* size = { ..., sizeof (struct _objc_module), ... } */
2156 expr = convert (long_integer_type_node,
2157 size_in_bytes (objc_module_template));
2158 initlist = tree_cons (NULL_TREE, expr, initlist);
2160 /* name = { ..., "foo.m", ... } */
2162 expr = add_objc_string (get_identifier (input_filename), class_names);
2163 initlist = tree_cons (NULL_TREE, expr, initlist);
2165 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2167 if (UOBJC_SYMBOLS_decl)
2168 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2170 expr = build_int_cst (NULL_TREE, 0);
2171 initlist = tree_cons (NULL_TREE, expr, initlist);
2173 return objc_build_constructor (type, nreverse (initlist));
2176 /* Write out the data structures to describe Objective C classes defined.
2178 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2181 build_module_descriptor (void)
2183 tree field_decl, field_decl_chain;
2186 push_lang_context (lang_name_c); /* extern "C" */
2189 objc_module_template
2190 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2193 field_decl = create_field_decl (long_integer_type_node, "version");
2194 field_decl_chain = field_decl;
2197 field_decl = create_field_decl (long_integer_type_node, "size");
2198 chainon (field_decl_chain, field_decl);
2201 field_decl = create_field_decl (string_type_node, "name");
2202 chainon (field_decl_chain, field_decl);
2204 /* struct _objc_symtab *symtab; */
2206 = create_field_decl (build_pointer_type
2207 (xref_tag (RECORD_TYPE,
2208 get_identifier (UTAG_SYMTAB))),
2210 chainon (field_decl_chain, field_decl);
2212 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2214 /* Create an instance of "_objc_module". */
2215 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2216 finish_var_decl (UOBJC_MODULES_decl,
2217 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2220 pop_lang_context ();
2224 /* The GNU runtime requires us to provide a static initializer function
2227 static void __objc_gnu_init (void) {
2228 __objc_exec_class (&L_OBJC_MODULES);
2232 build_module_initializer_routine (void)
2237 push_lang_context (lang_name_c); /* extern "C" */
2240 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2241 objc_start_function (get_identifier (TAG_GNUINIT),
2242 build_function_type (void_type_node,
2244 NULL_TREE, objc_get_parm_info (0));
2246 body = c_begin_compound_stmt (true);
2247 add_stmt (build_function_call
2251 build_unary_op (ADDR_EXPR,
2252 UOBJC_MODULES_decl, 0))));
2253 add_stmt (c_end_compound_stmt (body, true));
2255 TREE_PUBLIC (current_function_decl) = 0;
2258 /* For Objective-C++, we will need to call __objc_gnu_init
2259 from objc_generate_static_init_call() below. */
2260 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2263 GNU_INIT_decl = current_function_decl;
2267 pop_lang_context ();
2272 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2273 to be called by the module initializer routine. */
2276 objc_static_init_needed_p (void)
2278 return (GNU_INIT_decl != NULL_TREE);
2281 /* Generate a call to the __objc_gnu_init initializer function. */
2284 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2286 add_stmt (build_stmt (EXPR_STMT,
2287 build_function_call (GNU_INIT_decl, NULL_TREE)));
2291 #endif /* OBJCPLUS */
2293 /* Return the DECL of the string IDENT in the SECTION. */
2296 get_objc_string_decl (tree ident, enum string_section section)
2300 if (section == class_names)
2301 chain = class_names_chain;
2302 else if (section == meth_var_names)
2303 chain = meth_var_names_chain;
2304 else if (section == meth_var_types)
2305 chain = meth_var_types_chain;
2309 for (; chain != 0; chain = TREE_CHAIN (chain))
2310 if (TREE_VALUE (chain) == ident)
2311 return (TREE_PURPOSE (chain));
2317 /* Output references to all statically allocated objects. Return the DECL
2318 for the array built. */
2321 generate_static_references (void)
2323 tree decls = NULL_TREE, expr = NULL_TREE;
2324 tree class_name, class, decl, initlist;
2325 tree cl_chain, in_chain, type
2326 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2327 int num_inst, num_class;
2330 if (flag_next_runtime)
2333 for (cl_chain = objc_static_instances, num_class = 0;
2334 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2336 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2337 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2339 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2340 decl = start_var_decl (type, buf);
2342 /* Output {class_name, ...}. */
2343 class = TREE_VALUE (cl_chain);
2344 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2345 initlist = build_tree_list (NULL_TREE,
2346 build_unary_op (ADDR_EXPR, class_name, 1));
2348 /* Output {..., instance, ...}. */
2349 for (in_chain = TREE_PURPOSE (cl_chain);
2350 in_chain; in_chain = TREE_CHAIN (in_chain))
2352 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2353 initlist = tree_cons (NULL_TREE, expr, initlist);
2356 /* Output {..., NULL}. */
2357 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2359 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2360 finish_var_decl (decl, expr);
2362 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2365 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2366 expr = objc_build_constructor (type, nreverse (decls));
2367 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2368 finish_var_decl (static_instances_decl, expr);
2371 /* Output all strings. */
2374 generate_strings (void)
2376 tree chain, string_expr;
2377 tree string, decl, type;
2379 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2381 string = TREE_VALUE (chain);
2382 decl = TREE_PURPOSE (chain);
2383 type = build_array_type
2386 (build_int_cst (NULL_TREE,
2387 IDENTIFIER_LENGTH (string))));
2388 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2389 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2390 IDENTIFIER_POINTER (string));
2391 finish_var_decl (decl, string_expr);
2394 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2396 string = TREE_VALUE (chain);
2397 decl = TREE_PURPOSE (chain);
2398 type = build_array_type
2401 (build_int_cst (NULL_TREE,
2402 IDENTIFIER_LENGTH (string))));
2403 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2404 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2405 IDENTIFIER_POINTER (string));
2406 finish_var_decl (decl, string_expr);
2409 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2411 string = TREE_VALUE (chain);
2412 decl = TREE_PURPOSE (chain);
2413 type = build_array_type
2416 (build_int_cst (NULL_TREE,
2417 IDENTIFIER_LENGTH (string))));
2418 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2419 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2420 IDENTIFIER_POINTER (string));
2421 finish_var_decl (decl, string_expr);
2425 static GTY(()) int selector_reference_idx;
2428 build_selector_reference_decl (void)
2433 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2434 decl = start_var_decl (objc_selector_type, buf);
2440 build_selector_table_decl (void)
2444 if (flag_typed_selectors)
2446 build_selector_template ();
2447 temp = build_array_type (objc_selector_template, NULL_TREE);
2450 temp = build_array_type (objc_selector_type, NULL_TREE);
2452 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2455 /* Just a handy wrapper for add_objc_string. */
2458 build_selector (tree ident)
2460 return convert (objc_selector_type,
2461 add_objc_string (ident, meth_var_names));
2465 build_selector_translation_table (void)
2467 tree chain, initlist = NULL_TREE;
2469 tree decl = NULL_TREE;
2471 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2475 if (warn_selector && objc_implementation_context)
2479 for (method_chain = meth_var_names_chain;
2481 method_chain = TREE_CHAIN (method_chain))
2483 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2492 if (flag_next_runtime && TREE_PURPOSE (chain))
2493 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2495 loc = &input_location;
2496 warning (0, "%Hcreating selector for nonexistent method %qE",
2497 loc, TREE_VALUE (chain));
2501 expr = build_selector (TREE_VALUE (chain));
2502 /* add one for the '\0' character */
2503 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2505 if (flag_next_runtime)
2507 decl = TREE_PURPOSE (chain);
2508 finish_var_decl (decl, expr);
2512 if (flag_typed_selectors)
2514 tree eltlist = NULL_TREE;
2515 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2516 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2517 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2518 expr = objc_build_constructor (objc_selector_template,
2519 nreverse (eltlist));
2522 initlist = tree_cons (NULL_TREE, expr, initlist);
2526 if (! flag_next_runtime)
2528 /* Cause the selector table (previously forward-declared)
2529 to be actually output. */
2530 initlist = tree_cons (NULL_TREE,
2531 flag_typed_selectors
2532 ? objc_build_constructor
2533 (objc_selector_template,
2534 tree_cons (NULL_TREE,
2535 build_int_cst (NULL_TREE, 0),
2536 tree_cons (NULL_TREE,
2537 build_int_cst (NULL_TREE, 0),
2539 : build_int_cst (NULL_TREE, 0), initlist);
2540 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2541 nreverse (initlist));
2542 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2547 get_proto_encoding (tree proto)
2552 if (! METHOD_ENCODING (proto))
2554 encoding = encode_method_prototype (proto);
2555 METHOD_ENCODING (proto) = encoding;
2558 encoding = METHOD_ENCODING (proto);
2560 return add_objc_string (encoding, meth_var_types);
2563 return build_int_cst (NULL_TREE, 0);
2566 /* sel_ref_chain is a list whose "value" fields will be instances of
2567 identifier_node that represent the selector. */
2570 build_typed_selector_reference (tree ident, tree prototype)
2572 tree *chain = &sel_ref_chain;
2578 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2579 goto return_at_index;
2582 chain = &TREE_CHAIN (*chain);
2585 *chain = tree_cons (prototype, ident, NULL_TREE);
2588 expr = build_unary_op (ADDR_EXPR,
2589 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2590 build_int_cst (NULL_TREE, index)),
2592 return convert (objc_selector_type, expr);
2596 build_selector_reference (tree ident)
2598 tree *chain = &sel_ref_chain;
2604 if (TREE_VALUE (*chain) == ident)
2605 return (flag_next_runtime
2606 ? TREE_PURPOSE (*chain)
2607 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2608 build_int_cst (NULL_TREE, index)));
2611 chain = &TREE_CHAIN (*chain);
2614 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2616 *chain = tree_cons (expr, ident, NULL_TREE);
2618 return (flag_next_runtime
2620 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2621 build_int_cst (NULL_TREE, index)));
2624 static GTY(()) int class_reference_idx;
2627 build_class_reference_decl (void)
2632 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2633 decl = start_var_decl (objc_class_type, buf);
2638 /* Create a class reference, but don't create a variable to reference
2642 add_class_reference (tree ident)
2646 if ((chain = cls_ref_chain))
2651 if (ident == TREE_VALUE (chain))
2655 chain = TREE_CHAIN (chain);
2659 /* Append to the end of the list */
2660 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2663 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2666 /* Get a class reference, creating it if necessary. Also create the
2667 reference variable. */
2670 objc_get_class_reference (tree ident)
2672 tree orig_ident = (DECL_P (ident)
2675 ? OBJC_TYPE_NAME (ident)
2677 bool local_scope = false;
2680 if (processing_template_decl)
2681 /* Must wait until template instantiation time. */
2682 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2685 if (TREE_CODE (ident) == TYPE_DECL)
2686 ident = (DECL_ORIGINAL_TYPE (ident)
2687 ? DECL_ORIGINAL_TYPE (ident)
2688 : TREE_TYPE (ident));
2691 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2692 && TYPE_CONTEXT (ident) != global_namespace)
2696 if (local_scope || !(ident = objc_is_class_name (ident)))
2698 error ("%qs is not an Objective-C class name or alias",
2699 IDENTIFIER_POINTER (orig_ident));
2700 return error_mark_node;
2703 if (flag_next_runtime && !flag_zero_link)
2708 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2709 if (TREE_VALUE (*chain) == ident)
2711 if (! TREE_PURPOSE (*chain))
2712 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2714 return TREE_PURPOSE (*chain);
2717 decl = build_class_reference_decl ();
2718 *chain = tree_cons (decl, ident, NULL_TREE);
2725 add_class_reference (ident);
2727 params = build_tree_list (NULL_TREE,
2728 my_build_string_pointer
2729 (IDENTIFIER_LENGTH (ident) + 1,
2730 IDENTIFIER_POINTER (ident)));
2732 assemble_external (objc_get_class_decl);
2733 return build_function_call (objc_get_class_decl, params);
2737 /* For each string section we have a chain which maps identifier nodes
2738 to decls for the strings. */
2741 add_objc_string (tree ident, enum string_section section)
2745 if (section == class_names)
2746 chain = &class_names_chain;
2747 else if (section == meth_var_names)
2748 chain = &meth_var_names_chain;
2749 else if (section == meth_var_types)
2750 chain = &meth_var_types_chain;
2756 if (TREE_VALUE (*chain) == ident)
2757 return convert (string_type_node,
2758 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2760 chain = &TREE_CHAIN (*chain);
2763 decl = build_objc_string_decl (section);
2765 *chain = tree_cons (decl, ident, NULL_TREE);
2767 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2770 static GTY(()) int class_names_idx;
2771 static GTY(()) int meth_var_names_idx;
2772 static GTY(()) int meth_var_types_idx;
2775 build_objc_string_decl (enum string_section section)
2780 if (section == class_names)
2781 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2782 else if (section == meth_var_names)
2783 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2784 else if (section == meth_var_types)
2785 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2787 ident = get_identifier (buf);
2789 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2790 DECL_EXTERNAL (decl) = 1;
2791 TREE_PUBLIC (decl) = 0;
2792 TREE_USED (decl) = 1;
2793 TREE_CONSTANT (decl) = 1;
2794 DECL_CONTEXT (decl) = 0;
2795 DECL_ARTIFICIAL (decl) = 1;
2797 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2800 make_decl_rtl (decl);
2801 pushdecl_top_level (decl);
2808 objc_declare_alias (tree alias_ident, tree class_ident)
2810 tree underlying_class;
2813 if (current_namespace != global_namespace) {
2814 error ("Objective-C declarations may only appear in global scope");
2816 #endif /* OBJCPLUS */
2818 if (!(underlying_class = objc_is_class_name (class_ident)))
2819 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2820 else if (objc_is_class_name (alias_ident))
2821 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2824 /* Implement @compatibility_alias as a typedef. */
2826 push_lang_context (lang_name_c); /* extern "C" */
2828 lang_hooks.decls.pushdecl (build_decl
2831 xref_tag (RECORD_TYPE, underlying_class)));
2833 pop_lang_context ();
2835 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2840 objc_declare_class (tree ident_list)
2844 if (current_namespace != global_namespace) {
2845 error ("Objective-C declarations may only appear in global scope");
2847 #endif /* OBJCPLUS */
2849 for (list = ident_list; list; list = TREE_CHAIN (list))
2851 tree ident = TREE_VALUE (list);
2853 if (! objc_is_class_name (ident))
2855 tree record = lookup_name (ident), type = record;
2859 if (TREE_CODE (record) == TYPE_DECL)
2860 type = DECL_ORIGINAL_TYPE (record);
2862 if (!TYPE_HAS_OBJC_INFO (type)
2863 || !TYPE_OBJC_INTERFACE (type))
2865 error ("%qs redeclared as different kind of symbol",
2866 IDENTIFIER_POINTER (ident));
2867 error ("%Jprevious declaration of '%D'",
2872 record = xref_tag (RECORD_TYPE, ident);
2873 INIT_TYPE_OBJC_INFO (record);
2874 TYPE_OBJC_INTERFACE (record) = ident;
2875 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2881 objc_is_class_name (tree ident)
2885 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2886 && identifier_global_value (ident))
2887 ident = identifier_global_value (ident);
2888 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2889 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2891 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2892 ident = OBJC_TYPE_NAME (ident);
2894 if (ident && TREE_CODE (ident) == TYPE_DECL)
2895 ident = DECL_NAME (ident);
2897 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2900 if (lookup_interface (ident))
2903 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2905 if (ident == TREE_VALUE (chain))
2909 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2911 if (ident == TREE_VALUE (chain))
2912 return TREE_PURPOSE (chain);
2918 /* Check whether TYPE is either 'id' or 'Class'. */
2921 objc_is_id (tree type)
2923 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2924 && identifier_global_value (type))
2925 type = identifier_global_value (type);
2927 if (type && TREE_CODE (type) == TYPE_DECL)
2928 type = TREE_TYPE (type);
2930 /* NB: This function may be called before the ObjC front-end has
2931 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2932 return (objc_object_type && type
2933 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2938 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2939 class instance. This is needed by other parts of the compiler to
2940 handle ObjC types gracefully. */
2943 objc_is_object_ptr (tree type)
2947 type = TYPE_MAIN_VARIANT (type);
2948 if (!POINTER_TYPE_P (type))
2951 ret = objc_is_id (type);
2953 ret = objc_is_class_name (TREE_TYPE (type));
2959 objc_is_gcable_type (tree type, int or_strong_p)
2965 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
2967 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
2969 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
2971 type = TREE_TYPE (type);
2972 if (TREE_CODE (type) != RECORD_TYPE)
2974 name = TYPE_NAME (type);
2975 return (objc_is_class_name (name) != NULL_TREE);
2979 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
2981 if (expr == oldexpr)
2984 switch (TREE_CODE (expr))
2987 return objc_build_component_ref
2988 (objc_substitute_decl (TREE_OPERAND (expr, 0),
2991 DECL_NAME (TREE_OPERAND (expr, 1)));
2993 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2996 TREE_OPERAND (expr, 1));
2998 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3007 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3010 /* The LHS parameter contains the expression 'outervar->memberspec';
3011 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3012 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3015 = objc_substitute_decl
3016 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3018 = (flag_objc_direct_dispatch
3019 ? objc_assign_ivar_fast_decl
3020 : objc_assign_ivar_decl);
3022 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3024 func_params = tree_cons (NULL_TREE,
3025 convert (objc_object_type, rhs),
3026 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3027 tree_cons (NULL_TREE, offs,
3030 assemble_external (func);
3031 return build_function_call (func, func_params);
3035 objc_build_global_assignment (tree lhs, tree rhs)
3037 tree func_params = tree_cons (NULL_TREE,
3038 convert (objc_object_type, rhs),
3039 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3040 build_unary_op (ADDR_EXPR, lhs, 0)),
3043 assemble_external (objc_assign_global_decl);
3044 return build_function_call (objc_assign_global_decl, func_params);
3048 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3050 tree func_params = tree_cons (NULL_TREE,
3051 convert (objc_object_type, rhs),
3052 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3053 build_unary_op (ADDR_EXPR, lhs, 0)),
3056 assemble_external (objc_assign_strong_cast_decl);
3057 return build_function_call (objc_assign_strong_cast_decl, func_params);
3061 objc_is_gcable_p (tree expr)
3063 return (TREE_CODE (expr) == COMPONENT_REF
3064 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3065 : TREE_CODE (expr) == ARRAY_REF
3066 ? (objc_is_gcable_p (TREE_TYPE (expr))
3067 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3068 : TREE_CODE (expr) == ARRAY_TYPE
3069 ? objc_is_gcable_p (TREE_TYPE (expr))
3071 ? objc_is_gcable_type (expr, 1)
3072 : (objc_is_gcable_p (TREE_TYPE (expr))
3074 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3078 objc_is_ivar_reference_p (tree expr)
3080 return (TREE_CODE (expr) == ARRAY_REF
3081 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3082 : TREE_CODE (expr) == COMPONENT_REF
3083 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3088 objc_is_global_reference_p (tree expr)
3090 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3091 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3093 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3098 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3100 tree result = NULL_TREE, outer;
3101 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3103 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3104 will have been transformed to the form '*(type *)&expr'. */
3105 if (TREE_CODE (lhs) == INDIRECT_REF)
3107 outer = TREE_OPERAND (lhs, 0);
3109 while (!strong_cast_p
3110 && (TREE_CODE (outer) == CONVERT_EXPR
3111 || TREE_CODE (outer) == NOP_EXPR
3112 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3114 tree lhstype = TREE_TYPE (outer);
3116 /* Descend down the cast chain, and record the first objc_gc
3118 if (POINTER_TYPE_P (lhstype))
3121 = lookup_attribute ("objc_gc",
3122 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3128 outer = TREE_OPERAND (outer, 0);
3132 /* If we have a __strong cast, it trumps all else. */
3135 if (modifycode != NOP_EXPR)
3136 goto invalid_pointer_arithmetic;
3138 if (warn_assign_intercept)
3139 warning (0, "strong-cast assignment has been intercepted");
3141 result = objc_build_strong_cast_assignment (lhs, rhs);
3146 /* the lhs must be of a suitable type, regardless of its underlying
3148 if (!objc_is_gcable_p (lhs))
3154 && (TREE_CODE (outer) == COMPONENT_REF
3155 || TREE_CODE (outer) == ARRAY_REF))
3156 outer = TREE_OPERAND (outer, 0);
3158 if (TREE_CODE (outer) == INDIRECT_REF)
3160 outer = TREE_OPERAND (outer, 0);
3164 outer_gc_p = objc_is_gcable_p (outer);
3166 /* Handle ivar assignments. */
3167 if (objc_is_ivar_reference_p (lhs))
3169 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3170 doesn't cut it here), the best we can do here is suggest a cast. */
3171 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3173 /* We may still be able to use the global write barrier... */
3174 if (!indirect_p && objc_is_global_reference_p (outer))
3175 goto global_reference;
3178 if (modifycode == NOP_EXPR)
3180 if (warn_assign_intercept)
3181 warning (0, "strong-cast may possibly be needed");
3187 if (modifycode != NOP_EXPR)
3188 goto invalid_pointer_arithmetic;
3190 if (warn_assign_intercept)
3191 warning (0, "instance variable assignment has been intercepted");
3193 result = objc_build_ivar_assignment (outer, lhs, rhs);
3198 /* Likewise, intercept assignment to global/static variables if their type is
3200 if (objc_is_global_reference_p (outer))
3206 if (modifycode != NOP_EXPR)
3208 invalid_pointer_arithmetic:
3210 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3215 if (warn_assign_intercept)
3216 warning (0, "global/static variable assignment has been intercepted");
3218 result = objc_build_global_assignment (lhs, rhs);
3221 /* In all other cases, fall back to the normal mechanism. */
3226 struct interface_tuple GTY(())
3232 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3235 hash_interface (const void *p)
3237 const struct interface_tuple *d = p;
3238 return htab_hash_pointer (d->id);
3242 eq_interface (const void *p1, const void *p2)
3244 const struct interface_tuple *d = p1;
3249 lookup_interface (tree ident)
3252 if (ident && TREE_CODE (ident) == TYPE_DECL)
3253 ident = DECL_NAME (ident);
3256 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3260 struct interface_tuple **slot;
3265 slot = (struct interface_tuple **)
3266 htab_find_slot_with_hash (interface_htab, ident,
3267 htab_hash_pointer (ident),
3270 i = (*slot)->class_name;
3276 /* Implement @defs (<classname>) within struct bodies. */
3279 objc_get_class_ivars (tree class_name)
3281 tree interface = lookup_interface (class_name);
3284 return get_class_ivars (interface, true);
3286 error ("cannot find interface declaration for %qs",
3287 IDENTIFIER_POINTER (class_name));
3289 return error_mark_node;
3292 /* Used by: build_private_template, continue_class,
3293 and for @defs constructs. */
3296 get_class_ivars (tree interface, bool inherited)
3298 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3300 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3301 by the current class (i.e., they do not include super-class ivars).
3302 However, the CLASS_IVARS list will be side-effected by a call to
3303 finish_struct(), which will fill in field offsets. */
3304 if (!CLASS_IVARS (interface))
3305 CLASS_IVARS (interface) = ivar_chain;
3310 while (CLASS_SUPER_NAME (interface))
3312 /* Prepend super-class ivars. */
3313 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3314 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3322 objc_create_temporary_var (tree type)
3326 decl = build_decl (VAR_DECL, NULL_TREE, type);
3327 TREE_USED (decl) = 1;
3328 DECL_ARTIFICIAL (decl) = 1;
3329 DECL_IGNORED_P (decl) = 1;
3330 DECL_CONTEXT (decl) = current_function_decl;
3335 /* Exception handling constructs. We begin by having the parser do most
3336 of the work and passing us blocks. What we do next depends on whether
3337 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3338 We abstract all of this in a handful of appropriately named routines. */
3340 /* Stack of open try blocks. */
3342 struct objc_try_context
3344 struct objc_try_context *outer;
3346 /* Statements (or statement lists) as processed by the parser. */
3350 /* Some file position locations. */
3351 location_t try_locus;
3352 location_t end_try_locus;
3353 location_t end_catch_locus;
3354 location_t finally_locus;
3355 location_t end_finally_locus;
3357 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3358 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3361 /* The CATCH_EXPR of an open @catch clause. */
3364 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3370 static struct objc_try_context *cur_try_context;
3372 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3373 that represents TYPE. For Objective-C, this is just the class name. */
3374 /* ??? Isn't there a class object or some such? Is it easy to get? */
3378 objc_eh_runtime_type (tree type)
3380 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3384 /* Initialize exception handling. */
3387 objc_init_exceptions (void)
3389 static bool done = false;
3394 if (flag_objc_sjlj_exceptions)
3396 /* On Darwin, ObjC exceptions require a sufficiently recent
3397 version of the runtime, so the user must ask for them explicitly. */
3398 if (!flag_objc_exceptions)
3399 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3400 "exception syntax");
3405 c_eh_initialized_p = true;
3406 eh_personality_libfunc
3407 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3408 ? "__gnu_objc_personality_sj0"
3409 : "__gnu_objc_personality_v0");
3410 using_eh_for_cleanups ();
3411 lang_eh_runtime_type = objc_eh_runtime_type;
3416 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3417 we'll arrange for it to be initialized (and associated with a binding)
3421 objc_build_exc_ptr (void)
3423 if (flag_objc_sjlj_exceptions)
3425 tree var = cur_try_context->caught_decl;
3428 var = objc_create_temporary_var (objc_object_type);
3429 cur_try_context->caught_decl = var;
3434 return build (EXC_PTR_EXPR, objc_object_type);
3437 /* Build "objc_exception_try_exit(&_stack)". */
3440 next_sjlj_build_try_exit (void)
3443 t = build_fold_addr_expr (cur_try_context->stack_decl);
3444 t = tree_cons (NULL, t, NULL);
3445 t = build_function_call (objc_exception_try_exit_decl, t);
3450 objc_exception_try_enter (&_stack);
3451 if (_setjmp(&_stack.buf))
3455 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3456 empty, ready for the caller to fill them in. */
3459 next_sjlj_build_enter_and_setjmp (void)
3461 tree t, enter, sj, cond;
3463 t = build_fold_addr_expr (cur_try_context->stack_decl);
3464 t = tree_cons (NULL, t, NULL);
3465 enter = build_function_call (objc_exception_try_enter_decl, t);
3467 t = objc_build_component_ref (cur_try_context->stack_decl,
3468 get_identifier ("buf"));
3469 t = build_fold_addr_expr (t);
3471 /* Convert _setjmp argument to type that is expected. */
3472 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3473 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3475 t = convert (ptr_type_node, t);
3477 t = convert (ptr_type_node, t);
3479 t = tree_cons (NULL, t, NULL);
3480 sj = build_function_call (objc_setjmp_decl, t);
3482 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3483 cond = c_common_truthvalue_conversion (cond);
3485 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3489 DECL = objc_exception_extract(&_stack);
3493 next_sjlj_build_exc_extract (tree decl)
3497 t = build_fold_addr_expr (cur_try_context->stack_decl);
3498 t = tree_cons (NULL, t, NULL);
3499 t = build_function_call (objc_exception_extract_decl, t);
3500 t = convert (TREE_TYPE (decl), t);
3501 t = build (MODIFY_EXPR, void_type_node, decl, t);
3507 if (objc_exception_match(obj_get_class(TYPE), _caught)
3514 objc_exception_try_exit(&_stack);
3516 from the sequence of CATCH_EXPRs in the current try context. */
3519 next_sjlj_build_catch_list (void)
3521 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3523 tree *last = &catch_seq;
3524 bool saw_id = false;
3526 for (; !tsi_end_p (i); tsi_next (&i))
3528 tree stmt = tsi_stmt (i);
3529 tree type = CATCH_TYPES (stmt);
3530 tree body = CATCH_BODY (stmt);
3542 if (type == error_mark_node)
3543 cond = error_mark_node;
3546 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3547 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3548 args = tree_cons (NULL, t, args);
3549 t = build_function_call (objc_exception_match_decl, args);
3550 cond = c_common_truthvalue_conversion (t);
3552 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3553 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3556 last = &COND_EXPR_ELSE (t);
3562 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3563 cur_try_context->caught_decl);
3564 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3565 append_to_statement_list (t, last);
3567 t = next_sjlj_build_try_exit ();
3568 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3569 append_to_statement_list (t, last);
3575 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3576 exception handling. We aim to build:
3579 struct _objc_exception_data _stack;
3580 id volatile _rethrow = 0;
3583 objc_exception_try_enter (&_stack);
3584 if (_setjmp(&_stack.buf))
3586 id _caught = objc_exception_extract(&_stack);
3587 objc_exception_try_enter (&_stack);
3588 if (_setjmp(&_stack.buf))
3589 _rethrow = objc_exception_extract(&_stack);
3599 objc_exception_try_exit(&_stack);
3602 objc_exception_throw(_rethrow);
3606 If CATCH-LIST is empty, we can omit all of the block containing
3607 "_caught" except for the setting of _rethrow. Note the use of
3608 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3609 but handles goto and other exits from the block. */
3612 next_sjlj_build_try_catch_finally (void)
3614 tree rethrow_decl, stack_decl, t;
3615 tree catch_seq, try_fin, bind;
3617 /* Create the declarations involved. */
3618 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3619 stack_decl = objc_create_temporary_var (t);
3620 cur_try_context->stack_decl = stack_decl;
3622 rethrow_decl = objc_create_temporary_var (objc_object_type);
3623 cur_try_context->rethrow_decl = rethrow_decl;
3624 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3625 TREE_CHAIN (rethrow_decl) = stack_decl;
3627 /* Build the outermost variable binding level. */
3628 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3629 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3630 TREE_SIDE_EFFECTS (bind) = 1;
3632 /* Initialize rethrow_decl. */
3633 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3634 convert (objc_object_type, null_pointer_node));
3635 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3636 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3638 /* Build the outermost TRY_FINALLY_EXPR. */
3639 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3640 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3641 TREE_SIDE_EFFECTS (try_fin) = 1;
3642 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3644 /* Create the complete catch sequence. */
3645 if (cur_try_context->catch_list)
3647 tree caught_decl = objc_build_exc_ptr ();
3648 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3650 t = next_sjlj_build_exc_extract (caught_decl);
3651 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3653 t = next_sjlj_build_enter_and_setjmp ();
3654 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3655 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3656 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3659 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3660 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3662 /* Build the main register-and-try if statement. */
3663 t = next_sjlj_build_enter_and_setjmp ();
3664 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3665 COND_EXPR_THEN (t) = catch_seq;
3666 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3667 TREE_OPERAND (try_fin, 0) = t;
3669 /* Build the complete FINALLY statement list. */
3670 t = next_sjlj_build_try_exit ();
3671 t = build_stmt (COND_EXPR,
3672 c_common_truthvalue_conversion (rethrow_decl),
3674 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3675 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3677 append_to_statement_list (cur_try_context->finally_body,
3678 &TREE_OPERAND (try_fin, 1));
3680 t = tree_cons (NULL, rethrow_decl, NULL);
3681 t = build_function_call (objc_exception_throw_decl, t);
3682 t = build_stmt (COND_EXPR,
3683 c_common_truthvalue_conversion (rethrow_decl),
3685 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3686 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3691 /* Called just after parsing the @try and its associated BODY. We now
3692 must prepare for the tricky bits -- handling the catches and finally. */
3695 objc_begin_try_stmt (location_t try_locus, tree body)
3697 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3698 c->outer = cur_try_context;
3700 c->try_locus = try_locus;
3701 c->end_try_locus = input_location;
3702 cur_try_context = c;
3704 objc_init_exceptions ();
3706 if (flag_objc_sjlj_exceptions)
3707 objc_mark_locals_volatile (NULL);
3710 /* Called just after parsing "@catch (parm)". Open a binding level,
3711 enter DECL into the binding level, and initialize it. Leave the
3712 binding level open while the body of the compound statement is parsed. */
3715 objc_begin_catch_clause (tree decl)
3717 tree compound, type, t;
3719 /* Begin a new scope that the entire catch clause will live in. */
3720 compound = c_begin_compound_stmt (true);
3722 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3723 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3724 lang_hooks.decls.pushdecl (decl);
3726 /* Since a decl is required here by syntax, don't warn if its unused. */
3727 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3728 be what the previous objc implementation did. */
3729 TREE_USED (decl) = 1;
3731 /* Verify that the type of the catch is valid. It must be a pointer
3732 to an Objective-C class, or "id" (which is catch-all). */
3733 type = TREE_TYPE (decl);
3735 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3737 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3739 error ("@catch parameter is not a known Objective-C class type");
3740 type = error_mark_node;
3742 else if (cur_try_context->catch_list)
3744 /* Examine previous @catch clauses and see if we've already
3745 caught the type in question. */
3746 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3747 for (; !tsi_end_p (i); tsi_next (&i))
3749 tree stmt = tsi_stmt (i);
3750 t = CATCH_TYPES (stmt);
3751 if (t == error_mark_node)
3753 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3755 warning (0, "exception of type %<%T%> will be caught",
3757 warning (0, "%H by earlier handler for %<%T%>",
3758 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3764 /* Record the data for the catch in the try context so that we can
3765 finalize it later. */
3766 t = build_stmt (CATCH_EXPR, type, compound);
3767 cur_try_context->current_catch = t;
3769 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3770 t = objc_build_exc_ptr ();
3771 t = convert (TREE_TYPE (decl), t);
3772 t = build (MODIFY_EXPR, void_type_node, decl, t);
3776 /* Called just after parsing the closing brace of a @catch clause. Close
3777 the open binding level, and record a CATCH_EXPR for it. */
3780 objc_finish_catch_clause (void)
3782 tree c = cur_try_context->current_catch;
3783 cur_try_context->current_catch = NULL;
3784 cur_try_context->end_catch_locus = input_location;
3786 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3787 append_to_statement_list (c, &cur_try_context->catch_list);
3790 /* Called after parsing a @finally clause and its associated BODY.
3791 Record the body for later placement. */
3794 objc_build_finally_clause (location_t finally_locus, tree body)
3796 cur_try_context->finally_body = body;
3797 cur_try_context->finally_locus = finally_locus;
3798 cur_try_context->end_finally_locus = input_location;
3801 /* Called to finalize a @try construct. */
3804 objc_finish_try_stmt (void)
3806 struct objc_try_context *c = cur_try_context;
3809 if (c->catch_list == NULL && c->finally_body == NULL)
3810 error ("%<@try%> without %<@catch%> or %<@finally%>");
3812 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3813 if (flag_objc_sjlj_exceptions)
3815 if (!cur_try_context->finally_body)
3817 cur_try_context->finally_locus = input_location;
3818 cur_try_context->end_finally_locus = input_location;
3820 stmt = next_sjlj_build_try_catch_finally ();
3824 /* Otherwise, nest the CATCH inside a FINALLY. */
3828 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3829 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3831 if (c->finally_body)
3833 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3834 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3839 cur_try_context = c->outer;
3845 objc_build_throw_stmt (tree throw_expr)
3849 objc_init_exceptions ();
3851 if (throw_expr == NULL)
3853 /* If we're not inside a @catch block, there is no "current
3854 exception" to be rethrown. */
3855 if (cur_try_context == NULL
3856 || cur_try_context->current_catch == NULL)
3858 error ("%<@throw%> (rethrow) used outside of a @catch block");
3862 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3863 value that we get from the runtime. */
3864 throw_expr = objc_build_exc_ptr ();
3867 /* A throw is just a call to the runtime throw function with the
3868 object as a parameter. */
3869 args = tree_cons (NULL, throw_expr, NULL);
3870 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3874 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3878 /* First lock the mutex. */
3879 mutex = save_expr (mutex);
3880 args = tree_cons (NULL, mutex, NULL);
3881 call = build_function_call (objc_sync_enter_decl, args);
3882 SET_EXPR_LOCATION (call, start_locus);
3885 /* Build the mutex unlock. */
3886 args = tree_cons (NULL, mutex, NULL);
3887 call = build_function_call (objc_sync_exit_decl, args);
3888 SET_EXPR_LOCATION (call, input_location);
3890 /* Put the that and the body in a TRY_FINALLY. */
3891 objc_begin_try_stmt (start_locus, body);
3892 objc_build_finally_clause (input_location, call);
3893 return objc_finish_try_stmt ();
3897 /* Predefine the following data type:
3899 struct _objc_exception_data
3905 /* The following yuckiness should prevent users from having to #include
3906 <setjmp.h> in their code... */
3908 #ifdef TARGET_POWERPC
3909 /* snarfed from /usr/include/ppc/setjmp.h */
3910 #define _JBLEN (26 + 36 + 129 + 1)
3912 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3917 build_next_objc_exception_stuff (void)
3919 tree field_decl, field_decl_chain, index, temp_type;
3921 objc_exception_data_template
3922 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3924 /* int buf[_JBLEN]; */
3926 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3927 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3929 field_decl_chain = field_decl;
3931 /* void *pointers[4]; */
3933 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3934 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3936 chainon (field_decl_chain, field_decl);
3938 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3940 /* int _setjmp(...); */
3941 /* If the user includes <setjmp.h>, this shall be superseded by
3942 'int _setjmp(jmp_buf);' */
3943 temp_type = build_function_type (integer_type_node, NULL_TREE);
3945 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3947 /* id objc_exception_extract(struct _objc_exception_data *); */
3949 = build_function_type (objc_object_type,
3950 tree_cons (NULL_TREE,
3951 build_pointer_type (objc_exception_data_template),
3953 objc_exception_extract_decl
3954 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3955 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3956 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3958 = build_function_type (void_type_node,
3959 tree_cons (NULL_TREE,
3960 build_pointer_type (objc_exception_data_template),
3962 objc_exception_try_enter_decl
3963 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3964 objc_exception_try_exit_decl
3965 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3967 /* int objc_exception_match(id, id); */
3969 = build_function_type (integer_type_node,
3970 tree_cons (NULL_TREE, objc_object_type,
3971 tree_cons (NULL_TREE, objc_object_type,
3972 OBJC_VOID_AT_END)));
3973 objc_exception_match_decl
3974 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3976 /* id objc_assign_ivar (id, id, unsigned int); */
3977 /* id objc_assign_ivar_Fast (id, id, unsigned int)
3978 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
3980 = build_function_type (objc_object_type,
3982 (NULL_TREE, objc_object_type,
3983 tree_cons (NULL_TREE, objc_object_type,
3984 tree_cons (NULL_TREE,
3986 OBJC_VOID_AT_END))));
3987 objc_assign_ivar_decl
3988 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
3990 #ifdef OFFS_ASSIGNIVAR_FAST
3991 objc_assign_ivar_fast_decl
3992 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
3993 NOT_BUILT_IN, NULL, NULL_TREE);
3994 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
3995 = tree_cons (get_identifier ("hard_coded_address"),
3996 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
3999 /* Default to slower ivar method. */
4000 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4003 /* id objc_assign_global (id, id *); */
4004 /* id objc_assign_strongCast (id, id *); */
4005 temp_type = build_function_type (objc_object_type,
4006 tree_cons (NULL_TREE, objc_object_type,
4007 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4008 OBJC_VOID_AT_END)));
4009 objc_assign_global_decl
4010 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4011 objc_assign_strong_cast_decl
4012 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4016 build_objc_exception_stuff (void)
4018 tree noreturn_list, nothrow_list, temp_type;
4020 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4021 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4023 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4024 /* void objc_sync_enter(id); */
4025 /* void objc_sync_exit(id); */
4026 temp_type = build_function_type (void_type_node,
4027 tree_cons (NULL_TREE, objc_object_type,
4029 objc_exception_throw_decl
4030 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4032 objc_sync_enter_decl
4033 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4034 NULL, nothrow_list);
4036 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4037 NULL, nothrow_list);
4040 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4043 struct <classname> {
4044 struct _objc_class *isa;
4049 build_private_template (tree class)
4051 if (!CLASS_STATIC_TEMPLATE (class))
4053 tree record = objc_build_struct (CLASS_NAME (class),
4054 get_class_ivars (class, false),
4055 CLASS_SUPER_NAME (class));
4057 /* mark this record as class template - for class type checking */
4058 INIT_TYPE_OBJC_INFO (record);
4059 TYPE_OBJC_INTERFACE (record) = class;
4060 CLASS_STATIC_TEMPLATE (class) = record;
4062 /* Set the TREE_USED bit for this struct, so that stab generator
4063 can emit stabs for this struct type. */
4064 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4065 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4069 /* Begin code generation for protocols... */
4071 /* struct _objc_protocol {
4072 struct _objc_class *isa;
4073 char *protocol_name;
4074 struct _objc_protocol **protocol_list;
4075 struct _objc__method_prototype_list *instance_methods;
4076 struct _objc__method_prototype_list *class_methods;
4080 build_protocol_template (void)
4082 tree field_decl, field_decl_chain;
4084 objc_protocol_template = start_struct (RECORD_TYPE,
4085 get_identifier (UTAG_PROTOCOL));
4087 /* struct _objc_class *isa; */
4088 field_decl = create_field_decl (build_pointer_type
4089 (xref_tag (RECORD_TYPE,
4090 get_identifier (UTAG_CLASS))),
4092 field_decl_chain = field_decl;
4094 /* char *protocol_name; */
4095 field_decl = create_field_decl (string_type_node, "protocol_name");
4096 chainon (field_decl_chain, field_decl);
4098 /* struct _objc_protocol **protocol_list; */
4099 field_decl = create_field_decl (build_pointer_type
4101 (objc_protocol_template)),
4103 chainon (field_decl_chain, field_decl);
4105 /* struct _objc__method_prototype_list *instance_methods; */
4106 field_decl = create_field_decl (objc_method_proto_list_ptr,
4107 "instance_methods");
4108 chainon (field_decl_chain, field_decl);
4110 /* struct _objc__method_prototype_list *class_methods; */
4111 field_decl = create_field_decl (objc_method_proto_list_ptr,
4113 chainon (field_decl_chain, field_decl);
4115 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4119 build_descriptor_table_initializer (tree type, tree entries)
4121 tree initlist = NULL_TREE;
4125 tree eltlist = NULL_TREE;
4128 = tree_cons (NULL_TREE,
4129 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4131 = tree_cons (NULL_TREE,
4132 add_objc_string (METHOD_ENCODING (entries),
4137 = tree_cons (NULL_TREE,
4138 objc_build_constructor (type, nreverse (eltlist)),
4141 entries = TREE_CHAIN (entries);
4145 return objc_build_constructor (build_array_type (type, 0),
4146 nreverse (initlist));
4149 /* struct objc_method_prototype_list {
4151 struct objc_method_prototype {
4158 build_method_prototype_list_template (tree list_type, int size)
4160 tree objc_ivar_list_record;
4161 tree field_decl, field_decl_chain;
4163 /* Generate an unnamed struct definition. */
4165 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4167 /* int method_count; */
4168 field_decl = create_field_decl (integer_type_node, "method_count");
4169 field_decl_chain = field_decl;
4171 /* struct objc_method method_list[]; */
4172 field_decl = create_field_decl (build_array_type
4175 (build_int_cst (NULL_TREE, size - 1))),
4177 chainon (field_decl_chain, field_decl);
4179 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4181 return objc_ivar_list_record;
4185 build_method_prototype_template (void)
4188 tree field_decl, field_decl_chain;
4191 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4194 field_decl = create_field_decl (objc_selector_type, "_cmd");
4195 field_decl_chain = field_decl;
4197 /* char *method_types; */
4198 field_decl = create_field_decl (string_type_node, "method_types");
4199 chainon (field_decl_chain, field_decl);
4201 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4203 return proto_record;
4207 objc_method_parm_type (tree type)
4209 type = TREE_VALUE (TREE_TYPE (type));
4210 if (TREE_CODE (type) == TYPE_DECL)
4211 type = TREE_TYPE (type);
4216 objc_encoded_type_size (tree type)
4218 int sz = int_size_in_bytes (type);
4220 /* Make all integer and enum types at least as large
4222 if (sz > 0 && INTEGRAL_TYPE_P (type))
4223 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4224 /* Treat arrays as pointers, since that's how they're
4226 else if (TREE_CODE (type) == ARRAY_TYPE)
4227 sz = int_size_in_bytes (ptr_type_node);
4232 encode_method_prototype (tree method_decl)
4239 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4240 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4242 /* Encode return type. */
4243 encode_type (objc_method_parm_type (method_decl),
4244 obstack_object_size (&util_obstack),
4245 OBJC_ENCODE_INLINE_DEFS);
4248 /* The first two arguments (self and _cmd) are pointers; account for
4250 i = int_size_in_bytes (ptr_type_node);
4251 parm_offset = 2 * i;
4252 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4253 parms = TREE_CHAIN (parms))
4255 tree type = objc_method_parm_type (parms);
4256 int sz = objc_encoded_type_size (type);
4258 /* If a type size is not known, bail out. */
4261 error ("%Jtype '%D' does not have a known size",
4263 /* Pretend that the encoding succeeded; the compilation will
4264 fail nevertheless. */
4265 goto finish_encoding;
4270 sprintf (buf, "%d@0:%d", parm_offset, i);
4271 obstack_grow (&util_obstack, buf, strlen (buf));
4273 /* Argument types. */
4274 parm_offset = 2 * i;
4275 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4276 parms = TREE_CHAIN (parms))
4278 tree type = objc_method_parm_type (parms);
4280 /* Process argument qualifiers for user supplied arguments. */
4281 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4284 encode_type (type, obstack_object_size (&util_obstack),
4285 OBJC_ENCODE_INLINE_DEFS);
4287 /* Compute offset. */
4288 sprintf (buf, "%d", parm_offset);
4289 parm_offset += objc_encoded_type_size (type);
4291 obstack_grow (&util_obstack, buf, strlen (buf));
4295 obstack_1grow (&util_obstack, '\0');
4296 result = get_identifier (obstack_finish (&util_obstack));
4297 obstack_free (&util_obstack, util_firstobj);
4302 generate_descriptor_table (tree type, const char *name, int size, tree list,
4305 tree decl, initlist;
4307 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4309 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4310 initlist = tree_cons (NULL_TREE, list, initlist);
4312 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4318 generate_method_descriptors (tree protocol)
4320 tree initlist, chain, method_list_template;
4323 if (!objc_method_prototype_template)
4324 objc_method_prototype_template = build_method_prototype_template ();
4326 chain = PROTOCOL_CLS_METHODS (protocol);
4329 size = list_length (chain);
4331 method_list_template
4332 = build_method_prototype_list_template (objc_method_prototype_template,
4336 = build_descriptor_table_initializer (objc_method_prototype_template,
4339 UOBJC_CLASS_METHODS_decl
4340 = generate_descriptor_table (method_list_template,
4341 "_OBJC_PROTOCOL_CLASS_METHODS",
4342 size, initlist, protocol);
4345 UOBJC_CLASS_METHODS_decl = 0;
4347 chain = PROTOCOL_NST_METHODS (protocol);
4350 size = list_length (chain);
4352 method_list_template
4353 = build_method_prototype_list_template (objc_method_prototype_template,
4356 = build_descriptor_table_initializer (objc_method_prototype_template,
4359 UOBJC_INSTANCE_METHODS_decl
4360 = generate_descriptor_table (method_list_template,
4361 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4362 size, initlist, protocol);
4365 UOBJC_INSTANCE_METHODS_decl = 0;
4369 generate_protocol_references (tree plist)
4373 /* Forward declare protocols referenced. */
4374 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4376 tree proto = TREE_VALUE (lproto);
4378 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4379 && PROTOCOL_NAME (proto))
4381 if (! PROTOCOL_FORWARD_DECL (proto))
4382 build_protocol_reference (proto);
4384 if (PROTOCOL_LIST (proto))
4385 generate_protocol_references (PROTOCOL_LIST (proto));
4390 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4394 objc_generate_cxx_ctor_or_dtor (bool dtor)
4396 tree fn, body, compound_stmt, ivar;
4398 /* - (id) .cxx_construct { ... return self; } */
4399 /* - (void) .cxx_construct { ... } */
4401 objc_set_method_type (MINUS_EXPR);
4402 objc_start_method_definition
4403 (objc_build_method_signature (build_tree_list (NULL_TREE,
4406 : objc_object_type),
4407 get_identifier (dtor
4409 : TAG_CXX_CONSTRUCT),
4410 make_node (TREE_LIST),
4412 body = begin_function_body ();
4413 compound_stmt = begin_compound_stmt (0);
4415 ivar = CLASS_IVARS (implementation_template);
4416 /* Destroy ivars in reverse order. */
4418 ivar = nreverse (copy_list (ivar));
4420 for (; ivar; ivar = TREE_CHAIN (ivar))
4422 if (TREE_CODE (ivar) == FIELD_DECL)
4424 tree type = TREE_TYPE (ivar);
4426 /* Call the ivar's default constructor or destructor. Do not
4427 call the destructor unless a corresponding constructor call
4428 has also been made (or is not needed). */
4429 if (IS_AGGR_TYPE (type)
4431 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4432 && (!TYPE_NEEDS_CONSTRUCTING (type)
4433 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4434 : (TYPE_NEEDS_CONSTRUCTING (type)
4435 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4437 (build_special_member_call
4438 (build_ivar_reference (DECL_NAME (ivar)),
4439 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4440 NULL_TREE, type, LOOKUP_NORMAL));
4444 /* The constructor returns 'self'. */
4446 finish_return_stmt (self_decl);
4448 finish_compound_stmt (compound_stmt);
4449 finish_function_body (body);
4450 fn = current_function_decl;
4452 objc_finish_method_definition (fn);
4455 /* The following routine will examine the current @interface for any
4456 non-POD C++ ivars requiring non-trivial construction and/or
4457 destruction, and then synthesize special '- .cxx_construct' and/or
4458 '- .cxx_destruct' methods which will run the appropriate
4459 construction or destruction code. Note that ivars inherited from
4460 super-classes are _not_ considered. */
4462 objc_generate_cxx_cdtors (void)
4464 bool need_ctor = false, need_dtor = false;
4467 /* We do not want to do this for categories, since they do not have
4470 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4473 /* First, determine if we even need a constructor and/or destructor. */
4475 for (ivar = CLASS_IVARS (implementation_template); ivar;
4476 ivar = TREE_CHAIN (ivar))
4478 if (TREE_CODE (ivar) == FIELD_DECL)
4480 tree type = TREE_TYPE (ivar);
4482 if (IS_AGGR_TYPE (type))
4484 if (TYPE_NEEDS_CONSTRUCTING (type)
4485 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4486 /* NB: If a default constructor is not available, we will not
4487 be able to initialize this ivar; the add_instance_variable()
4488 routine will already have warned about this. */
4491 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4492 && (!TYPE_NEEDS_CONSTRUCTING (type)
4493 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4494 /* NB: If a default constructor is not available, we will not
4495 call the destructor either, for symmetry. */
4501 /* Generate '- .cxx_construct' if needed. */
4504 objc_generate_cxx_ctor_or_dtor (false);
4506 /* Generate '- .cxx_destruct' if needed. */
4509 objc_generate_cxx_ctor_or_dtor (true);
4511 /* The 'imp_list' variable points at an imp_entry record for the current
4512 @implementation. Record the existence of '- .cxx_construct' and/or
4513 '- .cxx_destruct' methods therein; it will be included in the
4514 metadata for the class. */
4515 if (flag_next_runtime)
4516 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4520 /* For each protocol which was referenced either from a @protocol()
4521 expression, or because a class/category implements it (then a
4522 pointer to the protocol is stored in the struct describing the
4523 class/category), we create a statically allocated instance of the
4524 Protocol class. The code is written in such a way as to generate
4525 as few Protocol objects as possible; we generate a unique Protocol
4526 instance for each protocol, and we don't generate a Protocol
4527 instance if the protocol is never referenced (either from a
4528 @protocol() or from a class/category implementation). These
4529 statically allocated objects can be referred to via the static
4530 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4532 The statically allocated Protocol objects that we generate here
4533 need to be fixed up at runtime in order to be used: the 'isa'
4534 pointer of the objects need to be set up to point to the 'Protocol'
4535 class, as known at runtime.
4537 The NeXT runtime fixes up all protocols at program startup time,
4538 before main() is entered. It uses a low-level trick to look up all
4539 those symbols, then loops on them and fixes them up.
4541 The GNU runtime as well fixes up all protocols before user code
4542 from the module is executed; it requires pointers to those symbols
4543 to be put in the objc_symtab (which is then passed as argument to
4544 the function __objc_exec_class() which the compiler sets up to be
4545 executed automatically when the module is loaded); setup of those
4546 Protocol objects happen in two ways in the GNU runtime: all
4547 Protocol objects referred to by a class or category implementation
4548 are fixed up when the class/category is loaded; all Protocol
4549 objects referred to by a @protocol() expression are added by the
4550 compiler to the list of statically allocated instances to fixup
4551 (the same list holding the statically allocated constant string
4552 objects). Because, as explained above, the compiler generates as
4553 few Protocol objects as possible, some Protocol object might end up
4554 being referenced multiple times when compiled with the GNU runtime,
4555 and end up being fixed up multiple times at runtime initialization.
4556 But that doesn't hurt, it's just a little inefficient. */
4559 generate_protocols (void)
4563 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4565 /* If a protocol was directly referenced, pull in indirect references. */
4566 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4567 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4568 generate_protocol_references (PROTOCOL_LIST (p));
4570 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4572 tree nst_methods = PROTOCOL_NST_METHODS (p);
4573 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4575 /* If protocol wasn't referenced, don't generate any code. */
4576 decl = PROTOCOL_FORWARD_DECL (p);
4581 /* Make sure we link in the Protocol class. */
4582 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4586 if (! METHOD_ENCODING (nst_methods))
4588 encoding = encode_method_prototype (nst_methods);
4589 METHOD_ENCODING (nst_methods) = encoding;
4591 nst_methods = TREE_CHAIN (nst_methods);
4596 if (! METHOD_ENCODING (cls_methods))
4598 encoding = encode_method_prototype (cls_methods);
4599 METHOD_ENCODING (cls_methods) = encoding;
4602 cls_methods = TREE_CHAIN (cls_methods);
4604 generate_method_descriptors (p);
4606 if (PROTOCOL_LIST (p))
4607 refs_decl = generate_protocol_list (p);
4611 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4612 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4615 refs_expr = convert (build_pointer_type (build_pointer_type
4616 (objc_protocol_template)),
4617 build_unary_op (ADDR_EXPR, refs_decl, 0));
4619 refs_expr = build_int_cst (NULL_TREE, 0);
4621 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4622 by generate_method_descriptors, which is called above. */
4623 initlist = build_protocol_initializer (TREE_TYPE (decl),
4624 protocol_name_expr, refs_expr,
4625 UOBJC_INSTANCE_METHODS_decl,
4626 UOBJC_CLASS_METHODS_decl);
4627 finish_var_decl (decl, initlist);
4632 build_protocol_initializer (tree type, tree protocol_name,
4633 tree protocol_list, tree instance_methods,
4636 tree initlist = NULL_TREE, expr;
4637 tree cast_type = build_pointer_type
4638 (xref_tag (RECORD_TYPE,
4639 get_identifier (UTAG_CLASS)));
4641 /* Filling the "isa" in with one allows the runtime system to
4642 detect that the version change...should remove before final release. */
4644 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4645 initlist = tree_cons (NULL_TREE, expr, initlist);
4646 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4647 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4649 if (!instance_methods)
4650 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4653 expr = convert (objc_method_proto_list_ptr,
4654 build_unary_op (ADDR_EXPR, instance_methods, 0));
4655 initlist = tree_cons (NULL_TREE, expr, initlist);
4659 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4662 expr = convert (objc_method_proto_list_ptr,
4663 build_unary_op (ADDR_EXPR, class_methods, 0));
4664 initlist = tree_cons (NULL_TREE, expr, initlist);
4667 return objc_build_constructor (type, nreverse (initlist));
4670 /* struct _objc_category {
4671 char *category_name;
4673 struct _objc_method_list *instance_methods;
4674 struct _objc_method_list *class_methods;
4675 struct _objc_protocol_list *protocols;
4679 build_category_template (void)
4681 tree field_decl, field_decl_chain;
4683 objc_category_template = start_struct (RECORD_TYPE,
4684 get_identifier (UTAG_CATEGORY));
4686 /* char *category_name; */
4687 field_decl = create_field_decl (string_type_node, "category_name");
4688 field_decl_chain = field_decl;
4690 /* char *class_name; */
4691 field_decl = create_field_decl (string_type_node, "class_name");
4692 chainon (field_decl_chain, field_decl);
4694 /* struct _objc_method_list *instance_methods; */
4695 field_decl = create_field_decl (objc_method_list_ptr,
4696 "instance_methods");
4697 chainon (field_decl_chain, field_decl);
4699 /* struct _objc_method_list *class_methods; */
4700 field_decl = create_field_decl (objc_method_list_ptr,
4702 chainon (field_decl_chain, field_decl);
4704 /* struct _objc_protocol **protocol_list; */
4705 field_decl = create_field_decl (build_pointer_type
4707 (objc_protocol_template)),
4709 chainon (field_decl_chain, field_decl);
4711 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4714 /* struct _objc_selector {
4720 build_selector_template (void)
4723 tree field_decl, field_decl_chain;
4725 objc_selector_template
4726 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4729 field_decl = create_field_decl (objc_selector_type, "sel_id");
4730 field_decl_chain = field_decl;
4732 /* char *sel_type; */
4733 field_decl = create_field_decl (string_type_node, "sel_type");
4734 chainon (field_decl_chain, field_decl);
4736 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4739 /* struct _objc_class {
4740 struct _objc_class *isa;
4741 struct _objc_class *super_class;
4746 struct _objc_ivar_list *ivars;
4747 struct _objc_method_list *methods;
4748 #ifdef __NEXT_RUNTIME__
4749 struct objc_cache *cache;
4751 struct sarray *dtable;
4752 struct _objc_class *subclass_list;
4753 struct _objc_class *sibling_class;
4755 struct _objc_protocol_list *protocols;
4756 #ifdef __NEXT_RUNTIME__
4759 void *gc_object_type;
4762 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4763 the NeXT/Apple runtime; still, the compiler must generate them to
4764 maintain backward binary compatibility (and to allow for future
4768 build_class_template (void)
4770 tree field_decl, field_decl_chain;
4773 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4775 /* struct _objc_class *isa; */
4776 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4778 field_decl_chain = field_decl;
4780 /* struct _objc_class *super_class; */
4781 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4783 chainon (field_decl_chain, field_decl);
4786 field_decl = create_field_decl (string_type_node, "name");
4787 chainon (field_decl_chain, field_decl);
4790 field_decl = create_field_decl (long_integer_type_node, "version");
4791 chainon (field_decl_chain, field_decl);
4794 field_decl = create_field_decl (long_integer_type_node, "info");
4795 chainon (field_decl_chain, field_decl);
4797 /* long instance_size; */
4798 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4799 chainon (field_decl_chain, field_decl);
4801 /* struct _objc_ivar_list *ivars; */
4802 field_decl = create_field_decl (objc_ivar_list_ptr,
4804 chainon (field_decl_chain, field_decl);
4806 /* struct _objc_method_list *methods; */
4807 field_decl = create_field_decl (objc_method_list_ptr,
4809 chainon (field_decl_chain, field_decl);
4811 if (flag_next_runtime)
4813 /* struct objc_cache *cache; */
4814 field_decl = create_field_decl (build_pointer_type
4815 (xref_tag (RECORD_TYPE,
4819 chainon (field_decl_chain, field_decl);
4823 /* struct sarray *dtable; */
4824 field_decl = create_field_decl (build_pointer_type
4825 (xref_tag (RECORD_TYPE,
4829 chainon (field_decl_chain, field_decl);
4831 /* struct objc_class *subclass_list; */
4832 field_decl = create_field_decl (build_pointer_type
4833 (objc_class_template),
4835 chainon (field_decl_chain, field_decl);
4837 /* struct objc_class *sibling_class; */
4838 field_decl = create_field_decl (build_pointer_type
4839 (objc_class_template),
4841 chainon (field_decl_chain, field_decl);
4844 /* struct _objc_protocol **protocol_list; */
4845 field_decl = create_field_decl (build_pointer_type
4847 (xref_tag (RECORD_TYPE,
4851 chainon (field_decl_chain, field_decl);
4853 if (flag_next_runtime)
4856 field_decl = create_field_decl (build_pointer_type (void_type_node),
4858 chainon (field_decl_chain, field_decl);
4861 /* void *gc_object_type; */
4862 field_decl = create_field_decl (build_pointer_type (void_type_node),
4864 chainon (field_decl_chain, field_decl);
4866 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4869 /* Generate appropriate forward declarations for an implementation. */
4872 synth_forward_declarations (void)
4876 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4877 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4878 objc_class_template);
4880 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4881 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4882 objc_class_template);
4884 /* Pre-build the following entities - for speed/convenience. */
4886 an_id = get_identifier ("super_class");
4887 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4888 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4892 error_with_ivar (const char *message, tree decl)
4894 error ("%J%s %qs", decl,
4895 message, gen_declaration (decl));
4900 check_ivars (tree inter, tree imp)
4902 tree intdecls = CLASS_RAW_IVARS (inter);
4903 tree impdecls = CLASS_RAW_IVARS (imp);
4910 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4911 intdecls = TREE_CHAIN (intdecls);
4913 if (intdecls == 0 && impdecls == 0)
4915 if (intdecls == 0 || impdecls == 0)
4917 error ("inconsistent instance variable specification");
4921 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4923 if (!comptypes (t1, t2)
4924 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4925 DECL_INITIAL (impdecls)))
4927 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4929 error_with_ivar ("conflicting instance variable type",
4931 error_with_ivar ("previous declaration of",
4934 else /* both the type and the name don't match */
4936 error ("inconsistent instance variable specification");
4941 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4943 error_with_ivar ("conflicting instance variable name",
4945 error_with_ivar ("previous declaration of",
4949 intdecls = TREE_CHAIN (intdecls);
4950 impdecls = TREE_CHAIN (impdecls);
4954 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4955 This needs to be done just once per compilation. */
4957 /* struct _objc_super {
4958 struct _objc_object *self;
4959 struct _objc_class *super_class;
4963 build_super_template (void)
4965 tree field_decl, field_decl_chain;
4967 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4969 /* struct _objc_object *self; */
4970 field_decl = create_field_decl (objc_object_type, "self");
4971 field_decl_chain = field_decl;
4973 /* struct _objc_class *super_class; */
4974 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4976 chainon (field_decl_chain, field_decl);
4978 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4981 /* struct _objc_ivar {
4988 build_ivar_template (void)
4990 tree objc_ivar_id, objc_ivar_record;
4991 tree field_decl, field_decl_chain;
4993 objc_ivar_id = get_identifier (UTAG_IVAR);
4994 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4996 /* char *ivar_name; */
4997 field_decl = create_field_decl (string_type_node, "ivar_name");
4998 field_decl_chain = field_decl;
5000 /* char *ivar_type; */
5001 field_decl = create_field_decl (string_type_node, "ivar_type");
5002 chainon (field_decl_chain, field_decl);
5004 /* int ivar_offset; */
5005 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5006 chainon (field_decl_chain, field_decl);
5008 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5010 return objc_ivar_record;
5015 struct objc_ivar ivar_list[ivar_count];
5019 build_ivar_list_template (tree list_type, int size)
5021 tree objc_ivar_list_record;
5022 tree field_decl, field_decl_chain;
5024 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5026 /* int ivar_count; */
5027 field_decl = create_field_decl (integer_type_node, "ivar_count");
5028 field_decl_chain = field_decl;
5030 /* struct objc_ivar ivar_list[]; */
5031 field_decl = create_field_decl (build_array_type
5034 (build_int_cst (NULL_TREE, size - 1))),
5036 chainon (field_decl_chain, field_decl);
5038 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5040 return objc_ivar_list_record;
5044 struct _objc__method_prototype_list *method_next;
5046 struct objc_method method_list[method_count];
5050 build_method_list_template (tree list_type, int size)
5052 tree objc_ivar_list_record;
5053 tree field_decl, field_decl_chain;
5055 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5057 /* struct _objc__method_prototype_list *method_next; */
5058 field_decl = create_field_decl (objc_method_proto_list_ptr,
5060 field_decl_chain = field_decl;
5062 /* int method_count; */
5063 field_decl = create_field_decl (integer_type_node, "method_count");
5064 chainon (field_decl_chain, field_decl);
5066 /* struct objc_method method_list[]; */
5067 field_decl = create_field_decl (build_array_type
5070 (build_int_cst (NULL_TREE, size - 1))),
5072 chainon (field_decl_chain, field_decl);
5074 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5076 return objc_ivar_list_record;
5080 build_ivar_list_initializer (tree type, tree field_decl)
5082 tree initlist = NULL_TREE;
5086 tree ivar = NULL_TREE;
5089 if (DECL_NAME (field_decl))
5090 ivar = tree_cons (NULL_TREE,
5091 add_objc_string (DECL_NAME (field_decl),
5095 /* Unnamed bit-field ivar (yuck). */
5096 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5099 encode_field_decl (field_decl,
5100 obstack_object_size (&util_obstack),
5101 OBJC_ENCODE_DONT_INLINE_DEFS);
5103 /* Null terminate string. */
5104 obstack_1grow (&util_obstack, 0);
5108 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5111 obstack_free (&util_obstack, util_firstobj);
5114 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5115 initlist = tree_cons (NULL_TREE,
5116 objc_build_constructor (type, nreverse (ivar)),
5119 field_decl = TREE_CHAIN (field_decl);
5120 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5124 return objc_build_constructor (build_array_type (type, 0),
5125 nreverse (initlist));
5129 generate_ivars_list (tree type, const char *name, int size, tree list)
5131 tree decl, initlist;
5133 decl = start_var_decl (type, synth_id_with_class_suffix
5134 (name, objc_implementation_context));
5136 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5137 initlist = tree_cons (NULL_TREE, list, initlist);
5139 finish_var_decl (decl,
5140 objc_build_constructor (TREE_TYPE (decl),
5141 nreverse (initlist)));
5146 /* Count only the fields occurring in T. */
5148 ivar_list_length (tree t)
5152 for (; t; t = TREE_CHAIN (t))
5153 if (TREE_CODE (t) == FIELD_DECL)
5160 generate_ivar_lists (void)
5162 tree initlist, ivar_list_template, chain;
5165 generating_instance_variables = 1;
5167 if (!objc_ivar_template)
5168 objc_ivar_template = build_ivar_template ();
5170 /* Only generate class variables for the root of the inheritance
5171 hierarchy since these will be the same for every class. */
5173 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5174 && (chain = TYPE_FIELDS (objc_class_template)))
5176 size = ivar_list_length (chain);
5178 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5179 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5181 UOBJC_CLASS_VARIABLES_decl
5182 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5186 UOBJC_CLASS_VARIABLES_decl = 0;
5188 chain = CLASS_IVARS (implementation_template);
5191 size = ivar_list_length (chain);
5192 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5193 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5195 UOBJC_INSTANCE_VARIABLES_decl
5196 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5200 UOBJC_INSTANCE_VARIABLES_decl = 0;
5202 generating_instance_variables = 0;
5206 build_dispatch_table_initializer (tree type, tree entries)
5208 tree initlist = NULL_TREE;
5212 tree elemlist = NULL_TREE;
5214 elemlist = tree_cons (NULL_TREE,
5215 build_selector (METHOD_SEL_NAME (entries)),
5218 /* Generate the method encoding if we don't have one already. */
5219 if (! METHOD_ENCODING (entries))
5220 METHOD_ENCODING (entries) =
5221 encode_method_prototype (entries);
5223 elemlist = tree_cons (NULL_TREE,
5224 add_objc_string (METHOD_ENCODING (entries),
5229 = tree_cons (NULL_TREE,
5230 convert (ptr_type_node,
5231 build_unary_op (ADDR_EXPR,
5232 METHOD_DEFINITION (entries), 1)),
5235 initlist = tree_cons (NULL_TREE,
5236 objc_build_constructor (type, nreverse (elemlist)),
5239 entries = TREE_CHAIN (entries);
5243 return objc_build_constructor (build_array_type (type, 0),
5244 nreverse (initlist));
5247 /* To accomplish method prototyping without generating all kinds of
5248 inane warnings, the definition of the dispatch table entries were
5251 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5253 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5256 build_method_template (void)
5259 tree field_decl, field_decl_chain;
5261 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5264 field_decl = create_field_decl (objc_selector_type, "_cmd");
5265 field_decl_chain = field_decl;
5267 /* char *method_types; */
5268 field_decl = create_field_decl (string_type_node, "method_types");
5269 chainon (field_decl_chain, field_decl);
5272 field_decl = create_field_decl (build_pointer_type (void_type_node),
5274 chainon (field_decl_chain, field_decl);
5276 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5283 generate_dispatch_table (tree type, const char *name, int size, tree list)
5285 tree decl, initlist;
5287 decl = start_var_decl (type, synth_id_with_class_suffix
5288 (name, objc_implementation_context));
5290 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5291 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5292 initlist = tree_cons (NULL_TREE, list, initlist);
5294 finish_var_decl (decl,
5295 objc_build_constructor (TREE_TYPE (decl),
5296 nreverse (initlist)));
5302 mark_referenced_methods (void)
5304 struct imp_entry *impent;
5307 for (impent = imp_list; impent; impent = impent->next)
5309 chain = CLASS_CLS_METHODS (impent->imp_context);
5312 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5313 chain = TREE_CHAIN (chain);
5316 chain = CLASS_NST_METHODS (impent->imp_context);
5319 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5320 chain = TREE_CHAIN (chain);
5326 generate_dispatch_tables (void)
5328 tree initlist, chain, method_list_template;
5331 if (!objc_method_template)
5332 objc_method_template = build_method_template ();
5334 chain = CLASS_CLS_METHODS (objc_implementation_context);
5337 size = list_length (chain);
5339 method_list_template
5340 = build_method_list_template (objc_method_template, size);
5342 = build_dispatch_table_initializer (objc_method_template, chain);
5344 UOBJC_CLASS_METHODS_decl
5345 = generate_dispatch_table (method_list_template,
5346 ((TREE_CODE (objc_implementation_context)
5347 == CLASS_IMPLEMENTATION_TYPE)
5348 ? "_OBJC_CLASS_METHODS"
5349 : "_OBJC_CATEGORY_CLASS_METHODS"),
5353 UOBJC_CLASS_METHODS_decl = 0;
5355 chain = CLASS_NST_METHODS (objc_implementation_context);
5358 size = list_length (chain);
5360 method_list_template
5361 = build_method_list_template (objc_method_template, size);
5363 = build_dispatch_table_initializer (objc_method_template, chain);
5365 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5366 UOBJC_INSTANCE_METHODS_decl
5367 = generate_dispatch_table (method_list_template,
5368 "_OBJC_INSTANCE_METHODS",
5371 /* We have a category. */
5372 UOBJC_INSTANCE_METHODS_decl
5373 = generate_dispatch_table (method_list_template,
5374 "_OBJC_CATEGORY_INSTANCE_METHODS",
5378 UOBJC_INSTANCE_METHODS_decl = 0;
5382 generate_protocol_list (tree i_or_p)
5385 tree refs_decl, lproto, e, plist;
5387 const char *ref_name;
5389 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5390 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5391 plist = CLASS_PROTOCOL_LIST (i_or_p);
5392 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5393 plist = PROTOCOL_LIST (i_or_p);
5398 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5399 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5400 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5403 /* Build initializer. */
5404 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5405 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5406 initlist = tree_cons (NULL_TREE, e, initlist);
5408 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5410 tree pval = TREE_VALUE (lproto);
5412 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5413 && PROTOCOL_FORWARD_DECL (pval))
5415 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5416 initlist = tree_cons (NULL_TREE, e, initlist);
5420 /* static struct objc_protocol *refs[n]; */
5422 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5423 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5424 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5425 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5426 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5427 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5431 refs_decl = start_var_decl
5433 (build_pointer_type (objc_protocol_template),
5434 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5437 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5438 nreverse (initlist)));
5444 build_category_initializer (tree type, tree cat_name, tree class_name,
5445 tree instance_methods, tree class_methods,
5448 tree initlist = NULL_TREE, expr;
5450 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5451 initlist = tree_cons (NULL_TREE, class_name, initlist);
5453 if (!instance_methods)
5454 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5457 expr = convert (objc_method_list_ptr,
5458 build_unary_op (ADDR_EXPR, instance_methods, 0));
5459 initlist = tree_cons (NULL_TREE, expr, initlist);
5462 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5465 expr = convert (objc_method_list_ptr,
5466 build_unary_op (ADDR_EXPR, class_methods, 0));
5467 initlist = tree_cons (NULL_TREE, expr, initlist);
5470 /* protocol_list = */
5472 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5475 expr = convert (build_pointer_type
5477 (objc_protocol_template)),
5478 build_unary_op (ADDR_EXPR, protocol_list, 0));
5479 initlist = tree_cons (NULL_TREE, expr, initlist);
5482 return objc_build_constructor (type, nreverse (initlist));
5485 /* struct _objc_class {
5486 struct objc_class *isa;
5487 struct objc_class *super_class;
5492 struct objc_ivar_list *ivars;
5493 struct objc_method_list *methods;
5494 if (flag_next_runtime)
5495 struct objc_cache *cache;
5497 struct sarray *dtable;
5498 struct objc_class *subclass_list;
5499 struct objc_class *sibling_class;
5501 struct objc_protocol_list *protocols;
5502 if (flag_next_runtime)
5504 void *gc_object_type;
5508 build_shared_structure_initializer (tree type, tree isa, tree super,
5509 tree name, tree size, int status,
5510 tree dispatch_table, tree ivar_list,
5513 tree initlist = NULL_TREE, expr;
5516 initlist = tree_cons (NULL_TREE, isa, initlist);
5519 initlist = tree_cons (NULL_TREE, super, initlist);
5522 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5525 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5529 initlist = tree_cons (NULL_TREE,
5530 build_int_cst (long_integer_type_node, status),
5533 /* instance_size = */
5534 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5537 /* objc_ivar_list = */
5539 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5542 expr = convert (objc_ivar_list_ptr,
5543 build_unary_op (ADDR_EXPR, ivar_list, 0));
5544 initlist = tree_cons (NULL_TREE, expr, initlist);
5547 /* objc_method_list = */
5548 if (!dispatch_table)
5549 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5552 expr = convert (objc_method_list_ptr,
5553 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5554 initlist = tree_cons (NULL_TREE, expr, initlist);
5557 if (flag_next_runtime)
5558 /* method_cache = */
5559 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5563 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5565 /* subclass_list = */
5566 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5568 /* sibling_class = */
5569 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5572 /* protocol_list = */
5573 if (! protocol_list)
5574 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5577 expr = convert (build_pointer_type
5579 (objc_protocol_template)),
5580 build_unary_op (ADDR_EXPR, protocol_list, 0));
5581 initlist = tree_cons (NULL_TREE, expr, initlist);
5584 if (flag_next_runtime)
5586 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5588 /* gc_object_type = NULL */
5589 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5591 return objc_build_constructor (type, nreverse (initlist));
5594 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5597 lookup_category (tree class, tree cat_name)
5599 tree category = CLASS_CATEGORY_LIST (class);
5601 while (category && CLASS_SUPER_NAME (category) != cat_name)
5602 category = CLASS_CATEGORY_LIST (category);
5606 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5609 generate_category (tree cat)
5612 tree initlist, cat_name_expr, class_name_expr;
5613 tree protocol_decl, category;
5615 add_class_reference (CLASS_NAME (cat));
5616 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5618 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5620 category = lookup_category (implementation_template,
5621 CLASS_SUPER_NAME (cat));
5623 if (category && CLASS_PROTOCOL_LIST (category))
5625 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5626 protocol_decl = generate_protocol_list (category);
5631 decl = start_var_decl (objc_category_template,
5632 synth_id_with_class_suffix
5633 ("_OBJC_CATEGORY", objc_implementation_context));
5635 initlist = build_category_initializer (TREE_TYPE (decl),
5636 cat_name_expr, class_name_expr,
5637 UOBJC_INSTANCE_METHODS_decl,
5638 UOBJC_CLASS_METHODS_decl,
5641 finish_var_decl (decl, initlist);
5644 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5645 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5648 generate_shared_structures (int cls_flags)
5650 tree sc_spec, decl_specs, decl;
5651 tree name_expr, super_expr, root_expr;
5652 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5653 tree cast_type, initlist, protocol_decl;
5655 my_super_id = CLASS_SUPER_NAME (implementation_template);
5658 add_class_reference (my_super_id);
5660 /* Compute "my_root_id" - this is required for code generation.
5661 the "isa" for all meta class structures points to the root of
5662 the inheritance hierarchy (e.g. "__Object")... */
5663 my_root_id = my_super_id;
5666 tree my_root_int = lookup_interface (my_root_id);
5668 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5669 my_root_id = CLASS_SUPER_NAME (my_root_int);
5676 /* No super class. */
5677 my_root_id = CLASS_NAME (implementation_template);
5679 cast_type = build_pointer_type (objc_class_template);
5680 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5683 /* Install class `isa' and `super' pointers at runtime. */
5686 super_expr = add_objc_string (my_super_id, class_names);
5687 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5690 super_expr = build_int_cst (NULL_TREE, 0);
5692 root_expr = add_objc_string (my_root_id, class_names);
5693 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5695 if (CLASS_PROTOCOL_LIST (implementation_template))
5697 generate_protocol_references
5698 (CLASS_PROTOCOL_LIST (implementation_template));
5699 protocol_decl = generate_protocol_list (implementation_template);
5704 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5706 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5707 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5709 decl = start_var_decl (objc_class_template,
5711 (DECL_NAME (UOBJC_METACLASS_decl)));
5714 = build_shared_structure_initializer
5716 root_expr, super_expr, name_expr,
5717 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5719 UOBJC_CLASS_METHODS_decl,
5720 UOBJC_CLASS_VARIABLES_decl,
5723 finish_var_decl (decl, initlist);
5725 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5727 decl = start_var_decl (objc_class_template,
5729 (DECL_NAME (UOBJC_CLASS_decl)));
5732 = build_shared_structure_initializer
5734 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5735 super_expr, name_expr,
5736 convert (integer_type_node,
5737 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5738 (implementation_template))),
5739 1 /*CLS_FACTORY*/ | cls_flags,
5740 UOBJC_INSTANCE_METHODS_decl,
5741 UOBJC_INSTANCE_VARIABLES_decl,
5744 finish_var_decl (decl, initlist);
5749 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5751 static char string[BUFSIZE];
5753 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5754 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5756 sprintf (string, "%s_%s", preamble,
5757 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5759 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5760 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5762 /* We have a category. */
5763 const char *const class_name
5764 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5765 const char *const class_super_name
5766 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5767 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5769 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5771 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5772 sprintf (string, "%s_%s", preamble, protocol_name);
5780 /* If type is empty or only type qualifiers are present, add default
5781 type of id (otherwise grokdeclarator will default to int). */
5784 adjust_type_for_id_default (tree type)
5787 type = make_node (TREE_LIST);
5789 if (!TREE_VALUE (type))
5790 TREE_VALUE (type) = objc_object_type;
5791 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5792 && TYPED_OBJECT (TREE_VALUE (type)))
5793 error ("can not use an object as parameter to a method");
5800 selector ':' '(' typename ')' identifier
5803 Transform an Objective-C keyword argument into
5804 the C equivalent parameter declarator.
5806 In: key_name, an "identifier_node" (optional).
5807 arg_type, a "tree_list" (optional).
5808 arg_name, an "identifier_node".
5810 Note: It would be really nice to strongly type the preceding
5811 arguments in the function prototype; however, then I
5812 could not use the "accessor" macros defined in "tree.h".
5814 Out: an instance of "keyword_decl". */
5817 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5821 /* If no type is specified, default to "id". */
5822 arg_type = adjust_type_for_id_default (arg_type);
5824 keyword_decl = make_node (KEYWORD_DECL);
5826 TREE_TYPE (keyword_decl) = arg_type;
5827 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5828 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5830 return keyword_decl;
5833 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5836 build_keyword_selector (tree selector)
5839 tree key_chain, key_name;
5842 /* Scan the selector to see how much space we'll need. */
5843 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5845 if (TREE_CODE (selector) == KEYWORD_DECL)
5846 key_name = KEYWORD_KEY_NAME (key_chain);
5847 else if (TREE_CODE (selector) == TREE_LIST)
5848 key_name = TREE_PURPOSE (key_chain);
5853 len += IDENTIFIER_LENGTH (key_name) + 1;
5855 /* Just a ':' arg. */
5859 buf = (char *) alloca (len + 1);
5860 /* Start the buffer out as an empty string. */
5863 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5865 if (TREE_CODE (selector) == KEYWORD_DECL)
5866 key_name = KEYWORD_KEY_NAME (key_chain);
5867 else if (TREE_CODE (selector) == TREE_LIST)
5869 key_name = TREE_PURPOSE (key_chain);
5870 /* The keyword decl chain will later be used as a function argument
5871 chain. Unhook the selector itself so as to not confuse other
5872 parts of the compiler. */
5873 TREE_PURPOSE (key_chain) = NULL_TREE;
5879 strcat (buf, IDENTIFIER_POINTER (key_name));
5883 return get_identifier (buf);
5886 /* Used for declarations and definitions. */
5889 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5890 tree add_args, bool ellipsis)
5894 /* If no type is specified, default to "id". */
5895 ret_type = adjust_type_for_id_default (ret_type);
5897 method_decl = make_node (code);
5898 TREE_TYPE (method_decl) = ret_type;
5900 /* If we have a keyword selector, create an identifier_node that
5901 represents the full selector name (`:' included)... */
5902 if (TREE_CODE (selector) == KEYWORD_DECL)
5904 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5905 METHOD_SEL_ARGS (method_decl) = selector;
5906 METHOD_ADD_ARGS (method_decl) = add_args;
5907 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5911 METHOD_SEL_NAME (method_decl) = selector;
5912 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5913 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5919 #define METHOD_DEF 0
5920 #define METHOD_REF 1
5922 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5923 an argument list for method METH. CONTEXT is either METHOD_DEF or
5924 METHOD_REF, saying whether we are trying to define a method or call
5925 one. SUPERFLAG says this is for a send to super; this makes a
5926 difference for the NeXT calling sequence in which the lookup and
5927 the method call are done together. If METH is null, user-defined
5928 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5931 get_arg_type_list (tree meth, int context, int superflag)
5935 /* Receiver type. */
5936 if (flag_next_runtime && superflag)
5937 arglist = build_tree_list (NULL_TREE, objc_super_type);
5938 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5939 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5941 arglist = build_tree_list (NULL_TREE, objc_object_type);
5943 /* Selector type - will eventually change to `int'. */
5944 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5946 /* No actual method prototype given -- assume that remaining arguments
5951 /* Build a list of argument types. */
5952 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5954 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5956 /* Decay arrays and functions into pointers. */
5957 if (TREE_CODE (arg_type) == ARRAY_TYPE)
5958 arg_type = build_pointer_type (TREE_TYPE (arg_type));
5959 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
5960 arg_type = build_pointer_type (arg_type);
5962 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5965 if (METHOD_ADD_ARGS (meth))
5967 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5968 akey; akey = TREE_CHAIN (akey))
5970 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5972 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5975 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
5976 goto lack_of_ellipsis;
5981 chainon (arglist, OBJC_VOID_AT_END);
5988 check_duplicates (hash hsh, int methods, int is_class)
5990 tree meth = NULL_TREE;
5998 /* We have two or more methods with the same name but
6002 /* But just how different are those types? If
6003 -Wno-strict-selector-match is specified, we shall not
6004 complain if the differences are solely among types with
6005 identical size and alignment. */
6006 if (!warn_strict_selector_match)
6008 for (loop = hsh->list; loop; loop = loop->next)
6009 if (!comp_proto_with_proto (meth, loop->value, 0))
6016 warning (0, "multiple %s named %<%c%s%> found",
6017 methods ? "methods" : "selectors",
6018 (is_class ? '+' : '-'),
6019 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6021 warn_with_method (methods ? "using" : "found",
6022 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6026 for (loop = hsh->list; loop; loop = loop->next)
6027 warn_with_method ("also found",
6028 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6037 /* If RECEIVER is a class reference, return the identifier node for
6038 the referenced class. RECEIVER is created by objc_get_class_reference,
6039 so we check the exact form created depending on which runtimes are
6043 receiver_is_class_object (tree receiver, int self, int super)
6045 tree chain, exp, arg;
6047 /* The receiver is 'self' or 'super' in the context of a class method. */
6048 if (objc_method_context
6049 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6052 ? CLASS_SUPER_NAME (implementation_template)
6053 : CLASS_NAME (implementation_template));
6055 if (flag_next_runtime)
6057 /* The receiver is a variable created by
6058 build_class_reference_decl. */
6059 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6060 /* Look up the identifier. */
6061 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6062 if (TREE_PURPOSE (chain) == receiver)
6063 return TREE_VALUE (chain);
6066 /* The receiver is a function call that returns an id. Check if
6067 it is a call to objc_getClass, if so, pick up the class name. */
6068 if (TREE_CODE (receiver) == CALL_EXPR
6069 && (exp = TREE_OPERAND (receiver, 0))
6070 && TREE_CODE (exp) == ADDR_EXPR
6071 && (exp = TREE_OPERAND (exp, 0))
6072 && TREE_CODE (exp) == FUNCTION_DECL
6073 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6074 prototypes for objc_get_class(). Thankfully, they seem to share the
6075 same function type. */
6076 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6077 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6078 /* We have a call to objc_get_class/objc_getClass! */
6079 && (arg = TREE_OPERAND (receiver, 1))
6080 && TREE_CODE (arg) == TREE_LIST
6081 && (arg = TREE_VALUE (arg)))
6084 if (TREE_CODE (arg) == ADDR_EXPR
6085 && (arg = TREE_OPERAND (arg, 0))
6086 && TREE_CODE (arg) == STRING_CST)
6087 /* Finally, we have the class name. */
6088 return get_identifier (TREE_STRING_POINTER (arg));
6093 /* If we are currently building a message expr, this holds
6094 the identifier of the selector of the message. This is
6095 used when printing warnings about argument mismatches. */
6097 static tree current_objc_message_selector = 0;
6100 objc_message_selector (void)
6102 return current_objc_message_selector;
6105 /* Construct an expression for sending a message.
6106 MESS has the object to send to in TREE_PURPOSE
6107 and the argument list (including selector) in TREE_VALUE.
6109 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6110 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6113 objc_build_message_expr (tree mess)
6115 tree receiver = TREE_PURPOSE (mess);
6118 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6120 tree args = TREE_VALUE (mess);
6122 tree method_params = NULL_TREE;
6124 if (TREE_CODE (receiver) == ERROR_MARK)
6125 return error_mark_node;
6127 /* Obtain the full selector name. */
6128 if (TREE_CODE (args) == IDENTIFIER_NODE)
6129 /* A unary selector. */
6131 else if (TREE_CODE (args) == TREE_LIST)
6132 sel_name = build_keyword_selector (args);
6136 /* Build the parameter list to give to the method. */
6137 if (TREE_CODE (args) == TREE_LIST)
6139 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6142 tree chain = args, prev = NULL_TREE;
6144 /* We have a keyword selector--check for comma expressions. */
6147 tree element = TREE_VALUE (chain);
6149 /* We have a comma expression, must collapse... */
6150 if (TREE_CODE (element) == TREE_LIST)
6153 TREE_CHAIN (prev) = element;
6158 chain = TREE_CHAIN (chain);
6160 method_params = args;
6165 if (processing_template_decl)
6166 /* Must wait until template instantiation time. */
6167 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6171 return objc_finish_message_expr (receiver, sel_name, method_params);
6174 /* Look up method SEL_NAME that would be suitable for receiver
6175 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6176 nonzero), and report on any duplicates. */
6179 lookup_method_in_hash_lists (tree sel_name, int is_class)
6181 hash method_prototype = NULL;
6184 method_prototype = hash_lookup (nst_method_hash_list,
6187 if (!method_prototype)
6189 method_prototype = hash_lookup (cls_method_hash_list,
6194 return check_duplicates (method_prototype, 1, is_class);
6197 /* The 'objc_finish_message_expr' routine is called from within
6198 'objc_build_message_expr' for non-template functions. In the case of
6199 C++ template functions, it is called from 'build_expr_from_tree'
6200 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6203 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6205 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6206 tree selector, retval, class_tree;
6207 int self, super, have_cast;
6209 /* Extract the receiver of the message, as well as its type
6210 (where the latter may take the form of a cast or be inferred
6211 from the implementation context). */
6213 while (TREE_CODE (rtype) == COMPOUND_EXPR
6214 || TREE_CODE (rtype) == MODIFY_EXPR
6215 || TREE_CODE (rtype) == NOP_EXPR
6216 || TREE_CODE (rtype) == CONVERT_EXPR
6217 || TREE_CODE (rtype) == COMPONENT_REF)
6218 rtype = TREE_OPERAND (rtype, 0);
6219 self = (rtype == self_decl);
6220 super = (rtype == UOBJC_SUPER_decl);
6221 rtype = TREE_TYPE (receiver);
6222 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6223 || (TREE_CODE (receiver) == COMPOUND_EXPR
6224 && !IS_SUPER (rtype)));
6226 /* If we are calling [super dealloc], reset our warning flag. */
6227 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6228 should_call_super_dealloc = 0;
6230 /* If the receiver is a class object, retrieve the corresponding
6231 @interface, if one exists. */
6232 class_tree = receiver_is_class_object (receiver, self, super);
6234 /* Now determine the receiver type (if an explicit cast has not been
6239 rtype = lookup_interface (class_tree);
6240 /* Handle `self' and `super'. */
6243 if (!CLASS_SUPER_NAME (implementation_template))
6245 error ("no super class declared in @interface for %qs",
6246 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6247 return error_mark_node;
6249 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6252 rtype = lookup_interface (CLASS_NAME (implementation_template));
6255 /* If receiver is of type `id' or `Class' (or if the @interface for a
6256 class is not visible), we shall be satisfied with the existence of
6257 any instance or class method. */
6258 if (objc_is_id (rtype))
6260 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6261 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6262 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6268 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6269 in protocols themselves for the method prototype. */
6271 = lookup_method_in_protocol_list (rprotos, sel_name,
6272 class_tree != NULL_TREE);
6274 /* If messaging 'Class <Proto>' but did not find a class method
6275 prototype, search for an instance method instead, and warn
6276 about having done so. */
6277 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6280 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6282 if (method_prototype)
6283 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6284 IDENTIFIER_POINTER (sel_name),
6285 IDENTIFIER_POINTER (sel_name));
6291 tree orig_rtype = rtype, saved_rtype;
6293 if (TREE_CODE (rtype) == POINTER_TYPE)
6294 rtype = TREE_TYPE (rtype);
6295 /* Traverse typedef aliases */
6296 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6297 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6298 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6299 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6300 saved_rtype = rtype;
6301 if (TYPED_OBJECT (rtype))
6303 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6304 rtype = TYPE_OBJC_INTERFACE (rtype);
6306 /* If we could not find an @interface declaration, we must have
6307 only seen a @class declaration; so, we cannot say anything
6308 more intelligent about which methods the receiver will
6310 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6312 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6313 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6315 /* We have a valid ObjC class name. Look up the method name
6316 in the published @interface for the class (and its
6319 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6321 /* If the method was not found in the @interface, it may still
6322 exist locally as part of the @implementation. */
6323 if (!method_prototype && objc_implementation_context
6324 && CLASS_NAME (objc_implementation_context)
6325 == OBJC_TYPE_NAME (rtype))
6329 ? CLASS_CLS_METHODS (objc_implementation_context)
6330 : CLASS_NST_METHODS (objc_implementation_context)),
6333 /* If we haven't found a candidate method by now, try looking for
6334 it in the protocol list. */
6335 if (!method_prototype && rprotos)
6337 = lookup_method_in_protocol_list (rprotos, sel_name,
6338 class_tree != NULL_TREE);
6342 warning (0, "invalid receiver type %qs",
6343 gen_type_name (orig_rtype));
6344 /* After issuing the "invalid receiver" warning, perform method
6345 lookup as if we were messaging 'id'. */
6346 rtype = rprotos = NULL_TREE;
6351 /* For 'id' or 'Class' receivers, search in the global hash table
6352 as a last resort. For all receivers, warn if protocol searches
6354 if (!method_prototype)
6357 warning (0, "%<%c%s%> not found in protocol(s)",
6358 (class_tree ? '+' : '-'),
6359 IDENTIFIER_POINTER (sel_name));
6363 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6366 if (!method_prototype)
6368 static bool warn_missing_methods = false;
6371 warning (0, "%qs may not respond to %<%c%s%>",
6372 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6373 (class_tree ? '+' : '-'),
6374 IDENTIFIER_POINTER (sel_name));
6375 /* If we are messaging an 'id' or 'Class' object and made it here,
6376 then we have failed to find _any_ instance or class method,
6379 warning (0, "no %<%c%s%> method found",
6380 (class_tree ? '+' : '-'),
6381 IDENTIFIER_POINTER (sel_name));
6383 if (!warn_missing_methods)
6385 warning (0, "(Messages without a matching method signature");
6386 warning (0, "will be assumed to return %<id%> and accept");
6387 warning (0, "%<...%> as arguments.)");
6388 warn_missing_methods = true;
6392 /* Save the selector name for printing error messages. */
6393 current_objc_message_selector = sel_name;
6395 /* Build the parameters list for looking up the method.
6396 These are the object itself and the selector. */
6398 if (flag_typed_selectors)
6399 selector = build_typed_selector_reference (sel_name, method_prototype);
6401 selector = build_selector_reference (sel_name);
6403 retval = build_objc_method_call (super, method_prototype,
6405 selector, method_params);
6407 current_objc_message_selector = 0;
6412 /* Build a tree expression to send OBJECT the operation SELECTOR,
6413 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6414 assuming the method has prototype METHOD_PROTOTYPE.
6415 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6416 Use METHOD_PARAMS as list of args to pass to the method.
6417 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6420 build_objc_method_call (int super_flag, tree method_prototype,
6421 tree lookup_object, tree selector,
6424 tree sender = (super_flag ? umsg_super_decl :
6425 (!flag_next_runtime || flag_nil_receivers
6426 ? (flag_objc_direct_dispatch
6429 : umsg_nonnil_decl));
6430 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6432 /* If a prototype for the method to be called exists, then cast
6433 the sender's return type and arguments to match that of the method.
6434 Otherwise, leave sender as is. */
6437 ? TREE_VALUE (TREE_TYPE (method_prototype))
6438 : objc_object_type);
6440 = build_pointer_type
6441 (build_function_type
6444 (method_prototype, METHOD_REF, super_flag)));
6447 lookup_object = build_c_cast (rcv_p, lookup_object);
6449 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6450 lookup_object = save_expr (lookup_object);
6452 if (flag_next_runtime)
6454 /* If we are returning a struct in memory, and the address
6455 of that memory location is passed as a hidden first
6456 argument, then change which messenger entry point this
6457 expr will call. NB: Note that sender_cast remains
6458 unchanged (it already has a struct return type). */
6459 if (!targetm.calls.struct_value_rtx (0, 0)
6460 && (TREE_CODE (ret_type) == RECORD_TYPE
6461 || TREE_CODE (ret_type) == UNION_TYPE)
6462 && targetm.calls.return_in_memory (ret_type, 0))
6463 sender = (super_flag ? umsg_super_stret_decl :
6464 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6466 method_params = tree_cons (NULL_TREE, lookup_object,
6467 tree_cons (NULL_TREE, selector,
6469 method = build_fold_addr_expr (sender);
6473 /* This is the portable (GNU) way. */
6476 /* First, call the lookup function to get a pointer to the method,
6477 then cast the pointer, then call it with the method arguments. */
6479 object = (super_flag ? self_decl : lookup_object);
6481 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6482 t = tree_cons (NULL_TREE, lookup_object, t);
6483 method = build_function_call (sender, t);
6485 /* Pass the object to the method. */
6486 method_params = tree_cons (NULL_TREE, object,
6487 tree_cons (NULL_TREE, selector,
6491 /* ??? Selector is not at this point something we can use inside
6492 the compiler itself. Set it to garbage for the nonce. */
6493 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6494 return build_function_call (t, method_params);
6498 build_protocol_reference (tree p)
6501 const char *proto_name;
6503 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6505 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6506 decl = start_var_decl (objc_protocol_template, proto_name);
6508 PROTOCOL_FORWARD_DECL (p) = decl;
6511 /* This function is called by the parser when (and only when) a
6512 @protocol() expression is found, in order to compile it. */
6514 objc_build_protocol_expr (tree protoname)
6517 tree p = lookup_protocol (protoname);
6521 error ("cannot find protocol declaration for %qs",
6522 IDENTIFIER_POINTER (protoname));
6523 return error_mark_node;
6526 if (!PROTOCOL_FORWARD_DECL (p))
6527 build_protocol_reference (p);
6529 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6531 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6532 if we have it, rather than converting it here. */
6533 expr = convert (objc_protocol_type, expr);
6535 /* The @protocol() expression is being compiled into a pointer to a
6536 statically allocated instance of the Protocol class. To become
6537 usable at runtime, the 'isa' pointer of the instance need to be
6538 fixed up at runtime by the runtime library, to point to the
6539 actual 'Protocol' class. */
6541 /* For the GNU runtime, put the static Protocol instance in the list
6542 of statically allocated instances, so that we make sure that its
6543 'isa' pointer is fixed up at runtime by the GNU runtime library
6544 to point to the Protocol class (at runtime, when loading the
6545 module, the GNU runtime library loops on the statically allocated
6546 instances (as found in the defs field in objc_symtab) and fixups
6547 all the 'isa' pointers of those objects). */
6548 if (! flag_next_runtime)
6550 /* This type is a struct containing the fields of a Protocol
6551 object. (Cfr. objc_protocol_type instead is the type of a pointer
6552 to such a struct). */
6553 tree protocol_struct_type = xref_tag
6554 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6557 /* Look for the list of Protocol statically allocated instances
6558 to fixup at runtime. Create a new list to hold Protocol
6559 statically allocated instances, if the list is not found. At
6560 present there is only another list, holding NSConstantString
6561 static instances to be fixed up at runtime. */
6562 for (chain = &objc_static_instances;
6563 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6564 chain = &TREE_CHAIN (*chain));
6567 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6568 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6572 /* Add this statically allocated instance to the Protocol list. */
6573 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6574 PROTOCOL_FORWARD_DECL (p),
6575 TREE_PURPOSE (*chain));
6582 /* This function is called by the parser when a @selector() expression
6583 is found, in order to compile it. It is only called by the parser
6584 and only to compile a @selector(). */
6586 objc_build_selector_expr (tree selnamelist)
6590 /* Obtain the full selector name. */
6591 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6592 /* A unary selector. */
6593 selname = selnamelist;
6594 else if (TREE_CODE (selnamelist) == TREE_LIST)
6595 selname = build_keyword_selector (selnamelist);
6599 /* If we are required to check @selector() expressions as they
6600 are found, check that the selector has been declared. */
6601 if (warn_undeclared_selector)
6603 /* Look the selector up in the list of all known class and
6604 instance methods (up to this line) to check that the selector
6608 /* First try with instance methods. */
6609 hsh = hash_lookup (nst_method_hash_list, selname);
6611 /* If not found, try with class methods. */
6614 hsh = hash_lookup (cls_method_hash_list, selname);
6617 /* If still not found, print out a warning. */
6620 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6625 if (flag_typed_selectors)
6626 return build_typed_selector_reference (selname, 0);
6628 return build_selector_reference (selname);
6632 objc_build_encode_expr (tree type)
6637 encode_type (type, obstack_object_size (&util_obstack),
6638 OBJC_ENCODE_INLINE_DEFS);
6639 obstack_1grow (&util_obstack, 0); /* null terminate string */
6640 string = obstack_finish (&util_obstack);
6642 /* Synthesize a string that represents the encoded struct/union. */
6643 result = my_build_string (strlen (string) + 1, string);
6644 obstack_free (&util_obstack, util_firstobj);
6649 build_ivar_reference (tree id)
6651 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6653 /* Historically, a class method that produced objects (factory
6654 method) would assign `self' to the instance that it
6655 allocated. This would effectively turn the class method into
6656 an instance method. Following this assignment, the instance
6657 variables could be accessed. That practice, while safe,
6658 violates the simple rule that a class method should not refer
6659 to an instance variable. It's better to catch the cases
6660 where this is done unknowingly than to support the above
6662 warning (0, "instance variable %qs accessed in class method",
6663 IDENTIFIER_POINTER (id));
6664 self_decl = convert (objc_instance_type, self_decl); /* cast */
6667 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6670 /* Compute a hash value for a given method SEL_NAME. */
6673 hash_func (tree sel_name)
6675 const unsigned char *s
6676 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6680 h = h * 67 + *s++ - 113;
6687 nst_method_hash_list
6688 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6689 cls_method_hash_list
6690 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6692 /* Initialize the hash table used to hold the constant string objects. */
6693 string_htab = htab_create_ggc (31, string_hash,
6696 /* Initialize the hash table used to hold EH-volatilized types. */
6697 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6698 volatilized_eq, NULL);
6701 /* WARNING!!!! hash_enter is called with a method, and will peek
6702 inside to find its selector! But hash_lookup is given a selector
6703 directly, and looks for the selector that's inside the found
6704 entry's key (method) for comparison. */
6707 hash_enter (hash *hashlist, tree method)
6710 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6712 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6714 obj->next = hashlist[slot];
6717 hashlist[slot] = obj; /* append to front */
6721 hash_lookup (hash *hashlist, tree sel_name)
6725 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6729 if (sel_name == METHOD_SEL_NAME (target->key))
6732 target = target->next;
6738 hash_add_attr (hash entry, tree value)
6742 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6743 obj->next = entry->list;
6746 entry->list = obj; /* append to front */
6750 lookup_method (tree mchain, tree method)
6754 if (TREE_CODE (method) == IDENTIFIER_NODE)
6757 key = METHOD_SEL_NAME (method);
6761 if (METHOD_SEL_NAME (mchain) == key)
6764 mchain = TREE_CHAIN (mchain);
6769 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6770 in INTERFACE, along with any categories and protocols attached thereto.
6771 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6772 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6773 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6774 be found in INTERFACE or any of its superclasses, look for an _instance_
6775 method of the same name in the root class as a last resort.
6777 If a suitable method cannot be found, return NULL_TREE. */
6780 lookup_method_static (tree interface, tree ident, int flags)
6782 tree meth = NULL_TREE, root_inter = NULL_TREE;
6783 tree inter = interface;
6784 int is_class = (flags & OBJC_LOOKUP_CLASS);
6785 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6789 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6790 tree category = inter;
6792 /* First, look up the method in the class itself. */
6793 if ((meth = lookup_method (chain, ident)))
6796 /* Failing that, look for the method in each category of the class. */
6797 while ((category = CLASS_CATEGORY_LIST (category)))
6799 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6801 /* Check directly in each category. */
6802 if ((meth = lookup_method (chain, ident)))
6805 /* Failing that, check in each category's protocols. */
6806 if (CLASS_PROTOCOL_LIST (category))
6808 if ((meth = (lookup_method_in_protocol_list
6809 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6814 /* If not found in categories, check in protocols of the main class. */
6815 if (CLASS_PROTOCOL_LIST (inter))
6817 if ((meth = (lookup_method_in_protocol_list
6818 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6822 /* If we were instructed not to look in superclasses, don't. */
6823 if (no_superclasses)
6826 /* Failing that, climb up the inheritance hierarchy. */
6828 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6832 /* If no class (factory) method was found, check if an _instance_
6833 method of the same name exists in the root class. This is what
6834 the Objective-C runtime will do. If an instance method was not
6836 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6839 /* Add the method to the hash list if it doesn't contain an identical
6842 add_method_to_hash_list (hash *hash_list, tree method)
6846 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6848 /* Install on a global chain. */
6849 hash_enter (hash_list, method);
6853 /* Check types against those; if different, add to a list. */
6855 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6856 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6857 already_there |= comp_proto_with_proto (method, loop->value, 1);
6859 hash_add_attr (hsh, method);
6864 objc_add_method (tree class, tree method, int is_class)
6868 if (!(mth = lookup_method (is_class
6869 ? CLASS_CLS_METHODS (class)
6870 : CLASS_NST_METHODS (class), method)))
6872 /* put method on list in reverse order */
6875 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6876 CLASS_CLS_METHODS (class) = method;
6880 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6881 CLASS_NST_METHODS (class) = method;
6886 /* When processing an @interface for a class or category, give hard
6887 errors on methods with identical selectors but differing argument
6888 and/or return types. We do not do this for @implementations, because
6889 C/C++ will do it for us (i.e., there will be duplicate function
6890 definition errors). */
6891 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6892 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6893 && !comp_proto_with_proto (method, mth, 1))
6894 error ("duplicate declaration of method %<%c%s%>",
6895 is_class ? '+' : '-',
6896 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6900 add_method_to_hash_list (cls_method_hash_list, method);
6903 add_method_to_hash_list (nst_method_hash_list, method);
6905 /* Instance methods in root classes (and categories thereof)
6906 may act as class methods as a last resort. We also add
6907 instance methods listed in @protocol declarations to
6908 the class hash table, on the assumption that @protocols
6909 may be adopted by root classes or categories. */
6910 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6911 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6912 class = lookup_interface (CLASS_NAME (class));
6914 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6915 || !CLASS_SUPER_NAME (class))
6916 add_method_to_hash_list (cls_method_hash_list, method);
6923 add_class (tree class_name, tree name)
6925 struct interface_tuple **slot;
6927 /* Put interfaces on list in reverse order. */
6928 TREE_CHAIN (class_name) = interface_chain;
6929 interface_chain = class_name;
6931 if (interface_htab == NULL)
6932 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6933 slot = (struct interface_tuple **)
6934 htab_find_slot_with_hash (interface_htab, name,
6935 htab_hash_pointer (name),
6939 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6942 (*slot)->class_name = class_name;
6944 return interface_chain;
6948 add_category (tree class, tree category)
6950 /* Put categories on list in reverse order. */
6951 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6955 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
6956 IDENTIFIER_POINTER (CLASS_NAME (class)),
6957 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6961 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6962 CLASS_CATEGORY_LIST (class) = category;
6966 /* Called after parsing each instance variable declaration. Necessary to
6967 preserve typedefs and implement public/private...
6969 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6972 add_instance_variable (tree class, int public, tree field_decl)
6974 tree field_type = TREE_TYPE (field_decl);
6975 const char *ivar_name = DECL_NAME (field_decl)
6976 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6980 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6982 error ("illegal reference type specified for instance variable %qs",
6984 /* Return class as is without adding this ivar. */
6989 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6990 || TYPE_SIZE (field_type) == error_mark_node)
6991 /* 'type[0]' is allowed, but 'type[]' is not! */
6993 error ("instance variable %qs has unknown size", ivar_name);
6994 /* Return class as is without adding this ivar. */
6999 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7000 need to either (1) warn the user about it or (2) generate suitable
7001 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7002 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7003 if (IS_AGGR_TYPE (field_type)
7004 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7005 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7006 || TYPE_POLYMORPHIC_P (field_type)))
7008 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7010 if (flag_objc_call_cxx_cdtors)
7012 /* Since the ObjC runtime will be calling the constructors and
7013 destructors for us, the only thing we can't handle is the lack
7014 of a default constructor. */
7015 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7016 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7018 warning (0, "type `%s' has no default constructor to call",
7021 /* If we cannot call a constructor, we should also avoid
7022 calling the destructor, for symmetry. */
7023 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7024 warning (0, "destructor for `%s' shall not be run either",
7030 static bool warn_cxx_ivars = false;
7032 if (TYPE_POLYMORPHIC_P (field_type))
7034 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7036 error ("type `%s' has virtual member functions", type_name);
7037 error ("illegal aggregate type `%s' specified "
7038 "for instance variable `%s'",
7039 type_name, ivar_name);
7040 /* Return class as is without adding this ivar. */
7044 /* User-defined constructors and destructors are not known to Obj-C
7045 and hence will not be called. This may or may not be a problem. */
7046 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7047 warning (0, "type `%s' has a user-defined constructor", type_name);
7048 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7049 warning (0, "type `%s' has a user-defined destructor", type_name);
7051 if (!warn_cxx_ivars)
7053 warning (0, "C++ constructors and destructors will not "
7054 "be invoked for Objective-C fields");
7055 warn_cxx_ivars = true;
7061 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7065 TREE_PUBLIC (field_decl) = 0;
7066 TREE_PRIVATE (field_decl) = 0;
7067 TREE_PROTECTED (field_decl) = 1;
7071 TREE_PUBLIC (field_decl) = 1;
7072 TREE_PRIVATE (field_decl) = 0;
7073 TREE_PROTECTED (field_decl) = 0;
7077 TREE_PUBLIC (field_decl) = 0;
7078 TREE_PRIVATE (field_decl) = 1;
7079 TREE_PROTECTED (field_decl) = 0;
7084 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7090 is_ivar (tree decl_chain, tree ident)
7092 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7093 if (DECL_NAME (decl_chain) == ident)
7098 /* True if the ivar is private and we are not in its implementation. */
7101 is_private (tree decl)
7103 return (TREE_PRIVATE (decl)
7104 && ! is_ivar (CLASS_IVARS (implementation_template),
7108 /* We have an instance variable reference;, check to see if it is public. */
7111 objc_is_public (tree expr, tree identifier)
7113 tree basetype, decl;
7116 if (processing_template_decl)
7120 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7122 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7124 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7126 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7130 error ("cannot find interface declaration for %qs",
7131 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7135 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7137 if (TREE_PUBLIC (decl))
7140 /* Important difference between the Stepstone translator:
7141 all instance variables should be public within the context
7142 of the implementation. */
7143 if (objc_implementation_context
7144 && ((TREE_CODE (objc_implementation_context)
7145 == CLASS_IMPLEMENTATION_TYPE)
7146 || (TREE_CODE (objc_implementation_context)
7147 == CATEGORY_IMPLEMENTATION_TYPE)))
7149 tree curtype = TYPE_MAIN_VARIANT
7150 (CLASS_STATIC_TEMPLATE
7151 (implementation_template));
7153 if (basetype == curtype
7154 || DERIVED_FROM_P (basetype, curtype))
7156 int private = is_private (decl);
7159 error ("instance variable %qs is declared private",
7160 IDENTIFIER_POINTER (DECL_NAME (decl)));
7166 /* The 2.95.2 compiler sometimes allowed C functions to access
7167 non-@public ivars. We will let this slide for now... */
7168 if (!objc_method_context)
7170 warning (0, "instance variable %qs is %s; "
7171 "this will be a hard error in the future",
7172 IDENTIFIER_POINTER (identifier),
7173 TREE_PRIVATE (decl) ? "@private" : "@protected");
7177 error ("instance variable %qs is declared %s",
7178 IDENTIFIER_POINTER (identifier),
7179 TREE_PRIVATE (decl) ? "private" : "protected");
7188 /* Make sure all entries in CHAIN are also in LIST. */
7191 check_methods (tree chain, tree list, int mtype)
7197 if (!lookup_method (list, chain))
7201 if (TREE_CODE (objc_implementation_context)
7202 == CLASS_IMPLEMENTATION_TYPE)
7203 warning (0, "incomplete implementation of class %qs",
7204 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7205 else if (TREE_CODE (objc_implementation_context)
7206 == CATEGORY_IMPLEMENTATION_TYPE)
7207 warning (0, "incomplete implementation of category %qs",
7208 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7212 warning (0, "method definition for %<%c%s%> not found",
7213 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7216 chain = TREE_CHAIN (chain);
7222 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7225 conforms_to_protocol (tree class, tree protocol)
7227 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7229 tree p = CLASS_PROTOCOL_LIST (class);
7230 while (p && TREE_VALUE (p) != protocol)
7235 tree super = (CLASS_SUPER_NAME (class)
7236 ? lookup_interface (CLASS_SUPER_NAME (class))
7238 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7247 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7248 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7251 check_methods_accessible (tree chain, tree context, int mtype)
7255 tree base_context = context;
7259 context = base_context;
7263 list = CLASS_CLS_METHODS (context);
7265 list = CLASS_NST_METHODS (context);
7267 if (lookup_method (list, chain))
7270 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7271 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7272 context = (CLASS_SUPER_NAME (context)
7273 ? lookup_interface (CLASS_SUPER_NAME (context))
7276 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7277 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7278 context = (CLASS_NAME (context)
7279 ? lookup_interface (CLASS_NAME (context))
7285 if (context == NULL_TREE)
7289 if (TREE_CODE (objc_implementation_context)
7290 == CLASS_IMPLEMENTATION_TYPE)
7291 warning (0, "incomplete implementation of class %qs",
7293 (CLASS_NAME (objc_implementation_context)));
7294 else if (TREE_CODE (objc_implementation_context)
7295 == CATEGORY_IMPLEMENTATION_TYPE)
7296 warning (0, "incomplete implementation of category %qs",
7298 (CLASS_SUPER_NAME (objc_implementation_context)));
7301 warning (0, "method definition for %<%c%s%> not found",
7302 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7305 chain = TREE_CHAIN (chain); /* next method... */
7310 /* Check whether the current interface (accessible via
7311 'objc_implementation_context') actually implements protocol P, along
7312 with any protocols that P inherits. */
7315 check_protocol (tree p, const char *type, const char *name)
7317 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7321 /* Ensure that all protocols have bodies! */
7324 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7325 CLASS_CLS_METHODS (objc_implementation_context),
7327 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7328 CLASS_NST_METHODS (objc_implementation_context),
7333 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7334 objc_implementation_context,
7336 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7337 objc_implementation_context,
7342 warning (0, "%s %qs does not fully implement the %qs protocol",
7343 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7346 /* Check protocols recursively. */
7347 if (PROTOCOL_LIST (p))
7349 tree subs = PROTOCOL_LIST (p);
7351 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7355 tree sub = TREE_VALUE (subs);
7357 /* If the superclass does not conform to the protocols
7358 inherited by P, then we must! */
7359 if (!super_class || !conforms_to_protocol (super_class, sub))
7360 check_protocol (sub, type, name);
7361 subs = TREE_CHAIN (subs);
7366 /* Check whether the current interface (accessible via
7367 'objc_implementation_context') actually implements the protocols listed
7371 check_protocols (tree proto_list, const char *type, const char *name)
7373 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7375 tree p = TREE_VALUE (proto_list);
7377 check_protocol (p, type, name);
7381 /* Make sure that the class CLASS_NAME is defined
7382 CODE says which kind of thing CLASS_NAME ought to be.
7383 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7384 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7387 start_class (enum tree_code code, tree class_name, tree super_name,
7393 if (current_namespace != global_namespace) {
7394 error ("Objective-C declarations may only appear in global scope");
7396 #endif /* OBJCPLUS */
7398 if (objc_implementation_context)
7400 warning (0, "%<@end%> missing in implementation context");
7401 finish_class (objc_implementation_context);
7402 objc_ivar_chain = NULL_TREE;
7403 objc_implementation_context = NULL_TREE;
7406 class = make_node (code);
7407 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7409 /* Check for existence of the super class, if one was specified. Note
7410 that we must have seen an @interface, not just a @class. If we
7411 are looking at a @compatibility_alias, traverse it first. */
7412 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7415 tree super = objc_is_class_name (super_name);
7417 if (!super || !lookup_interface (super))
7419 error ("cannot find interface declaration for %qs, superclass of %qs",
7420 IDENTIFIER_POINTER (super ? super : super_name),
7421 IDENTIFIER_POINTER (class_name));
7422 super_name = NULL_TREE;
7428 CLASS_NAME (class) = class_name;
7429 CLASS_SUPER_NAME (class) = super_name;
7430 CLASS_CLS_METHODS (class) = NULL_TREE;
7432 if (! objc_is_class_name (class_name)
7433 && (decl = lookup_name (class_name)))
7435 error ("%qs redeclared as different kind of symbol",
7436 IDENTIFIER_POINTER (class_name));
7437 error ("%Jprevious declaration of '%D'",
7441 if (code == CLASS_IMPLEMENTATION_TYPE)
7446 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7447 if (TREE_VALUE (chain) == class_name)
7449 error ("reimplementation of class %qs",
7450 IDENTIFIER_POINTER (class_name));
7451 return error_mark_node;
7453 implemented_classes = tree_cons (NULL_TREE, class_name,
7454 implemented_classes);
7457 /* Reset for multiple classes per file. */
7460 objc_implementation_context = class;
7462 /* Lookup the interface for this implementation. */
7464 if (!(implementation_template = lookup_interface (class_name)))
7466 warning (0, "cannot find interface declaration for %qs",
7467 IDENTIFIER_POINTER (class_name));
7468 add_class (implementation_template = objc_implementation_context,
7472 /* If a super class has been specified in the implementation,
7473 insure it conforms to the one specified in the interface. */
7476 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7478 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7479 const char *const name =
7480 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7481 error ("conflicting super class name %qs",
7482 IDENTIFIER_POINTER (super_name));
7483 error ("previous declaration of %qs", name);
7486 else if (! super_name)
7488 CLASS_SUPER_NAME (objc_implementation_context)
7489 = CLASS_SUPER_NAME (implementation_template);
7493 else if (code == CLASS_INTERFACE_TYPE)
7495 if (lookup_interface (class_name))
7497 error ("duplicate interface declaration for class %qs",
7499 warning (0, "duplicate interface declaration for class %qs",
7501 IDENTIFIER_POINTER (class_name));
7503 add_class (class, class_name);
7506 CLASS_PROTOCOL_LIST (class)
7507 = lookup_and_install_protocols (protocol_list);
7510 else if (code == CATEGORY_INTERFACE_TYPE)
7512 tree class_category_is_assoc_with;
7514 /* For a category, class_name is really the name of the class that
7515 the following set of methods will be associated with. We must
7516 find the interface so that can derive the objects template. */
7518 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7520 error ("cannot find interface declaration for %qs",
7521 IDENTIFIER_POINTER (class_name));
7522 exit (FATAL_EXIT_CODE);
7525 add_category (class_category_is_assoc_with, class);
7528 CLASS_PROTOCOL_LIST (class)
7529 = lookup_and_install_protocols (protocol_list);
7532 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7534 /* Reset for multiple classes per file. */
7537 objc_implementation_context = class;
7539 /* For a category, class_name is really the name of the class that
7540 the following set of methods will be associated with. We must
7541 find the interface so that can derive the objects template. */
7543 if (!(implementation_template = lookup_interface (class_name)))
7545 error ("cannot find interface declaration for %qs",
7546 IDENTIFIER_POINTER (class_name));
7547 exit (FATAL_EXIT_CODE);
7554 continue_class (tree class)
7556 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7557 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7559 struct imp_entry *imp_entry;
7561 /* Check consistency of the instance variables. */
7563 if (CLASS_RAW_IVARS (class))
7564 check_ivars (implementation_template, class);
7566 /* code generation */
7569 push_lang_context (lang_name_c);
7572 build_private_template (implementation_template);
7573 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7574 objc_instance_type = build_pointer_type (uprivate_record);
7576 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7578 imp_entry->next = imp_list;
7579 imp_entry->imp_context = class;
7580 imp_entry->imp_template = implementation_template;
7582 synth_forward_declarations ();
7583 imp_entry->class_decl = UOBJC_CLASS_decl;
7584 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7585 imp_entry->has_cxx_cdtors = 0;
7587 /* Append to front and increment count. */
7588 imp_list = imp_entry;
7589 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7595 pop_lang_context ();
7596 #endif /* OBJCPLUS */
7598 return get_class_ivars (implementation_template, true);
7601 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7604 push_lang_context (lang_name_c);
7605 #endif /* OBJCPLUS */
7607 build_private_template (class);
7610 pop_lang_context ();
7611 #endif /* OBJCPLUS */
7617 return error_mark_node;
7620 /* This is called once we see the "@end" in an interface/implementation. */
7623 finish_class (tree class)
7625 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7627 /* All code generation is done in finish_objc. */
7629 if (implementation_template != objc_implementation_context)
7631 /* Ensure that all method listed in the interface contain bodies. */
7632 check_methods (CLASS_CLS_METHODS (implementation_template),
7633 CLASS_CLS_METHODS (objc_implementation_context), '+');
7634 check_methods (CLASS_NST_METHODS (implementation_template),
7635 CLASS_NST_METHODS (objc_implementation_context), '-');
7637 if (CLASS_PROTOCOL_LIST (implementation_template))
7638 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7640 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7644 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7646 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7650 /* Ensure all method listed in the interface contain bodies. */
7651 check_methods (CLASS_CLS_METHODS (category),
7652 CLASS_CLS_METHODS (objc_implementation_context), '+');
7653 check_methods (CLASS_NST_METHODS (category),
7654 CLASS_NST_METHODS (objc_implementation_context), '-');
7656 if (CLASS_PROTOCOL_LIST (category))
7657 check_protocols (CLASS_PROTOCOL_LIST (category),
7659 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7665 add_protocol (tree protocol)
7667 /* Put protocol on list in reverse order. */
7668 TREE_CHAIN (protocol) = protocol_chain;
7669 protocol_chain = protocol;
7670 return protocol_chain;
7674 lookup_protocol (tree ident)
7678 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7679 if (ident == PROTOCOL_NAME (chain))
7685 /* This function forward declares the protocols named by NAMES. If
7686 they are already declared or defined, the function has no effect. */
7689 objc_declare_protocols (tree names)
7694 if (current_namespace != global_namespace) {
7695 error ("Objective-C declarations may only appear in global scope");
7697 #endif /* OBJCPLUS */
7699 for (list = names; list; list = TREE_CHAIN (list))
7701 tree name = TREE_VALUE (list);
7703 if (lookup_protocol (name) == NULL_TREE)
7705 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7707 TYPE_LANG_SLOT_1 (protocol)
7708 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7709 PROTOCOL_NAME (protocol) = name;
7710 PROTOCOL_LIST (protocol) = NULL_TREE;
7711 add_protocol (protocol);
7712 PROTOCOL_DEFINED (protocol) = 0;
7713 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7719 start_protocol (enum tree_code code, tree name, tree list)
7724 if (current_namespace != global_namespace) {
7725 error ("Objective-C declarations may only appear in global scope");
7727 #endif /* OBJCPLUS */
7729 protocol = lookup_protocol (name);
7733 protocol = make_node (code);
7734 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7736 PROTOCOL_NAME (protocol) = name;
7737 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7738 add_protocol (protocol);
7739 PROTOCOL_DEFINED (protocol) = 1;
7740 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7742 check_protocol_recursively (protocol, list);
7744 else if (! PROTOCOL_DEFINED (protocol))
7746 PROTOCOL_DEFINED (protocol) = 1;
7747 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7749 check_protocol_recursively (protocol, list);
7753 warning (0, "duplicate declaration for protocol %qs",
7754 IDENTIFIER_POINTER (name));
7760 /* "Encode" a data type into a string, which grows in util_obstack.
7761 ??? What is the FORMAT? Someone please document this! */
7764 encode_type_qualifiers (tree declspecs)
7768 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7770 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7771 obstack_1grow (&util_obstack, 'n');
7772 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7773 obstack_1grow (&util_obstack, 'N');
7774 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7775 obstack_1grow (&util_obstack, 'o');
7776 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7777 obstack_1grow (&util_obstack, 'O');
7778 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7779 obstack_1grow (&util_obstack, 'R');
7780 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7781 obstack_1grow (&util_obstack, 'V');
7785 /* Encode a pointer type. */
7788 encode_pointer (tree type, int curtype, int format)
7790 tree pointer_to = TREE_TYPE (type);
7792 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7794 if (OBJC_TYPE_NAME (pointer_to)
7795 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7797 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7799 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7801 obstack_1grow (&util_obstack, '@');
7804 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7805 && TYPE_OBJC_INTERFACE (pointer_to))
7807 if (generating_instance_variables)
7809 obstack_1grow (&util_obstack, '@');
7810 obstack_1grow (&util_obstack, '"');
7811 obstack_grow (&util_obstack, name, strlen (name));
7812 obstack_1grow (&util_obstack, '"');
7817 obstack_1grow (&util_obstack, '@');
7821 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7823 obstack_1grow (&util_obstack, '#');
7826 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7828 obstack_1grow (&util_obstack, ':');
7833 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7834 && TYPE_MODE (pointer_to) == QImode)
7836 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7837 ? OBJC_TYPE_NAME (pointer_to)
7838 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7840 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7842 /* It appears that "r*" means "const char *" rather than
7844 if (TYPE_READONLY (pointer_to))
7845 obstack_1grow (&util_obstack, 'r');
7847 obstack_1grow (&util_obstack, '*');
7852 /* We have a type that does not get special treatment. */
7854 /* NeXT extension */
7855 obstack_1grow (&util_obstack, '^');
7856 encode_type (pointer_to, curtype, format);
7860 encode_array (tree type, int curtype, int format)
7862 tree an_int_cst = TYPE_SIZE (type);
7863 tree array_of = TREE_TYPE (type);
7866 /* An incomplete array is treated like a pointer. */
7867 if (an_int_cst == NULL)
7869 encode_pointer (type, curtype, format);
7873 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7874 (TREE_INT_CST_LOW (an_int_cst)
7875 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7877 obstack_grow (&util_obstack, buffer, strlen (buffer));
7878 encode_type (array_of, curtype, format);
7879 obstack_1grow (&util_obstack, ']');
7884 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7886 tree field = TYPE_FIELDS (type);
7888 for (; field; field = TREE_CHAIN (field))
7891 /* C++ static members, and things that are not field at all,
7892 should not appear in the encoding. */
7893 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7897 /* Recursively encode fields of embedded base classes. */
7898 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7899 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7901 encode_aggregate_fields (TREE_TYPE (field),
7902 pointed_to, curtype, format);
7906 if (generating_instance_variables && !pointed_to)
7908 tree fname = DECL_NAME (field);
7910 obstack_1grow (&util_obstack, '"');
7912 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7913 obstack_grow (&util_obstack,
7914 IDENTIFIER_POINTER (fname),
7915 strlen (IDENTIFIER_POINTER (fname)));
7917 obstack_1grow (&util_obstack, '"');
7920 encode_field_decl (field, curtype, format);
7925 encode_aggregate_within (tree type, int curtype, int format, int left,
7929 /* NB: aggregates that are pointed to have slightly different encoding
7930 rules in that you never encode the names of instance variables. */
7931 int ob_size = obstack_object_size (&util_obstack);
7932 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7933 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7934 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7936 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7937 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7939 /* Traverse struct aliases; it is important to get the
7940 original struct and its tag name (if any). */
7941 type = TYPE_MAIN_VARIANT (type);
7942 name = OBJC_TYPE_NAME (type);
7943 /* Open parenth/bracket. */
7944 obstack_1grow (&util_obstack, left);
7946 /* Encode the struct/union tag name, or '?' if a tag was
7947 not provided. Typedef aliases do not qualify. */
7948 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7950 /* Did this struct have a tag? */
7951 && !TYPE_WAS_ANONYMOUS (type)
7954 obstack_grow (&util_obstack,
7955 IDENTIFIER_POINTER (name),
7956 strlen (IDENTIFIER_POINTER (name)));
7958 obstack_1grow (&util_obstack, '?');
7960 /* Encode the types (and possibly names) of the inner fields,
7962 if (inline_contents)
7964 obstack_1grow (&util_obstack, '=');
7965 encode_aggregate_fields (type, pointed_to, curtype, format);
7967 /* Close parenth/bracket. */
7968 obstack_1grow (&util_obstack, right);
7972 encode_aggregate (tree type, int curtype, int format)
7974 enum tree_code code = TREE_CODE (type);
7980 encode_aggregate_within (type, curtype, format, '{', '}');
7985 encode_aggregate_within (type, curtype, format, '(', ')');
7990 obstack_1grow (&util_obstack, 'i');
7998 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8002 encode_next_bitfield (int width)
8005 sprintf (buffer, "b%d", width);
8006 obstack_grow (&util_obstack, buffer, strlen (buffer));
8009 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8011 encode_type (tree type, int curtype, int format)
8013 enum tree_code code = TREE_CODE (type);
8016 if (TYPE_READONLY (type))
8017 obstack_1grow (&util_obstack, 'r');
8019 if (code == INTEGER_TYPE)
8021 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8023 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8024 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8026 if (type == long_unsigned_type_node
8027 || type == long_integer_type_node)
8028 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8030 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8032 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8035 obstack_1grow (&util_obstack, c);
8038 else if (code == REAL_TYPE)
8040 /* Floating point types. */
8041 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8043 case 32: c = 'f'; break;
8046 case 128: c = 'd'; break;
8049 obstack_1grow (&util_obstack, c);
8052 else if (code == VOID_TYPE)
8053 obstack_1grow (&util_obstack, 'v');
8055 else if (code == BOOLEAN_TYPE)
8056 obstack_1grow (&util_obstack, 'B');
8058 else if (code == ARRAY_TYPE)
8059 encode_array (type, curtype, format);
8061 else if (code == POINTER_TYPE)
8062 encode_pointer (type, curtype, format);
8064 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8065 encode_aggregate (type, curtype, format);
8067 else if (code == FUNCTION_TYPE) /* '?' */
8068 obstack_1grow (&util_obstack, '?');
8072 encode_gnu_bitfield (int position, tree type, int size)
8074 enum tree_code code = TREE_CODE (type);
8076 char charType = '?';
8078 if (code == INTEGER_TYPE)
8080 if (integer_zerop (TYPE_MIN_VALUE (type)))
8082 /* Unsigned integer types. */
8084 if (TYPE_MODE (type) == QImode)
8086 else if (TYPE_MODE (type) == HImode)
8088 else if (TYPE_MODE (type) == SImode)
8090 if (type == long_unsigned_type_node)
8095 else if (TYPE_MODE (type) == DImode)
8100 /* Signed integer types. */
8102 if (TYPE_MODE (type) == QImode)
8104 else if (TYPE_MODE (type) == HImode)
8106 else if (TYPE_MODE (type) == SImode)
8108 if (type == long_integer_type_node)
8114 else if (TYPE_MODE (type) == DImode)
8118 else if (code == ENUMERAL_TYPE)
8123 sprintf (buffer, "b%d%c%d", position, charType, size);
8124 obstack_grow (&util_obstack, buffer, strlen (buffer));
8128 encode_field_decl (tree field_decl, int curtype, int format)
8133 /* C++ static members, and things that are not fields at all,
8134 should not appear in the encoding. */
8135 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8139 type = TREE_TYPE (field_decl);
8141 /* Generate the bitfield typing information, if needed. Note the difference
8142 between GNU and NeXT runtimes. */
8143 if (DECL_BIT_FIELD_TYPE (field_decl))
8145 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8147 if (flag_next_runtime)
8148 encode_next_bitfield (size);
8150 encode_gnu_bitfield (int_bit_position (field_decl),
8151 DECL_BIT_FIELD_TYPE (field_decl), size);
8154 encode_type (TREE_TYPE (field_decl), curtype, format);
8157 static GTY(()) tree objc_parmlist = NULL_TREE;
8159 /* Append PARM to a list of formal parameters of a method, making a necessary
8160 array-to-pointer adjustment along the way. */
8163 objc_push_parm (tree parm)
8165 /* Decay arrays and functions into pointers. */
8166 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8167 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8168 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8169 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8171 DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
8172 DECL_ARG_TYPE (parm)
8173 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8175 /* Record constancy and volatility. */
8176 c_apply_type_quals_to_decl
8177 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8178 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8179 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8181 objc_parmlist = chainon (objc_parmlist, parm);
8184 /* Retrieve the formal parameter list constructed via preceding calls to
8185 objc_push_parm(). */
8189 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8191 static struct c_arg_info *
8192 objc_get_parm_info (int have_ellipsis)
8196 tree parm_info = objc_parmlist;
8197 objc_parmlist = NULL_TREE;
8201 tree parm_info = objc_parmlist;
8202 struct c_arg_info *arg_info;
8203 /* The C front-end requires an elaborate song and dance at
8206 declare_parm_level ();
8209 tree next = TREE_CHAIN (parm_info);
8211 TREE_CHAIN (parm_info) = NULL_TREE;
8212 parm_info = pushdecl (parm_info);
8213 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8216 arg_info = get_parm_info (have_ellipsis);
8218 objc_parmlist = NULL_TREE;
8223 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8224 method definitions. In the case of instance methods, we can be more
8225 specific as to the type of 'self'. */
8228 synth_self_and_ucmd_args (void)
8232 if (objc_method_context
8233 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8234 self_type = objc_instance_type;
8236 /* Really a `struct objc_class *'. However, we allow people to
8237 assign to self, which changes its type midstream. */
8238 self_type = objc_object_type;
8241 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8244 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8247 /* Transform an Objective-C method definition into a static C function
8248 definition, synthesizing the first two arguments, "self" and "_cmd",
8252 start_method_def (tree method)
8258 struct c_arg_info *parm_info;
8260 int have_ellipsis = 0;
8262 /* If we are defining a "dealloc" method in a non-root class, we
8263 will need to check if a [super dealloc] is missing, and warn if
8265 if(CLASS_SUPER_NAME (objc_implementation_context)
8266 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8267 should_call_super_dealloc = 1;
8269 should_call_super_dealloc = 0;
8271 /* Required to implement _msgSuper. */
8272 objc_method_context = method;
8273 UOBJC_SUPER_decl = NULL_TREE;
8275 /* Generate prototype declarations for arguments..."new-style". */
8276 synth_self_and_ucmd_args ();
8278 /* Generate argument declarations if a keyword_decl. */
8279 parmlist = METHOD_SEL_ARGS (method);
8282 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8284 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8285 objc_push_parm (parm);
8286 parmlist = TREE_CHAIN (parmlist);
8289 if (METHOD_ADD_ARGS (method))
8293 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8294 akey; akey = TREE_CHAIN (akey))
8296 objc_push_parm (TREE_VALUE (akey));
8299 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8303 parm_info = objc_get_parm_info (have_ellipsis);
8305 really_start_method (objc_method_context, parm_info);
8309 warn_with_method (const char *message, int mtype, tree method)
8311 /* Add a readable method name to the warning. */
8312 warning (0, "%J%s %<%c%s%>", method,
8313 message, mtype, gen_method_decl (method));
8316 /* Return 1 if TYPE1 is equivalent to TYPE2
8317 for purposes of method overloading. */
8320 objc_types_are_equivalent (tree type1, tree type2)
8325 /* Strip away indirections. */
8326 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8327 && (TREE_CODE (type1) == TREE_CODE (type2)))
8328 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8329 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8332 type1 = (TYPE_HAS_OBJC_INFO (type1)
8333 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8335 type2 = (TYPE_HAS_OBJC_INFO (type2)
8336 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8339 if (list_length (type1) == list_length (type2))
8341 for (; type2; type2 = TREE_CHAIN (type2))
8342 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8349 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8352 objc_types_share_size_and_alignment (tree type1, tree type2)
8354 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8355 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8358 /* Return 1 if PROTO1 is equivalent to PROTO2
8359 for purposes of method overloading. Ordinarily, the type signatures
8360 should match up exactly, unless STRICT is zero, in which case we
8361 shall allow differences in which the size and alignment of a type
8365 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8369 /* The following test is needed in case there are hashing
8371 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8374 /* Compare return types. */
8375 type1 = TREE_VALUE (TREE_TYPE (proto1));
8376 type2 = TREE_VALUE (TREE_TYPE (proto2));
8378 if (!objc_types_are_equivalent (type1, type2)
8379 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8382 /* Compare argument types. */
8383 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8384 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8386 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8388 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8390 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8391 TREE_VALUE (type2))))
8395 return (!type1 && !type2);
8398 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8399 this occurs. ObjC method dispatches are _not_ like C++ virtual
8400 member function dispatches, and we account for the difference here. */
8403 objc_fold_obj_type_ref (tree ref, tree known_type)
8405 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8406 tree known_type ATTRIBUTE_UNUSED)
8410 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8412 /* If the receiver does not have virtual member functions, there
8413 is nothing we can (or need to) do here. */
8417 /* Let C++ handle C++ virtual functions. */
8418 return cp_fold_obj_type_ref (ref, known_type);
8420 /* For plain ObjC, we currently do not need to do anything. */
8426 objc_start_function (tree name, tree type, tree attrs,
8430 struct c_arg_info *params
8434 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8437 DECL_ARGUMENTS (fndecl) = params;
8438 DECL_INITIAL (fndecl) = error_mark_node;
8439 DECL_EXTERNAL (fndecl) = 0;
8440 TREE_STATIC (fndecl) = 1;
8441 retrofit_lang_decl (fndecl);
8442 cplus_decl_attributes (&fndecl, attrs, 0);
8443 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8445 struct c_label_context_se *nstack_se;
8446 struct c_label_context_vm *nstack_vm;
8447 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8448 nstack_se->labels_def = NULL;
8449 nstack_se->labels_used = NULL;
8450 nstack_se->next = label_context_stack_se;
8451 label_context_stack_se = nstack_se;
8452 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8453 nstack_vm->labels_def = NULL;
8454 nstack_vm->labels_used = NULL;
8455 nstack_vm->scope = 0;
8456 nstack_vm->next = label_context_stack_vm;
8457 label_context_stack_vm = nstack_vm;
8458 current_function_returns_value = 0; /* Assume, until we see it does. */
8459 current_function_returns_null = 0;
8461 decl_attributes (&fndecl, attrs, 0);
8462 announce_function (fndecl);
8463 DECL_INITIAL (fndecl) = error_mark_node;
8464 DECL_EXTERNAL (fndecl) = 0;
8465 TREE_STATIC (fndecl) = 1;
8466 current_function_decl = pushdecl (fndecl);
8468 declare_parm_level ();
8469 DECL_RESULT (current_function_decl)
8470 = build_decl (RESULT_DECL, NULL_TREE,
8471 TREE_TYPE (TREE_TYPE (current_function_decl)));
8472 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8473 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8474 start_fname_decls ();
8475 store_parm_decls_from (params);
8478 TREE_USED (current_function_decl) = 1;
8481 /* - Generate an identifier for the function. the format is "_n_cls",
8482 where 1 <= n <= nMethods, and cls is the name the implementation we
8484 - Install the return type from the method declaration.
8485 - If we have a prototype, check for type consistency. */
8488 really_start_method (tree method,
8492 struct c_arg_info *parmlist
8496 tree ret_type, meth_type;
8498 const char *sel_name, *class_name, *cat_name;
8501 /* Synth the storage class & assemble the return type. */
8502 ret_type = TREE_VALUE (TREE_TYPE (method));
8504 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8505 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8506 cat_name = ((TREE_CODE (objc_implementation_context)
8507 == CLASS_IMPLEMENTATION_TYPE)
8509 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8512 /* Make sure this is big enough for any plausible method label. */
8513 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8514 + (cat_name ? strlen (cat_name) : 0));
8516 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8517 class_name, cat_name, sel_name, method_slot);
8519 method_id = get_identifier (buf);
8522 /* Objective-C methods cannot be overloaded, so we don't need
8523 the type encoding appended. It looks bad anyway... */
8524 push_lang_context (lang_name_c);
8528 = build_function_type (ret_type,
8529 get_arg_type_list (method, METHOD_DEF, 0));
8530 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8532 /* Set self_decl from the first argument. */
8533 self_decl = DECL_ARGUMENTS (current_function_decl);
8535 /* Suppress unused warnings. */
8536 TREE_USED (self_decl) = 1;
8537 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8539 pop_lang_context ();
8542 METHOD_DEFINITION (method) = current_function_decl;
8544 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8546 if (implementation_template != objc_implementation_context)
8549 = lookup_method_static (implementation_template,
8550 METHOD_SEL_NAME (method),
8551 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8552 | OBJC_LOOKUP_NO_SUPER));
8556 if (!comp_proto_with_proto (method, proto, 1))
8558 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8560 warn_with_method ("conflicting types for", type, method);
8561 warn_with_method ("previous declaration of", type, proto);
8566 /* We have a method @implementation even though we did not
8567 see a corresponding @interface declaration (which is allowed
8568 by Objective-C rules). Go ahead and place the method in
8569 the @interface anyway, so that message dispatch lookups
8571 tree interface = implementation_template;
8573 if (TREE_CODE (objc_implementation_context)
8574 == CATEGORY_IMPLEMENTATION_TYPE)
8575 interface = lookup_category
8577 CLASS_SUPER_NAME (objc_implementation_context));
8580 objc_add_method (interface, copy_node (method),
8581 TREE_CODE (method) == CLASS_METHOD_DECL);
8586 static void *UOBJC_SUPER_scope = 0;
8588 /* _n_Method (id self, SEL sel, ...)
8590 struct objc_super _S;
8591 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8595 get_super_receiver (void)
8597 if (objc_method_context)
8599 tree super_expr, super_expr_list;
8601 if (!UOBJC_SUPER_decl)
8603 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8604 objc_super_template);
8605 /* This prevents `unused variable' warnings when compiling with -Wall. */
8606 TREE_USED (UOBJC_SUPER_decl) = 1;
8607 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8608 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8609 UOBJC_SUPER_scope = objc_get_current_scope ();
8612 /* Set receiver to self. */
8613 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8614 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8615 super_expr_list = super_expr;
8617 /* Set class to begin searching. */
8618 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8619 get_identifier ("super_class"));
8621 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8623 /* [_cls, __cls]Super are "pre-built" in
8624 synth_forward_declarations. */
8626 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8627 ((TREE_CODE (objc_method_context)
8628 == INSTANCE_METHOD_DECL)
8630 : uucls_super_ref));
8634 /* We have a category. */
8636 tree super_name = CLASS_SUPER_NAME (implementation_template);
8639 /* Barf if super used in a category of Object. */
8642 error ("no super class declared in interface for %qs",
8643 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8644 return error_mark_node;
8647 if (flag_next_runtime && !flag_zero_link)
8649 super_class = objc_get_class_reference (super_name);
8650 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8651 /* If we are in a class method, we must retrieve the
8652 _metaclass_ for the current class, pointed at by
8653 the class's "isa" pointer. The following assumes that
8654 "isa" is the first ivar in a class (which it must be). */
8656 = build_indirect_ref
8657 (build_c_cast (build_pointer_type (objc_class_type),
8658 super_class), "unary *");
8662 add_class_reference (super_name);
8663 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8664 ? objc_get_class_decl : objc_get_meta_class_decl);
8665 assemble_external (super_class);
8667 = build_function_call
8671 my_build_string_pointer
8672 (IDENTIFIER_LENGTH (super_name) + 1,
8673 IDENTIFIER_POINTER (super_name))));
8677 = build_modify_expr (super_expr, NOP_EXPR,
8678 build_c_cast (TREE_TYPE (super_expr),
8682 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8684 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8685 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8687 return super_expr_list;
8691 error ("[super ...] must appear in a method context");
8692 return error_mark_node;
8696 /* When exiting a scope, sever links to a 'super' declaration (if any)
8697 therein contained. */
8700 objc_clear_super_receiver (void)
8702 if (objc_method_context
8703 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8704 UOBJC_SUPER_decl = 0;
8705 UOBJC_SUPER_scope = 0;
8710 objc_finish_method_definition (tree fndecl)
8712 /* We cannot validly inline ObjC methods, at least not without a language
8713 extension to declare that a method need not be dynamically
8714 dispatched, so suppress all thoughts of doing so. */
8715 DECL_INLINE (fndecl) = 0;
8716 DECL_UNINLINABLE (fndecl) = 1;
8719 /* The C++ front-end will have called finish_function() for us. */
8723 METHOD_ENCODING (objc_method_context)
8724 = encode_method_prototype (objc_method_context);
8726 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8727 since the optimizer may find "may be used before set" errors. */
8728 objc_method_context = NULL_TREE;
8730 if (should_call_super_dealloc)
8731 warning (0, "method possibly missing a [super dealloc] call");
8736 lang_report_error_function (tree decl)
8738 if (objc_method_context)
8740 fprintf (stderr, "In method %qs\n",
8741 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8750 /* Given a tree DECL node, produce a printable description of it in the given
8751 buffer, overwriting the buffer. */
8754 gen_declaration (tree decl)
8760 gen_type_name_0 (TREE_TYPE (decl));
8762 if (DECL_NAME (decl))
8764 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8765 strcat (errbuf, " ");
8767 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8770 if (DECL_INITIAL (decl)
8771 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8772 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8773 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8779 /* Given a tree TYPE node, produce a printable description of it in the given
8780 buffer, overwriting the buffer. */
8783 gen_type_name_0 (tree type)
8785 tree orig = type, proto;
8787 if (TYPE_P (type) && TYPE_NAME (type))
8788 type = TYPE_NAME (type);
8789 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8791 tree inner = TREE_TYPE (type);
8793 while (TREE_CODE (inner) == ARRAY_TYPE)
8794 inner = TREE_TYPE (inner);
8796 gen_type_name_0 (inner);
8798 if (!POINTER_TYPE_P (inner))
8799 strcat (errbuf, " ");
8801 if (POINTER_TYPE_P (type))
8802 strcat (errbuf, "*");
8804 while (type != inner)
8806 strcat (errbuf, "[");
8808 if (TYPE_DOMAIN (type))
8812 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8814 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8815 strcat (errbuf, sz);
8818 strcat (errbuf, "]");
8819 type = TREE_TYPE (type);
8825 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8826 type = DECL_NAME (type);
8828 strcat (errbuf, IDENTIFIER_POINTER (type));
8830 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8831 if (objc_is_id (orig))
8832 orig = TREE_TYPE (orig);
8834 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8838 strcat (errbuf, " <");
8842 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8843 proto = TREE_CHAIN (proto);
8844 strcat (errbuf, proto ? ", " : ">");
8853 gen_type_name (tree type)
8857 return gen_type_name_0 (type);
8860 /* Given a method tree, put a printable description into the given
8861 buffer (overwriting) and return a pointer to the buffer. */
8864 gen_method_decl (tree method)
8868 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8869 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8870 strcat (errbuf, ")");
8871 chain = METHOD_SEL_ARGS (method);
8875 /* We have a chain of keyword_decls. */
8878 if (KEYWORD_KEY_NAME (chain))
8879 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8881 strcat (errbuf, ":(");
8882 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8883 strcat (errbuf, ")");
8885 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8886 if ((chain = TREE_CHAIN (chain)))
8887 strcat (errbuf, " ");
8891 if (METHOD_ADD_ARGS (method))
8893 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8895 /* Know we have a chain of parm_decls. */
8898 strcat (errbuf, ", ");
8899 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8900 chain = TREE_CHAIN (chain);
8903 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8904 strcat (errbuf, ", ...");
8909 /* We have a unary selector. */
8910 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8918 /* Dump an @interface declaration of the supplied class CHAIN to the
8919 supplied file FP. Used to implement the -gen-decls option (which
8920 prints out an @interface declaration of all classes compiled in
8921 this run); potentially useful for debugging the compiler too. */
8923 dump_interface (FILE *fp, tree chain)
8925 /* FIXME: A heap overflow here whenever a method (or ivar)
8926 declaration is so long that it doesn't fit in the buffer. The
8927 code and all the related functions should be rewritten to avoid
8928 using fixed size buffers. */
8929 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8930 tree ivar_decls = CLASS_RAW_IVARS (chain);
8931 tree nst_methods = CLASS_NST_METHODS (chain);
8932 tree cls_methods = CLASS_CLS_METHODS (chain);
8934 fprintf (fp, "\n@interface %s", my_name);
8936 /* CLASS_SUPER_NAME is used to store the superclass name for
8937 classes, and the category name for categories. */
8938 if (CLASS_SUPER_NAME (chain))
8940 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8942 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8943 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8945 fprintf (fp, " (%s)\n", name);
8949 fprintf (fp, " : %s\n", name);
8955 /* FIXME - the following doesn't seem to work at the moment. */
8958 fprintf (fp, "{\n");
8961 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8962 ivar_decls = TREE_CHAIN (ivar_decls);
8965 fprintf (fp, "}\n");
8970 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8971 nst_methods = TREE_CHAIN (nst_methods);
8976 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8977 cls_methods = TREE_CHAIN (cls_methods);
8980 fprintf (fp, "@end\n");
8983 /* Demangle function for Objective-C */
8985 objc_demangle (const char *mangled)
8987 char *demangled, *cp;
8989 if (mangled[0] == '_' &&
8990 (mangled[1] == 'i' || mangled[1] == 'c') &&
8993 cp = demangled = xmalloc(strlen(mangled) + 2);
8994 if (mangled[1] == 'i')
8995 *cp++ = '-'; /* for instance method */
8997 *cp++ = '+'; /* for class method */
8998 *cp++ = '['; /* opening left brace */
8999 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9000 while (*cp && *cp == '_')
9001 cp++; /* skip any initial underbars in class name */
9002 cp = strchr(cp, '_'); /* find first non-initial underbar */
9005 free(demangled); /* not mangled name */
9008 if (cp[1] == '_') /* easy case: no category name */
9010 *cp++ = ' '; /* replace two '_' with one ' ' */
9011 strcpy(cp, mangled + (cp - demangled) + 2);
9015 *cp++ = '('; /* less easy case: category name */
9016 cp = strchr(cp, '_');
9019 free(demangled); /* not mangled name */
9023 *cp++ = ' '; /* overwriting 1st char of method name... */
9024 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9026 while (*cp && *cp == '_')
9027 cp++; /* skip any initial underbars in method name */
9030 *cp = ':'; /* replace remaining '_' with ':' */
9031 *cp++ = ']'; /* closing right brace */
9032 *cp++ = 0; /* string terminator */
9036 return mangled; /* not an objc mangled name */
9040 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9042 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9048 gcc_obstack_init (&util_obstack);
9049 util_firstobj = (char *) obstack_finish (&util_obstack);
9051 errbuf = (char *) xmalloc (1024 * 10);
9053 synth_module_prologue ();
9059 struct imp_entry *impent;
9061 /* The internally generated initializers appear to have missing braces.
9062 Don't warn about this. */
9063 int save_warn_missing_braces = warn_missing_braces;
9064 warn_missing_braces = 0;
9066 /* A missing @end may not be detected by the parser. */
9067 if (objc_implementation_context)
9069 warning (0, "%<@end%> missing in implementation context");
9070 finish_class (objc_implementation_context);
9071 objc_ivar_chain = NULL_TREE;
9072 objc_implementation_context = NULL_TREE;
9075 /* Process the static instances here because initialization of objc_symtab
9077 if (objc_static_instances)
9078 generate_static_references ();
9080 if (imp_list || class_names_chain
9081 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9082 generate_objc_symtab_decl ();
9084 for (impent = imp_list; impent; impent = impent->next)
9086 objc_implementation_context = impent->imp_context;
9087 implementation_template = impent->imp_template;
9089 UOBJC_CLASS_decl = impent->class_decl;
9090 UOBJC_METACLASS_decl = impent->meta_decl;
9092 /* Dump the @interface of each class as we compile it, if the
9093 -gen-decls option is in use. TODO: Dump the classes in the
9094 order they were found, rather than in reverse order as we
9096 if (flag_gen_declaration)
9098 dump_interface (gen_declaration_file, objc_implementation_context);
9101 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9103 /* all of the following reference the string pool... */
9104 generate_ivar_lists ();
9105 generate_dispatch_tables ();
9106 generate_shared_structures (impent->has_cxx_cdtors
9107 ? CLS_HAS_CXX_STRUCTORS
9112 generate_dispatch_tables ();
9113 generate_category (objc_implementation_context);
9117 /* If we are using an array of selectors, we must always
9118 finish up the array decl even if no selectors were used. */
9119 if (! flag_next_runtime || sel_ref_chain)
9120 build_selector_translation_table ();
9123 generate_protocols ();
9125 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9126 generate_objc_image_info ();
9128 /* Arrange for ObjC data structures to be initialized at run time. */
9129 if (objc_implementation_context || class_names_chain || objc_static_instances
9130 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9132 build_module_descriptor ();
9134 if (!flag_next_runtime)
9135 build_module_initializer_routine ();
9138 /* Dump the class references. This forces the appropriate classes
9139 to be linked into the executable image, preserving unix archive
9140 semantics. This can be removed when we move to a more dynamically
9141 linked environment. */
9143 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9145 handle_class_ref (chain);
9146 if (TREE_PURPOSE (chain))
9147 generate_classref_translation_entry (chain);
9150 for (impent = imp_list; impent; impent = impent->next)
9151 handle_impent (impent);
9153 /* Dump the string table last. */
9155 generate_strings ();
9162 /* Run through the selector hash tables and print a warning for any
9163 selector which has multiple methods. */
9165 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9167 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9168 check_duplicates (hsh, 0, 1);
9169 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9170 check_duplicates (hsh, 0, 1);
9174 warn_missing_braces = save_warn_missing_braces;
9177 /* Subroutines of finish_objc. */
9180 generate_classref_translation_entry (tree chain)
9182 tree expr, decl, type;
9184 decl = TREE_PURPOSE (chain);
9185 type = TREE_TYPE (decl);
9187 expr = add_objc_string (TREE_VALUE (chain), class_names);
9188 expr = convert (type, expr); /* cast! */
9190 /* The decl that is the one that we
9191 forward declared in build_class_reference. */
9192 finish_var_decl (decl, expr);
9197 handle_class_ref (tree chain)
9199 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9200 char *string = (char *) alloca (strlen (name) + 30);
9204 sprintf (string, "%sobjc_class_name_%s",
9205 (flag_next_runtime ? "." : "__"), name);
9207 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9208 if (flag_next_runtime)
9210 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9215 /* Make a decl for this name, so we can use its address in a tree. */
9216 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9217 DECL_EXTERNAL (decl) = 1;
9218 TREE_PUBLIC (decl) = 1;
9221 rest_of_decl_compilation (decl, 0, 0);
9223 /* Make a decl for the address. */
9224 sprintf (string, "%sobjc_class_ref_%s",
9225 (flag_next_runtime ? "." : "__"), name);
9226 exp = build1 (ADDR_EXPR, string_type_node, decl);
9227 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9228 DECL_INITIAL (decl) = exp;
9229 TREE_STATIC (decl) = 1;
9230 TREE_USED (decl) = 1;
9233 rest_of_decl_compilation (decl, 0, 0);
9237 handle_impent (struct imp_entry *impent)
9241 objc_implementation_context = impent->imp_context;
9242 implementation_template = impent->imp_template;
9244 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9246 const char *const class_name =
9247 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9249 string = (char *) alloca (strlen (class_name) + 30);
9251 sprintf (string, "%sobjc_class_name_%s",
9252 (flag_next_runtime ? "." : "__"), class_name);
9254 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9256 const char *const class_name =
9257 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9258 const char *const class_super_name =
9259 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9261 string = (char *) alloca (strlen (class_name)
9262 + strlen (class_super_name) + 30);
9264 /* Do the same for categories. Even though no references to
9265 these symbols are generated automatically by the compiler, it
9266 gives you a handle to pull them into an archive by hand. */
9267 sprintf (string, "*%sobjc_category_name_%s_%s",
9268 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9273 #ifdef ASM_DECLARE_CLASS_REFERENCE
9274 if (flag_next_runtime)
9276 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9284 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9285 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9286 TREE_PUBLIC (decl) = 1;
9287 TREE_READONLY (decl) = 1;
9288 TREE_USED (decl) = 1;
9289 TREE_CONSTANT (decl) = 1;
9290 DECL_CONTEXT (decl) = 0;
9291 DECL_ARTIFICIAL (decl) = 1;
9292 DECL_INITIAL (decl) = init;
9293 assemble_variable (decl, 1, 0, 0);
9297 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9298 later requires that ObjC translation units participating in F&C be
9299 specially marked. The following routine accomplishes this. */
9301 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9304 generate_objc_image_info (void)
9306 tree decl, initlist;
9308 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9309 | (flag_objc_gc ? 2 : 0));
9311 decl = start_var_decl (build_array_type
9313 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9314 "_OBJC_IMAGE_INFO");
9316 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9317 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9318 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9320 finish_var_decl (decl, initlist);
9323 /* Look up ID as an instance variable. OTHER contains the result of
9324 the C or C++ lookup, which we may want to use instead. */
9327 objc_lookup_ivar (tree other, tree id)
9331 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9332 if (!objc_method_context)
9335 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9336 /* We have a message to super. */
9337 return get_super_receiver ();
9339 /* In a class method, look up an instance variable only as a last
9341 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9342 && other && other != error_mark_node)
9345 /* Look up the ivar, but do not use it if it is not accessible. */
9346 ivar = is_ivar (objc_ivar_chain, id);
9348 if (!ivar || is_private (ivar))
9351 /* In an instance method, a local variable (or parameter) may hide the
9352 instance variable. */
9353 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9354 && other && other != error_mark_node
9356 && CP_DECL_CONTEXT (other) != global_namespace)
9358 && !DECL_FILE_SCOPE_P (other))
9361 warning (0, "local declaration of %qs hides instance variable",
9362 IDENTIFIER_POINTER (id));
9367 /* At this point, we are either in an instance method with no obscuring
9368 local definitions, or in a class method with no alternate definitions
9370 return build_ivar_reference (id);
9373 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9374 needs to be done if we are calling a function through a cast. */
9377 objc_rewrite_function_call (tree function, tree params)
9379 if (TREE_CODE (function) == NOP_EXPR
9380 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9381 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9384 function = build (OBJ_TYPE_REF, TREE_TYPE (function),
9385 TREE_OPERAND (function, 0),
9386 TREE_VALUE (params), size_zero_node);
9392 /* Look for the special case of OBJC_TYPE_REF with the address of
9393 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9396 enum gimplify_status
9397 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9399 enum gimplify_status r0, r1;
9400 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9401 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9402 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9405 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9406 value of the OBJ_TYPE_REF, so force them to be emitted
9407 during subexpression evaluation rather than after the
9408 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9409 C to use direct rather than indirect calls when the
9410 object expression has a postincrement. */
9411 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9412 is_gimple_val, fb_rvalue);
9413 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9414 is_gimple_val, fb_rvalue);
9416 return MIN (r0, r1);
9420 return cp_gimplify_expr (expr_p, pre_p, post_p);
9422 return c_gimplify_expr (expr_p, pre_p, post_p);
9426 /* Given a CALL expression, find the function being called. The ObjC
9427 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9430 objc_get_callee_fndecl (tree call_expr)
9432 tree addr = TREE_OPERAND (call_expr, 0);
9433 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9436 addr = OBJ_TYPE_REF_EXPR (addr);
9438 /* If the address is just `&f' for some function `f', then we know
9439 that `f' is being called. */
9440 if (TREE_CODE (addr) == ADDR_EXPR
9441 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9442 return TREE_OPERAND (addr, 0);
9447 #include "gt-objc-objc-act.h"