1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
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 /* If gen_declaration desired, open the output file. */
488 if (flag_gen_declaration)
490 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
491 gen_declaration_file = fopen (dumpname, "w");
492 if (gen_declaration_file == 0)
493 fatal_error ("can't open %s: %m", dumpname);
497 if (flag_next_runtime)
499 TAG_GETCLASS = "objc_getClass";
500 TAG_GETMETACLASS = "objc_getMetaClass";
501 TAG_MSGSEND = "objc_msgSend";
502 TAG_MSGSENDSUPER = "objc_msgSendSuper";
503 TAG_MSGSEND_STRET = "objc_msgSend_stret";
504 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
505 default_constant_string_class_name = "NSConstantString";
509 TAG_GETCLASS = "objc_get_class";
510 TAG_GETMETACLASS = "objc_get_meta_class";
511 TAG_MSGSEND = "objc_msg_lookup";
512 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
513 /* GNU runtime does not provide special functions to support
514 structure-returning methods. */
515 default_constant_string_class_name = "NXConstantString";
516 flag_typed_selectors = 1;
521 if (print_struct_values)
522 generate_struct_by_value_array ();
528 objc_finish_file (void)
530 mark_referenced_methods ();
533 /* We need to instantiate templates _before_ we emit ObjC metadata;
534 if we do not, some metadata (such as selectors) may go missing. */
536 instantiate_pending_templates (0);
539 /* Finalize Objective-C runtime data. No need to generate tables
540 and code if only checking syntax, or if generating a PCH file. */
541 if (!flag_syntax_only && !pch_file)
544 if (gen_declaration_file)
545 fclose (gen_declaration_file);
548 /* Return the first occurrence of a method declaration corresponding
549 to sel_name in rproto_list. Search rproto_list recursively.
550 If is_class is 0, search for instance methods, otherwise for class
553 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
559 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
561 p = TREE_VALUE (rproto);
563 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
565 if ((fnd = lookup_method (is_class
566 ? PROTOCOL_CLS_METHODS (p)
567 : PROTOCOL_NST_METHODS (p), sel_name)))
569 else if (PROTOCOL_LIST (p))
570 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
575 ; /* An identifier...if we could not find a protocol. */
586 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
590 /* Make sure the protocol is supported by the object on the rhs. */
591 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
594 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
596 p = TREE_VALUE (rproto);
598 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
603 else if (PROTOCOL_LIST (p))
604 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
613 ; /* An identifier...if we could not find a protocol. */
620 objc_start_class_interface (tree klass, tree super_class, tree protos)
622 objc_interface_context
624 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
625 objc_public_flag = 0;
629 objc_start_category_interface (tree klass, tree categ, tree protos)
631 objc_interface_context
632 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
634 = continue_class (objc_interface_context);
638 objc_start_protocol (tree name, tree protos)
640 objc_interface_context
641 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
645 objc_continue_interface (void)
648 = continue_class (objc_interface_context);
652 objc_finish_interface (void)
654 finish_class (objc_interface_context);
655 objc_interface_context = NULL_TREE;
659 objc_start_class_implementation (tree klass, tree super_class)
661 objc_implementation_context
663 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
664 objc_public_flag = 0;
668 objc_start_category_implementation (tree klass, tree categ)
670 objc_implementation_context
671 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
673 = continue_class (objc_implementation_context);
677 objc_continue_implementation (void)
680 = continue_class (objc_implementation_context);
684 objc_finish_implementation (void)
687 if (flag_objc_call_cxx_cdtors)
688 objc_generate_cxx_cdtors ();
691 if (objc_implementation_context)
693 finish_class (objc_implementation_context);
694 objc_ivar_chain = NULL_TREE;
695 objc_implementation_context = NULL_TREE;
698 warning (0, "%<@end%> must appear in an @implementation context");
702 objc_set_visibility (int visibility)
704 objc_public_flag = visibility;
708 objc_set_method_type (enum tree_code type)
710 objc_inherit_code = (type == PLUS_EXPR
712 : INSTANCE_METHOD_DECL);
716 objc_build_method_signature (tree rettype, tree selector,
717 tree optparms, bool ellipsis)
719 return build_method_decl (objc_inherit_code, rettype, selector,
724 objc_add_method_declaration (tree decl)
726 if (!objc_interface_context)
727 fatal_error ("method declaration not in @interface context");
729 objc_add_method (objc_interface_context,
731 objc_inherit_code == CLASS_METHOD_DECL);
735 objc_start_method_definition (tree decl)
737 if (!objc_implementation_context)
738 fatal_error ("method definition not in @implementation context");
740 objc_add_method (objc_implementation_context,
742 objc_inherit_code == CLASS_METHOD_DECL);
743 start_method_def (decl);
747 objc_add_instance_variable (tree decl)
749 (void) add_instance_variable (objc_ivar_context,
754 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
758 objc_is_reserved_word (tree ident)
760 unsigned char code = C_RID_CODE (ident);
762 return (OBJC_IS_AT_KEYWORD (code)
763 || code == RID_CLASS || code == RID_PUBLIC
764 || code == RID_PROTECTED || code == RID_PRIVATE
765 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
768 /* Return true if TYPE is 'id'. */
771 objc_is_object_id (tree type)
773 return OBJC_TYPE_NAME (type) == objc_object_id;
777 objc_is_class_id (tree type)
779 return OBJC_TYPE_NAME (type) == objc_class_id;
782 /* Construct a C struct with same name as KLASS, a base struct with tag
783 SUPER_NAME (if any), and FIELDS indicated. */
786 objc_build_struct (tree klass, tree fields, tree super_name)
788 tree name = CLASS_NAME (klass);
789 tree s = start_struct (RECORD_TYPE, name);
790 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
791 tree t, objc_info = NULL_TREE;
795 /* Prepend a packed variant of the base class into the layout. This
796 is necessary to preserve ObjC ABI compatibility. */
797 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
798 tree field = TYPE_FIELDS (super);
800 while (field && TREE_CHAIN (field)
801 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
802 field = TREE_CHAIN (field);
804 /* For ObjC ABI purposes, the "packed" size of a base class is the
805 the sum of the offset and the size (in bits) of the last field
808 = (field && TREE_CODE (field) == FIELD_DECL
809 ? size_binop (PLUS_EXPR,
810 size_binop (PLUS_EXPR,
813 convert (bitsizetype,
814 DECL_FIELD_OFFSET (field)),
815 bitsize_int (BITS_PER_UNIT)),
816 DECL_FIELD_BIT_OFFSET (field)),
818 : bitsize_zero_node);
819 DECL_SIZE_UNIT (base)
820 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
821 size_int (BITS_PER_UNIT));
822 DECL_ARTIFICIAL (base) = 1;
823 DECL_ALIGN (base) = 1;
824 DECL_FIELD_CONTEXT (base) = s;
826 DECL_FIELD_IS_BASE (base) = 1;
829 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
830 #endif /* are following the ObjC ABI here. */
831 TREE_CHAIN (base) = fields;
835 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
836 in all variants of this RECORD_TYPE to be clobbered, but it is therein
837 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
838 Hence, we must squirrel away the ObjC-specific information before calling
839 finish_struct(), and then reinstate it afterwards. */
841 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
843 = chainon (objc_info,
844 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
846 /* Point the struct at its related Objective-C class. */
847 INIT_TYPE_OBJC_INFO (s);
848 TYPE_OBJC_INTERFACE (s) = klass;
850 s = finish_struct (s, fields, NULL_TREE);
852 for (t = TYPE_NEXT_VARIANT (s); t;
853 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
855 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
856 /* Replace the IDENTIFIER_NODE with an actual @interface. */
857 TYPE_OBJC_INTERFACE (t) = klass;
860 /* Use TYPE_BINFO structures to point at the super class, if any. */
861 objc_xref_basetypes (s, super);
863 /* Mark this struct as a class template. */
864 CLASS_STATIC_TEMPLATE (klass) = s;
869 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
870 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
873 objc_build_volatilized_type (tree type)
877 /* Check if we have not constructed the desired variant already. */
878 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
880 /* The type qualifiers must (obviously) match up. */
881 if (!TYPE_VOLATILE (t)
882 || (TYPE_READONLY (t) != TYPE_READONLY (type))
883 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
886 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
887 info, if any) must match up. */
888 if (POINTER_TYPE_P (t)
889 && (TREE_TYPE (t) != TREE_TYPE (type)))
892 /* Everything matches up! */
896 /* Ok, we could not re-use any of the pre-existing variants. Create
898 t = build_variant_type_copy (type);
899 TYPE_VOLATILE (t) = 1;
901 /* Set up the canonical type information. */
902 if (TYPE_STRUCTURAL_EQUALITY_P (type))
903 SET_TYPE_STRUCTURAL_EQUALITY (t);
904 else if (TYPE_CANONICAL (type) != type)
905 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
907 TYPE_CANONICAL (t) = t;
912 /* Mark DECL as being 'volatile' for purposes of Darwin
913 _setjmp()/_longjmp() exception handling. Called from
914 objc_mark_locals_volatile(). */
916 objc_volatilize_decl (tree decl)
918 /* Do not mess with variables that are 'static' or (already)
920 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
921 && (TREE_CODE (decl) == VAR_DECL
922 || TREE_CODE (decl) == PARM_DECL))
924 tree t = TREE_TYPE (decl);
925 struct volatilized_type key;
928 t = objc_build_volatilized_type (t);
930 loc = htab_find_slot (volatilized_htab, &key, INSERT);
934 *loc = ggc_alloc (sizeof (key));
935 ((struct volatilized_type *) *loc)->type = t;
938 TREE_TYPE (decl) = t;
939 TREE_THIS_VOLATILE (decl) = 1;
940 TREE_SIDE_EFFECTS (decl) = 1;
941 DECL_REGISTER (decl) = 0;
943 C_DECL_REGISTER (decl) = 0;
948 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
949 (including its categories and superclasses) or by object type TYP.
950 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
953 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
955 bool class_type = (cls != NULL_TREE);
961 /* Check protocols adopted by the class and its categories. */
962 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
964 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
968 /* Repeat for superclasses. */
969 cls = lookup_interface (CLASS_SUPER_NAME (cls));
972 /* Check for any protocols attached directly to the object type. */
973 if (TYPE_HAS_OBJC_INFO (typ))
975 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
981 strcpy (errbuf, class_type ? "class \'" : "type \'");
982 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
983 strcat (errbuf, "\' does not ");
984 /* NB: Types 'id' and 'Class' cannot reasonably be described as
985 "implementing" a given protocol, since they do not have an
987 strcat (errbuf, class_type ? "implement" : "conform to");
988 strcat (errbuf, " the \'");
989 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
990 strcat (errbuf, "\' protocol");
997 /* Check if class RCLS and instance struct type RTYP conform to at least the
998 same protocols that LCLS and LTYP conform to. */
1001 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1004 bool have_lproto = false;
1008 /* NB: We do _not_ look at categories defined for LCLS; these may or
1009 may not get loaded in, and therefore it is unreasonable to require
1010 that RCLS/RTYP must implement any of their protocols. */
1011 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1015 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1019 /* Repeat for superclasses. */
1020 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1023 /* Check for any protocols attached directly to the object type. */
1024 if (TYPE_HAS_OBJC_INFO (ltyp))
1026 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1030 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1035 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1036 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1037 away with simply checking for 'id' or 'Class' (!RCLS), since this
1038 routine will not get called in other cases. */
1039 return have_lproto || (rcls != NULL_TREE);
1042 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1043 an instance of RTYP to an instance of LTYP or to compare the two
1044 (if ARGNO is equal to -3), per ObjC type system rules. Before
1045 returning 'true', this routine may issue warnings related to, e.g.,
1046 protocol conformance. When returning 'false', the routine must
1047 produce absolutely no warnings; the C or C++ front-end will do so
1048 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1049 the routine must return 'false'.
1051 The ARGNO parameter is encoded as follows:
1052 >= 1 Parameter number (CALLEE contains function being called);
1056 -3 Comparison (LTYP and RTYP may match in either direction). */
1059 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1061 tree lcls, rcls, lproto, rproto;
1062 bool pointers_compatible;
1064 /* We must be dealing with pointer types */
1065 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1070 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1071 rtyp = TREE_TYPE (rtyp);
1073 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1075 /* Past this point, we are only interested in ObjC class instances,
1076 or 'id' or 'Class'. */
1077 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1080 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1081 && !TYPE_HAS_OBJC_INFO (ltyp))
1084 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1085 && !TYPE_HAS_OBJC_INFO (rtyp))
1088 /* Past this point, we are committed to returning 'true' to the caller.
1089 However, we can still warn about type and/or protocol mismatches. */
1091 if (TYPE_HAS_OBJC_INFO (ltyp))
1093 lcls = TYPE_OBJC_INTERFACE (ltyp);
1094 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1097 lcls = lproto = NULL_TREE;
1099 if (TYPE_HAS_OBJC_INFO (rtyp))
1101 rcls = TYPE_OBJC_INTERFACE (rtyp);
1102 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1105 rcls = rproto = NULL_TREE;
1107 /* If we could not find an @interface declaration, we must have
1108 only seen a @class declaration; for purposes of type comparison,
1109 treat it as a stand-alone (root) class. */
1111 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1114 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1117 /* If either type is an unqualified 'id', we're done. */
1118 if ((!lproto && objc_is_object_id (ltyp))
1119 || (!rproto && objc_is_object_id (rtyp)))
1122 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1124 /* If the underlying types are the same, and at most one of them has
1125 a protocol list, we do not need to issue any diagnostics. */
1126 if (pointers_compatible && (!lproto || !rproto))
1129 /* If exactly one of the types is 'Class', issue a diagnostic; any
1130 exceptions of this rule have already been handled. */
1131 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1132 pointers_compatible = false;
1133 /* Otherwise, check for inheritance relations. */
1136 if (!pointers_compatible)
1138 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1140 if (!pointers_compatible)
1141 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1143 if (!pointers_compatible && argno == -3)
1144 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1147 /* If the pointers match modulo protocols, check for protocol conformance
1149 if (pointers_compatible)
1151 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1154 if (!pointers_compatible && argno == -3)
1155 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1159 if (!pointers_compatible)
1161 /* NB: For the time being, we shall make our warnings look like their
1162 C counterparts. In the future, we may wish to make them more
1167 warning (0, "comparison of distinct Objective-C types lacks a cast");
1171 warning (0, "initialization from distinct Objective-C type");
1175 warning (0, "assignment from distinct Objective-C type");
1179 warning (0, "distinct Objective-C type in return");
1183 warning (0, "passing argument %d of %qE from distinct "
1184 "Objective-C type", argno, callee);
1192 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1193 lives in the volatilized hash table, ignore the 'volatile' bit when
1194 making the comparison. */
1197 objc_type_quals_match (tree ltyp, tree rtyp)
1199 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1200 struct volatilized_type key;
1204 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1205 lquals &= ~TYPE_QUAL_VOLATILE;
1209 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1210 rquals &= ~TYPE_QUAL_VOLATILE;
1212 return (lquals == rquals);
1216 /* Determine if CHILD is derived from PARENT. The routine assumes that
1217 both parameters are RECORD_TYPEs, and is non-reflexive. */
1220 objc_derived_from_p (tree parent, tree child)
1222 parent = TYPE_MAIN_VARIANT (parent);
1224 for (child = TYPE_MAIN_VARIANT (child);
1225 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1227 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1228 (TYPE_BINFO (child),
1231 if (child == parent)
1240 objc_build_component_ref (tree datum, tree component)
1242 /* If COMPONENT is NULL, the caller is referring to the anonymous
1243 base class field. */
1246 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1248 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1251 /* The 'build_component_ref' routine has been removed from the C++
1252 front-end, but 'finish_class_member_access_expr' seems to be
1253 a worthy substitute. */
1255 return finish_class_member_access_expr (datum, component, false,
1256 tf_warning_or_error);
1258 return build_component_ref (datum, component);
1262 /* Recursively copy inheritance information rooted at BINFO. To do this,
1263 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1266 objc_copy_binfo (tree binfo)
1268 tree btype = BINFO_TYPE (binfo);
1269 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1273 BINFO_TYPE (binfo2) = btype;
1274 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1275 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1277 /* Recursively copy base binfos of BINFO. */
1278 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1280 tree base_binfo2 = objc_copy_binfo (base_binfo);
1282 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1283 BINFO_BASE_APPEND (binfo2, base_binfo2);
1289 /* Record superclass information provided in BASETYPE for ObjC class REF.
1290 This is loosely based on cp/decl.c:xref_basetypes(). */
1293 objc_xref_basetypes (tree ref, tree basetype)
1295 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1297 TYPE_BINFO (ref) = binfo;
1298 BINFO_OFFSET (binfo) = size_zero_node;
1299 BINFO_TYPE (binfo) = ref;
1303 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1305 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1306 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1307 BINFO_BASE_APPEND (binfo, base_binfo);
1308 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1313 volatilized_hash (const void *ptr)
1315 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1317 return htab_hash_pointer(typ);
1321 volatilized_eq (const void *ptr1, const void *ptr2)
1323 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1324 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1326 return typ1 == typ2;
1329 /* Called from finish_decl. */
1332 objc_check_decl (tree decl)
1334 tree type = TREE_TYPE (decl);
1336 if (TREE_CODE (type) != RECORD_TYPE)
1338 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1339 error ("statically allocated instance of Objective-C class %qs",
1340 IDENTIFIER_POINTER (type));
1343 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1344 either name an Objective-C class, or refer to the special 'id' or 'Class'
1345 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1348 objc_get_protocol_qualified_type (tree interface, tree protocols)
1350 /* If INTERFACE is not provided, default to 'id'. */
1351 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1352 bool is_ptr = (type != NULL_TREE);
1356 type = objc_is_class_name (interface);
1359 type = xref_tag (RECORD_TYPE, type);
1366 type = build_variant_type_copy (type);
1368 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1372 tree orig_pointee_type = TREE_TYPE (type);
1373 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1375 /* Set up the canonical type information. */
1376 TYPE_CANONICAL (type)
1377 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1379 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1380 type = TREE_TYPE (type);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1385 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1390 type = TYPE_POINTER_TO (type);
1392 TYPE_OBJC_INTERFACE (type)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1404 check_protocol_recursively (tree proto, tree list)
1408 for (p = list; p; p = TREE_CHAIN (p))
1410 tree pp = TREE_VALUE (p);
1412 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1413 pp = lookup_protocol (pp);
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1419 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1427 lookup_and_install_protocols (tree protocols)
1430 tree return_value = NULL_TREE;
1432 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1434 tree ident = TREE_VALUE (proto);
1435 tree p = lookup_protocol (ident);
1438 return_value = chainon (return_value,
1439 build_tree_list (NULL_TREE, p));
1440 else if (ident != error_mark_node)
1441 error ("cannot find protocol declaration for %qs",
1442 IDENTIFIER_POINTER (ident));
1445 return return_value;
1448 /* Create a declaration for field NAME of a given TYPE. */
1451 create_field_decl (tree type, const char *name)
1453 return build_decl (FIELD_DECL, get_identifier (name), type);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1460 start_var_decl (tree type, const char *name)
1462 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1464 TREE_STATIC (var) = 1;
1465 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var) = 1;
1467 DECL_ARTIFICIAL (var) = 1;
1468 DECL_CONTEXT (var) = NULL_TREE;
1470 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1476 /* Finish off the variable declaration created by start_var_decl(). */
1479 finish_var_decl (tree var, tree initializer)
1481 finish_decl (var, initializer, NULL_TREE);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1492 setup_string_decl (void)
1497 /* %s in format will provide room for terminating null */
1498 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1499 + strlen (constant_string_class_name);
1500 name = XNEWVEC (char, length);
1501 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1502 constant_string_class_name);
1503 constant_string_global_id = get_identifier (name);
1504 string_class_decl = lookup_name (constant_string_global_id);
1506 return string_class_decl;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1521 synth_module_prologue (void)
1524 enum debug_info_type save_write_symbols = write_symbols;
1525 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn'r been called yet. */
1529 write_symbols = NO_DEBUG;
1530 debug_hooks = &do_nothing_debug_hooks;
1533 push_lang_context (lang_name_c); /* extern "C" */
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id = get_identifier (TAG_OBJECT);
1539 objc_class_id = get_identifier (TAG_CLASS);
1541 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1542 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1544 objc_object_type = build_pointer_type (objc_object_reference);
1545 objc_class_type = build_pointer_type (objc_class_reference);
1547 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1548 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1555 TREE_NO_WARNING (type) = 1;
1556 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1559 TREE_NO_WARNING (type) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1564 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1565 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime)
1571 /* `struct objc_selector *' */
1573 = build_pointer_type (xref_tag (RECORD_TYPE,
1574 get_identifier (TAG_SELECTOR)));
1576 /* `const struct objc_selector *' */
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE,
1580 get_identifier (TAG_SELECTOR)),
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1587 get_identifier (TAG_SUPER)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr = build_pointer_type
1591 (xref_tag (RECORD_TYPE,
1592 get_identifier (UTAG_METHOD_LIST)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1596 objc_ivar_list_ptr = build_pointer_type
1597 (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_IVAR_LIST)));
1600 /* TREE_NOTHROW is cleared for the message-sending functions,
1601 because the function that gets called can throw in Obj-C++, or
1602 could itself call something that can throw even in Obj-C. */
1604 if (flag_next_runtime)
1606 /* NB: In order to call one of the ..._stret (struct-returning)
1607 functions, the function *MUST* first be cast to a signature that
1608 corresponds to the actual ObjC method being invoked. This is
1609 what is done by the build_objc_method_call() routine below. */
1611 /* id objc_msgSend (id, SEL, ...); */
1612 /* id objc_msgSendNonNil (id, SEL, ...); */
1613 /* id objc_msgSend_stret (id, SEL, ...); */
1614 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1616 = build_function_type (objc_object_type,
1617 tree_cons (NULL_TREE, objc_object_type,
1618 tree_cons (NULL_TREE, objc_selector_type,
1620 umsg_decl = add_builtin_function (TAG_MSGSEND,
1621 type, 0, NOT_BUILT_IN,
1623 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1624 type, 0, NOT_BUILT_IN,
1626 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1627 type, 0, NOT_BUILT_IN,
1629 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1630 type, 0, NOT_BUILT_IN,
1633 /* These can throw, because the function that gets called can throw
1634 in Obj-C++, or could itself call something that can throw even
1636 TREE_NOTHROW (umsg_decl) = 0;
1637 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1638 TREE_NOTHROW (umsg_stret_decl) = 0;
1639 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1641 /* id objc_msgSend_Fast (id, SEL, ...)
1642 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1643 #ifdef OFFS_MSGSEND_FAST
1644 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1645 type, 0, NOT_BUILT_IN,
1647 TREE_NOTHROW (umsg_fast_decl) = 0;
1648 DECL_ATTRIBUTES (umsg_fast_decl)
1649 = tree_cons (get_identifier ("hard_coded_address"),
1650 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1653 /* No direct dispatch available. */
1654 umsg_fast_decl = umsg_decl;
1657 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1658 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1660 = build_function_type (objc_object_type,
1661 tree_cons (NULL_TREE, objc_super_type,
1662 tree_cons (NULL_TREE, objc_selector_type,
1664 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1665 type, 0, NOT_BUILT_IN,
1667 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1668 type, 0, NOT_BUILT_IN, 0,
1670 TREE_NOTHROW (umsg_super_decl) = 0;
1671 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1675 /* GNU runtime messenger entry points. */
1677 /* typedef id (*IMP)(id, SEL, ...); */
1679 = build_pointer_type
1680 (build_function_type (objc_object_type,
1681 tree_cons (NULL_TREE, objc_object_type,
1682 tree_cons (NULL_TREE, objc_selector_type,
1685 /* IMP objc_msg_lookup (id, SEL); */
1687 = build_function_type (IMP_type,
1688 tree_cons (NULL_TREE, objc_object_type,
1689 tree_cons (NULL_TREE, objc_selector_type,
1690 OBJC_VOID_AT_END)));
1691 umsg_decl = add_builtin_function (TAG_MSGSEND,
1692 type, 0, NOT_BUILT_IN,
1694 TREE_NOTHROW (umsg_decl) = 0;
1696 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1698 = build_function_type (IMP_type,
1699 tree_cons (NULL_TREE, objc_super_type,
1700 tree_cons (NULL_TREE, objc_selector_type,
1701 OBJC_VOID_AT_END)));
1702 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1703 type, 0, NOT_BUILT_IN,
1705 TREE_NOTHROW (umsg_super_decl) = 0;
1707 /* The following GNU runtime entry point is called to initialize
1710 __objc_exec_class (void *); */
1712 = build_function_type (void_type_node,
1713 tree_cons (NULL_TREE, ptr_type_node,
1715 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1716 type, 0, NOT_BUILT_IN,
1720 /* id objc_getClass (const char *); */
1722 type = build_function_type (objc_object_type,
1723 tree_cons (NULL_TREE,
1724 const_string_type_node,
1728 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1731 /* id objc_getMetaClass (const char *); */
1733 objc_get_meta_class_decl
1734 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1736 build_class_template ();
1737 build_super_template ();
1738 build_protocol_template ();
1739 build_category_template ();
1740 build_objc_exception_stuff ();
1742 if (flag_next_runtime)
1743 build_next_objc_exception_stuff ();
1745 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1747 if (! flag_next_runtime)
1748 build_selector_table_decl ();
1750 /* Forward declare constant_string_id and constant_string_type. */
1751 if (!constant_string_class_name)
1752 constant_string_class_name = default_constant_string_class_name;
1754 constant_string_id = get_identifier (constant_string_class_name);
1755 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1757 /* Pre-build the following entities - for speed/convenience. */
1758 self_id = get_identifier ("self");
1759 ucmd_id = get_identifier ("_cmd");
1762 pop_lang_context ();
1765 write_symbols = save_write_symbols;
1766 debug_hooks = save_hooks;
1769 /* Ensure that the ivar list for NSConstantString/NXConstantString
1770 (or whatever was specified via `-fconstant-string-class')
1771 contains fields at least as large as the following three, so that
1772 the runtime can stomp on them with confidence:
1774 struct STRING_OBJECT_CLASS_NAME
1778 unsigned int length;
1782 check_string_class_template (void)
1784 tree field_decl = objc_get_class_ivars (constant_string_id);
1786 #define AT_LEAST_AS_LARGE_AS(F, T) \
1787 (F && TREE_CODE (F) == FIELD_DECL \
1788 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1789 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1791 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1794 field_decl = TREE_CHAIN (field_decl);
1795 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1798 field_decl = TREE_CHAIN (field_decl);
1799 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1801 #undef AT_LEAST_AS_LARGE_AS
1804 /* Avoid calling `check_string_class_template ()' more than once. */
1805 static GTY(()) int string_layout_checked;
1807 /* Construct an internal string layout to be used as a template for
1808 creating NSConstantString/NXConstantString instances. */
1811 objc_build_internal_const_str_type (void)
1813 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1814 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1815 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1817 TREE_CHAIN (field) = fields; fields = field;
1818 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1819 TREE_CHAIN (field) = fields; fields = field;
1820 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1822 finish_builtin_struct (type, "__builtin_ObjCString",
1828 /* Custom build_string which sets TREE_TYPE! */
1831 my_build_string (int len, const char *str)
1833 return fix_string_type (build_string (len, str));
1836 /* Build a string with contents STR and length LEN and convert it to a
1840 my_build_string_pointer (int len, const char *str)
1842 tree string = my_build_string (len, str);
1843 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1844 return build1 (ADDR_EXPR, ptrtype, string);
1848 string_hash (const void *ptr)
1850 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1851 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1852 int i, len = TREE_STRING_LENGTH (str);
1855 for (i = 0; i < len; i++)
1856 h = ((h * 613) + p[i]);
1862 string_eq (const void *ptr1, const void *ptr2)
1864 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1865 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1866 int len1 = TREE_STRING_LENGTH (str1);
1868 return (len1 == TREE_STRING_LENGTH (str2)
1869 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1873 /* Given a chain of STRING_CST's, build a static instance of
1874 NXConstantString which points at the concatenation of those
1875 strings. We place the string object in the __string_objects
1876 section of the __OBJC segment. The Objective-C runtime will
1877 initialize the isa pointers of the string objects to point at the
1878 NXConstantString class object. */
1881 objc_build_string_object (tree string)
1883 tree initlist, constructor, constant_string_class;
1886 struct string_descriptor *desc, key;
1889 /* Prep the string argument. */
1890 string = fix_string_type (string);
1891 TREE_SET_CODE (string, STRING_CST);
1892 length = TREE_STRING_LENGTH (string) - 1;
1894 /* Check whether the string class being used actually exists and has the
1895 correct ivar layout. */
1896 if (!string_layout_checked)
1898 string_layout_checked = -1;
1899 constant_string_class = lookup_interface (constant_string_id);
1900 internal_const_str_type = objc_build_internal_const_str_type ();
1902 if (!constant_string_class
1903 || !(constant_string_type
1904 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1905 error ("cannot find interface declaration for %qs",
1906 IDENTIFIER_POINTER (constant_string_id));
1907 /* The NSConstantString/NXConstantString ivar layout is now known. */
1908 else if (!check_string_class_template ())
1909 error ("interface %qs does not have valid constant string layout",
1910 IDENTIFIER_POINTER (constant_string_id));
1911 /* For the NeXT runtime, we can generate a literal reference
1912 to the string class, don't need to run a constructor. */
1913 else if (flag_next_runtime && !setup_string_decl ())
1914 error ("cannot find reference tag for class %qs",
1915 IDENTIFIER_POINTER (constant_string_id));
1918 string_layout_checked = 1; /* Success! */
1919 add_class_reference (constant_string_id);
1923 if (string_layout_checked == -1)
1924 return error_mark_node;
1926 /* Perhaps we already constructed a constant string just like this one? */
1927 key.literal = string;
1928 loc = htab_find_slot (string_htab, &key, INSERT);
1929 desc = (struct string_descriptor *) *loc;
1934 *loc = desc = GGC_NEW (struct string_descriptor);
1935 desc->literal = string;
1937 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1938 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1939 fields = TYPE_FIELDS (internal_const_str_type);
1941 = build_tree_list (fields,
1943 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1944 : build_int_cst (NULL_TREE, 0));
1945 fields = TREE_CHAIN (fields);
1946 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1948 fields = TREE_CHAIN (fields);
1949 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1951 constructor = objc_build_constructor (internal_const_str_type,
1952 nreverse (initlist));
1954 if (!flag_next_runtime)
1956 = objc_add_static_instance (constructor, constant_string_type);
1959 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1960 DECL_INITIAL (var) = constructor;
1961 TREE_STATIC (var) = 1;
1962 pushdecl_top_level (var);
1965 desc->constructor = constructor;
1968 addr = convert (build_pointer_type (constant_string_type),
1969 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1974 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1976 static GTY(()) int num_static_inst;
1979 objc_add_static_instance (tree constructor, tree class_decl)
1984 /* Find the list of static instances for the CLASS_DECL. Create one if
1986 for (chain = &objc_static_instances;
1987 *chain && TREE_VALUE (*chain) != class_decl;
1988 chain = &TREE_CHAIN (*chain));
1991 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1992 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1995 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1996 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1997 DECL_COMMON (decl) = 1;
1998 TREE_STATIC (decl) = 1;
1999 DECL_ARTIFICIAL (decl) = 1;
2000 TREE_USED (decl) = 1;
2001 DECL_INITIAL (decl) = constructor;
2003 /* We may be writing something else just now.
2004 Postpone till end of input. */
2005 DECL_DEFER_OUTPUT (decl) = 1;
2006 pushdecl_top_level (decl);
2007 rest_of_decl_compilation (decl, 1, 0);
2009 /* Add the DECL to the head of this CLASS' list. */
2010 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2015 /* Build a static constant CONSTRUCTOR
2016 with type TYPE and elements ELTS. */
2019 objc_build_constructor (tree type, tree elts)
2021 tree constructor = build_constructor_from_list (type, elts);
2023 TREE_CONSTANT (constructor) = 1;
2024 TREE_STATIC (constructor) = 1;
2025 TREE_READONLY (constructor) = 1;
2028 /* Adjust for impedance mismatch. We should figure out how to build
2029 CONSTRUCTORs that consistently please both the C and C++ gods. */
2030 if (!TREE_PURPOSE (elts))
2031 TREE_TYPE (constructor) = init_list_type_node;
2037 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2039 /* Predefine the following data type:
2047 void *defs[cls_def_cnt + cat_def_cnt];
2051 build_objc_symtab_template (void)
2053 tree field_decl, field_decl_chain;
2055 objc_symtab_template
2056 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2058 /* long sel_ref_cnt; */
2059 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2060 field_decl_chain = field_decl;
2063 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2065 chainon (field_decl_chain, field_decl);
2067 /* short cls_def_cnt; */
2068 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2069 chainon (field_decl_chain, field_decl);
2071 /* short cat_def_cnt; */
2072 field_decl = create_field_decl (short_integer_type_node,
2074 chainon (field_decl_chain, field_decl);
2076 if (imp_count || cat_count || !flag_next_runtime)
2078 /* void *defs[imp_count + cat_count (+ 1)]; */
2079 /* NB: The index is one less than the size of the array. */
2080 int index = imp_count + cat_count
2081 + (flag_next_runtime? -1: 0);
2082 field_decl = create_field_decl
2085 build_index_type (build_int_cst (NULL_TREE, index))),
2087 chainon (field_decl_chain, field_decl);
2090 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2093 /* Create the initial value for the `defs' field of _objc_symtab.
2094 This is a CONSTRUCTOR. */
2097 init_def_list (tree type)
2099 tree expr, initlist = NULL_TREE;
2100 struct imp_entry *impent;
2103 for (impent = imp_list; impent; impent = impent->next)
2105 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2107 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2108 initlist = tree_cons (NULL_TREE, expr, initlist);
2113 for (impent = imp_list; impent; impent = impent->next)
2115 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2117 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2118 initlist = tree_cons (NULL_TREE, expr, initlist);
2122 if (!flag_next_runtime)
2124 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2127 if (static_instances_decl)
2128 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2130 expr = build_int_cst (NULL_TREE, 0);
2132 initlist = tree_cons (NULL_TREE, expr, initlist);
2135 return objc_build_constructor (type, nreverse (initlist));
2138 /* Construct the initial value for all of _objc_symtab. */
2141 init_objc_symtab (tree type)
2145 /* sel_ref_cnt = { ..., 5, ... } */
2147 initlist = build_tree_list (NULL_TREE,
2148 build_int_cst (long_integer_type_node, 0));
2150 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2152 if (flag_next_runtime || ! sel_ref_chain)
2153 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2156 = tree_cons (NULL_TREE,
2157 convert (build_pointer_type (objc_selector_type),
2158 build_unary_op (ADDR_EXPR,
2159 UOBJC_SELECTOR_TABLE_decl, 1)),
2162 /* cls_def_cnt = { ..., 5, ... } */
2164 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2166 /* cat_def_cnt = { ..., 5, ... } */
2168 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2170 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2172 if (imp_count || cat_count || !flag_next_runtime)
2175 tree field = TYPE_FIELDS (type);
2176 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2178 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2182 return objc_build_constructor (type, nreverse (initlist));
2185 /* Generate forward declarations for metadata such as
2186 'OBJC_CLASS_...'. */
2189 build_metadata_decl (const char *name, tree type)
2193 /* struct TYPE NAME_<name>; */
2194 decl = start_var_decl (type, synth_id_with_class_suffix
2196 objc_implementation_context));
2201 /* Push forward-declarations of all the categories so that
2202 init_def_list can use them in a CONSTRUCTOR. */
2205 forward_declare_categories (void)
2207 struct imp_entry *impent;
2208 tree sav = objc_implementation_context;
2210 for (impent = imp_list; impent; impent = impent->next)
2212 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2214 /* Set an invisible arg to synth_id_with_class_suffix. */
2215 objc_implementation_context = impent->imp_context;
2216 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2217 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2218 objc_category_template);
2221 objc_implementation_context = sav;
2224 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2225 and initialized appropriately. */
2228 generate_objc_symtab_decl (void)
2230 /* forward declare categories */
2232 forward_declare_categories ();
2234 build_objc_symtab_template ();
2235 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2236 finish_var_decl (UOBJC_SYMBOLS_decl,
2237 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2241 init_module_descriptor (tree type)
2243 tree initlist, expr;
2245 /* version = { 1, ... } */
2247 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2248 initlist = build_tree_list (NULL_TREE, expr);
2250 /* size = { ..., sizeof (struct _objc_module), ... } */
2252 expr = convert (long_integer_type_node,
2253 size_in_bytes (objc_module_template));
2254 initlist = tree_cons (NULL_TREE, expr, initlist);
2256 /* Don't provide any file name for security reasons. */
2257 /* name = { ..., "", ... } */
2259 expr = add_objc_string (get_identifier (""), class_names);
2260 initlist = tree_cons (NULL_TREE, expr, initlist);
2262 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2264 if (UOBJC_SYMBOLS_decl)
2265 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2267 expr = build_int_cst (NULL_TREE, 0);
2268 initlist = tree_cons (NULL_TREE, expr, initlist);
2270 return objc_build_constructor (type, nreverse (initlist));
2273 /* Write out the data structures to describe Objective C classes defined.
2275 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2278 build_module_descriptor (void)
2280 tree field_decl, field_decl_chain;
2283 push_lang_context (lang_name_c); /* extern "C" */
2286 objc_module_template
2287 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2290 field_decl = create_field_decl (long_integer_type_node, "version");
2291 field_decl_chain = field_decl;
2294 field_decl = create_field_decl (long_integer_type_node, "size");
2295 chainon (field_decl_chain, field_decl);
2298 field_decl = create_field_decl (string_type_node, "name");
2299 chainon (field_decl_chain, field_decl);
2301 /* struct _objc_symtab *symtab; */
2303 = create_field_decl (build_pointer_type
2304 (xref_tag (RECORD_TYPE,
2305 get_identifier (UTAG_SYMTAB))),
2307 chainon (field_decl_chain, field_decl);
2309 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2311 /* Create an instance of "_objc_module". */
2312 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2313 finish_var_decl (UOBJC_MODULES_decl,
2314 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2317 pop_lang_context ();
2321 /* The GNU runtime requires us to provide a static initializer function
2324 static void __objc_gnu_init (void) {
2325 __objc_exec_class (&L_OBJC_MODULES);
2329 build_module_initializer_routine (void)
2334 push_lang_context (lang_name_c); /* extern "C" */
2337 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2338 objc_start_function (get_identifier (TAG_GNUINIT),
2339 build_function_type (void_type_node,
2341 NULL_TREE, objc_get_parm_info (0));
2343 body = c_begin_compound_stmt (true);
2344 add_stmt (build_function_call
2348 build_unary_op (ADDR_EXPR,
2349 UOBJC_MODULES_decl, 0))));
2350 add_stmt (c_end_compound_stmt (body, true));
2352 TREE_PUBLIC (current_function_decl) = 0;
2355 /* For Objective-C++, we will need to call __objc_gnu_init
2356 from objc_generate_static_init_call() below. */
2357 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2360 GNU_INIT_decl = current_function_decl;
2364 pop_lang_context ();
2369 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2370 to be called by the module initializer routine. */
2373 objc_static_init_needed_p (void)
2375 return (GNU_INIT_decl != NULL_TREE);
2378 /* Generate a call to the __objc_gnu_init initializer function. */
2381 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2383 add_stmt (build_stmt (EXPR_STMT,
2384 build_function_call (GNU_INIT_decl, NULL_TREE)));
2388 #endif /* OBJCPLUS */
2390 /* Return the DECL of the string IDENT in the SECTION. */
2393 get_objc_string_decl (tree ident, enum string_section section)
2397 if (section == class_names)
2398 chain = class_names_chain;
2399 else if (section == meth_var_names)
2400 chain = meth_var_names_chain;
2401 else if (section == meth_var_types)
2402 chain = meth_var_types_chain;
2406 for (; chain != 0; chain = TREE_CHAIN (chain))
2407 if (TREE_VALUE (chain) == ident)
2408 return (TREE_PURPOSE (chain));
2414 /* Output references to all statically allocated objects. Return the DECL
2415 for the array built. */
2418 generate_static_references (void)
2420 tree decls = NULL_TREE, expr = NULL_TREE;
2421 tree class_name, klass, decl, initlist;
2422 tree cl_chain, in_chain, type
2423 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2424 int num_inst, num_class;
2427 if (flag_next_runtime)
2430 for (cl_chain = objc_static_instances, num_class = 0;
2431 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2433 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2434 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2436 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2437 decl = start_var_decl (type, buf);
2439 /* Output {class_name, ...}. */
2440 klass = TREE_VALUE (cl_chain);
2441 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2442 initlist = build_tree_list (NULL_TREE,
2443 build_unary_op (ADDR_EXPR, class_name, 1));
2445 /* Output {..., instance, ...}. */
2446 for (in_chain = TREE_PURPOSE (cl_chain);
2447 in_chain; in_chain = TREE_CHAIN (in_chain))
2449 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2450 initlist = tree_cons (NULL_TREE, expr, initlist);
2453 /* Output {..., NULL}. */
2454 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2456 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2457 finish_var_decl (decl, expr);
2459 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2462 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2463 expr = objc_build_constructor (type, nreverse (decls));
2464 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2465 finish_var_decl (static_instances_decl, expr);
2468 static GTY(()) int selector_reference_idx;
2471 build_selector_reference_decl (void)
2476 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2477 decl = start_var_decl (objc_selector_type, buf);
2483 build_selector_table_decl (void)
2487 if (flag_typed_selectors)
2489 build_selector_template ();
2490 temp = build_array_type (objc_selector_template, NULL_TREE);
2493 temp = build_array_type (objc_selector_type, NULL_TREE);
2495 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2498 /* Just a handy wrapper for add_objc_string. */
2501 build_selector (tree ident)
2503 return convert (objc_selector_type,
2504 add_objc_string (ident, meth_var_names));
2508 build_selector_translation_table (void)
2510 tree chain, initlist = NULL_TREE;
2512 tree decl = NULL_TREE;
2514 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2518 if (warn_selector && objc_implementation_context)
2522 for (method_chain = meth_var_names_chain;
2524 method_chain = TREE_CHAIN (method_chain))
2526 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2535 if (flag_next_runtime && TREE_PURPOSE (chain))
2536 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2538 loc = &input_location;
2539 warning (0, "%Hcreating selector for nonexistent method %qE",
2540 loc, TREE_VALUE (chain));
2544 expr = build_selector (TREE_VALUE (chain));
2545 /* add one for the '\0' character */
2546 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2548 if (flag_next_runtime)
2550 decl = TREE_PURPOSE (chain);
2551 finish_var_decl (decl, expr);
2555 if (flag_typed_selectors)
2557 tree eltlist = NULL_TREE;
2558 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2559 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2560 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2561 expr = objc_build_constructor (objc_selector_template,
2562 nreverse (eltlist));
2565 initlist = tree_cons (NULL_TREE, expr, initlist);
2569 if (! flag_next_runtime)
2571 /* Cause the selector table (previously forward-declared)
2572 to be actually output. */
2573 initlist = tree_cons (NULL_TREE,
2574 flag_typed_selectors
2575 ? objc_build_constructor
2576 (objc_selector_template,
2577 tree_cons (NULL_TREE,
2578 build_int_cst (NULL_TREE, 0),
2579 tree_cons (NULL_TREE,
2580 build_int_cst (NULL_TREE, 0),
2582 : build_int_cst (NULL_TREE, 0), initlist);
2583 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2584 nreverse (initlist));
2585 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2590 get_proto_encoding (tree proto)
2595 if (! METHOD_ENCODING (proto))
2597 encoding = encode_method_prototype (proto);
2598 METHOD_ENCODING (proto) = encoding;
2601 encoding = METHOD_ENCODING (proto);
2603 return add_objc_string (encoding, meth_var_types);
2606 return build_int_cst (NULL_TREE, 0);
2609 /* sel_ref_chain is a list whose "value" fields will be instances of
2610 identifier_node that represent the selector. */
2613 build_typed_selector_reference (tree ident, tree prototype)
2615 tree *chain = &sel_ref_chain;
2621 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2622 goto return_at_index;
2625 chain = &TREE_CHAIN (*chain);
2628 *chain = tree_cons (prototype, ident, NULL_TREE);
2631 expr = build_unary_op (ADDR_EXPR,
2632 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2633 build_int_cst (NULL_TREE, index)),
2635 return convert (objc_selector_type, expr);
2639 build_selector_reference (tree ident)
2641 tree *chain = &sel_ref_chain;
2647 if (TREE_VALUE (*chain) == ident)
2648 return (flag_next_runtime
2649 ? TREE_PURPOSE (*chain)
2650 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2651 build_int_cst (NULL_TREE, index)));
2654 chain = &TREE_CHAIN (*chain);
2657 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2659 *chain = tree_cons (expr, ident, NULL_TREE);
2661 return (flag_next_runtime
2663 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2664 build_int_cst (NULL_TREE, index)));
2667 static GTY(()) int class_reference_idx;
2670 build_class_reference_decl (void)
2675 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2676 decl = start_var_decl (objc_class_type, buf);
2681 /* Create a class reference, but don't create a variable to reference
2685 add_class_reference (tree ident)
2689 if ((chain = cls_ref_chain))
2694 if (ident == TREE_VALUE (chain))
2698 chain = TREE_CHAIN (chain);
2702 /* Append to the end of the list */
2703 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2706 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2709 /* Get a class reference, creating it if necessary. Also create the
2710 reference variable. */
2713 objc_get_class_reference (tree ident)
2715 tree orig_ident = (DECL_P (ident)
2718 ? OBJC_TYPE_NAME (ident)
2720 bool local_scope = false;
2723 if (processing_template_decl)
2724 /* Must wait until template instantiation time. */
2725 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2728 if (TREE_CODE (ident) == TYPE_DECL)
2729 ident = (DECL_ORIGINAL_TYPE (ident)
2730 ? DECL_ORIGINAL_TYPE (ident)
2731 : TREE_TYPE (ident));
2734 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2735 && TYPE_CONTEXT (ident) != global_namespace)
2739 if (local_scope || !(ident = objc_is_class_name (ident)))
2741 error ("%qs is not an Objective-C class name or alias",
2742 IDENTIFIER_POINTER (orig_ident));
2743 return error_mark_node;
2746 if (flag_next_runtime && !flag_zero_link)
2751 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2752 if (TREE_VALUE (*chain) == ident)
2754 if (! TREE_PURPOSE (*chain))
2755 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2757 return TREE_PURPOSE (*chain);
2760 decl = build_class_reference_decl ();
2761 *chain = tree_cons (decl, ident, NULL_TREE);
2768 add_class_reference (ident);
2770 params = build_tree_list (NULL_TREE,
2771 my_build_string_pointer
2772 (IDENTIFIER_LENGTH (ident) + 1,
2773 IDENTIFIER_POINTER (ident)));
2775 assemble_external (objc_get_class_decl);
2776 return build_function_call (objc_get_class_decl, params);
2780 /* For each string section we have a chain which maps identifier nodes
2781 to decls for the strings. */
2784 add_objc_string (tree ident, enum string_section section)
2786 tree *chain, decl, type, string_expr;
2788 if (section == class_names)
2789 chain = &class_names_chain;
2790 else if (section == meth_var_names)
2791 chain = &meth_var_names_chain;
2792 else if (section == meth_var_types)
2793 chain = &meth_var_types_chain;
2799 if (TREE_VALUE (*chain) == ident)
2800 return convert (string_type_node,
2801 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2803 chain = &TREE_CHAIN (*chain);
2806 decl = build_objc_string_decl (section);
2808 type = build_array_type
2811 (build_int_cst (NULL_TREE,
2812 IDENTIFIER_LENGTH (ident))));
2813 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2814 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2815 IDENTIFIER_POINTER (ident));
2816 finish_var_decl (decl, string_expr);
2818 *chain = tree_cons (decl, ident, NULL_TREE);
2820 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2823 static GTY(()) int class_names_idx;
2824 static GTY(()) int meth_var_names_idx;
2825 static GTY(()) int meth_var_types_idx;
2828 build_objc_string_decl (enum string_section section)
2833 if (section == class_names)
2834 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2835 else if (section == meth_var_names)
2836 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2837 else if (section == meth_var_types)
2838 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2840 ident = get_identifier (buf);
2842 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2843 DECL_EXTERNAL (decl) = 1;
2844 TREE_PUBLIC (decl) = 0;
2845 TREE_USED (decl) = 1;
2846 TREE_CONSTANT (decl) = 1;
2847 DECL_CONTEXT (decl) = 0;
2848 DECL_ARTIFICIAL (decl) = 1;
2850 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2853 make_decl_rtl (decl);
2854 pushdecl_top_level (decl);
2861 objc_declare_alias (tree alias_ident, tree class_ident)
2863 tree underlying_class;
2866 if (current_namespace != global_namespace) {
2867 error ("Objective-C declarations may only appear in global scope");
2869 #endif /* OBJCPLUS */
2871 if (!(underlying_class = objc_is_class_name (class_ident)))
2872 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2873 else if (objc_is_class_name (alias_ident))
2874 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2877 /* Implement @compatibility_alias as a typedef. */
2879 push_lang_context (lang_name_c); /* extern "C" */
2881 lang_hooks.decls.pushdecl (build_decl
2884 xref_tag (RECORD_TYPE, underlying_class)));
2886 pop_lang_context ();
2888 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2893 objc_declare_class (tree ident_list)
2897 if (current_namespace != global_namespace) {
2898 error ("Objective-C declarations may only appear in global scope");
2900 #endif /* OBJCPLUS */
2902 for (list = ident_list; list; list = TREE_CHAIN (list))
2904 tree ident = TREE_VALUE (list);
2906 if (! objc_is_class_name (ident))
2908 tree record = lookup_name (ident), type = record;
2912 if (TREE_CODE (record) == TYPE_DECL)
2913 type = DECL_ORIGINAL_TYPE (record);
2915 if (!TYPE_HAS_OBJC_INFO (type)
2916 || !TYPE_OBJC_INTERFACE (type))
2918 error ("%qs redeclared as different kind of symbol",
2919 IDENTIFIER_POINTER (ident));
2920 error ("previous declaration of %q+D",
2925 record = xref_tag (RECORD_TYPE, ident);
2926 INIT_TYPE_OBJC_INFO (record);
2927 TYPE_OBJC_INTERFACE (record) = ident;
2928 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2934 objc_is_class_name (tree ident)
2938 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2939 && identifier_global_value (ident))
2940 ident = identifier_global_value (ident);
2941 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2942 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2944 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2945 ident = OBJC_TYPE_NAME (ident);
2947 if (ident && TREE_CODE (ident) == TYPE_DECL)
2948 ident = DECL_NAME (ident);
2950 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2953 if (lookup_interface (ident))
2956 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2958 if (ident == TREE_VALUE (chain))
2962 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2964 if (ident == TREE_VALUE (chain))
2965 return TREE_PURPOSE (chain);
2971 /* Check whether TYPE is either 'id' or 'Class'. */
2974 objc_is_id (tree type)
2976 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2977 && identifier_global_value (type))
2978 type = identifier_global_value (type);
2980 if (type && TREE_CODE (type) == TYPE_DECL)
2981 type = TREE_TYPE (type);
2983 /* NB: This function may be called before the ObjC front-end has
2984 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2985 return (objc_object_type && type
2986 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2991 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2992 class instance. This is needed by other parts of the compiler to
2993 handle ObjC types gracefully. */
2996 objc_is_object_ptr (tree type)
3000 type = TYPE_MAIN_VARIANT (type);
3001 if (!POINTER_TYPE_P (type))
3004 ret = objc_is_id (type);
3006 ret = objc_is_class_name (TREE_TYPE (type));
3012 objc_is_gcable_type (tree type, int or_strong_p)
3018 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3020 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3022 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3024 type = TREE_TYPE (type);
3025 if (TREE_CODE (type) != RECORD_TYPE)
3027 name = TYPE_NAME (type);
3028 return (objc_is_class_name (name) != NULL_TREE);
3032 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3034 if (expr == oldexpr)
3037 switch (TREE_CODE (expr))
3040 return objc_build_component_ref
3041 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3044 DECL_NAME (TREE_OPERAND (expr, 1)));
3046 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3049 TREE_OPERAND (expr, 1));
3051 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3060 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3063 /* The LHS parameter contains the expression 'outervar->memberspec';
3064 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3065 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3068 = objc_substitute_decl
3069 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3071 = (flag_objc_direct_dispatch
3072 ? objc_assign_ivar_fast_decl
3073 : objc_assign_ivar_decl);
3075 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3077 func_params = tree_cons (NULL_TREE,
3078 convert (objc_object_type, rhs),
3079 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3080 tree_cons (NULL_TREE, offs,
3083 assemble_external (func);
3084 return build_function_call (func, func_params);
3088 objc_build_global_assignment (tree lhs, tree rhs)
3090 tree func_params = tree_cons (NULL_TREE,
3091 convert (objc_object_type, rhs),
3092 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3093 build_unary_op (ADDR_EXPR, lhs, 0)),
3096 assemble_external (objc_assign_global_decl);
3097 return build_function_call (objc_assign_global_decl, func_params);
3101 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3103 tree func_params = tree_cons (NULL_TREE,
3104 convert (objc_object_type, rhs),
3105 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3106 build_unary_op (ADDR_EXPR, lhs, 0)),
3109 assemble_external (objc_assign_strong_cast_decl);
3110 return build_function_call (objc_assign_strong_cast_decl, func_params);
3114 objc_is_gcable_p (tree expr)
3116 return (TREE_CODE (expr) == COMPONENT_REF
3117 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3118 : TREE_CODE (expr) == ARRAY_REF
3119 ? (objc_is_gcable_p (TREE_TYPE (expr))
3120 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3121 : TREE_CODE (expr) == ARRAY_TYPE
3122 ? objc_is_gcable_p (TREE_TYPE (expr))
3124 ? objc_is_gcable_type (expr, 1)
3125 : (objc_is_gcable_p (TREE_TYPE (expr))
3127 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3131 objc_is_ivar_reference_p (tree expr)
3133 return (TREE_CODE (expr) == ARRAY_REF
3134 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3135 : TREE_CODE (expr) == COMPONENT_REF
3136 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3141 objc_is_global_reference_p (tree expr)
3143 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3144 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3146 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3151 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3153 tree result = NULL_TREE, outer;
3154 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3156 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3157 will have been transformed to the form '*(type *)&expr'. */
3158 if (TREE_CODE (lhs) == INDIRECT_REF)
3160 outer = TREE_OPERAND (lhs, 0);
3162 while (!strong_cast_p
3163 && (CONVERT_EXPR_P (outer)
3164 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3166 tree lhstype = TREE_TYPE (outer);
3168 /* Descend down the cast chain, and record the first objc_gc
3170 if (POINTER_TYPE_P (lhstype))
3173 = lookup_attribute ("objc_gc",
3174 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3180 outer = TREE_OPERAND (outer, 0);
3184 /* If we have a __strong cast, it trumps all else. */
3187 if (modifycode != NOP_EXPR)
3188 goto invalid_pointer_arithmetic;
3190 if (warn_assign_intercept)
3191 warning (0, "strong-cast assignment has been intercepted");
3193 result = objc_build_strong_cast_assignment (lhs, rhs);
3198 /* the lhs must be of a suitable type, regardless of its underlying
3200 if (!objc_is_gcable_p (lhs))
3206 && (TREE_CODE (outer) == COMPONENT_REF
3207 || TREE_CODE (outer) == ARRAY_REF))
3208 outer = TREE_OPERAND (outer, 0);
3210 if (TREE_CODE (outer) == INDIRECT_REF)
3212 outer = TREE_OPERAND (outer, 0);
3216 outer_gc_p = objc_is_gcable_p (outer);
3218 /* Handle ivar assignments. */
3219 if (objc_is_ivar_reference_p (lhs))
3221 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3222 doesn't cut it here), the best we can do here is suggest a cast. */
3223 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3225 /* We may still be able to use the global write barrier... */
3226 if (!indirect_p && objc_is_global_reference_p (outer))
3227 goto global_reference;
3230 if (modifycode == NOP_EXPR)
3232 if (warn_assign_intercept)
3233 warning (0, "strong-cast may possibly be needed");
3239 if (modifycode != NOP_EXPR)
3240 goto invalid_pointer_arithmetic;
3242 if (warn_assign_intercept)
3243 warning (0, "instance variable assignment has been intercepted");
3245 result = objc_build_ivar_assignment (outer, lhs, rhs);
3250 /* Likewise, intercept assignment to global/static variables if their type is
3252 if (objc_is_global_reference_p (outer))
3258 if (modifycode != NOP_EXPR)
3260 invalid_pointer_arithmetic:
3262 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3267 if (warn_assign_intercept)
3268 warning (0, "global/static variable assignment has been intercepted");
3270 result = objc_build_global_assignment (lhs, rhs);
3273 /* In all other cases, fall back to the normal mechanism. */
3278 struct interface_tuple GTY(())
3284 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3287 hash_interface (const void *p)
3289 const struct interface_tuple *d = (const struct interface_tuple *) p;
3290 return IDENTIFIER_HASH_VALUE (d->id);
3294 eq_interface (const void *p1, const void *p2)
3296 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3301 lookup_interface (tree ident)
3304 if (ident && TREE_CODE (ident) == TYPE_DECL)
3305 ident = DECL_NAME (ident);
3308 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3312 struct interface_tuple **slot;
3317 slot = (struct interface_tuple **)
3318 htab_find_slot_with_hash (interface_htab, ident,
3319 IDENTIFIER_HASH_VALUE (ident),
3322 i = (*slot)->class_name;
3328 /* Implement @defs (<classname>) within struct bodies. */
3331 objc_get_class_ivars (tree class_name)
3333 tree interface = lookup_interface (class_name);
3336 return get_class_ivars (interface, true);
3338 error ("cannot find interface declaration for %qs",
3339 IDENTIFIER_POINTER (class_name));
3341 return error_mark_node;
3344 /* Used by: build_private_template, continue_class,
3345 and for @defs constructs. */
3348 get_class_ivars (tree interface, bool inherited)
3350 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3352 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3353 by the current class (i.e., they do not include super-class ivars).
3354 However, the CLASS_IVARS list will be side-effected by a call to
3355 finish_struct(), which will fill in field offsets. */
3356 if (!CLASS_IVARS (interface))
3357 CLASS_IVARS (interface) = ivar_chain;
3362 while (CLASS_SUPER_NAME (interface))
3364 /* Prepend super-class ivars. */
3365 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3366 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3374 objc_create_temporary_var (tree type)
3378 decl = build_decl (VAR_DECL, NULL_TREE, type);
3379 TREE_USED (decl) = 1;
3380 DECL_ARTIFICIAL (decl) = 1;
3381 DECL_IGNORED_P (decl) = 1;
3382 DECL_CONTEXT (decl) = current_function_decl;
3387 /* Exception handling constructs. We begin by having the parser do most
3388 of the work and passing us blocks. What we do next depends on whether
3389 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3390 We abstract all of this in a handful of appropriately named routines. */
3392 /* Stack of open try blocks. */
3394 struct objc_try_context
3396 struct objc_try_context *outer;
3398 /* Statements (or statement lists) as processed by the parser. */
3402 /* Some file position locations. */
3403 location_t try_locus;
3404 location_t end_try_locus;
3405 location_t end_catch_locus;
3406 location_t finally_locus;
3407 location_t end_finally_locus;
3409 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3410 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3413 /* The CATCH_EXPR of an open @catch clause. */
3416 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3422 static struct objc_try_context *cur_try_context;
3424 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3425 that represents TYPE. For Objective-C, this is just the class name. */
3426 /* ??? Isn't there a class object or some such? Is it easy to get? */
3430 objc_eh_runtime_type (tree type)
3432 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3436 /* Initialize exception handling. */
3439 objc_init_exceptions (void)
3441 static bool done = false;
3446 if (flag_objc_sjlj_exceptions)
3448 /* On Darwin, ObjC exceptions require a sufficiently recent
3449 version of the runtime, so the user must ask for them explicitly. */
3450 if (!flag_objc_exceptions)
3451 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3452 "exception syntax");
3457 c_eh_initialized_p = true;
3458 eh_personality_libfunc
3459 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3460 ? "__gnu_objc_personality_sj0"
3461 : "__gnu_objc_personality_v0");
3462 default_init_unwind_resume_libfunc ();
3463 using_eh_for_cleanups ();
3464 lang_eh_runtime_type = objc_eh_runtime_type;
3469 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3470 we'll arrange for it to be initialized (and associated with a binding)
3474 objc_build_exc_ptr (void)
3476 if (flag_objc_sjlj_exceptions)
3478 tree var = cur_try_context->caught_decl;
3481 var = objc_create_temporary_var (objc_object_type);
3482 cur_try_context->caught_decl = var;
3487 return build0 (EXC_PTR_EXPR, objc_object_type);
3490 /* Build "objc_exception_try_exit(&_stack)". */
3493 next_sjlj_build_try_exit (void)
3496 t = build_fold_addr_expr (cur_try_context->stack_decl);
3497 t = tree_cons (NULL, t, NULL);
3498 t = build_function_call (objc_exception_try_exit_decl, t);
3503 objc_exception_try_enter (&_stack);
3504 if (_setjmp(&_stack.buf))
3508 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3509 empty, ready for the caller to fill them in. */
3512 next_sjlj_build_enter_and_setjmp (void)
3514 tree t, enter, sj, cond;
3516 t = build_fold_addr_expr (cur_try_context->stack_decl);
3517 t = tree_cons (NULL, t, NULL);
3518 enter = build_function_call (objc_exception_try_enter_decl, t);
3520 t = objc_build_component_ref (cur_try_context->stack_decl,
3521 get_identifier ("buf"));
3522 t = build_fold_addr_expr (t);
3524 /* Convert _setjmp argument to type that is expected. */
3525 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3526 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3528 t = convert (ptr_type_node, t);
3530 t = convert (ptr_type_node, t);
3532 t = tree_cons (NULL, t, NULL);
3533 sj = build_function_call (objc_setjmp_decl, t);
3535 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3536 cond = c_common_truthvalue_conversion (cond);
3538 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3543 DECL = objc_exception_extract(&_stack); */
3546 next_sjlj_build_exc_extract (tree decl)
3550 t = build_fold_addr_expr (cur_try_context->stack_decl);
3551 t = tree_cons (NULL, t, NULL);
3552 t = build_function_call (objc_exception_extract_decl, t);
3553 t = convert (TREE_TYPE (decl), t);
3554 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3560 if (objc_exception_match(obj_get_class(TYPE), _caught)
3567 objc_exception_try_exit(&_stack);
3569 from the sequence of CATCH_EXPRs in the current try context. */
3572 next_sjlj_build_catch_list (void)
3574 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3576 tree *last = &catch_seq;
3577 bool saw_id = false;
3579 for (; !tsi_end_p (i); tsi_next (&i))
3581 tree stmt = tsi_stmt (i);
3582 tree type = CATCH_TYPES (stmt);
3583 tree body = CATCH_BODY (stmt);
3595 if (type == error_mark_node)
3596 cond = error_mark_node;
3599 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3600 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3601 args = tree_cons (NULL, t, args);
3602 t = build_function_call (objc_exception_match_decl, args);
3603 cond = c_common_truthvalue_conversion (t);
3605 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3606 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3609 last = &COND_EXPR_ELSE (t);
3615 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3616 cur_try_context->caught_decl);
3617 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3618 append_to_statement_list (t, last);
3620 t = next_sjlj_build_try_exit ();
3621 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3622 append_to_statement_list (t, last);
3628 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3629 exception handling. We aim to build:
3632 struct _objc_exception_data _stack;
3636 objc_exception_try_enter (&_stack);
3637 if (_setjmp(&_stack.buf))
3639 id _caught = objc_exception_extract(&_stack);
3640 objc_exception_try_enter (&_stack);
3641 if (_setjmp(&_stack.buf))
3642 _rethrow = objc_exception_extract(&_stack);
3652 objc_exception_try_exit(&_stack);
3655 objc_exception_throw(_rethrow);
3659 If CATCH-LIST is empty, we can omit all of the block containing
3660 "_caught" except for the setting of _rethrow. Note the use of
3661 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3662 but handles goto and other exits from the block. */
3665 next_sjlj_build_try_catch_finally (void)
3667 tree rethrow_decl, stack_decl, t;
3668 tree catch_seq, try_fin, bind;
3670 /* Create the declarations involved. */
3671 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3672 stack_decl = objc_create_temporary_var (t);
3673 cur_try_context->stack_decl = stack_decl;
3675 rethrow_decl = objc_create_temporary_var (objc_object_type);
3676 cur_try_context->rethrow_decl = rethrow_decl;
3677 TREE_CHAIN (rethrow_decl) = stack_decl;
3679 /* Build the outermost variable binding level. */
3680 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3681 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3682 TREE_SIDE_EFFECTS (bind) = 1;
3684 /* Initialize rethrow_decl. */
3685 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3686 convert (objc_object_type, null_pointer_node));
3687 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3688 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3690 /* Build the outermost TRY_FINALLY_EXPR. */
3691 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3692 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3693 TREE_SIDE_EFFECTS (try_fin) = 1;
3694 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3696 /* Create the complete catch sequence. */
3697 if (cur_try_context->catch_list)
3699 tree caught_decl = objc_build_exc_ptr ();
3700 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3701 TREE_SIDE_EFFECTS (catch_seq) = 1;
3703 t = next_sjlj_build_exc_extract (caught_decl);
3704 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3706 t = next_sjlj_build_enter_and_setjmp ();
3707 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3708 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3709 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3712 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3713 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3715 /* Build the main register-and-try if statement. */
3716 t = next_sjlj_build_enter_and_setjmp ();
3717 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3718 COND_EXPR_THEN (t) = catch_seq;
3719 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3720 TREE_OPERAND (try_fin, 0) = t;
3722 /* Build the complete FINALLY statement list. */
3723 t = next_sjlj_build_try_exit ();
3724 t = build_stmt (COND_EXPR,
3725 c_common_truthvalue_conversion (rethrow_decl),
3727 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3728 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3730 append_to_statement_list (cur_try_context->finally_body,
3731 &TREE_OPERAND (try_fin, 1));
3733 t = tree_cons (NULL, rethrow_decl, NULL);
3734 t = build_function_call (objc_exception_throw_decl, t);
3735 t = build_stmt (COND_EXPR,
3736 c_common_truthvalue_conversion (rethrow_decl),
3738 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3739 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3744 /* Called just after parsing the @try and its associated BODY. We now
3745 must prepare for the tricky bits -- handling the catches and finally. */
3748 objc_begin_try_stmt (location_t try_locus, tree body)
3750 struct objc_try_context *c = XCNEW (struct objc_try_context);
3751 c->outer = cur_try_context;
3753 c->try_locus = try_locus;
3754 c->end_try_locus = input_location;
3755 cur_try_context = c;
3757 objc_init_exceptions ();
3759 if (flag_objc_sjlj_exceptions)
3760 objc_mark_locals_volatile (NULL);
3763 /* Called just after parsing "@catch (parm)". Open a binding level,
3764 enter DECL into the binding level, and initialize it. Leave the
3765 binding level open while the body of the compound statement is parsed. */
3768 objc_begin_catch_clause (tree decl)
3770 tree compound, type, t;
3772 /* Begin a new scope that the entire catch clause will live in. */
3773 compound = c_begin_compound_stmt (true);
3775 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3776 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3777 lang_hooks.decls.pushdecl (decl);
3779 /* Since a decl is required here by syntax, don't warn if its unused. */
3780 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3781 be what the previous objc implementation did. */
3782 TREE_USED (decl) = 1;
3784 /* Verify that the type of the catch is valid. It must be a pointer
3785 to an Objective-C class, or "id" (which is catch-all). */
3786 type = TREE_TYPE (decl);
3788 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3790 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3792 error ("@catch parameter is not a known Objective-C class type");
3793 type = error_mark_node;
3795 else if (cur_try_context->catch_list)
3797 /* Examine previous @catch clauses and see if we've already
3798 caught the type in question. */
3799 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3800 for (; !tsi_end_p (i); tsi_next (&i))
3802 tree stmt = tsi_stmt (i);
3803 t = CATCH_TYPES (stmt);
3804 if (t == error_mark_node)
3806 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3808 warning (0, "exception of type %<%T%> will be caught",
3810 warning (0, "%H by earlier handler for %<%T%>",
3811 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3817 /* Record the data for the catch in the try context so that we can
3818 finalize it later. */
3819 t = build_stmt (CATCH_EXPR, type, compound);
3820 cur_try_context->current_catch = t;
3822 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3823 t = objc_build_exc_ptr ();
3824 t = convert (TREE_TYPE (decl), t);
3825 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3829 /* Called just after parsing the closing brace of a @catch clause. Close
3830 the open binding level, and record a CATCH_EXPR for it. */
3833 objc_finish_catch_clause (void)
3835 tree c = cur_try_context->current_catch;
3836 cur_try_context->current_catch = NULL;
3837 cur_try_context->end_catch_locus = input_location;
3839 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3840 append_to_statement_list (c, &cur_try_context->catch_list);
3843 /* Called after parsing a @finally clause and its associated BODY.
3844 Record the body for later placement. */
3847 objc_build_finally_clause (location_t finally_locus, tree body)
3849 cur_try_context->finally_body = body;
3850 cur_try_context->finally_locus = finally_locus;
3851 cur_try_context->end_finally_locus = input_location;
3854 /* Called to finalize a @try construct. */
3857 objc_finish_try_stmt (void)
3859 struct objc_try_context *c = cur_try_context;
3862 if (c->catch_list == NULL && c->finally_body == NULL)
3863 error ("%<@try%> without %<@catch%> or %<@finally%>");
3865 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3866 if (flag_objc_sjlj_exceptions)
3868 if (!cur_try_context->finally_body)
3870 cur_try_context->finally_locus = input_location;
3871 cur_try_context->end_finally_locus = input_location;
3873 stmt = next_sjlj_build_try_catch_finally ();
3877 /* Otherwise, nest the CATCH inside a FINALLY. */
3881 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3882 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3884 if (c->finally_body)
3886 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3887 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3892 cur_try_context = c->outer;
3898 objc_build_throw_stmt (tree throw_expr)
3902 objc_init_exceptions ();
3904 if (throw_expr == NULL)
3906 /* If we're not inside a @catch block, there is no "current
3907 exception" to be rethrown. */
3908 if (cur_try_context == NULL
3909 || cur_try_context->current_catch == NULL)
3911 error ("%<@throw%> (rethrow) used outside of a @catch block");
3915 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3916 value that we get from the runtime. */
3917 throw_expr = objc_build_exc_ptr ();
3920 /* A throw is just a call to the runtime throw function with the
3921 object as a parameter. */
3922 args = tree_cons (NULL, throw_expr, NULL);
3923 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3927 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3931 /* First lock the mutex. */
3932 mutex = save_expr (mutex);
3933 args = tree_cons (NULL, mutex, NULL);
3934 call = build_function_call (objc_sync_enter_decl, args);
3935 SET_EXPR_LOCATION (call, start_locus);
3938 /* Build the mutex unlock. */
3939 args = tree_cons (NULL, mutex, NULL);
3940 call = build_function_call (objc_sync_exit_decl, args);
3941 SET_EXPR_LOCATION (call, input_location);
3943 /* Put the that and the body in a TRY_FINALLY. */
3944 objc_begin_try_stmt (start_locus, body);
3945 objc_build_finally_clause (input_location, call);
3946 return objc_finish_try_stmt ();
3950 /* Predefine the following data type:
3952 struct _objc_exception_data
3954 int buf[OBJC_JBLEN];
3958 /* The following yuckiness should prevent users from having to #include
3959 <setjmp.h> in their code... */
3961 /* Define to a harmless positive value so the below code doesn't die. */
3963 #define OBJC_JBLEN 18
3967 build_next_objc_exception_stuff (void)
3969 tree field_decl, field_decl_chain, index, temp_type;
3971 objc_exception_data_template
3972 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3974 /* int buf[OBJC_JBLEN]; */
3976 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3977 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3979 field_decl_chain = field_decl;
3981 /* void *pointers[4]; */
3983 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3984 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3986 chainon (field_decl_chain, field_decl);
3988 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3990 /* int _setjmp(...); */
3991 /* If the user includes <setjmp.h>, this shall be superseded by
3992 'int _setjmp(jmp_buf);' */
3993 temp_type = build_function_type (integer_type_node, NULL_TREE);
3995 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3997 /* id objc_exception_extract(struct _objc_exception_data *); */
3999 = build_function_type (objc_object_type,
4000 tree_cons (NULL_TREE,
4001 build_pointer_type (objc_exception_data_template),
4003 objc_exception_extract_decl
4004 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4006 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4007 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4009 = build_function_type (void_type_node,
4010 tree_cons (NULL_TREE,
4011 build_pointer_type (objc_exception_data_template),
4013 objc_exception_try_enter_decl
4014 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4016 objc_exception_try_exit_decl
4017 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4020 /* int objc_exception_match(id, id); */
4022 = build_function_type (integer_type_node,
4023 tree_cons (NULL_TREE, objc_object_type,
4024 tree_cons (NULL_TREE, objc_object_type,
4025 OBJC_VOID_AT_END)));
4026 objc_exception_match_decl
4027 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4030 /* id objc_assign_ivar (id, id, unsigned int); */
4031 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4032 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4034 = build_function_type (objc_object_type,
4036 (NULL_TREE, objc_object_type,
4037 tree_cons (NULL_TREE, objc_object_type,
4038 tree_cons (NULL_TREE,
4040 OBJC_VOID_AT_END))));
4041 objc_assign_ivar_decl
4042 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4044 #ifdef OFFS_ASSIGNIVAR_FAST
4045 objc_assign_ivar_fast_decl
4046 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4047 NOT_BUILT_IN, NULL, NULL_TREE);
4048 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4049 = tree_cons (get_identifier ("hard_coded_address"),
4050 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4053 /* Default to slower ivar method. */
4054 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4057 /* id objc_assign_global (id, id *); */
4058 /* id objc_assign_strongCast (id, id *); */
4059 temp_type = build_function_type (objc_object_type,
4060 tree_cons (NULL_TREE, objc_object_type,
4061 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4062 OBJC_VOID_AT_END)));
4063 objc_assign_global_decl
4064 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4066 objc_assign_strong_cast_decl
4067 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4072 build_objc_exception_stuff (void)
4074 tree noreturn_list, nothrow_list, temp_type;
4076 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4077 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4079 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4080 /* void objc_sync_enter(id); */
4081 /* void objc_sync_exit(id); */
4082 temp_type = build_function_type (void_type_node,
4083 tree_cons (NULL_TREE, objc_object_type,
4085 objc_exception_throw_decl
4086 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4088 objc_sync_enter_decl
4089 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4090 NULL, nothrow_list);
4092 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4093 NULL, nothrow_list);
4096 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4099 struct <classname> {
4100 struct _objc_class *isa;
4105 build_private_template (tree klass)
4107 if (!CLASS_STATIC_TEMPLATE (klass))
4109 tree record = objc_build_struct (klass,
4110 get_class_ivars (klass, false),
4111 CLASS_SUPER_NAME (klass));
4113 /* Set the TREE_USED bit for this struct, so that stab generator
4114 can emit stabs for this struct type. */
4115 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4116 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4120 /* Begin code generation for protocols... */
4122 /* struct _objc_protocol {
4123 struct _objc_class *isa;
4124 char *protocol_name;
4125 struct _objc_protocol **protocol_list;
4126 struct _objc__method_prototype_list *instance_methods;
4127 struct _objc__method_prototype_list *class_methods;
4131 build_protocol_template (void)
4133 tree field_decl, field_decl_chain;
4135 objc_protocol_template = start_struct (RECORD_TYPE,
4136 get_identifier (UTAG_PROTOCOL));
4138 /* struct _objc_class *isa; */
4139 field_decl = create_field_decl (build_pointer_type
4140 (xref_tag (RECORD_TYPE,
4141 get_identifier (UTAG_CLASS))),
4143 field_decl_chain = field_decl;
4145 /* char *protocol_name; */
4146 field_decl = create_field_decl (string_type_node, "protocol_name");
4147 chainon (field_decl_chain, field_decl);
4149 /* struct _objc_protocol **protocol_list; */
4150 field_decl = create_field_decl (build_pointer_type
4152 (objc_protocol_template)),
4154 chainon (field_decl_chain, field_decl);
4156 /* struct _objc__method_prototype_list *instance_methods; */
4157 field_decl = create_field_decl (objc_method_proto_list_ptr,
4158 "instance_methods");
4159 chainon (field_decl_chain, field_decl);
4161 /* struct _objc__method_prototype_list *class_methods; */
4162 field_decl = create_field_decl (objc_method_proto_list_ptr,
4164 chainon (field_decl_chain, field_decl);
4166 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4170 build_descriptor_table_initializer (tree type, tree entries)
4172 tree initlist = NULL_TREE;
4176 tree eltlist = NULL_TREE;
4179 = tree_cons (NULL_TREE,
4180 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4182 = tree_cons (NULL_TREE,
4183 add_objc_string (METHOD_ENCODING (entries),
4188 = tree_cons (NULL_TREE,
4189 objc_build_constructor (type, nreverse (eltlist)),
4192 entries = TREE_CHAIN (entries);
4196 return objc_build_constructor (build_array_type (type, 0),
4197 nreverse (initlist));
4200 /* struct objc_method_prototype_list {
4202 struct objc_method_prototype {
4209 build_method_prototype_list_template (tree list_type, int size)
4211 tree objc_ivar_list_record;
4212 tree field_decl, field_decl_chain;
4214 /* Generate an unnamed struct definition. */
4216 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4218 /* int method_count; */
4219 field_decl = create_field_decl (integer_type_node, "method_count");
4220 field_decl_chain = field_decl;
4222 /* struct objc_method method_list[]; */
4223 field_decl = create_field_decl (build_array_type
4226 (build_int_cst (NULL_TREE, size - 1))),
4228 chainon (field_decl_chain, field_decl);
4230 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4232 return objc_ivar_list_record;
4236 build_method_prototype_template (void)
4239 tree field_decl, field_decl_chain;
4242 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4245 field_decl = create_field_decl (objc_selector_type, "_cmd");
4246 field_decl_chain = field_decl;
4248 /* char *method_types; */
4249 field_decl = create_field_decl (string_type_node, "method_types");
4250 chainon (field_decl_chain, field_decl);
4252 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4254 return proto_record;
4258 objc_method_parm_type (tree type)
4260 type = TREE_VALUE (TREE_TYPE (type));
4261 if (TREE_CODE (type) == TYPE_DECL)
4262 type = TREE_TYPE (type);
4267 objc_encoded_type_size (tree type)
4269 int sz = int_size_in_bytes (type);
4271 /* Make all integer and enum types at least as large
4273 if (sz > 0 && INTEGRAL_TYPE_P (type))
4274 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4275 /* Treat arrays as pointers, since that's how they're
4277 else if (TREE_CODE (type) == ARRAY_TYPE)
4278 sz = int_size_in_bytes (ptr_type_node);
4283 encode_method_prototype (tree method_decl)
4290 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4291 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4293 /* Encode return type. */
4294 encode_type (objc_method_parm_type (method_decl),
4295 obstack_object_size (&util_obstack),
4296 OBJC_ENCODE_INLINE_DEFS);
4299 /* The first two arguments (self and _cmd) are pointers; account for
4301 i = int_size_in_bytes (ptr_type_node);
4302 parm_offset = 2 * i;
4303 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4304 parms = TREE_CHAIN (parms))
4306 tree type = objc_method_parm_type (parms);
4307 int sz = objc_encoded_type_size (type);
4309 /* If a type size is not known, bail out. */
4312 error ("type %q+D does not have a known size",
4314 /* Pretend that the encoding succeeded; the compilation will
4315 fail nevertheless. */
4316 goto finish_encoding;
4321 sprintf (buf, "%d@0:%d", parm_offset, i);
4322 obstack_grow (&util_obstack, buf, strlen (buf));
4324 /* Argument types. */
4325 parm_offset = 2 * i;
4326 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4327 parms = TREE_CHAIN (parms))
4329 tree type = objc_method_parm_type (parms);
4331 /* Process argument qualifiers for user supplied arguments. */
4332 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4335 encode_type (type, obstack_object_size (&util_obstack),
4336 OBJC_ENCODE_INLINE_DEFS);
4338 /* Compute offset. */
4339 sprintf (buf, "%d", parm_offset);
4340 parm_offset += objc_encoded_type_size (type);
4342 obstack_grow (&util_obstack, buf, strlen (buf));
4346 obstack_1grow (&util_obstack, '\0');
4347 result = get_identifier (XOBFINISH (&util_obstack, char *));
4348 obstack_free (&util_obstack, util_firstobj);
4353 generate_descriptor_table (tree type, const char *name, int size, tree list,
4356 tree decl, initlist;
4358 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4360 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4361 initlist = tree_cons (NULL_TREE, list, initlist);
4363 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4369 generate_method_descriptors (tree protocol)
4371 tree initlist, chain, method_list_template;
4374 if (!objc_method_prototype_template)
4375 objc_method_prototype_template = build_method_prototype_template ();
4377 chain = PROTOCOL_CLS_METHODS (protocol);
4380 size = list_length (chain);
4382 method_list_template
4383 = build_method_prototype_list_template (objc_method_prototype_template,
4387 = build_descriptor_table_initializer (objc_method_prototype_template,
4390 UOBJC_CLASS_METHODS_decl
4391 = generate_descriptor_table (method_list_template,
4392 "_OBJC_PROTOCOL_CLASS_METHODS",
4393 size, initlist, protocol);
4396 UOBJC_CLASS_METHODS_decl = 0;
4398 chain = PROTOCOL_NST_METHODS (protocol);
4401 size = list_length (chain);
4403 method_list_template
4404 = build_method_prototype_list_template (objc_method_prototype_template,
4407 = build_descriptor_table_initializer (objc_method_prototype_template,
4410 UOBJC_INSTANCE_METHODS_decl
4411 = generate_descriptor_table (method_list_template,
4412 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4413 size, initlist, protocol);
4416 UOBJC_INSTANCE_METHODS_decl = 0;
4420 generate_protocol_references (tree plist)
4424 /* Forward declare protocols referenced. */
4425 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4427 tree proto = TREE_VALUE (lproto);
4429 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4430 && PROTOCOL_NAME (proto))
4432 if (! PROTOCOL_FORWARD_DECL (proto))
4433 build_protocol_reference (proto);
4435 if (PROTOCOL_LIST (proto))
4436 generate_protocol_references (PROTOCOL_LIST (proto));
4441 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4445 objc_generate_cxx_ctor_or_dtor (bool dtor)
4447 tree fn, body, compound_stmt, ivar;
4449 /* - (id) .cxx_construct { ... return self; } */
4450 /* - (void) .cxx_construct { ... } */
4452 objc_set_method_type (MINUS_EXPR);
4453 objc_start_method_definition
4454 (objc_build_method_signature (build_tree_list (NULL_TREE,
4457 : objc_object_type),
4458 get_identifier (dtor
4460 : TAG_CXX_CONSTRUCT),
4461 make_node (TREE_LIST),
4463 body = begin_function_body ();
4464 compound_stmt = begin_compound_stmt (0);
4466 ivar = CLASS_IVARS (implementation_template);
4467 /* Destroy ivars in reverse order. */
4469 ivar = nreverse (copy_list (ivar));
4471 for (; ivar; ivar = TREE_CHAIN (ivar))
4473 if (TREE_CODE (ivar) == FIELD_DECL)
4475 tree type = TREE_TYPE (ivar);
4477 /* Call the ivar's default constructor or destructor. Do not
4478 call the destructor unless a corresponding constructor call
4479 has also been made (or is not needed). */
4480 if (MAYBE_CLASS_TYPE_P (type)
4482 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4483 && (!TYPE_NEEDS_CONSTRUCTING (type)
4484 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4485 : (TYPE_NEEDS_CONSTRUCTING (type)
4486 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4488 (build_special_member_call
4489 (build_ivar_reference (DECL_NAME (ivar)),
4490 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4491 NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
4495 /* The constructor returns 'self'. */
4497 finish_return_stmt (self_decl);
4499 finish_compound_stmt (compound_stmt);
4500 finish_function_body (body);
4501 fn = current_function_decl;
4503 objc_finish_method_definition (fn);
4506 /* The following routine will examine the current @interface for any
4507 non-POD C++ ivars requiring non-trivial construction and/or
4508 destruction, and then synthesize special '- .cxx_construct' and/or
4509 '- .cxx_destruct' methods which will run the appropriate
4510 construction or destruction code. Note that ivars inherited from
4511 super-classes are _not_ considered. */
4513 objc_generate_cxx_cdtors (void)
4515 bool need_ctor = false, need_dtor = false;
4518 /* We do not want to do this for categories, since they do not have
4521 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4524 /* First, determine if we even need a constructor and/or destructor. */
4526 for (ivar = CLASS_IVARS (implementation_template); ivar;
4527 ivar = TREE_CHAIN (ivar))
4529 if (TREE_CODE (ivar) == FIELD_DECL)
4531 tree type = TREE_TYPE (ivar);
4533 if (MAYBE_CLASS_TYPE_P (type))
4535 if (TYPE_NEEDS_CONSTRUCTING (type)
4536 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4537 /* NB: If a default constructor is not available, we will not
4538 be able to initialize this ivar; the add_instance_variable()
4539 routine will already have warned about this. */
4542 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4543 && (!TYPE_NEEDS_CONSTRUCTING (type)
4544 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4545 /* NB: If a default constructor is not available, we will not
4546 call the destructor either, for symmetry. */
4552 /* Generate '- .cxx_construct' if needed. */
4555 objc_generate_cxx_ctor_or_dtor (false);
4557 /* Generate '- .cxx_destruct' if needed. */
4560 objc_generate_cxx_ctor_or_dtor (true);
4562 /* The 'imp_list' variable points at an imp_entry record for the current
4563 @implementation. Record the existence of '- .cxx_construct' and/or
4564 '- .cxx_destruct' methods therein; it will be included in the
4565 metadata for the class. */
4566 if (flag_next_runtime)
4567 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4571 /* For each protocol which was referenced either from a @protocol()
4572 expression, or because a class/category implements it (then a
4573 pointer to the protocol is stored in the struct describing the
4574 class/category), we create a statically allocated instance of the
4575 Protocol class. The code is written in such a way as to generate
4576 as few Protocol objects as possible; we generate a unique Protocol
4577 instance for each protocol, and we don't generate a Protocol
4578 instance if the protocol is never referenced (either from a
4579 @protocol() or from a class/category implementation). These
4580 statically allocated objects can be referred to via the static
4581 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4583 The statically allocated Protocol objects that we generate here
4584 need to be fixed up at runtime in order to be used: the 'isa'
4585 pointer of the objects need to be set up to point to the 'Protocol'
4586 class, as known at runtime.
4588 The NeXT runtime fixes up all protocols at program startup time,
4589 before main() is entered. It uses a low-level trick to look up all
4590 those symbols, then loops on them and fixes them up.
4592 The GNU runtime as well fixes up all protocols before user code
4593 from the module is executed; it requires pointers to those symbols
4594 to be put in the objc_symtab (which is then passed as argument to
4595 the function __objc_exec_class() which the compiler sets up to be
4596 executed automatically when the module is loaded); setup of those
4597 Protocol objects happen in two ways in the GNU runtime: all
4598 Protocol objects referred to by a class or category implementation
4599 are fixed up when the class/category is loaded; all Protocol
4600 objects referred to by a @protocol() expression are added by the
4601 compiler to the list of statically allocated instances to fixup
4602 (the same list holding the statically allocated constant string
4603 objects). Because, as explained above, the compiler generates as
4604 few Protocol objects as possible, some Protocol object might end up
4605 being referenced multiple times when compiled with the GNU runtime,
4606 and end up being fixed up multiple times at runtime initialization.
4607 But that doesn't hurt, it's just a little inefficient. */
4610 generate_protocols (void)
4614 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4616 /* If a protocol was directly referenced, pull in indirect references. */
4617 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4618 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4619 generate_protocol_references (PROTOCOL_LIST (p));
4621 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4623 tree nst_methods = PROTOCOL_NST_METHODS (p);
4624 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4626 /* If protocol wasn't referenced, don't generate any code. */
4627 decl = PROTOCOL_FORWARD_DECL (p);
4632 /* Make sure we link in the Protocol class. */
4633 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4637 if (! METHOD_ENCODING (nst_methods))
4639 encoding = encode_method_prototype (nst_methods);
4640 METHOD_ENCODING (nst_methods) = encoding;
4642 nst_methods = TREE_CHAIN (nst_methods);
4647 if (! METHOD_ENCODING (cls_methods))
4649 encoding = encode_method_prototype (cls_methods);
4650 METHOD_ENCODING (cls_methods) = encoding;
4653 cls_methods = TREE_CHAIN (cls_methods);
4655 generate_method_descriptors (p);
4657 if (PROTOCOL_LIST (p))
4658 refs_decl = generate_protocol_list (p);
4662 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4663 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4666 refs_expr = convert (build_pointer_type (build_pointer_type
4667 (objc_protocol_template)),
4668 build_unary_op (ADDR_EXPR, refs_decl, 0));
4670 refs_expr = build_int_cst (NULL_TREE, 0);
4672 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4673 by generate_method_descriptors, which is called above. */
4674 initlist = build_protocol_initializer (TREE_TYPE (decl),
4675 protocol_name_expr, refs_expr,
4676 UOBJC_INSTANCE_METHODS_decl,
4677 UOBJC_CLASS_METHODS_decl);
4678 finish_var_decl (decl, initlist);
4683 build_protocol_initializer (tree type, tree protocol_name,
4684 tree protocol_list, tree instance_methods,
4687 tree initlist = NULL_TREE, expr;
4688 tree cast_type = build_pointer_type
4689 (xref_tag (RECORD_TYPE,
4690 get_identifier (UTAG_CLASS)));
4692 /* Filling the "isa" in with one allows the runtime system to
4693 detect that the version change...should remove before final release. */
4695 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4696 initlist = tree_cons (NULL_TREE, expr, initlist);
4697 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4698 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4700 if (!instance_methods)
4701 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4704 expr = convert (objc_method_proto_list_ptr,
4705 build_unary_op (ADDR_EXPR, instance_methods, 0));
4706 initlist = tree_cons (NULL_TREE, expr, initlist);
4710 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4713 expr = convert (objc_method_proto_list_ptr,
4714 build_unary_op (ADDR_EXPR, class_methods, 0));
4715 initlist = tree_cons (NULL_TREE, expr, initlist);
4718 return objc_build_constructor (type, nreverse (initlist));
4721 /* struct _objc_category {
4722 char *category_name;
4724 struct _objc_method_list *instance_methods;
4725 struct _objc_method_list *class_methods;
4726 struct _objc_protocol_list *protocols;
4730 build_category_template (void)
4732 tree field_decl, field_decl_chain;
4734 objc_category_template = start_struct (RECORD_TYPE,
4735 get_identifier (UTAG_CATEGORY));
4737 /* char *category_name; */
4738 field_decl = create_field_decl (string_type_node, "category_name");
4739 field_decl_chain = field_decl;
4741 /* char *class_name; */
4742 field_decl = create_field_decl (string_type_node, "class_name");
4743 chainon (field_decl_chain, field_decl);
4745 /* struct _objc_method_list *instance_methods; */
4746 field_decl = create_field_decl (objc_method_list_ptr,
4747 "instance_methods");
4748 chainon (field_decl_chain, field_decl);
4750 /* struct _objc_method_list *class_methods; */
4751 field_decl = create_field_decl (objc_method_list_ptr,
4753 chainon (field_decl_chain, field_decl);
4755 /* struct _objc_protocol **protocol_list; */
4756 field_decl = create_field_decl (build_pointer_type
4758 (objc_protocol_template)),
4760 chainon (field_decl_chain, field_decl);
4762 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4765 /* struct _objc_selector {
4771 build_selector_template (void)
4774 tree field_decl, field_decl_chain;
4776 objc_selector_template
4777 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4780 field_decl = create_field_decl (objc_selector_type, "sel_id");
4781 field_decl_chain = field_decl;
4783 /* char *sel_type; */
4784 field_decl = create_field_decl (string_type_node, "sel_type");
4785 chainon (field_decl_chain, field_decl);
4787 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4790 /* struct _objc_class {
4791 struct _objc_class *isa;
4792 struct _objc_class *super_class;
4797 struct _objc_ivar_list *ivars;
4798 struct _objc_method_list *methods;
4799 #ifdef __NEXT_RUNTIME__
4800 struct objc_cache *cache;
4802 struct sarray *dtable;
4803 struct _objc_class *subclass_list;
4804 struct _objc_class *sibling_class;
4806 struct _objc_protocol_list *protocols;
4807 #ifdef __NEXT_RUNTIME__
4810 void *gc_object_type;
4813 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4814 the NeXT/Apple runtime; still, the compiler must generate them to
4815 maintain backward binary compatibility (and to allow for future
4819 build_class_template (void)
4821 tree field_decl, field_decl_chain;
4824 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4826 /* struct _objc_class *isa; */
4827 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4829 field_decl_chain = field_decl;
4831 /* struct _objc_class *super_class; */
4832 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4834 chainon (field_decl_chain, field_decl);
4837 field_decl = create_field_decl (string_type_node, "name");
4838 chainon (field_decl_chain, field_decl);
4841 field_decl = create_field_decl (long_integer_type_node, "version");
4842 chainon (field_decl_chain, field_decl);
4845 field_decl = create_field_decl (long_integer_type_node, "info");
4846 chainon (field_decl_chain, field_decl);
4848 /* long instance_size; */
4849 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4850 chainon (field_decl_chain, field_decl);
4852 /* struct _objc_ivar_list *ivars; */
4853 field_decl = create_field_decl (objc_ivar_list_ptr,
4855 chainon (field_decl_chain, field_decl);
4857 /* struct _objc_method_list *methods; */
4858 field_decl = create_field_decl (objc_method_list_ptr,
4860 chainon (field_decl_chain, field_decl);
4862 if (flag_next_runtime)
4864 /* struct objc_cache *cache; */
4865 field_decl = create_field_decl (build_pointer_type
4866 (xref_tag (RECORD_TYPE,
4870 chainon (field_decl_chain, field_decl);
4874 /* struct sarray *dtable; */
4875 field_decl = create_field_decl (build_pointer_type
4876 (xref_tag (RECORD_TYPE,
4880 chainon (field_decl_chain, field_decl);
4882 /* struct objc_class *subclass_list; */
4883 field_decl = create_field_decl (build_pointer_type
4884 (objc_class_template),
4886 chainon (field_decl_chain, field_decl);
4888 /* struct objc_class *sibling_class; */
4889 field_decl = create_field_decl (build_pointer_type
4890 (objc_class_template),
4892 chainon (field_decl_chain, field_decl);
4895 /* struct _objc_protocol **protocol_list; */
4896 field_decl = create_field_decl (build_pointer_type
4898 (xref_tag (RECORD_TYPE,
4902 chainon (field_decl_chain, field_decl);
4904 if (flag_next_runtime)
4907 field_decl = create_field_decl (build_pointer_type (void_type_node),
4909 chainon (field_decl_chain, field_decl);
4912 /* void *gc_object_type; */
4913 field_decl = create_field_decl (build_pointer_type (void_type_node),
4915 chainon (field_decl_chain, field_decl);
4917 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4920 /* Generate appropriate forward declarations for an implementation. */
4923 synth_forward_declarations (void)
4927 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4928 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4929 objc_class_template);
4931 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4932 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4933 objc_class_template);
4935 /* Pre-build the following entities - for speed/convenience. */
4937 an_id = get_identifier ("super_class");
4938 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4939 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4943 error_with_ivar (const char *message, tree decl)
4945 error ("%J%s %qs", decl,
4946 message, gen_declaration (decl));
4951 check_ivars (tree inter, tree imp)
4953 tree intdecls = CLASS_RAW_IVARS (inter);
4954 tree impdecls = CLASS_RAW_IVARS (imp);
4961 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4962 intdecls = TREE_CHAIN (intdecls);
4964 if (intdecls == 0 && impdecls == 0)
4966 if (intdecls == 0 || impdecls == 0)
4968 error ("inconsistent instance variable specification");
4972 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4974 if (!comptypes (t1, t2)
4975 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4976 DECL_INITIAL (impdecls)))
4978 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4980 error_with_ivar ("conflicting instance variable type",
4982 error_with_ivar ("previous declaration of",
4985 else /* both the type and the name don't match */
4987 error ("inconsistent instance variable specification");
4992 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4994 error_with_ivar ("conflicting instance variable name",
4996 error_with_ivar ("previous declaration of",
5000 intdecls = TREE_CHAIN (intdecls);
5001 impdecls = TREE_CHAIN (impdecls);
5005 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5006 This needs to be done just once per compilation. */
5008 /* struct _objc_super {
5009 struct _objc_object *self;
5010 struct _objc_class *super_class;
5014 build_super_template (void)
5016 tree field_decl, field_decl_chain;
5018 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5020 /* struct _objc_object *self; */
5021 field_decl = create_field_decl (objc_object_type, "self");
5022 field_decl_chain = field_decl;
5024 /* struct _objc_class *super_class; */
5025 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5027 chainon (field_decl_chain, field_decl);
5029 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5032 /* struct _objc_ivar {
5039 build_ivar_template (void)
5041 tree objc_ivar_id, objc_ivar_record;
5042 tree field_decl, field_decl_chain;
5044 objc_ivar_id = get_identifier (UTAG_IVAR);
5045 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5047 /* char *ivar_name; */
5048 field_decl = create_field_decl (string_type_node, "ivar_name");
5049 field_decl_chain = field_decl;
5051 /* char *ivar_type; */
5052 field_decl = create_field_decl (string_type_node, "ivar_type");
5053 chainon (field_decl_chain, field_decl);
5055 /* int ivar_offset; */
5056 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5057 chainon (field_decl_chain, field_decl);
5059 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5061 return objc_ivar_record;
5066 struct objc_ivar ivar_list[ivar_count];
5070 build_ivar_list_template (tree list_type, int size)
5072 tree objc_ivar_list_record;
5073 tree field_decl, field_decl_chain;
5075 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5077 /* int ivar_count; */
5078 field_decl = create_field_decl (integer_type_node, "ivar_count");
5079 field_decl_chain = field_decl;
5081 /* struct objc_ivar ivar_list[]; */
5082 field_decl = create_field_decl (build_array_type
5085 (build_int_cst (NULL_TREE, size - 1))),
5087 chainon (field_decl_chain, field_decl);
5089 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5091 return objc_ivar_list_record;
5095 struct _objc__method_prototype_list *method_next;
5097 struct objc_method method_list[method_count];
5101 build_method_list_template (tree list_type, int size)
5103 tree objc_ivar_list_record;
5104 tree field_decl, field_decl_chain;
5106 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5108 /* struct _objc__method_prototype_list *method_next; */
5109 field_decl = create_field_decl (objc_method_proto_list_ptr,
5111 field_decl_chain = field_decl;
5113 /* int method_count; */
5114 field_decl = create_field_decl (integer_type_node, "method_count");
5115 chainon (field_decl_chain, field_decl);
5117 /* struct objc_method method_list[]; */
5118 field_decl = create_field_decl (build_array_type
5121 (build_int_cst (NULL_TREE, size - 1))),
5123 chainon (field_decl_chain, field_decl);
5125 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5127 return objc_ivar_list_record;
5131 build_ivar_list_initializer (tree type, tree field_decl)
5133 tree initlist = NULL_TREE;
5137 tree ivar = NULL_TREE;
5140 if (DECL_NAME (field_decl))
5141 ivar = tree_cons (NULL_TREE,
5142 add_objc_string (DECL_NAME (field_decl),
5146 /* Unnamed bit-field ivar (yuck). */
5147 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5150 encode_field_decl (field_decl,
5151 obstack_object_size (&util_obstack),
5152 OBJC_ENCODE_DONT_INLINE_DEFS);
5154 /* Null terminate string. */
5155 obstack_1grow (&util_obstack, 0);
5159 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5162 obstack_free (&util_obstack, util_firstobj);
5165 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5166 initlist = tree_cons (NULL_TREE,
5167 objc_build_constructor (type, nreverse (ivar)),
5170 field_decl = TREE_CHAIN (field_decl);
5171 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5175 return objc_build_constructor (build_array_type (type, 0),
5176 nreverse (initlist));
5180 generate_ivars_list (tree type, const char *name, int size, tree list)
5182 tree decl, initlist;
5184 decl = start_var_decl (type, synth_id_with_class_suffix
5185 (name, objc_implementation_context));
5187 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5188 initlist = tree_cons (NULL_TREE, list, initlist);
5190 finish_var_decl (decl,
5191 objc_build_constructor (TREE_TYPE (decl),
5192 nreverse (initlist)));
5197 /* Count only the fields occurring in T. */
5200 ivar_list_length (tree t)
5204 for (; t; t = TREE_CHAIN (t))
5205 if (TREE_CODE (t) == FIELD_DECL)
5212 generate_ivar_lists (void)
5214 tree initlist, ivar_list_template, chain;
5217 generating_instance_variables = 1;
5219 if (!objc_ivar_template)
5220 objc_ivar_template = build_ivar_template ();
5222 /* Only generate class variables for the root of the inheritance
5223 hierarchy since these will be the same for every class. */
5225 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5226 && (chain = TYPE_FIELDS (objc_class_template)))
5228 size = ivar_list_length (chain);
5230 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5231 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5233 UOBJC_CLASS_VARIABLES_decl
5234 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5238 UOBJC_CLASS_VARIABLES_decl = 0;
5240 chain = CLASS_IVARS (implementation_template);
5243 size = ivar_list_length (chain);
5244 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5245 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5247 UOBJC_INSTANCE_VARIABLES_decl
5248 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5252 UOBJC_INSTANCE_VARIABLES_decl = 0;
5254 generating_instance_variables = 0;
5258 build_dispatch_table_initializer (tree type, tree entries)
5260 tree initlist = NULL_TREE;
5264 tree elemlist = NULL_TREE;
5266 elemlist = tree_cons (NULL_TREE,
5267 build_selector (METHOD_SEL_NAME (entries)),
5270 /* Generate the method encoding if we don't have one already. */
5271 if (! METHOD_ENCODING (entries))
5272 METHOD_ENCODING (entries) =
5273 encode_method_prototype (entries);
5275 elemlist = tree_cons (NULL_TREE,
5276 add_objc_string (METHOD_ENCODING (entries),
5281 = tree_cons (NULL_TREE,
5282 convert (ptr_type_node,
5283 build_unary_op (ADDR_EXPR,
5284 METHOD_DEFINITION (entries), 1)),
5287 initlist = tree_cons (NULL_TREE,
5288 objc_build_constructor (type, nreverse (elemlist)),
5291 entries = TREE_CHAIN (entries);
5295 return objc_build_constructor (build_array_type (type, 0),
5296 nreverse (initlist));
5299 /* To accomplish method prototyping without generating all kinds of
5300 inane warnings, the definition of the dispatch table entries were
5303 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5305 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5308 build_method_template (void)
5311 tree field_decl, field_decl_chain;
5313 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5316 field_decl = create_field_decl (objc_selector_type, "_cmd");
5317 field_decl_chain = field_decl;
5319 /* char *method_types; */
5320 field_decl = create_field_decl (string_type_node, "method_types");
5321 chainon (field_decl_chain, field_decl);
5324 field_decl = create_field_decl (build_pointer_type (void_type_node),
5326 chainon (field_decl_chain, field_decl);
5328 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5335 generate_dispatch_table (tree type, const char *name, int size, tree list)
5337 tree decl, initlist;
5339 decl = start_var_decl (type, synth_id_with_class_suffix
5340 (name, objc_implementation_context));
5342 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5343 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5344 initlist = tree_cons (NULL_TREE, list, initlist);
5346 finish_var_decl (decl,
5347 objc_build_constructor (TREE_TYPE (decl),
5348 nreverse (initlist)));
5354 mark_referenced_methods (void)
5356 struct imp_entry *impent;
5359 for (impent = imp_list; impent; impent = impent->next)
5361 chain = CLASS_CLS_METHODS (impent->imp_context);
5364 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5365 chain = TREE_CHAIN (chain);
5368 chain = CLASS_NST_METHODS (impent->imp_context);
5371 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5372 chain = TREE_CHAIN (chain);
5378 generate_dispatch_tables (void)
5380 tree initlist, chain, method_list_template;
5383 if (!objc_method_template)
5384 objc_method_template = build_method_template ();
5386 chain = CLASS_CLS_METHODS (objc_implementation_context);
5389 size = list_length (chain);
5391 method_list_template
5392 = build_method_list_template (objc_method_template, size);
5394 = build_dispatch_table_initializer (objc_method_template, chain);
5396 UOBJC_CLASS_METHODS_decl
5397 = generate_dispatch_table (method_list_template,
5398 ((TREE_CODE (objc_implementation_context)
5399 == CLASS_IMPLEMENTATION_TYPE)
5400 ? "_OBJC_CLASS_METHODS"
5401 : "_OBJC_CATEGORY_CLASS_METHODS"),
5405 UOBJC_CLASS_METHODS_decl = 0;
5407 chain = CLASS_NST_METHODS (objc_implementation_context);
5410 size = list_length (chain);
5412 method_list_template
5413 = build_method_list_template (objc_method_template, size);
5415 = build_dispatch_table_initializer (objc_method_template, chain);
5417 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5418 UOBJC_INSTANCE_METHODS_decl
5419 = generate_dispatch_table (method_list_template,
5420 "_OBJC_INSTANCE_METHODS",
5423 /* We have a category. */
5424 UOBJC_INSTANCE_METHODS_decl
5425 = generate_dispatch_table (method_list_template,
5426 "_OBJC_CATEGORY_INSTANCE_METHODS",
5430 UOBJC_INSTANCE_METHODS_decl = 0;
5434 generate_protocol_list (tree i_or_p)
5437 tree refs_decl, lproto, e, plist;
5439 const char *ref_name;
5441 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5442 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5443 plist = CLASS_PROTOCOL_LIST (i_or_p);
5444 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5445 plist = PROTOCOL_LIST (i_or_p);
5450 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5451 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5452 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5455 /* Build initializer. */
5456 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5457 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5458 initlist = tree_cons (NULL_TREE, e, initlist);
5460 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5462 tree pval = TREE_VALUE (lproto);
5464 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5465 && PROTOCOL_FORWARD_DECL (pval))
5467 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5468 initlist = tree_cons (NULL_TREE, e, initlist);
5472 /* static struct objc_protocol *refs[n]; */
5474 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5475 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5476 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5477 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5478 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5479 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5483 refs_decl = start_var_decl
5485 (build_pointer_type (objc_protocol_template),
5486 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5489 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5490 nreverse (initlist)));
5496 build_category_initializer (tree type, tree cat_name, tree class_name,
5497 tree instance_methods, tree class_methods,
5500 tree initlist = NULL_TREE, expr;
5502 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5503 initlist = tree_cons (NULL_TREE, class_name, initlist);
5505 if (!instance_methods)
5506 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5509 expr = convert (objc_method_list_ptr,
5510 build_unary_op (ADDR_EXPR, instance_methods, 0));
5511 initlist = tree_cons (NULL_TREE, expr, initlist);
5514 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5517 expr = convert (objc_method_list_ptr,
5518 build_unary_op (ADDR_EXPR, class_methods, 0));
5519 initlist = tree_cons (NULL_TREE, expr, initlist);
5522 /* protocol_list = */
5524 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5527 expr = convert (build_pointer_type
5529 (objc_protocol_template)),
5530 build_unary_op (ADDR_EXPR, protocol_list, 0));
5531 initlist = tree_cons (NULL_TREE, expr, initlist);
5534 return objc_build_constructor (type, nreverse (initlist));
5537 /* struct _objc_class {
5538 struct objc_class *isa;
5539 struct objc_class *super_class;
5544 struct objc_ivar_list *ivars;
5545 struct objc_method_list *methods;
5546 if (flag_next_runtime)
5547 struct objc_cache *cache;
5549 struct sarray *dtable;
5550 struct objc_class *subclass_list;
5551 struct objc_class *sibling_class;
5553 struct objc_protocol_list *protocols;
5554 if (flag_next_runtime)
5556 void *gc_object_type;
5560 build_shared_structure_initializer (tree type, tree isa, tree super,
5561 tree name, tree size, int status,
5562 tree dispatch_table, tree ivar_list,
5565 tree initlist = NULL_TREE, expr;
5568 initlist = tree_cons (NULL_TREE, isa, initlist);
5571 initlist = tree_cons (NULL_TREE, super, initlist);
5574 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5577 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5581 initlist = tree_cons (NULL_TREE,
5582 build_int_cst (long_integer_type_node, status),
5585 /* instance_size = */
5586 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5589 /* objc_ivar_list = */
5591 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5594 expr = convert (objc_ivar_list_ptr,
5595 build_unary_op (ADDR_EXPR, ivar_list, 0));
5596 initlist = tree_cons (NULL_TREE, expr, initlist);
5599 /* objc_method_list = */
5600 if (!dispatch_table)
5601 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5604 expr = convert (objc_method_list_ptr,
5605 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5606 initlist = tree_cons (NULL_TREE, expr, initlist);
5609 if (flag_next_runtime)
5610 /* method_cache = */
5611 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5615 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5617 /* subclass_list = */
5618 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5620 /* sibling_class = */
5621 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5624 /* protocol_list = */
5625 if (! protocol_list)
5626 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5629 expr = convert (build_pointer_type
5631 (objc_protocol_template)),
5632 build_unary_op (ADDR_EXPR, protocol_list, 0));
5633 initlist = tree_cons (NULL_TREE, expr, initlist);
5636 if (flag_next_runtime)
5638 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5640 /* gc_object_type = NULL */
5641 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5643 return objc_build_constructor (type, nreverse (initlist));
5646 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5649 lookup_category (tree klass, tree cat_name)
5651 tree category = CLASS_CATEGORY_LIST (klass);
5653 while (category && CLASS_SUPER_NAME (category) != cat_name)
5654 category = CLASS_CATEGORY_LIST (category);
5658 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5661 generate_category (tree cat)
5664 tree initlist, cat_name_expr, class_name_expr;
5665 tree protocol_decl, category;
5667 add_class_reference (CLASS_NAME (cat));
5668 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5670 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5672 category = lookup_category (implementation_template,
5673 CLASS_SUPER_NAME (cat));
5675 if (category && CLASS_PROTOCOL_LIST (category))
5677 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5678 protocol_decl = generate_protocol_list (category);
5683 decl = start_var_decl (objc_category_template,
5684 synth_id_with_class_suffix
5685 ("_OBJC_CATEGORY", objc_implementation_context));
5687 initlist = build_category_initializer (TREE_TYPE (decl),
5688 cat_name_expr, class_name_expr,
5689 UOBJC_INSTANCE_METHODS_decl,
5690 UOBJC_CLASS_METHODS_decl,
5693 finish_var_decl (decl, initlist);
5696 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5697 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5700 generate_shared_structures (int cls_flags)
5702 tree sc_spec, decl_specs, decl;
5703 tree name_expr, super_expr, root_expr;
5704 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5705 tree cast_type, initlist, protocol_decl;
5707 my_super_id = CLASS_SUPER_NAME (implementation_template);
5710 add_class_reference (my_super_id);
5712 /* Compute "my_root_id" - this is required for code generation.
5713 the "isa" for all meta class structures points to the root of
5714 the inheritance hierarchy (e.g. "__Object")... */
5715 my_root_id = my_super_id;
5718 tree my_root_int = lookup_interface (my_root_id);
5720 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5721 my_root_id = CLASS_SUPER_NAME (my_root_int);
5728 /* No super class. */
5729 my_root_id = CLASS_NAME (implementation_template);
5731 cast_type = build_pointer_type (objc_class_template);
5732 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5735 /* Install class `isa' and `super' pointers at runtime. */
5738 super_expr = add_objc_string (my_super_id, class_names);
5739 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5742 super_expr = build_int_cst (NULL_TREE, 0);
5744 root_expr = add_objc_string (my_root_id, class_names);
5745 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5747 if (CLASS_PROTOCOL_LIST (implementation_template))
5749 generate_protocol_references
5750 (CLASS_PROTOCOL_LIST (implementation_template));
5751 protocol_decl = generate_protocol_list (implementation_template);
5756 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5758 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5759 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5761 decl = start_var_decl (objc_class_template,
5763 (DECL_NAME (UOBJC_METACLASS_decl)));
5766 = build_shared_structure_initializer
5768 root_expr, super_expr, name_expr,
5769 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5771 UOBJC_CLASS_METHODS_decl,
5772 UOBJC_CLASS_VARIABLES_decl,
5775 finish_var_decl (decl, initlist);
5777 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5779 decl = start_var_decl (objc_class_template,
5781 (DECL_NAME (UOBJC_CLASS_decl)));
5784 = build_shared_structure_initializer
5786 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5787 super_expr, name_expr,
5788 convert (integer_type_node,
5789 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5790 (implementation_template))),
5791 1 /*CLS_FACTORY*/ | cls_flags,
5792 UOBJC_INSTANCE_METHODS_decl,
5793 UOBJC_INSTANCE_VARIABLES_decl,
5796 finish_var_decl (decl, initlist);
5801 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5803 static char string[BUFSIZE];
5805 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5806 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5808 sprintf (string, "%s_%s", preamble,
5809 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5811 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5812 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5814 /* We have a category. */
5815 const char *const class_name
5816 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5817 const char *const class_super_name
5818 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5819 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5821 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5823 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5824 sprintf (string, "%s_%s", preamble, protocol_name);
5832 /* If type is empty or only type qualifiers are present, add default
5833 type of id (otherwise grokdeclarator will default to int). */
5836 adjust_type_for_id_default (tree type)
5839 type = make_node (TREE_LIST);
5841 if (!TREE_VALUE (type))
5842 TREE_VALUE (type) = objc_object_type;
5843 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5844 && TYPED_OBJECT (TREE_VALUE (type)))
5845 error ("can not use an object as parameter to a method");
5852 selector ':' '(' typename ')' identifier
5855 Transform an Objective-C keyword argument into
5856 the C equivalent parameter declarator.
5858 In: key_name, an "identifier_node" (optional).
5859 arg_type, a "tree_list" (optional).
5860 arg_name, an "identifier_node".
5862 Note: It would be really nice to strongly type the preceding
5863 arguments in the function prototype; however, then I
5864 could not use the "accessor" macros defined in "tree.h".
5866 Out: an instance of "keyword_decl". */
5869 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5873 /* If no type is specified, default to "id". */
5874 arg_type = adjust_type_for_id_default (arg_type);
5876 keyword_decl = make_node (KEYWORD_DECL);
5878 TREE_TYPE (keyword_decl) = arg_type;
5879 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5880 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5882 return keyword_decl;
5885 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5888 build_keyword_selector (tree selector)
5891 tree key_chain, key_name;
5894 /* Scan the selector to see how much space we'll need. */
5895 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5897 if (TREE_CODE (selector) == KEYWORD_DECL)
5898 key_name = KEYWORD_KEY_NAME (key_chain);
5899 else if (TREE_CODE (selector) == TREE_LIST)
5900 key_name = TREE_PURPOSE (key_chain);
5905 len += IDENTIFIER_LENGTH (key_name) + 1;
5907 /* Just a ':' arg. */
5911 buf = (char *) alloca (len + 1);
5912 /* Start the buffer out as an empty string. */
5915 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5917 if (TREE_CODE (selector) == KEYWORD_DECL)
5918 key_name = KEYWORD_KEY_NAME (key_chain);
5919 else if (TREE_CODE (selector) == TREE_LIST)
5921 key_name = TREE_PURPOSE (key_chain);
5922 /* The keyword decl chain will later be used as a function argument
5923 chain. Unhook the selector itself so as to not confuse other
5924 parts of the compiler. */
5925 TREE_PURPOSE (key_chain) = NULL_TREE;
5931 strcat (buf, IDENTIFIER_POINTER (key_name));
5935 return get_identifier (buf);
5938 /* Used for declarations and definitions. */
5941 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5942 tree add_args, bool ellipsis)
5946 /* If no type is specified, default to "id". */
5947 ret_type = adjust_type_for_id_default (ret_type);
5949 method_decl = make_node (code);
5950 TREE_TYPE (method_decl) = ret_type;
5952 /* If we have a keyword selector, create an identifier_node that
5953 represents the full selector name (`:' included)... */
5954 if (TREE_CODE (selector) == KEYWORD_DECL)
5956 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5957 METHOD_SEL_ARGS (method_decl) = selector;
5958 METHOD_ADD_ARGS (method_decl) = add_args;
5959 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5963 METHOD_SEL_NAME (method_decl) = selector;
5964 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5965 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5971 #define METHOD_DEF 0
5972 #define METHOD_REF 1
5974 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5975 an argument list for method METH. CONTEXT is either METHOD_DEF or
5976 METHOD_REF, saying whether we are trying to define a method or call
5977 one. SUPERFLAG says this is for a send to super; this makes a
5978 difference for the NeXT calling sequence in which the lookup and
5979 the method call are done together. If METH is null, user-defined
5980 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5983 get_arg_type_list (tree meth, int context, int superflag)
5987 /* Receiver type. */
5988 if (flag_next_runtime && superflag)
5989 arglist = build_tree_list (NULL_TREE, objc_super_type);
5990 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5991 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5993 arglist = build_tree_list (NULL_TREE, objc_object_type);
5995 /* Selector type - will eventually change to `int'. */
5996 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5998 /* No actual method prototype given -- assume that remaining arguments
6003 /* Build a list of argument types. */
6004 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6006 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6008 /* Decay arrays and functions into pointers. */
6009 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6010 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6011 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6012 arg_type = build_pointer_type (arg_type);
6014 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6017 if (METHOD_ADD_ARGS (meth))
6019 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6020 akey; akey = TREE_CHAIN (akey))
6022 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6024 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6027 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6028 goto lack_of_ellipsis;
6033 chainon (arglist, OBJC_VOID_AT_END);
6040 check_duplicates (hash hsh, int methods, int is_class)
6042 tree meth = NULL_TREE;
6050 /* We have two or more methods with the same name but
6054 /* But just how different are those types? If
6055 -Wno-strict-selector-match is specified, we shall not
6056 complain if the differences are solely among types with
6057 identical size and alignment. */
6058 if (!warn_strict_selector_match)
6060 for (loop = hsh->list; loop; loop = loop->next)
6061 if (!comp_proto_with_proto (meth, loop->value, 0))
6068 warning (0, "multiple %s named %<%c%s%> found",
6069 methods ? "methods" : "selectors",
6070 (is_class ? '+' : '-'),
6071 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6073 warn_with_method (methods ? "using" : "found",
6074 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6078 for (loop = hsh->list; loop; loop = loop->next)
6079 warn_with_method ("also found",
6080 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6089 /* If RECEIVER is a class reference, return the identifier node for
6090 the referenced class. RECEIVER is created by objc_get_class_reference,
6091 so we check the exact form created depending on which runtimes are
6095 receiver_is_class_object (tree receiver, int self, int super)
6097 tree chain, exp, arg;
6099 /* The receiver is 'self' or 'super' in the context of a class method. */
6100 if (objc_method_context
6101 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6104 ? CLASS_SUPER_NAME (implementation_template)
6105 : CLASS_NAME (implementation_template));
6107 if (flag_next_runtime)
6109 /* The receiver is a variable created by
6110 build_class_reference_decl. */
6111 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6112 /* Look up the identifier. */
6113 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6114 if (TREE_PURPOSE (chain) == receiver)
6115 return TREE_VALUE (chain);
6118 /* The receiver is a function call that returns an id. Check if
6119 it is a call to objc_getClass, if so, pick up the class name. */
6120 if (TREE_CODE (receiver) == CALL_EXPR
6121 && (exp = CALL_EXPR_FN (receiver))
6122 && TREE_CODE (exp) == ADDR_EXPR
6123 && (exp = TREE_OPERAND (exp, 0))
6124 && TREE_CODE (exp) == FUNCTION_DECL
6125 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6126 prototypes for objc_get_class(). Thankfully, they seem to share the
6127 same function type. */
6128 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6129 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6130 /* We have a call to objc_get_class/objc_getClass! */
6131 && (arg = CALL_EXPR_ARG (receiver, 0)))
6134 if (TREE_CODE (arg) == ADDR_EXPR
6135 && (arg = TREE_OPERAND (arg, 0))
6136 && TREE_CODE (arg) == STRING_CST)
6137 /* Finally, we have the class name. */
6138 return get_identifier (TREE_STRING_POINTER (arg));
6143 /* If we are currently building a message expr, this holds
6144 the identifier of the selector of the message. This is
6145 used when printing warnings about argument mismatches. */
6147 static tree current_objc_message_selector = 0;
6150 objc_message_selector (void)
6152 return current_objc_message_selector;
6155 /* Construct an expression for sending a message.
6156 MESS has the object to send to in TREE_PURPOSE
6157 and the argument list (including selector) in TREE_VALUE.
6159 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6160 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6163 objc_build_message_expr (tree mess)
6165 tree receiver = TREE_PURPOSE (mess);
6168 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6170 tree args = TREE_VALUE (mess);
6172 tree method_params = NULL_TREE;
6174 if (TREE_CODE (receiver) == ERROR_MARK)
6175 return error_mark_node;
6177 /* Obtain the full selector name. */
6178 if (TREE_CODE (args) == IDENTIFIER_NODE)
6179 /* A unary selector. */
6181 else if (TREE_CODE (args) == TREE_LIST)
6182 sel_name = build_keyword_selector (args);
6186 /* Build the parameter list to give to the method. */
6187 if (TREE_CODE (args) == TREE_LIST)
6189 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6192 tree chain = args, prev = NULL_TREE;
6194 /* We have a keyword selector--check for comma expressions. */
6197 tree element = TREE_VALUE (chain);
6199 /* We have a comma expression, must collapse... */
6200 if (TREE_CODE (element) == TREE_LIST)
6203 TREE_CHAIN (prev) = element;
6208 chain = TREE_CHAIN (chain);
6210 method_params = args;
6215 if (processing_template_decl)
6216 /* Must wait until template instantiation time. */
6217 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6221 return objc_finish_message_expr (receiver, sel_name, method_params);
6224 /* Look up method SEL_NAME that would be suitable for receiver
6225 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6226 nonzero), and report on any duplicates. */
6229 lookup_method_in_hash_lists (tree sel_name, int is_class)
6231 hash method_prototype = NULL;
6234 method_prototype = hash_lookup (nst_method_hash_list,
6237 if (!method_prototype)
6239 method_prototype = hash_lookup (cls_method_hash_list,
6244 return check_duplicates (method_prototype, 1, is_class);
6247 /* The 'objc_finish_message_expr' routine is called from within
6248 'objc_build_message_expr' for non-template functions. In the case of
6249 C++ template functions, it is called from 'build_expr_from_tree'
6250 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6253 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6255 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6256 tree selector, retval, class_tree;
6257 int self, super, have_cast;
6259 /* Extract the receiver of the message, as well as its type
6260 (where the latter may take the form of a cast or be inferred
6261 from the implementation context). */
6263 while (TREE_CODE (rtype) == COMPOUND_EXPR
6264 || TREE_CODE (rtype) == MODIFY_EXPR
6265 || CONVERT_EXPR_P (rtype)
6266 || TREE_CODE (rtype) == COMPONENT_REF)
6267 rtype = TREE_OPERAND (rtype, 0);
6268 self = (rtype == self_decl);
6269 super = (rtype == UOBJC_SUPER_decl);
6270 rtype = TREE_TYPE (receiver);
6271 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6272 || (TREE_CODE (receiver) == COMPOUND_EXPR
6273 && !IS_SUPER (rtype)));
6275 /* If we are calling [super dealloc], reset our warning flag. */
6276 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6277 should_call_super_dealloc = 0;
6279 /* If the receiver is a class object, retrieve the corresponding
6280 @interface, if one exists. */
6281 class_tree = receiver_is_class_object (receiver, self, super);
6283 /* Now determine the receiver type (if an explicit cast has not been
6288 rtype = lookup_interface (class_tree);
6289 /* Handle `self' and `super'. */
6292 if (!CLASS_SUPER_NAME (implementation_template))
6294 error ("no super class declared in @interface for %qs",
6295 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6296 return error_mark_node;
6298 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6301 rtype = lookup_interface (CLASS_NAME (implementation_template));
6304 /* If receiver is of type `id' or `Class' (or if the @interface for a
6305 class is not visible), we shall be satisfied with the existence of
6306 any instance or class method. */
6307 if (objc_is_id (rtype))
6309 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6310 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6311 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6317 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6318 in protocols themselves for the method prototype. */
6320 = lookup_method_in_protocol_list (rprotos, sel_name,
6321 class_tree != NULL_TREE);
6323 /* If messaging 'Class <Proto>' but did not find a class method
6324 prototype, search for an instance method instead, and warn
6325 about having done so. */
6326 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6329 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6331 if (method_prototype)
6332 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6333 IDENTIFIER_POINTER (sel_name),
6334 IDENTIFIER_POINTER (sel_name));
6340 tree orig_rtype = rtype, saved_rtype;
6342 if (TREE_CODE (rtype) == POINTER_TYPE)
6343 rtype = TREE_TYPE (rtype);
6344 /* Traverse typedef aliases */
6345 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6346 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6347 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6348 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6349 saved_rtype = rtype;
6350 if (TYPED_OBJECT (rtype))
6352 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6353 rtype = TYPE_OBJC_INTERFACE (rtype);
6355 /* If we could not find an @interface declaration, we must have
6356 only seen a @class declaration; so, we cannot say anything
6357 more intelligent about which methods the receiver will
6359 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6361 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6362 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6364 /* We have a valid ObjC class name. Look up the method name
6365 in the published @interface for the class (and its
6368 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6370 /* If the method was not found in the @interface, it may still
6371 exist locally as part of the @implementation. */
6372 if (!method_prototype && objc_implementation_context
6373 && CLASS_NAME (objc_implementation_context)
6374 == OBJC_TYPE_NAME (rtype))
6378 ? CLASS_CLS_METHODS (objc_implementation_context)
6379 : CLASS_NST_METHODS (objc_implementation_context)),
6382 /* If we haven't found a candidate method by now, try looking for
6383 it in the protocol list. */
6384 if (!method_prototype && rprotos)
6386 = lookup_method_in_protocol_list (rprotos, sel_name,
6387 class_tree != NULL_TREE);
6391 warning (0, "invalid receiver type %qs",
6392 gen_type_name (orig_rtype));
6393 /* After issuing the "invalid receiver" warning, perform method
6394 lookup as if we were messaging 'id'. */
6395 rtype = rprotos = NULL_TREE;
6400 /* For 'id' or 'Class' receivers, search in the global hash table
6401 as a last resort. For all receivers, warn if protocol searches
6403 if (!method_prototype)
6406 warning (0, "%<%c%s%> not found in protocol(s)",
6407 (class_tree ? '+' : '-'),
6408 IDENTIFIER_POINTER (sel_name));
6412 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6415 if (!method_prototype)
6417 static bool warn_missing_methods = false;
6420 warning (0, "%qs may not respond to %<%c%s%>",
6421 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6422 (class_tree ? '+' : '-'),
6423 IDENTIFIER_POINTER (sel_name));
6424 /* If we are messaging an 'id' or 'Class' object and made it here,
6425 then we have failed to find _any_ instance or class method,
6428 warning (0, "no %<%c%s%> method found",
6429 (class_tree ? '+' : '-'),
6430 IDENTIFIER_POINTER (sel_name));
6432 if (!warn_missing_methods)
6434 warning (0, "(Messages without a matching method signature");
6435 warning (0, "will be assumed to return %<id%> and accept");
6436 warning (0, "%<...%> as arguments.)");
6437 warn_missing_methods = true;
6441 /* Save the selector name for printing error messages. */
6442 current_objc_message_selector = sel_name;
6444 /* Build the parameters list for looking up the method.
6445 These are the object itself and the selector. */
6447 if (flag_typed_selectors)
6448 selector = build_typed_selector_reference (sel_name, method_prototype);
6450 selector = build_selector_reference (sel_name);
6452 retval = build_objc_method_call (super, method_prototype,
6454 selector, method_params);
6456 current_objc_message_selector = 0;
6461 /* Build a tree expression to send OBJECT the operation SELECTOR,
6462 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6463 assuming the method has prototype METHOD_PROTOTYPE.
6464 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6465 Use METHOD_PARAMS as list of args to pass to the method.
6466 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6469 build_objc_method_call (int super_flag, tree method_prototype,
6470 tree lookup_object, tree selector,
6473 tree sender = (super_flag ? umsg_super_decl :
6474 (!flag_next_runtime || flag_nil_receivers
6475 ? (flag_objc_direct_dispatch
6478 : umsg_nonnil_decl));
6479 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6481 /* If a prototype for the method to be called exists, then cast
6482 the sender's return type and arguments to match that of the method.
6483 Otherwise, leave sender as is. */
6486 ? TREE_VALUE (TREE_TYPE (method_prototype))
6487 : objc_object_type);
6489 = build_pointer_type
6490 (build_function_type
6493 (method_prototype, METHOD_REF, super_flag)));
6496 lookup_object = build_c_cast (rcv_p, lookup_object);
6498 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6499 lookup_object = save_expr (lookup_object);
6501 if (flag_next_runtime)
6503 /* If we are returning a struct in memory, and the address
6504 of that memory location is passed as a hidden first
6505 argument, then change which messenger entry point this
6506 expr will call. NB: Note that sender_cast remains
6507 unchanged (it already has a struct return type). */
6508 if (!targetm.calls.struct_value_rtx (0, 0)
6509 && (TREE_CODE (ret_type) == RECORD_TYPE
6510 || TREE_CODE (ret_type) == UNION_TYPE)
6511 && targetm.calls.return_in_memory (ret_type, 0))
6512 sender = (super_flag ? umsg_super_stret_decl :
6513 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6515 method_params = tree_cons (NULL_TREE, lookup_object,
6516 tree_cons (NULL_TREE, selector,
6518 method = build_fold_addr_expr (sender);
6522 /* This is the portable (GNU) way. */
6525 /* First, call the lookup function to get a pointer to the method,
6526 then cast the pointer, then call it with the method arguments. */
6528 object = (super_flag ? self_decl : lookup_object);
6530 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6531 t = tree_cons (NULL_TREE, lookup_object, t);
6532 method = build_function_call (sender, t);
6534 /* Pass the object to the method. */
6535 method_params = tree_cons (NULL_TREE, object,
6536 tree_cons (NULL_TREE, selector,
6540 /* ??? Selector is not at this point something we can use inside
6541 the compiler itself. Set it to garbage for the nonce. */
6542 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6543 return build_function_call (t, method_params);
6547 build_protocol_reference (tree p)
6550 const char *proto_name;
6552 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6554 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6555 decl = start_var_decl (objc_protocol_template, proto_name);
6557 PROTOCOL_FORWARD_DECL (p) = decl;
6560 /* This function is called by the parser when (and only when) a
6561 @protocol() expression is found, in order to compile it. */
6563 objc_build_protocol_expr (tree protoname)
6566 tree p = lookup_protocol (protoname);
6570 error ("cannot find protocol declaration for %qs",
6571 IDENTIFIER_POINTER (protoname));
6572 return error_mark_node;
6575 if (!PROTOCOL_FORWARD_DECL (p))
6576 build_protocol_reference (p);
6578 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6580 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6581 if we have it, rather than converting it here. */
6582 expr = convert (objc_protocol_type, expr);
6584 /* The @protocol() expression is being compiled into a pointer to a
6585 statically allocated instance of the Protocol class. To become
6586 usable at runtime, the 'isa' pointer of the instance need to be
6587 fixed up at runtime by the runtime library, to point to the
6588 actual 'Protocol' class. */
6590 /* For the GNU runtime, put the static Protocol instance in the list
6591 of statically allocated instances, so that we make sure that its
6592 'isa' pointer is fixed up at runtime by the GNU runtime library
6593 to point to the Protocol class (at runtime, when loading the
6594 module, the GNU runtime library loops on the statically allocated
6595 instances (as found in the defs field in objc_symtab) and fixups
6596 all the 'isa' pointers of those objects). */
6597 if (! flag_next_runtime)
6599 /* This type is a struct containing the fields of a Protocol
6600 object. (Cfr. objc_protocol_type instead is the type of a pointer
6601 to such a struct). */
6602 tree protocol_struct_type = xref_tag
6603 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6606 /* Look for the list of Protocol statically allocated instances
6607 to fixup at runtime. Create a new list to hold Protocol
6608 statically allocated instances, if the list is not found. At
6609 present there is only another list, holding NSConstantString
6610 static instances to be fixed up at runtime. */
6611 for (chain = &objc_static_instances;
6612 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6613 chain = &TREE_CHAIN (*chain));
6616 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6617 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6621 /* Add this statically allocated instance to the Protocol list. */
6622 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6623 PROTOCOL_FORWARD_DECL (p),
6624 TREE_PURPOSE (*chain));
6631 /* This function is called by the parser when a @selector() expression
6632 is found, in order to compile it. It is only called by the parser
6633 and only to compile a @selector(). */
6635 objc_build_selector_expr (tree selnamelist)
6639 /* Obtain the full selector name. */
6640 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6641 /* A unary selector. */
6642 selname = selnamelist;
6643 else if (TREE_CODE (selnamelist) == TREE_LIST)
6644 selname = build_keyword_selector (selnamelist);
6648 /* If we are required to check @selector() expressions as they
6649 are found, check that the selector has been declared. */
6650 if (warn_undeclared_selector)
6652 /* Look the selector up in the list of all known class and
6653 instance methods (up to this line) to check that the selector
6657 /* First try with instance methods. */
6658 hsh = hash_lookup (nst_method_hash_list, selname);
6660 /* If not found, try with class methods. */
6663 hsh = hash_lookup (cls_method_hash_list, selname);
6666 /* If still not found, print out a warning. */
6669 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6674 if (flag_typed_selectors)
6675 return build_typed_selector_reference (selname, 0);
6677 return build_selector_reference (selname);
6681 objc_build_encode_expr (tree type)
6686 encode_type (type, obstack_object_size (&util_obstack),
6687 OBJC_ENCODE_INLINE_DEFS);
6688 obstack_1grow (&util_obstack, 0); /* null terminate string */
6689 string = XOBFINISH (&util_obstack, const char *);
6691 /* Synthesize a string that represents the encoded struct/union. */
6692 result = my_build_string (strlen (string) + 1, string);
6693 obstack_free (&util_obstack, util_firstobj);
6698 build_ivar_reference (tree id)
6700 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6702 /* Historically, a class method that produced objects (factory
6703 method) would assign `self' to the instance that it
6704 allocated. This would effectively turn the class method into
6705 an instance method. Following this assignment, the instance
6706 variables could be accessed. That practice, while safe,
6707 violates the simple rule that a class method should not refer
6708 to an instance variable. It's better to catch the cases
6709 where this is done unknowingly than to support the above
6711 warning (0, "instance variable %qs accessed in class method",
6712 IDENTIFIER_POINTER (id));
6713 self_decl = convert (objc_instance_type, self_decl); /* cast */
6716 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6719 /* Compute a hash value for a given method SEL_NAME. */
6722 hash_func (tree sel_name)
6724 const unsigned char *s
6725 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6729 h = h * 67 + *s++ - 113;
6736 nst_method_hash_list
6737 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6738 cls_method_hash_list
6739 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6741 /* Initialize the hash table used to hold the constant string objects. */
6742 string_htab = htab_create_ggc (31, string_hash,
6745 /* Initialize the hash table used to hold EH-volatilized types. */
6746 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6747 volatilized_eq, NULL);
6750 /* WARNING!!!! hash_enter is called with a method, and will peek
6751 inside to find its selector! But hash_lookup is given a selector
6752 directly, and looks for the selector that's inside the found
6753 entry's key (method) for comparison. */
6756 hash_enter (hash *hashlist, tree method)
6759 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6761 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6763 obj->next = hashlist[slot];
6766 hashlist[slot] = obj; /* append to front */
6770 hash_lookup (hash *hashlist, tree sel_name)
6774 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6778 if (sel_name == METHOD_SEL_NAME (target->key))
6781 target = target->next;
6787 hash_add_attr (hash entry, tree value)
6791 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6792 obj->next = entry->list;
6795 entry->list = obj; /* append to front */
6799 lookup_method (tree mchain, tree method)
6803 if (TREE_CODE (method) == IDENTIFIER_NODE)
6806 key = METHOD_SEL_NAME (method);
6810 if (METHOD_SEL_NAME (mchain) == key)
6813 mchain = TREE_CHAIN (mchain);
6818 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6819 in INTERFACE, along with any categories and protocols attached thereto.
6820 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6821 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6822 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6823 be found in INTERFACE or any of its superclasses, look for an _instance_
6824 method of the same name in the root class as a last resort.
6826 If a suitable method cannot be found, return NULL_TREE. */
6829 lookup_method_static (tree interface, tree ident, int flags)
6831 tree meth = NULL_TREE, root_inter = NULL_TREE;
6832 tree inter = interface;
6833 int is_class = (flags & OBJC_LOOKUP_CLASS);
6834 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6838 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6839 tree category = inter;
6841 /* First, look up the method in the class itself. */
6842 if ((meth = lookup_method (chain, ident)))
6845 /* Failing that, look for the method in each category of the class. */
6846 while ((category = CLASS_CATEGORY_LIST (category)))
6848 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6850 /* Check directly in each category. */
6851 if ((meth = lookup_method (chain, ident)))
6854 /* Failing that, check in each category's protocols. */
6855 if (CLASS_PROTOCOL_LIST (category))
6857 if ((meth = (lookup_method_in_protocol_list
6858 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6863 /* If not found in categories, check in protocols of the main class. */
6864 if (CLASS_PROTOCOL_LIST (inter))
6866 if ((meth = (lookup_method_in_protocol_list
6867 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6871 /* If we were instructed not to look in superclasses, don't. */
6872 if (no_superclasses)
6875 /* Failing that, climb up the inheritance hierarchy. */
6877 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6881 /* If no class (factory) method was found, check if an _instance_
6882 method of the same name exists in the root class. This is what
6883 the Objective-C runtime will do. If an instance method was not
6885 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6888 /* Add the method to the hash list if it doesn't contain an identical
6892 add_method_to_hash_list (hash *hash_list, tree method)
6896 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6898 /* Install on a global chain. */
6899 hash_enter (hash_list, method);
6903 /* Check types against those; if different, add to a list. */
6905 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6906 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6907 already_there |= comp_proto_with_proto (method, loop->value, 1);
6909 hash_add_attr (hsh, method);
6914 objc_add_method (tree klass, tree method, int is_class)
6918 if (!(mth = lookup_method (is_class
6919 ? CLASS_CLS_METHODS (klass)
6920 : CLASS_NST_METHODS (klass), method)))
6922 /* put method on list in reverse order */
6925 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
6926 CLASS_CLS_METHODS (klass) = method;
6930 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
6931 CLASS_NST_METHODS (klass) = method;
6936 /* When processing an @interface for a class or category, give hard
6937 errors on methods with identical selectors but differing argument
6938 and/or return types. We do not do this for @implementations, because
6939 C/C++ will do it for us (i.e., there will be duplicate function
6940 definition errors). */
6941 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
6942 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
6943 && !comp_proto_with_proto (method, mth, 1))
6944 error ("duplicate declaration of method %<%c%s%>",
6945 is_class ? '+' : '-',
6946 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6950 add_method_to_hash_list (cls_method_hash_list, method);
6953 add_method_to_hash_list (nst_method_hash_list, method);
6955 /* Instance methods in root classes (and categories thereof)
6956 may act as class methods as a last resort. We also add
6957 instance methods listed in @protocol declarations to
6958 the class hash table, on the assumption that @protocols
6959 may be adopted by root classes or categories. */
6960 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
6961 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
6962 klass = lookup_interface (CLASS_NAME (klass));
6964 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
6965 || !CLASS_SUPER_NAME (klass))
6966 add_method_to_hash_list (cls_method_hash_list, method);
6973 add_class (tree class_name, tree name)
6975 struct interface_tuple **slot;
6977 /* Put interfaces on list in reverse order. */
6978 TREE_CHAIN (class_name) = interface_chain;
6979 interface_chain = class_name;
6981 if (interface_htab == NULL)
6982 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6983 slot = (struct interface_tuple **)
6984 htab_find_slot_with_hash (interface_htab, name,
6985 IDENTIFIER_HASH_VALUE (name),
6989 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6992 (*slot)->class_name = class_name;
6994 return interface_chain;
6998 add_category (tree klass, tree category)
7000 /* Put categories on list in reverse order. */
7001 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7005 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7006 IDENTIFIER_POINTER (CLASS_NAME (klass)),
7007 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7011 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7012 CLASS_CATEGORY_LIST (klass) = category;
7016 /* Called after parsing each instance variable declaration. Necessary to
7017 preserve typedefs and implement public/private...
7019 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7022 add_instance_variable (tree klass, int visibility, tree field_decl)
7024 tree field_type = TREE_TYPE (field_decl);
7025 const char *ivar_name = DECL_NAME (field_decl)
7026 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7030 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7032 error ("illegal reference type specified for instance variable %qs",
7034 /* Return class as is without adding this ivar. */
7039 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7040 || TYPE_SIZE (field_type) == error_mark_node)
7041 /* 'type[0]' is allowed, but 'type[]' is not! */
7043 error ("instance variable %qs has unknown size", ivar_name);
7044 /* Return class as is without adding this ivar. */
7049 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7050 need to either (1) warn the user about it or (2) generate suitable
7051 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7052 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7053 if (MAYBE_CLASS_TYPE_P (field_type)
7054 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7055 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7056 || TYPE_POLYMORPHIC_P (field_type)))
7058 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7060 if (flag_objc_call_cxx_cdtors)
7062 /* Since the ObjC runtime will be calling the constructors and
7063 destructors for us, the only thing we can't handle is the lack
7064 of a default constructor. */
7065 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7066 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7068 warning (0, "type %qs has no default constructor to call",
7071 /* If we cannot call a constructor, we should also avoid
7072 calling the destructor, for symmetry. */
7073 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7074 warning (0, "destructor for %qs shall not be run either",
7080 static bool warn_cxx_ivars = false;
7082 if (TYPE_POLYMORPHIC_P (field_type))
7084 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7086 error ("type %qs has virtual member functions", type_name);
7087 error ("illegal aggregate type %qs specified "
7088 "for instance variable %qs",
7089 type_name, ivar_name);
7090 /* Return class as is without adding this ivar. */
7094 /* User-defined constructors and destructors are not known to Obj-C
7095 and hence will not be called. This may or may not be a problem. */
7096 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7097 warning (0, "type %qs has a user-defined constructor", type_name);
7098 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7099 warning (0, "type %qs has a user-defined destructor", type_name);
7101 if (!warn_cxx_ivars)
7103 warning (0, "C++ constructors and destructors will not "
7104 "be invoked for Objective-C fields");
7105 warn_cxx_ivars = true;
7111 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7115 TREE_PUBLIC (field_decl) = 0;
7116 TREE_PRIVATE (field_decl) = 0;
7117 TREE_PROTECTED (field_decl) = 1;
7121 TREE_PUBLIC (field_decl) = 1;
7122 TREE_PRIVATE (field_decl) = 0;
7123 TREE_PROTECTED (field_decl) = 0;
7127 TREE_PUBLIC (field_decl) = 0;
7128 TREE_PRIVATE (field_decl) = 1;
7129 TREE_PROTECTED (field_decl) = 0;
7134 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7140 is_ivar (tree decl_chain, tree ident)
7142 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7143 if (DECL_NAME (decl_chain) == ident)
7148 /* True if the ivar is private and we are not in its implementation. */
7151 is_private (tree decl)
7153 return (TREE_PRIVATE (decl)
7154 && ! is_ivar (CLASS_IVARS (implementation_template),
7158 /* We have an instance variable reference;, check to see if it is public. */
7161 objc_is_public (tree expr, tree identifier)
7163 tree basetype, decl;
7166 if (processing_template_decl)
7170 if (TREE_TYPE (expr) == error_mark_node)
7173 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7175 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7177 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7179 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7183 error ("cannot find interface declaration for %qs",
7184 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7188 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7190 if (TREE_PUBLIC (decl))
7193 /* Important difference between the Stepstone translator:
7194 all instance variables should be public within the context
7195 of the implementation. */
7196 if (objc_implementation_context
7197 && ((TREE_CODE (objc_implementation_context)
7198 == CLASS_IMPLEMENTATION_TYPE)
7199 || (TREE_CODE (objc_implementation_context)
7200 == CATEGORY_IMPLEMENTATION_TYPE)))
7202 tree curtype = TYPE_MAIN_VARIANT
7203 (CLASS_STATIC_TEMPLATE
7204 (implementation_template));
7206 if (basetype == curtype
7207 || DERIVED_FROM_P (basetype, curtype))
7209 int priv = is_private (decl);
7212 error ("instance variable %qs is declared private",
7213 IDENTIFIER_POINTER (DECL_NAME (decl)));
7219 /* The 2.95.2 compiler sometimes allowed C functions to access
7220 non-@public ivars. We will let this slide for now... */
7221 if (!objc_method_context)
7223 warning (0, "instance variable %qs is %s; "
7224 "this will be a hard error in the future",
7225 IDENTIFIER_POINTER (identifier),
7226 TREE_PRIVATE (decl) ? "@private" : "@protected");
7230 error ("instance variable %qs is declared %s",
7231 IDENTIFIER_POINTER (identifier),
7232 TREE_PRIVATE (decl) ? "private" : "protected");
7241 /* Make sure all entries in CHAIN are also in LIST. */
7244 check_methods (tree chain, tree list, int mtype)
7250 if (!lookup_method (list, chain))
7254 if (TREE_CODE (objc_implementation_context)
7255 == CLASS_IMPLEMENTATION_TYPE)
7256 warning (0, "incomplete implementation of class %qs",
7257 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7258 else if (TREE_CODE (objc_implementation_context)
7259 == CATEGORY_IMPLEMENTATION_TYPE)
7260 warning (0, "incomplete implementation of category %qs",
7261 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7265 warning (0, "method definition for %<%c%s%> not found",
7266 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7269 chain = TREE_CHAIN (chain);
7275 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7278 conforms_to_protocol (tree klass, tree protocol)
7280 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7282 tree p = CLASS_PROTOCOL_LIST (klass);
7283 while (p && TREE_VALUE (p) != protocol)
7288 tree super = (CLASS_SUPER_NAME (klass)
7289 ? lookup_interface (CLASS_SUPER_NAME (klass))
7291 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7300 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7301 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7304 check_methods_accessible (tree chain, tree context, int mtype)
7308 tree base_context = context;
7312 context = base_context;
7316 list = CLASS_CLS_METHODS (context);
7318 list = CLASS_NST_METHODS (context);
7320 if (lookup_method (list, chain))
7323 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7324 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7325 context = (CLASS_SUPER_NAME (context)
7326 ? lookup_interface (CLASS_SUPER_NAME (context))
7329 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7330 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7331 context = (CLASS_NAME (context)
7332 ? lookup_interface (CLASS_NAME (context))
7338 if (context == NULL_TREE)
7342 if (TREE_CODE (objc_implementation_context)
7343 == CLASS_IMPLEMENTATION_TYPE)
7344 warning (0, "incomplete implementation of class %qs",
7346 (CLASS_NAME (objc_implementation_context)));
7347 else if (TREE_CODE (objc_implementation_context)
7348 == CATEGORY_IMPLEMENTATION_TYPE)
7349 warning (0, "incomplete implementation of category %qs",
7351 (CLASS_SUPER_NAME (objc_implementation_context)));
7354 warning (0, "method definition for %<%c%s%> not found",
7355 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7358 chain = TREE_CHAIN (chain); /* next method... */
7363 /* Check whether the current interface (accessible via
7364 'objc_implementation_context') actually implements protocol P, along
7365 with any protocols that P inherits. */
7368 check_protocol (tree p, const char *type, const char *name)
7370 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7374 /* Ensure that all protocols have bodies! */
7377 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7378 CLASS_CLS_METHODS (objc_implementation_context),
7380 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7381 CLASS_NST_METHODS (objc_implementation_context),
7386 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7387 objc_implementation_context,
7389 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7390 objc_implementation_context,
7395 warning (0, "%s %qs does not fully implement the %qs protocol",
7396 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7399 /* Check protocols recursively. */
7400 if (PROTOCOL_LIST (p))
7402 tree subs = PROTOCOL_LIST (p);
7404 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7408 tree sub = TREE_VALUE (subs);
7410 /* If the superclass does not conform to the protocols
7411 inherited by P, then we must! */
7412 if (!super_class || !conforms_to_protocol (super_class, sub))
7413 check_protocol (sub, type, name);
7414 subs = TREE_CHAIN (subs);
7419 /* Check whether the current interface (accessible via
7420 'objc_implementation_context') actually implements the protocols listed
7424 check_protocols (tree proto_list, const char *type, const char *name)
7426 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7428 tree p = TREE_VALUE (proto_list);
7430 check_protocol (p, type, name);
7434 /* Make sure that the class CLASS_NAME is defined
7435 CODE says which kind of thing CLASS_NAME ought to be.
7436 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7437 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7440 start_class (enum tree_code code, tree class_name, tree super_name,
7446 if (current_namespace != global_namespace) {
7447 error ("Objective-C declarations may only appear in global scope");
7449 #endif /* OBJCPLUS */
7451 if (objc_implementation_context)
7453 warning (0, "%<@end%> missing in implementation context");
7454 finish_class (objc_implementation_context);
7455 objc_ivar_chain = NULL_TREE;
7456 objc_implementation_context = NULL_TREE;
7459 klass = make_node (code);
7460 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7462 /* Check for existence of the super class, if one was specified. Note
7463 that we must have seen an @interface, not just a @class. If we
7464 are looking at a @compatibility_alias, traverse it first. */
7465 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7468 tree super = objc_is_class_name (super_name);
7470 if (!super || !lookup_interface (super))
7472 error ("cannot find interface declaration for %qs, superclass of %qs",
7473 IDENTIFIER_POINTER (super ? super : super_name),
7474 IDENTIFIER_POINTER (class_name));
7475 super_name = NULL_TREE;
7481 CLASS_NAME (klass) = class_name;
7482 CLASS_SUPER_NAME (klass) = super_name;
7483 CLASS_CLS_METHODS (klass) = NULL_TREE;
7485 if (! objc_is_class_name (class_name)
7486 && (decl = lookup_name (class_name)))
7488 error ("%qs redeclared as different kind of symbol",
7489 IDENTIFIER_POINTER (class_name));
7490 error ("previous declaration of %q+D",
7494 if (code == CLASS_IMPLEMENTATION_TYPE)
7499 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7500 if (TREE_VALUE (chain) == class_name)
7502 error ("reimplementation of class %qs",
7503 IDENTIFIER_POINTER (class_name));
7504 return error_mark_node;
7506 implemented_classes = tree_cons (NULL_TREE, class_name,
7507 implemented_classes);
7510 /* Reset for multiple classes per file. */
7513 objc_implementation_context = klass;
7515 /* Lookup the interface for this implementation. */
7517 if (!(implementation_template = lookup_interface (class_name)))
7519 warning (0, "cannot find interface declaration for %qs",
7520 IDENTIFIER_POINTER (class_name));
7521 add_class (implementation_template = objc_implementation_context,
7525 /* If a super class has been specified in the implementation,
7526 insure it conforms to the one specified in the interface. */
7529 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7531 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7532 const char *const name =
7533 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7534 error ("conflicting super class name %qs",
7535 IDENTIFIER_POINTER (super_name));
7536 error ("previous declaration of %qs", name);
7539 else if (! super_name)
7541 CLASS_SUPER_NAME (objc_implementation_context)
7542 = CLASS_SUPER_NAME (implementation_template);
7546 else if (code == CLASS_INTERFACE_TYPE)
7548 if (lookup_interface (class_name))
7550 error ("duplicate interface declaration for class %qs",
7552 warning (0, "duplicate interface declaration for class %qs",
7554 IDENTIFIER_POINTER (class_name));
7556 add_class (klass, class_name);
7559 CLASS_PROTOCOL_LIST (klass)
7560 = lookup_and_install_protocols (protocol_list);
7563 else if (code == CATEGORY_INTERFACE_TYPE)
7565 tree class_category_is_assoc_with;
7567 /* For a category, class_name is really the name of the class that
7568 the following set of methods will be associated with. We must
7569 find the interface so that can derive the objects template. */
7571 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7573 error ("cannot find interface declaration for %qs",
7574 IDENTIFIER_POINTER (class_name));
7575 exit (FATAL_EXIT_CODE);
7578 add_category (class_category_is_assoc_with, klass);
7581 CLASS_PROTOCOL_LIST (klass)
7582 = lookup_and_install_protocols (protocol_list);
7585 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7587 /* Reset for multiple classes per file. */
7590 objc_implementation_context = klass;
7592 /* For a category, class_name is really the name of the class that
7593 the following set of methods will be associated with. We must
7594 find the interface so that can derive the objects template. */
7596 if (!(implementation_template = lookup_interface (class_name)))
7598 error ("cannot find interface declaration for %qs",
7599 IDENTIFIER_POINTER (class_name));
7600 exit (FATAL_EXIT_CODE);
7607 continue_class (tree klass)
7609 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7610 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7612 struct imp_entry *imp_entry;
7614 /* Check consistency of the instance variables. */
7616 if (CLASS_RAW_IVARS (klass))
7617 check_ivars (implementation_template, klass);
7619 /* code generation */
7622 push_lang_context (lang_name_c);
7625 build_private_template (implementation_template);
7626 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7627 objc_instance_type = build_pointer_type (uprivate_record);
7629 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7631 imp_entry->next = imp_list;
7632 imp_entry->imp_context = klass;
7633 imp_entry->imp_template = implementation_template;
7635 synth_forward_declarations ();
7636 imp_entry->class_decl = UOBJC_CLASS_decl;
7637 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7638 imp_entry->has_cxx_cdtors = 0;
7640 /* Append to front and increment count. */
7641 imp_list = imp_entry;
7642 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7648 pop_lang_context ();
7649 #endif /* OBJCPLUS */
7651 return get_class_ivars (implementation_template, true);
7654 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7657 push_lang_context (lang_name_c);
7658 #endif /* OBJCPLUS */
7660 build_private_template (klass);
7663 pop_lang_context ();
7664 #endif /* OBJCPLUS */
7670 return error_mark_node;
7673 /* This is called once we see the "@end" in an interface/implementation. */
7676 finish_class (tree klass)
7678 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7680 /* All code generation is done in finish_objc. */
7682 if (implementation_template != objc_implementation_context)
7684 /* Ensure that all method listed in the interface contain bodies. */
7685 check_methods (CLASS_CLS_METHODS (implementation_template),
7686 CLASS_CLS_METHODS (objc_implementation_context), '+');
7687 check_methods (CLASS_NST_METHODS (implementation_template),
7688 CLASS_NST_METHODS (objc_implementation_context), '-');
7690 if (CLASS_PROTOCOL_LIST (implementation_template))
7691 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7693 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7697 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7699 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7703 /* Ensure all method listed in the interface contain bodies. */
7704 check_methods (CLASS_CLS_METHODS (category),
7705 CLASS_CLS_METHODS (objc_implementation_context), '+');
7706 check_methods (CLASS_NST_METHODS (category),
7707 CLASS_NST_METHODS (objc_implementation_context), '-');
7709 if (CLASS_PROTOCOL_LIST (category))
7710 check_protocols (CLASS_PROTOCOL_LIST (category),
7712 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7718 add_protocol (tree protocol)
7720 /* Put protocol on list in reverse order. */
7721 TREE_CHAIN (protocol) = protocol_chain;
7722 protocol_chain = protocol;
7723 return protocol_chain;
7727 lookup_protocol (tree ident)
7731 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7732 if (ident == PROTOCOL_NAME (chain))
7738 /* This function forward declares the protocols named by NAMES. If
7739 they are already declared or defined, the function has no effect. */
7742 objc_declare_protocols (tree names)
7747 if (current_namespace != global_namespace) {
7748 error ("Objective-C declarations may only appear in global scope");
7750 #endif /* OBJCPLUS */
7752 for (list = names; list; list = TREE_CHAIN (list))
7754 tree name = TREE_VALUE (list);
7756 if (lookup_protocol (name) == NULL_TREE)
7758 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7760 TYPE_LANG_SLOT_1 (protocol)
7761 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7762 PROTOCOL_NAME (protocol) = name;
7763 PROTOCOL_LIST (protocol) = NULL_TREE;
7764 add_protocol (protocol);
7765 PROTOCOL_DEFINED (protocol) = 0;
7766 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7772 start_protocol (enum tree_code code, tree name, tree list)
7777 if (current_namespace != global_namespace) {
7778 error ("Objective-C declarations may only appear in global scope");
7780 #endif /* OBJCPLUS */
7782 protocol = lookup_protocol (name);
7786 protocol = make_node (code);
7787 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7789 PROTOCOL_NAME (protocol) = name;
7790 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7791 add_protocol (protocol);
7792 PROTOCOL_DEFINED (protocol) = 1;
7793 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7795 check_protocol_recursively (protocol, list);
7797 else if (! PROTOCOL_DEFINED (protocol))
7799 PROTOCOL_DEFINED (protocol) = 1;
7800 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7802 check_protocol_recursively (protocol, list);
7806 warning (0, "duplicate declaration for protocol %qs",
7807 IDENTIFIER_POINTER (name));
7813 /* "Encode" a data type into a string, which grows in util_obstack.
7814 ??? What is the FORMAT? Someone please document this! */
7817 encode_type_qualifiers (tree declspecs)
7821 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7823 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7824 obstack_1grow (&util_obstack, 'n');
7825 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7826 obstack_1grow (&util_obstack, 'N');
7827 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7828 obstack_1grow (&util_obstack, 'o');
7829 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7830 obstack_1grow (&util_obstack, 'O');
7831 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7832 obstack_1grow (&util_obstack, 'R');
7833 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7834 obstack_1grow (&util_obstack, 'V');
7838 /* Encode a pointer type. */
7841 encode_pointer (tree type, int curtype, int format)
7843 tree pointer_to = TREE_TYPE (type);
7845 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7847 if (OBJC_TYPE_NAME (pointer_to)
7848 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7850 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7852 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7854 obstack_1grow (&util_obstack, '@');
7857 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7858 && TYPE_OBJC_INTERFACE (pointer_to))
7860 if (generating_instance_variables)
7862 obstack_1grow (&util_obstack, '@');
7863 obstack_1grow (&util_obstack, '"');
7864 obstack_grow (&util_obstack, name, strlen (name));
7865 obstack_1grow (&util_obstack, '"');
7870 obstack_1grow (&util_obstack, '@');
7874 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7876 obstack_1grow (&util_obstack, '#');
7879 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7881 obstack_1grow (&util_obstack, ':');
7886 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7887 && TYPE_MODE (pointer_to) == QImode)
7889 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7890 ? OBJC_TYPE_NAME (pointer_to)
7891 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7893 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7895 /* It appears that "r*" means "const char *" rather than
7897 if (TYPE_READONLY (pointer_to))
7898 obstack_1grow (&util_obstack, 'r');
7900 obstack_1grow (&util_obstack, '*');
7905 /* We have a type that does not get special treatment. */
7907 /* NeXT extension */
7908 obstack_1grow (&util_obstack, '^');
7909 encode_type (pointer_to, curtype, format);
7913 encode_array (tree type, int curtype, int format)
7915 tree an_int_cst = TYPE_SIZE (type);
7916 tree array_of = TREE_TYPE (type);
7919 /* An incomplete array is treated like a pointer. */
7920 if (an_int_cst == NULL)
7922 encode_pointer (type, curtype, format);
7926 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7927 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7929 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7930 TREE_INT_CST_LOW (an_int_cst)
7931 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7933 obstack_grow (&util_obstack, buffer, strlen (buffer));
7934 encode_type (array_of, curtype, format);
7935 obstack_1grow (&util_obstack, ']');
7940 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7942 tree field = TYPE_FIELDS (type);
7944 for (; field; field = TREE_CHAIN (field))
7947 /* C++ static members, and things that are not field at all,
7948 should not appear in the encoding. */
7949 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7953 /* Recursively encode fields of embedded base classes. */
7954 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7955 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7957 encode_aggregate_fields (TREE_TYPE (field),
7958 pointed_to, curtype, format);
7962 if (generating_instance_variables && !pointed_to)
7964 tree fname = DECL_NAME (field);
7966 obstack_1grow (&util_obstack, '"');
7968 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7969 obstack_grow (&util_obstack,
7970 IDENTIFIER_POINTER (fname),
7971 strlen (IDENTIFIER_POINTER (fname)));
7973 obstack_1grow (&util_obstack, '"');
7976 encode_field_decl (field, curtype, format);
7981 encode_aggregate_within (tree type, int curtype, int format, int left,
7985 /* NB: aggregates that are pointed to have slightly different encoding
7986 rules in that you never encode the names of instance variables. */
7987 int ob_size = obstack_object_size (&util_obstack);
7988 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7989 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7990 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7992 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7993 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7995 /* Traverse struct aliases; it is important to get the
7996 original struct and its tag name (if any). */
7997 type = TYPE_MAIN_VARIANT (type);
7998 name = OBJC_TYPE_NAME (type);
7999 /* Open parenth/bracket. */
8000 obstack_1grow (&util_obstack, left);
8002 /* Encode the struct/union tag name, or '?' if a tag was
8003 not provided. Typedef aliases do not qualify. */
8004 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8006 /* Did this struct have a tag? */
8007 && !TYPE_WAS_ANONYMOUS (type)
8010 obstack_grow (&util_obstack,
8011 IDENTIFIER_POINTER (name),
8012 strlen (IDENTIFIER_POINTER (name)));
8014 obstack_1grow (&util_obstack, '?');
8016 /* Encode the types (and possibly names) of the inner fields,
8018 if (inline_contents)
8020 obstack_1grow (&util_obstack, '=');
8021 encode_aggregate_fields (type, pointed_to, curtype, format);
8023 /* Close parenth/bracket. */
8024 obstack_1grow (&util_obstack, right);
8028 encode_aggregate (tree type, int curtype, int format)
8030 enum tree_code code = TREE_CODE (type);
8036 encode_aggregate_within (type, curtype, format, '{', '}');
8041 encode_aggregate_within (type, curtype, format, '(', ')');
8046 obstack_1grow (&util_obstack, 'i');
8054 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8058 encode_next_bitfield (int width)
8061 sprintf (buffer, "b%d", width);
8062 obstack_grow (&util_obstack, buffer, strlen (buffer));
8065 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8067 encode_type (tree type, int curtype, int format)
8069 enum tree_code code = TREE_CODE (type);
8072 if (type == error_mark_node)
8075 if (TYPE_READONLY (type))
8076 obstack_1grow (&util_obstack, 'r');
8078 if (code == INTEGER_TYPE)
8080 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8082 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8083 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8085 if (type == long_unsigned_type_node
8086 || type == long_integer_type_node)
8087 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8089 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8091 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8094 obstack_1grow (&util_obstack, c);
8097 else if (code == REAL_TYPE)
8099 /* Floating point types. */
8100 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8102 case 32: c = 'f'; break;
8105 case 128: c = 'd'; break;
8108 obstack_1grow (&util_obstack, c);
8111 else if (code == VOID_TYPE)
8112 obstack_1grow (&util_obstack, 'v');
8114 else if (code == BOOLEAN_TYPE)
8115 obstack_1grow (&util_obstack, 'B');
8117 else if (code == ARRAY_TYPE)
8118 encode_array (type, curtype, format);
8120 else if (code == POINTER_TYPE)
8121 encode_pointer (type, curtype, format);
8123 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8124 encode_aggregate (type, curtype, format);
8126 else if (code == FUNCTION_TYPE) /* '?' */
8127 obstack_1grow (&util_obstack, '?');
8129 else if (code == COMPLEX_TYPE)
8131 obstack_1grow (&util_obstack, 'j');
8132 encode_type (TREE_TYPE (type), curtype, format);
8137 encode_gnu_bitfield (int position, tree type, int size)
8139 enum tree_code code = TREE_CODE (type);
8141 char charType = '?';
8143 if (code == INTEGER_TYPE)
8145 if (integer_zerop (TYPE_MIN_VALUE (type)))
8147 /* Unsigned integer types. */
8149 if (TYPE_MODE (type) == QImode)
8151 else if (TYPE_MODE (type) == HImode)
8153 else if (TYPE_MODE (type) == SImode)
8155 if (type == long_unsigned_type_node)
8160 else if (TYPE_MODE (type) == DImode)
8165 /* Signed integer types. */
8167 if (TYPE_MODE (type) == QImode)
8169 else if (TYPE_MODE (type) == HImode)
8171 else if (TYPE_MODE (type) == SImode)
8173 if (type == long_integer_type_node)
8179 else if (TYPE_MODE (type) == DImode)
8183 else if (code == ENUMERAL_TYPE)
8188 sprintf (buffer, "b%d%c%d", position, charType, size);
8189 obstack_grow (&util_obstack, buffer, strlen (buffer));
8193 encode_field_decl (tree field_decl, int curtype, int format)
8198 /* C++ static members, and things that are not fields at all,
8199 should not appear in the encoding. */
8200 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8204 type = TREE_TYPE (field_decl);
8206 /* Generate the bitfield typing information, if needed. Note the difference
8207 between GNU and NeXT runtimes. */
8208 if (DECL_BIT_FIELD_TYPE (field_decl))
8210 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8212 if (flag_next_runtime)
8213 encode_next_bitfield (size);
8215 encode_gnu_bitfield (int_bit_position (field_decl),
8216 DECL_BIT_FIELD_TYPE (field_decl), size);
8219 encode_type (TREE_TYPE (field_decl), curtype, format);
8222 static GTY(()) tree objc_parmlist = NULL_TREE;
8224 /* Append PARM to a list of formal parameters of a method, making a necessary
8225 array-to-pointer adjustment along the way. */
8228 objc_push_parm (tree parm)
8230 bool relayout_needed = false;
8232 if (TREE_TYPE (parm) == error_mark_node)
8234 objc_parmlist = chainon (objc_parmlist, parm);
8238 /* Decay arrays and functions into pointers. */
8239 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8241 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8242 relayout_needed = true;
8244 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8246 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8247 relayout_needed = true;
8250 if (relayout_needed)
8251 relayout_decl (parm);
8254 DECL_ARG_TYPE (parm)
8255 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8257 /* Record constancy and volatility. */
8258 c_apply_type_quals_to_decl
8259 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8260 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8261 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8263 objc_parmlist = chainon (objc_parmlist, parm);
8266 /* Retrieve the formal parameter list constructed via preceding calls to
8267 objc_push_parm(). */
8271 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8273 static struct c_arg_info *
8274 objc_get_parm_info (int have_ellipsis)
8278 tree parm_info = objc_parmlist;
8279 objc_parmlist = NULL_TREE;
8283 tree parm_info = objc_parmlist;
8284 struct c_arg_info *arg_info;
8285 /* The C front-end requires an elaborate song and dance at
8288 declare_parm_level ();
8291 tree next = TREE_CHAIN (parm_info);
8293 TREE_CHAIN (parm_info) = NULL_TREE;
8294 parm_info = pushdecl (parm_info);
8295 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8298 arg_info = get_parm_info (have_ellipsis);
8300 objc_parmlist = NULL_TREE;
8305 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8306 method definitions. In the case of instance methods, we can be more
8307 specific as to the type of 'self'. */
8310 synth_self_and_ucmd_args (void)
8314 if (objc_method_context
8315 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8316 self_type = objc_instance_type;
8318 /* Really a `struct objc_class *'. However, we allow people to
8319 assign to self, which changes its type midstream. */
8320 self_type = objc_object_type;
8323 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8326 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8329 /* Transform an Objective-C method definition into a static C function
8330 definition, synthesizing the first two arguments, "self" and "_cmd",
8334 start_method_def (tree method)
8340 struct c_arg_info *parm_info;
8342 int have_ellipsis = 0;
8344 /* If we are defining a "dealloc" method in a non-root class, we
8345 will need to check if a [super dealloc] is missing, and warn if
8347 if(CLASS_SUPER_NAME (objc_implementation_context)
8348 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8349 should_call_super_dealloc = 1;
8351 should_call_super_dealloc = 0;
8353 /* Required to implement _msgSuper. */
8354 objc_method_context = method;
8355 UOBJC_SUPER_decl = NULL_TREE;
8357 /* Generate prototype declarations for arguments..."new-style". */
8358 synth_self_and_ucmd_args ();
8360 /* Generate argument declarations if a keyword_decl. */
8361 parmlist = METHOD_SEL_ARGS (method);
8364 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8366 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8367 objc_push_parm (parm);
8368 parmlist = TREE_CHAIN (parmlist);
8371 if (METHOD_ADD_ARGS (method))
8375 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8376 akey; akey = TREE_CHAIN (akey))
8378 objc_push_parm (TREE_VALUE (akey));
8381 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8385 parm_info = objc_get_parm_info (have_ellipsis);
8387 really_start_method (objc_method_context, parm_info);
8391 warn_with_method (const char *message, int mtype, tree method)
8393 /* Add a readable method name to the warning. */
8394 warning (0, "%J%s %<%c%s%>", method,
8395 message, mtype, gen_method_decl (method));
8398 /* Return 1 if TYPE1 is equivalent to TYPE2
8399 for purposes of method overloading. */
8402 objc_types_are_equivalent (tree type1, tree type2)
8407 /* Strip away indirections. */
8408 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8409 && (TREE_CODE (type1) == TREE_CODE (type2)))
8410 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8411 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8414 type1 = (TYPE_HAS_OBJC_INFO (type1)
8415 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8417 type2 = (TYPE_HAS_OBJC_INFO (type2)
8418 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8421 if (list_length (type1) == list_length (type2))
8423 for (; type2; type2 = TREE_CHAIN (type2))
8424 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8431 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8434 objc_types_share_size_and_alignment (tree type1, tree type2)
8436 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8437 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8440 /* Return 1 if PROTO1 is equivalent to PROTO2
8441 for purposes of method overloading. Ordinarily, the type signatures
8442 should match up exactly, unless STRICT is zero, in which case we
8443 shall allow differences in which the size and alignment of a type
8447 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8451 /* The following test is needed in case there are hashing
8453 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8456 /* Compare return types. */
8457 type1 = TREE_VALUE (TREE_TYPE (proto1));
8458 type2 = TREE_VALUE (TREE_TYPE (proto2));
8460 if (!objc_types_are_equivalent (type1, type2)
8461 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8464 /* Compare argument types. */
8465 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8466 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8468 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8470 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8472 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8473 TREE_VALUE (type2))))
8477 return (!type1 && !type2);
8480 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8481 this occurs. ObjC method dispatches are _not_ like C++ virtual
8482 member function dispatches, and we account for the difference here. */
8485 objc_fold_obj_type_ref (tree ref, tree known_type)
8487 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8488 tree known_type ATTRIBUTE_UNUSED)
8492 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8494 /* If the receiver does not have virtual member functions, there
8495 is nothing we can (or need to) do here. */
8499 /* Let C++ handle C++ virtual functions. */
8500 return cp_fold_obj_type_ref (ref, known_type);
8502 /* For plain ObjC, we currently do not need to do anything. */
8508 objc_start_function (tree name, tree type, tree attrs,
8512 struct c_arg_info *params
8516 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8519 DECL_ARGUMENTS (fndecl) = params;
8520 DECL_INITIAL (fndecl) = error_mark_node;
8521 DECL_EXTERNAL (fndecl) = 0;
8522 TREE_STATIC (fndecl) = 1;
8523 retrofit_lang_decl (fndecl);
8524 cplus_decl_attributes (&fndecl, attrs, 0);
8525 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8527 struct c_label_context_se *nstack_se;
8528 struct c_label_context_vm *nstack_vm;
8529 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8530 nstack_se->labels_def = NULL;
8531 nstack_se->labels_used = NULL;
8532 nstack_se->next = label_context_stack_se;
8533 label_context_stack_se = nstack_se;
8534 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8535 nstack_vm->labels_def = NULL;
8536 nstack_vm->labels_used = NULL;
8537 nstack_vm->scope = 0;
8538 nstack_vm->next = label_context_stack_vm;
8539 label_context_stack_vm = nstack_vm;
8540 current_function_returns_value = 0; /* Assume, until we see it does. */
8541 current_function_returns_null = 0;
8543 decl_attributes (&fndecl, attrs, 0);
8544 announce_function (fndecl);
8545 DECL_INITIAL (fndecl) = error_mark_node;
8546 DECL_EXTERNAL (fndecl) = 0;
8547 TREE_STATIC (fndecl) = 1;
8548 current_function_decl = pushdecl (fndecl);
8550 declare_parm_level ();
8551 DECL_RESULT (current_function_decl)
8552 = build_decl (RESULT_DECL, NULL_TREE,
8553 TREE_TYPE (TREE_TYPE (current_function_decl)));
8554 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8555 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8556 start_fname_decls ();
8557 store_parm_decls_from (params);
8560 TREE_USED (current_function_decl) = 1;
8563 /* - Generate an identifier for the function. the format is "_n_cls",
8564 where 1 <= n <= nMethods, and cls is the name the implementation we
8566 - Install the return type from the method declaration.
8567 - If we have a prototype, check for type consistency. */
8570 really_start_method (tree method,
8574 struct c_arg_info *parmlist
8578 tree ret_type, meth_type;
8580 const char *sel_name, *class_name, *cat_name;
8583 /* Synth the storage class & assemble the return type. */
8584 ret_type = TREE_VALUE (TREE_TYPE (method));
8586 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8587 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8588 cat_name = ((TREE_CODE (objc_implementation_context)
8589 == CLASS_IMPLEMENTATION_TYPE)
8591 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8594 /* Make sure this is big enough for any plausible method label. */
8595 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8596 + (cat_name ? strlen (cat_name) : 0));
8598 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8599 class_name, cat_name, sel_name, method_slot);
8601 method_id = get_identifier (buf);
8604 /* Objective-C methods cannot be overloaded, so we don't need
8605 the type encoding appended. It looks bad anyway... */
8606 push_lang_context (lang_name_c);
8610 = build_function_type (ret_type,
8611 get_arg_type_list (method, METHOD_DEF, 0));
8612 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8614 /* Set self_decl from the first argument. */
8615 self_decl = DECL_ARGUMENTS (current_function_decl);
8617 /* Suppress unused warnings. */
8618 TREE_USED (self_decl) = 1;
8619 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8621 pop_lang_context ();
8624 METHOD_DEFINITION (method) = current_function_decl;
8626 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8628 if (implementation_template != objc_implementation_context)
8631 = lookup_method_static (implementation_template,
8632 METHOD_SEL_NAME (method),
8633 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8634 | OBJC_LOOKUP_NO_SUPER));
8638 if (!comp_proto_with_proto (method, proto, 1))
8640 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8642 warn_with_method ("conflicting types for", type, method);
8643 warn_with_method ("previous declaration of", type, proto);
8648 /* We have a method @implementation even though we did not
8649 see a corresponding @interface declaration (which is allowed
8650 by Objective-C rules). Go ahead and place the method in
8651 the @interface anyway, so that message dispatch lookups
8653 tree interface = implementation_template;
8655 if (TREE_CODE (objc_implementation_context)
8656 == CATEGORY_IMPLEMENTATION_TYPE)
8657 interface = lookup_category
8659 CLASS_SUPER_NAME (objc_implementation_context));
8662 objc_add_method (interface, copy_node (method),
8663 TREE_CODE (method) == CLASS_METHOD_DECL);
8668 static void *UOBJC_SUPER_scope = 0;
8670 /* _n_Method (id self, SEL sel, ...)
8672 struct objc_super _S;
8673 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8677 get_super_receiver (void)
8679 if (objc_method_context)
8681 tree super_expr, super_expr_list;
8683 if (!UOBJC_SUPER_decl)
8685 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8686 objc_super_template);
8687 /* This prevents `unused variable' warnings when compiling with -Wall. */
8688 TREE_USED (UOBJC_SUPER_decl) = 1;
8689 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8690 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8691 UOBJC_SUPER_scope = objc_get_current_scope ();
8694 /* Set receiver to self. */
8695 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8696 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8697 super_expr_list = super_expr;
8699 /* Set class to begin searching. */
8700 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8701 get_identifier ("super_class"));
8703 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8705 /* [_cls, __cls]Super are "pre-built" in
8706 synth_forward_declarations. */
8708 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8709 ((TREE_CODE (objc_method_context)
8710 == INSTANCE_METHOD_DECL)
8712 : uucls_super_ref));
8716 /* We have a category. */
8718 tree super_name = CLASS_SUPER_NAME (implementation_template);
8721 /* Barf if super used in a category of Object. */
8724 error ("no super class declared in interface for %qs",
8725 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8726 return error_mark_node;
8729 if (flag_next_runtime && !flag_zero_link)
8731 super_class = objc_get_class_reference (super_name);
8732 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8733 /* If we are in a class method, we must retrieve the
8734 _metaclass_ for the current class, pointed at by
8735 the class's "isa" pointer. The following assumes that
8736 "isa" is the first ivar in a class (which it must be). */
8738 = build_indirect_ref
8739 (build_c_cast (build_pointer_type (objc_class_type),
8740 super_class), "unary *");
8744 add_class_reference (super_name);
8745 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8746 ? objc_get_class_decl : objc_get_meta_class_decl);
8747 assemble_external (super_class);
8749 = build_function_call
8753 my_build_string_pointer
8754 (IDENTIFIER_LENGTH (super_name) + 1,
8755 IDENTIFIER_POINTER (super_name))));
8759 = build_modify_expr (super_expr, NOP_EXPR,
8760 build_c_cast (TREE_TYPE (super_expr),
8764 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8766 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8767 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8769 return super_expr_list;
8773 error ("[super ...] must appear in a method context");
8774 return error_mark_node;
8778 /* When exiting a scope, sever links to a 'super' declaration (if any)
8779 therein contained. */
8782 objc_clear_super_receiver (void)
8784 if (objc_method_context
8785 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8786 UOBJC_SUPER_decl = 0;
8787 UOBJC_SUPER_scope = 0;
8792 objc_finish_method_definition (tree fndecl)
8794 /* We cannot validly inline ObjC methods, at least not without a language
8795 extension to declare that a method need not be dynamically
8796 dispatched, so suppress all thoughts of doing so. */
8797 DECL_INLINE (fndecl) = 0;
8798 DECL_UNINLINABLE (fndecl) = 1;
8801 /* The C++ front-end will have called finish_function() for us. */
8805 METHOD_ENCODING (objc_method_context)
8806 = encode_method_prototype (objc_method_context);
8808 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8809 since the optimizer may find "may be used before set" errors. */
8810 objc_method_context = NULL_TREE;
8812 if (should_call_super_dealloc)
8813 warning (0, "method possibly missing a [super dealloc] call");
8818 lang_report_error_function (tree decl)
8820 if (objc_method_context)
8822 fprintf (stderr, "In method %qs\n",
8823 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8832 /* Given a tree DECL node, produce a printable description of it in the given
8833 buffer, overwriting the buffer. */
8836 gen_declaration (tree decl)
8842 gen_type_name_0 (TREE_TYPE (decl));
8844 if (DECL_NAME (decl))
8846 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8847 strcat (errbuf, " ");
8849 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8852 if (DECL_INITIAL (decl)
8853 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8854 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8855 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8861 /* Given a tree TYPE node, produce a printable description of it in the given
8862 buffer, overwriting the buffer. */
8865 gen_type_name_0 (tree type)
8867 tree orig = type, proto;
8869 if (TYPE_P (type) && TYPE_NAME (type))
8870 type = TYPE_NAME (type);
8871 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8873 tree inner = TREE_TYPE (type);
8875 while (TREE_CODE (inner) == ARRAY_TYPE)
8876 inner = TREE_TYPE (inner);
8878 gen_type_name_0 (inner);
8880 if (!POINTER_TYPE_P (inner))
8881 strcat (errbuf, " ");
8883 if (POINTER_TYPE_P (type))
8884 strcat (errbuf, "*");
8886 while (type != inner)
8888 strcat (errbuf, "[");
8890 if (TYPE_DOMAIN (type))
8894 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8896 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8897 strcat (errbuf, sz);
8900 strcat (errbuf, "]");
8901 type = TREE_TYPE (type);
8907 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8908 type = DECL_NAME (type);
8910 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8911 ? IDENTIFIER_POINTER (type)
8914 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8915 if (objc_is_id (orig))
8916 orig = TREE_TYPE (orig);
8918 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8922 strcat (errbuf, " <");
8926 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8927 proto = TREE_CHAIN (proto);
8928 strcat (errbuf, proto ? ", " : ">");
8937 gen_type_name (tree type)
8941 return gen_type_name_0 (type);
8944 /* Given a method tree, put a printable description into the given
8945 buffer (overwriting) and return a pointer to the buffer. */
8948 gen_method_decl (tree method)
8952 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8953 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8954 strcat (errbuf, ")");
8955 chain = METHOD_SEL_ARGS (method);
8959 /* We have a chain of keyword_decls. */
8962 if (KEYWORD_KEY_NAME (chain))
8963 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8965 strcat (errbuf, ":(");
8966 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8967 strcat (errbuf, ")");
8969 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8970 if ((chain = TREE_CHAIN (chain)))
8971 strcat (errbuf, " ");
8975 if (METHOD_ADD_ARGS (method))
8977 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8979 /* Know we have a chain of parm_decls. */
8982 strcat (errbuf, ", ");
8983 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8984 chain = TREE_CHAIN (chain);
8987 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8988 strcat (errbuf, ", ...");
8993 /* We have a unary selector. */
8994 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9002 /* Dump an @interface declaration of the supplied class CHAIN to the
9003 supplied file FP. Used to implement the -gen-decls option (which
9004 prints out an @interface declaration of all classes compiled in
9005 this run); potentially useful for debugging the compiler too. */
9007 dump_interface (FILE *fp, tree chain)
9009 /* FIXME: A heap overflow here whenever a method (or ivar)
9010 declaration is so long that it doesn't fit in the buffer. The
9011 code and all the related functions should be rewritten to avoid
9012 using fixed size buffers. */
9013 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9014 tree ivar_decls = CLASS_RAW_IVARS (chain);
9015 tree nst_methods = CLASS_NST_METHODS (chain);
9016 tree cls_methods = CLASS_CLS_METHODS (chain);
9018 fprintf (fp, "\n@interface %s", my_name);
9020 /* CLASS_SUPER_NAME is used to store the superclass name for
9021 classes, and the category name for categories. */
9022 if (CLASS_SUPER_NAME (chain))
9024 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9026 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9027 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9029 fprintf (fp, " (%s)\n", name);
9033 fprintf (fp, " : %s\n", name);
9039 /* FIXME - the following doesn't seem to work at the moment. */
9042 fprintf (fp, "{\n");
9045 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9046 ivar_decls = TREE_CHAIN (ivar_decls);
9049 fprintf (fp, "}\n");
9054 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9055 nst_methods = TREE_CHAIN (nst_methods);
9060 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9061 cls_methods = TREE_CHAIN (cls_methods);
9064 fprintf (fp, "@end\n");
9067 /* Demangle function for Objective-C */
9069 objc_demangle (const char *mangled)
9071 char *demangled, *cp;
9073 if (mangled[0] == '_' &&
9074 (mangled[1] == 'i' || mangled[1] == 'c') &&
9077 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9078 if (mangled[1] == 'i')
9079 *cp++ = '-'; /* for instance method */
9081 *cp++ = '+'; /* for class method */
9082 *cp++ = '['; /* opening left brace */
9083 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9084 while (*cp && *cp == '_')
9085 cp++; /* skip any initial underbars in class name */
9086 cp = strchr(cp, '_'); /* find first non-initial underbar */
9089 free(demangled); /* not mangled name */
9092 if (cp[1] == '_') /* easy case: no category name */
9094 *cp++ = ' '; /* replace two '_' with one ' ' */
9095 strcpy(cp, mangled + (cp - demangled) + 2);
9099 *cp++ = '('; /* less easy case: category name */
9100 cp = strchr(cp, '_');
9103 free(demangled); /* not mangled name */
9107 *cp++ = ' '; /* overwriting 1st char of method name... */
9108 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9110 while (*cp && *cp == '_')
9111 cp++; /* skip any initial underbars in method name */
9114 *cp = ':'; /* replace remaining '_' with ':' */
9115 *cp++ = ']'; /* closing right brace */
9116 *cp++ = 0; /* string terminator */
9120 return mangled; /* not an objc mangled name */
9124 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9126 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9132 gcc_obstack_init (&util_obstack);
9133 util_firstobj = (char *) obstack_finish (&util_obstack);
9135 errbuf = XNEWVEC (char, 1024 * 10);
9137 synth_module_prologue ();
9143 struct imp_entry *impent;
9145 /* The internally generated initializers appear to have missing braces.
9146 Don't warn about this. */
9147 int save_warn_missing_braces = warn_missing_braces;
9148 warn_missing_braces = 0;
9150 /* A missing @end may not be detected by the parser. */
9151 if (objc_implementation_context)
9153 warning (0, "%<@end%> missing in implementation context");
9154 finish_class (objc_implementation_context);
9155 objc_ivar_chain = NULL_TREE;
9156 objc_implementation_context = NULL_TREE;
9159 /* Process the static instances here because initialization of objc_symtab
9161 if (objc_static_instances)
9162 generate_static_references ();
9164 if (imp_list || class_names_chain
9165 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9166 generate_objc_symtab_decl ();
9168 for (impent = imp_list; impent; impent = impent->next)
9170 objc_implementation_context = impent->imp_context;
9171 implementation_template = impent->imp_template;
9173 UOBJC_CLASS_decl = impent->class_decl;
9174 UOBJC_METACLASS_decl = impent->meta_decl;
9176 /* Dump the @interface of each class as we compile it, if the
9177 -gen-decls option is in use. TODO: Dump the classes in the
9178 order they were found, rather than in reverse order as we
9180 if (flag_gen_declaration)
9182 dump_interface (gen_declaration_file, objc_implementation_context);
9185 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9187 /* all of the following reference the string pool... */
9188 generate_ivar_lists ();
9189 generate_dispatch_tables ();
9190 generate_shared_structures (impent->has_cxx_cdtors
9191 ? CLS_HAS_CXX_STRUCTORS
9196 generate_dispatch_tables ();
9197 generate_category (objc_implementation_context);
9201 /* If we are using an array of selectors, we must always
9202 finish up the array decl even if no selectors were used. */
9203 if (! flag_next_runtime || sel_ref_chain)
9204 build_selector_translation_table ();
9207 generate_protocols ();
9209 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9210 generate_objc_image_info ();
9212 /* Arrange for ObjC data structures to be initialized at run time. */
9213 if (objc_implementation_context || class_names_chain || objc_static_instances
9214 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9216 build_module_descriptor ();
9218 if (!flag_next_runtime)
9219 build_module_initializer_routine ();
9222 /* Dump the class references. This forces the appropriate classes
9223 to be linked into the executable image, preserving unix archive
9224 semantics. This can be removed when we move to a more dynamically
9225 linked environment. */
9227 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9229 handle_class_ref (chain);
9230 if (TREE_PURPOSE (chain))
9231 generate_classref_translation_entry (chain);
9234 for (impent = imp_list; impent; impent = impent->next)
9235 handle_impent (impent);
9242 /* Run through the selector hash tables and print a warning for any
9243 selector which has multiple methods. */
9245 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9247 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9248 check_duplicates (hsh, 0, 1);
9249 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9250 check_duplicates (hsh, 0, 1);
9254 warn_missing_braces = save_warn_missing_braces;
9257 /* Subroutines of finish_objc. */
9260 generate_classref_translation_entry (tree chain)
9262 tree expr, decl, type;
9264 decl = TREE_PURPOSE (chain);
9265 type = TREE_TYPE (decl);
9267 expr = add_objc_string (TREE_VALUE (chain), class_names);
9268 expr = convert (type, expr); /* cast! */
9270 /* The decl that is the one that we
9271 forward declared in build_class_reference. */
9272 finish_var_decl (decl, expr);
9277 handle_class_ref (tree chain)
9279 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9280 char *string = (char *) alloca (strlen (name) + 30);
9284 sprintf (string, "%sobjc_class_name_%s",
9285 (flag_next_runtime ? "." : "__"), name);
9287 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9288 if (flag_next_runtime)
9290 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9295 /* Make a decl for this name, so we can use its address in a tree. */
9296 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9297 DECL_EXTERNAL (decl) = 1;
9298 TREE_PUBLIC (decl) = 1;
9301 rest_of_decl_compilation (decl, 0, 0);
9303 /* Make a decl for the address. */
9304 sprintf (string, "%sobjc_class_ref_%s",
9305 (flag_next_runtime ? "." : "__"), name);
9306 exp = build1 (ADDR_EXPR, string_type_node, decl);
9307 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9308 DECL_INITIAL (decl) = exp;
9309 TREE_STATIC (decl) = 1;
9310 TREE_USED (decl) = 1;
9311 /* Force the output of the decl as this forces the reference of the class. */
9312 mark_decl_referenced (decl);
9315 rest_of_decl_compilation (decl, 0, 0);
9319 handle_impent (struct imp_entry *impent)
9323 objc_implementation_context = impent->imp_context;
9324 implementation_template = impent->imp_template;
9326 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9328 const char *const class_name =
9329 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9331 string = (char *) alloca (strlen (class_name) + 30);
9333 sprintf (string, "%sobjc_class_name_%s",
9334 (flag_next_runtime ? "." : "__"), class_name);
9336 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9338 const char *const class_name =
9339 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9340 const char *const class_super_name =
9341 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9343 string = (char *) alloca (strlen (class_name)
9344 + strlen (class_super_name) + 30);
9346 /* Do the same for categories. Even though no references to
9347 these symbols are generated automatically by the compiler, it
9348 gives you a handle to pull them into an archive by hand. */
9349 sprintf (string, "*%sobjc_category_name_%s_%s",
9350 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9355 #ifdef ASM_DECLARE_CLASS_REFERENCE
9356 if (flag_next_runtime)
9358 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9366 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9367 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9368 TREE_PUBLIC (decl) = 1;
9369 TREE_READONLY (decl) = 1;
9370 TREE_USED (decl) = 1;
9371 TREE_CONSTANT (decl) = 1;
9372 DECL_CONTEXT (decl) = 0;
9373 DECL_ARTIFICIAL (decl) = 1;
9374 DECL_INITIAL (decl) = init;
9375 assemble_variable (decl, 1, 0, 0);
9379 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9380 later requires that ObjC translation units participating in F&C be
9381 specially marked. The following routine accomplishes this. */
9383 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9386 generate_objc_image_info (void)
9388 tree decl, initlist;
9390 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9391 | (flag_objc_gc ? 2 : 0));
9393 decl = start_var_decl (build_array_type
9395 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9396 "_OBJC_IMAGE_INFO");
9398 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9399 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9400 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9402 finish_var_decl (decl, initlist);
9405 /* Look up ID as an instance variable. OTHER contains the result of
9406 the C or C++ lookup, which we may want to use instead. */
9409 objc_lookup_ivar (tree other, tree id)
9413 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9414 if (!objc_method_context)
9417 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9418 /* We have a message to super. */
9419 return get_super_receiver ();
9421 /* In a class method, look up an instance variable only as a last
9423 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9424 && other && other != error_mark_node)
9427 /* Look up the ivar, but do not use it if it is not accessible. */
9428 ivar = is_ivar (objc_ivar_chain, id);
9430 if (!ivar || is_private (ivar))
9433 /* In an instance method, a local variable (or parameter) may hide the
9434 instance variable. */
9435 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9436 && other && other != error_mark_node
9438 && CP_DECL_CONTEXT (other) != global_namespace)
9440 && !DECL_FILE_SCOPE_P (other))
9443 warning (0, "local declaration of %qs hides instance variable",
9444 IDENTIFIER_POINTER (id));
9449 /* At this point, we are either in an instance method with no obscuring
9450 local definitions, or in a class method with no alternate definitions
9452 return build_ivar_reference (id);
9455 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9456 needs to be done if we are calling a function through a cast. */
9459 objc_rewrite_function_call (tree function, tree params)
9461 if (TREE_CODE (function) == NOP_EXPR
9462 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9463 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9466 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9467 TREE_OPERAND (function, 0),
9468 TREE_VALUE (params), size_zero_node);
9474 /* Look for the special case of OBJC_TYPE_REF with the address of
9475 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9478 enum gimplify_status
9479 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9481 enum gimplify_status r0, r1;
9482 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9483 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9484 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9487 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9488 value of the OBJ_TYPE_REF, so force them to be emitted
9489 during subexpression evaluation rather than after the
9490 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9491 C to use direct rather than indirect calls when the
9492 object expression has a postincrement. */
9493 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9494 is_gimple_val, fb_rvalue);
9495 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9496 is_gimple_val, fb_rvalue);
9498 return MIN (r0, r1);
9502 return cp_gimplify_expr (expr_p, pre_p, post_p);
9504 return c_gimplify_expr (expr_p, pre_p, post_p);
9508 /* Given a CALL expression, find the function being called. The ObjC
9509 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9512 objc_get_callee_fndecl (const_tree call_expr)
9514 tree addr = CALL_EXPR_FN (call_expr);
9515 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9518 addr = OBJ_TYPE_REF_EXPR (addr);
9520 /* If the address is just `&f' for some function `f', then we know
9521 that `f' is being called. */
9522 if (TREE_CODE (addr) == ADDR_EXPR
9523 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9524 return TREE_OPERAND (addr, 0);
9529 #include "gt-objc-objc-act.h"