1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
116 /* Set up for use of obstacks. */
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
158 static void objc_start_function (tree, tree, tree, tree);
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
188 static tree objc_build_volatilized_type (tree);
191 static void objc_generate_cxx_cdtors (void);
194 static const char *synth_id_with_class_suffix (const char *, tree);
196 /* Hash tables to manage the global pool of method prototypes. */
198 hash *nst_method_hash_list = 0;
199 hash *cls_method_hash_list = 0;
201 static hash hash_lookup (hash *, tree);
202 static tree lookup_method (tree, tree);
203 static tree lookup_method_static (tree, tree, int);
207 class_names, /* class, category, protocol, module names */
208 meth_var_names, /* method and variable names */
209 meth_var_types /* method and variable type descriptors */
212 static tree add_objc_string (tree, enum string_section);
213 static tree build_objc_string_decl (enum string_section);
214 static void build_selector_table_decl (void);
216 /* Protocol additions. */
218 static tree lookup_protocol (tree);
219 static tree lookup_and_install_protocols (tree);
223 static void encode_type_qualifiers (tree);
224 static void encode_type (tree, int, int);
225 static void encode_field_decl (tree, int, int);
228 static void really_start_method (tree, tree);
230 static void really_start_method (tree, struct c_arg_info *);
232 static int comp_proto_with_proto (tree, tree, int);
233 static void objc_push_parm (tree);
235 static tree objc_get_parm_info (int);
237 static struct c_arg_info *objc_get_parm_info (int);
240 /* Utilities for debugging and error diagnostics. */
242 static void warn_with_method (const char *, int, tree);
243 static char *gen_type_name (tree);
244 static char *gen_type_name_0 (tree);
245 static char *gen_method_decl (tree);
246 static char *gen_declaration (tree);
248 /* Everything else. */
250 static tree create_field_decl (tree, const char *);
251 static void add_class_reference (tree);
252 static void build_protocol_template (void);
253 static tree encode_method_prototype (tree);
254 static void generate_classref_translation_entry (tree);
255 static void handle_class_ref (tree);
256 static void generate_struct_by_value_array (void)
258 static void mark_referenced_methods (void);
259 static void generate_objc_image_info (void);
261 /*** Private Interface (data) ***/
263 /* Reserved tag definitions. */
265 #define OBJECT_TYPEDEF_NAME "id"
266 #define CLASS_TYPEDEF_NAME "Class"
268 #define TAG_OBJECT "objc_object"
269 #define TAG_CLASS "objc_class"
270 #define TAG_SUPER "objc_super"
271 #define TAG_SELECTOR "objc_selector"
273 #define UTAG_CLASS "_objc_class"
274 #define UTAG_IVAR "_objc_ivar"
275 #define UTAG_IVAR_LIST "_objc_ivar_list"
276 #define UTAG_METHOD "_objc_method"
277 #define UTAG_METHOD_LIST "_objc_method_list"
278 #define UTAG_CATEGORY "_objc_category"
279 #define UTAG_MODULE "_objc_module"
280 #define UTAG_SYMTAB "_objc_symtab"
281 #define UTAG_SUPER "_objc_super"
282 #define UTAG_SELECTOR "_objc_selector"
284 #define UTAG_PROTOCOL "_objc_protocol"
285 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
286 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
288 /* Note that the string object global name is only needed for the
290 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
292 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
294 static const char *TAG_GETCLASS;
295 static const char *TAG_GETMETACLASS;
296 static const char *TAG_MSGSEND;
297 static const char *TAG_MSGSENDSUPER;
298 /* The NeXT Objective-C messenger may have two extra entry points, for use
299 when returning a structure. */
300 static const char *TAG_MSGSEND_STRET;
301 static const char *TAG_MSGSENDSUPER_STRET;
302 static const char *default_constant_string_class_name;
304 /* Runtime metadata flags. */
305 #define CLS_FACTORY 0x0001L
306 #define CLS_META 0x0002L
307 #define CLS_HAS_CXX_STRUCTORS 0x2000L
309 #define OBJC_MODIFIER_STATIC 0x00000001
310 #define OBJC_MODIFIER_FINAL 0x00000002
311 #define OBJC_MODIFIER_PUBLIC 0x00000004
312 #define OBJC_MODIFIER_PRIVATE 0x00000008
313 #define OBJC_MODIFIER_PROTECTED 0x00000010
314 #define OBJC_MODIFIER_NATIVE 0x00000020
315 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
316 #define OBJC_MODIFIER_ABSTRACT 0x00000080
317 #define OBJC_MODIFIER_VOLATILE 0x00000100
318 #define OBJC_MODIFIER_TRANSIENT 0x00000200
319 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
321 /* NeXT-specific tags. */
323 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
324 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
325 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
326 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
327 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
328 #define TAG_EXCEPTIONMATCH "objc_exception_match"
329 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
330 #define TAG_SYNCENTER "objc_sync_enter"
331 #define TAG_SYNCEXIT "objc_sync_exit"
332 #define TAG_SETJMP "_setjmp"
333 #define UTAG_EXCDATA "_objc_exception_data"
335 #define TAG_ASSIGNIVAR "objc_assign_ivar"
336 #define TAG_ASSIGNGLOBAL "objc_assign_global"
337 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
339 /* Branch entry points. All that matters here are the addresses;
340 functions with these names do not really exist in libobjc. */
342 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
343 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
345 #define TAG_CXX_CONSTRUCT ".cxx_construct"
346 #define TAG_CXX_DESTRUCT ".cxx_destruct"
348 /* GNU-specific tags. */
350 #define TAG_EXECCLASS "__objc_exec_class"
351 #define TAG_GNUINIT "__objc_gnu_init"
353 /* Flags for lookup_method_static(). */
354 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
355 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
357 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
358 tree objc_global_trees[OCTI_MAX];
360 static void handle_impent (struct imp_entry *);
362 struct imp_entry *imp_list = 0;
363 int imp_count = 0; /* `@implementation' */
364 int cat_count = 0; /* `@category' */
366 enum tree_code objc_inherit_code;
367 int objc_public_flag;
369 /* Use to generate method labels. */
370 static int method_slot = 0;
374 static char *errbuf; /* Buffer for error diagnostics */
376 /* Data imported from tree.c. */
378 extern enum debug_info_type write_symbols;
380 /* Data imported from toplev.c. */
382 extern const char *dump_base_name;
384 static int flag_typed_selectors;
386 /* Store all constructed constant strings in a hash table so that
387 they get uniqued properly. */
389 struct string_descriptor GTY(())
391 /* The literal argument . */
394 /* The resulting constant string. */
398 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
400 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
401 struct volatilized_type GTY(())
406 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
408 FILE *gen_declaration_file;
410 /* Tells "encode_pointer/encode_aggregate" whether we are generating
411 type descriptors for instance variables (as opposed to methods).
412 Type descriptors for instance variables contain more information
413 than methods (for static typing and embedded structures). */
415 static int generating_instance_variables = 0;
417 /* Some platforms pass small structures through registers versus
418 through an invisible pointer. Determine at what size structure is
419 the transition point between the two possibilities. */
422 generate_struct_by_value_array (void)
425 tree field_decl, field_decl_chain;
427 int aggregate_in_mem[32];
430 /* Presumably no platform passes 32 byte structures in a register. */
431 for (i = 1; i < 32; i++)
435 /* Create an unnamed struct that has `i' character components */
436 type = start_struct (RECORD_TYPE, NULL_TREE);
438 strcpy (buffer, "c1");
439 field_decl = create_field_decl (char_type_node,
441 field_decl_chain = field_decl;
443 for (j = 1; j < i; j++)
445 sprintf (buffer, "c%d", j + 1);
446 field_decl = create_field_decl (char_type_node,
448 chainon (field_decl_chain, field_decl);
450 finish_struct (type, field_decl_chain, NULL_TREE);
452 aggregate_in_mem[i] = aggregate_value_p (type, 0);
453 if (!aggregate_in_mem[i])
457 /* We found some structures that are returned in registers instead of memory
458 so output the necessary data. */
461 for (i = 31; i >= 0; i--)
462 if (!aggregate_in_mem[i])
464 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
466 /* The first member of the structure is always 0 because we don't handle
467 structures with 0 members */
468 printf ("static int struct_forward_array[] = {\n 0");
470 for (j = 1; j <= i; j++)
471 printf (", %d", aggregate_in_mem[j]);
482 if (cxx_init () == false)
484 if (c_objc_common_init () == false)
488 #ifndef USE_MAPPED_LOCATION
489 /* Force the line number back to 0; check_newline will have
490 raised it to 1, which will make the builtin functions appear
491 not to be built in. */
495 /* If gen_declaration desired, open the output file. */
496 if (flag_gen_declaration)
498 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
499 gen_declaration_file = fopen (dumpname, "w");
500 if (gen_declaration_file == 0)
501 fatal_error ("can't open %s: %m", dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_MSGSEND_STRET = "objc_msgSend_stret";
512 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
513 default_constant_string_class_name = "NSConstantString";
517 TAG_GETCLASS = "objc_get_class";
518 TAG_GETMETACLASS = "objc_get_meta_class";
519 TAG_MSGSEND = "objc_msg_lookup";
520 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
521 /* GNU runtime does not provide special functions to support
522 structure-returning methods. */
523 default_constant_string_class_name = "NXConstantString";
524 flag_typed_selectors = 1;
529 if (print_struct_values)
530 generate_struct_by_value_array ();
536 objc_finish_file (void)
538 mark_referenced_methods ();
541 /* We need to instantiate templates _before_ we emit ObjC metadata;
542 if we do not, some metadata (such as selectors) may go missing. */
544 instantiate_pending_templates (0);
547 /* Finalize Objective-C runtime data. No need to generate tables
548 and code if only checking syntax, or if generating a PCH file. */
549 if (!flag_syntax_only && !pch_file)
552 if (gen_declaration_file)
553 fclose (gen_declaration_file);
560 /* Return the first occurrence of a method declaration corresponding
561 to sel_name in rproto_list. Search rproto_list recursively.
562 If is_class is 0, search for instance methods, otherwise for class
565 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
571 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
573 p = TREE_VALUE (rproto);
575 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
577 if ((fnd = lookup_method (is_class
578 ? PROTOCOL_CLS_METHODS (p)
579 : PROTOCOL_NST_METHODS (p), sel_name)))
581 else if (PROTOCOL_LIST (p))
582 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
587 ; /* An identifier...if we could not find a protocol. */
598 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
602 /* Make sure the protocol is supported by the object on the rhs. */
603 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
606 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
608 p = TREE_VALUE (rproto);
610 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
615 else if (PROTOCOL_LIST (p))
616 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
625 ; /* An identifier...if we could not find a protocol. */
632 objc_start_class_interface (tree class, tree super_class, tree protos)
634 objc_interface_context
636 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
637 objc_public_flag = 0;
641 objc_start_category_interface (tree class, tree categ, tree protos)
643 objc_interface_context
644 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
646 = continue_class (objc_interface_context);
650 objc_start_protocol (tree name, tree protos)
652 objc_interface_context
653 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
657 objc_continue_interface (void)
660 = continue_class (objc_interface_context);
664 objc_finish_interface (void)
666 finish_class (objc_interface_context);
667 objc_interface_context = NULL_TREE;
671 objc_start_class_implementation (tree class, tree super_class)
673 objc_implementation_context
675 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
676 objc_public_flag = 0;
680 objc_start_category_implementation (tree class, tree categ)
682 objc_implementation_context
683 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
685 = continue_class (objc_implementation_context);
689 objc_continue_implementation (void)
692 = continue_class (objc_implementation_context);
696 objc_finish_implementation (void)
699 if (flag_objc_call_cxx_cdtors)
700 objc_generate_cxx_cdtors ();
703 if (objc_implementation_context)
705 finish_class (objc_implementation_context);
706 objc_ivar_chain = NULL_TREE;
707 objc_implementation_context = NULL_TREE;
710 warning (0, "%<@end%> must appear in an @implementation context");
714 objc_set_visibility (int visibility)
716 objc_public_flag = visibility;
720 objc_set_method_type (enum tree_code type)
722 objc_inherit_code = (type == PLUS_EXPR
724 : INSTANCE_METHOD_DECL);
728 objc_build_method_signature (tree rettype, tree selector,
729 tree optparms, bool ellipsis)
731 return build_method_decl (objc_inherit_code, rettype, selector,
736 objc_add_method_declaration (tree decl)
738 if (!objc_interface_context)
739 fatal_error ("method declaration not in @interface context");
741 objc_add_method (objc_interface_context,
743 objc_inherit_code == CLASS_METHOD_DECL);
747 objc_start_method_definition (tree decl)
749 if (!objc_implementation_context)
750 fatal_error ("method definition not in @implementation context");
752 objc_add_method (objc_implementation_context,
754 objc_inherit_code == CLASS_METHOD_DECL);
755 start_method_def (decl);
759 objc_add_instance_variable (tree decl)
761 (void) add_instance_variable (objc_ivar_context,
766 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
770 objc_is_reserved_word (tree ident)
772 unsigned char code = C_RID_CODE (ident);
774 return (OBJC_IS_AT_KEYWORD (code)
776 || code == RID_CLASS || code == RID_PUBLIC
777 || code == RID_PROTECTED || code == RID_PRIVATE
778 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
783 /* Return true if TYPE is 'id'. */
786 objc_is_object_id (tree type)
788 return OBJC_TYPE_NAME (type) == objc_object_id;
792 objc_is_class_id (tree type)
794 return OBJC_TYPE_NAME (type) == objc_class_id;
797 /* Construct a C struct with same name as CLASS, a base struct with tag
798 SUPER_NAME (if any), and FIELDS indicated. */
801 objc_build_struct (tree class, tree fields, tree super_name)
803 tree name = CLASS_NAME (class);
804 tree s = start_struct (RECORD_TYPE, name);
805 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
806 tree t, objc_info = NULL_TREE;
810 /* Prepend a packed variant of the base class into the layout. This
811 is necessary to preserve ObjC ABI compatibility. */
812 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
813 tree field = TYPE_FIELDS (super);
815 while (field && TREE_CHAIN (field)
816 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
817 field = TREE_CHAIN (field);
819 /* For ObjC ABI purposes, the "packed" size of a base class is the
820 the sum of the offset and the size (in bits) of the last field
823 = (field && TREE_CODE (field) == FIELD_DECL
824 ? size_binop (PLUS_EXPR,
825 size_binop (PLUS_EXPR,
828 convert (bitsizetype,
829 DECL_FIELD_OFFSET (field)),
830 bitsize_int (BITS_PER_UNIT)),
831 DECL_FIELD_BIT_OFFSET (field)),
833 : bitsize_zero_node);
834 DECL_SIZE_UNIT (base)
835 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
836 size_int (BITS_PER_UNIT));
837 DECL_ARTIFICIAL (base) = 1;
838 DECL_ALIGN (base) = 1;
839 DECL_FIELD_CONTEXT (base) = s;
841 DECL_FIELD_IS_BASE (base) = 1;
844 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
845 #endif /* are following the ObjC ABI here. */
846 TREE_CHAIN (base) = fields;
850 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
851 in all variants of this RECORD_TYPE to be clobbered, but it is therein
852 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
853 Hence, we must squirrel away the ObjC-specific information before calling
854 finish_struct(), and then reinstate it afterwards. */
856 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
858 = chainon (objc_info,
859 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
861 /* Point the struct at its related Objective-C class. */
862 INIT_TYPE_OBJC_INFO (s);
863 TYPE_OBJC_INTERFACE (s) = class;
865 s = finish_struct (s, fields, NULL_TREE);
867 for (t = TYPE_NEXT_VARIANT (s); t;
868 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
870 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
871 /* Replace the IDENTIFIER_NODE with an actual @interface. */
872 TYPE_OBJC_INTERFACE (t) = class;
875 /* Use TYPE_BINFO structures to point at the super class, if any. */
876 objc_xref_basetypes (s, super);
878 /* Mark this struct as a class template. */
879 CLASS_STATIC_TEMPLATE (class) = s;
884 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
885 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
888 objc_build_volatilized_type (tree type)
892 /* Check if we have not constructed the desired variant already. */
893 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
895 /* The type qualifiers must (obviously) match up. */
896 if (!TYPE_VOLATILE (t)
897 || (TYPE_READONLY (t) != TYPE_READONLY (type))
898 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
901 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
902 info, if any) must match up. */
903 if (POINTER_TYPE_P (t)
904 && (TREE_TYPE (t) != TREE_TYPE (type)))
907 /* Everything matches up! */
911 /* Ok, we could not re-use any of the pre-existing variants. Create
913 t = build_variant_type_copy (type);
914 TYPE_VOLATILE (t) = 1;
919 /* Mark DECL as being 'volatile' for purposes of Darwin
920 _setjmp()/_longjmp() exception handling. Called from
921 objc_mark_locals_volatile(). */
923 objc_volatilize_decl (tree decl)
925 /* Do not mess with variables that are 'static' or (already)
927 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
928 && (TREE_CODE (decl) == VAR_DECL
929 || TREE_CODE (decl) == PARM_DECL))
931 tree t = TREE_TYPE (decl);
932 struct volatilized_type key;
935 t = objc_build_volatilized_type (t);
937 loc = htab_find_slot (volatilized_htab, &key, INSERT);
941 *loc = ggc_alloc (sizeof (key));
942 ((struct volatilized_type *) *loc)->type = t;
945 TREE_TYPE (decl) = t;
946 TREE_THIS_VOLATILE (decl) = 1;
947 TREE_SIDE_EFFECTS (decl) = 1;
948 DECL_REGISTER (decl) = 0;
950 C_DECL_REGISTER (decl) = 0;
955 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
956 (including its categoreis and superclasses) or by object type TYP.
957 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
960 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
962 bool class_type = (cls != NULL_TREE);
968 /* Check protocols adopted by the class and its categories. */
969 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
971 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
975 /* Repeat for superclasses. */
976 cls = lookup_interface (CLASS_SUPER_NAME (cls));
979 /* Check for any protocols attached directly to the object type. */
980 if (TYPE_HAS_OBJC_INFO (typ))
982 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
988 strcpy (errbuf, class_type ? "class \'" : "type \'");
989 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
990 strcat (errbuf, "\' does not ");
991 /* NB: Types 'id' and 'Class' cannot reasonably be described as
992 "implementing" a given protocol, since they do not have an
994 strcat (errbuf, class_type ? "implement" : "conform to");
995 strcat (errbuf, " the \'");
996 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
997 strcat (errbuf, "\' protocol");
1004 /* Check if class RCLS and instance struct type RTYP conform to at least the
1005 same protocols that LCLS and LTYP conform to. */
1008 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1011 bool have_lproto = false;
1015 /* NB: We do _not_ look at categories defined for LCLS; these may or
1016 may not get loaded in, and therefore it is unreasonable to require
1017 that RCLS/RTYP must implement any of their protocols. */
1018 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1022 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1026 /* Repeat for superclasses. */
1027 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1030 /* Check for any protocols attached directly to the object type. */
1031 if (TYPE_HAS_OBJC_INFO (ltyp))
1033 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1037 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1042 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1043 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1044 away with simply checking for 'id' or 'Class' (!RCLS), since this
1045 routine will not get called in other cases. */
1046 return have_lproto || (rcls != NULL_TREE);
1049 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1050 an instance of RTYP to an instance of LTYP or to compare the two
1051 (if ARGNO is equal to -3), per ObjC type system rules. Before
1052 returning 'true', this routine may issue warnings related to, e.g.,
1053 protocol conformance. When returning 'false', the routine must
1054 produce absolutely no warnings; the C or C++ front-end will do so
1055 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1056 the routine must return 'false'.
1058 The ARGNO parameter is encoded as follows:
1059 >= 1 Parameter number (CALLEE contains function being called);
1063 -3 Comparison (LTYP and RTYP may match in either direction). */
1066 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1068 tree lcls, rcls, lproto, rproto;
1069 bool pointers_compatible;
1071 /* We must be dealing with pointer types */
1072 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1077 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1078 rtyp = TREE_TYPE (rtyp);
1080 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1082 /* Past this point, we are only interested in ObjC class instances,
1083 or 'id' or 'Class'. */
1084 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1087 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1088 && !TYPE_HAS_OBJC_INFO (ltyp))
1091 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1092 && !TYPE_HAS_OBJC_INFO (rtyp))
1095 /* Past this point, we are committed to returning 'true' to the caller.
1096 However, we can still warn about type and/or protocol mismatches. */
1098 if (TYPE_HAS_OBJC_INFO (ltyp))
1100 lcls = TYPE_OBJC_INTERFACE (ltyp);
1101 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1104 lcls = lproto = NULL_TREE;
1106 if (TYPE_HAS_OBJC_INFO (rtyp))
1108 rcls = TYPE_OBJC_INTERFACE (rtyp);
1109 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1112 rcls = rproto = NULL_TREE;
1114 /* If we could not find an @interface declaration, we must have
1115 only seen a @class declaration; for purposes of type comparison,
1116 treat it as a stand-alone (root) class. */
1118 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1121 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1124 /* If either type is an unqualified 'id', we're done. */
1125 if ((!lproto && objc_is_object_id (ltyp))
1126 || (!rproto && objc_is_object_id (rtyp)))
1129 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1131 /* If the underlying types are the same, and at most one of them has
1132 a protocol list, we do not need to issue any diagnostics. */
1133 if (pointers_compatible && (!lproto || !rproto))
1136 /* If exactly one of the types is 'Class', issue a diagnostic; any
1137 exceptions of this rule have already been handled. */
1138 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1139 pointers_compatible = false;
1140 /* Otherwise, check for inheritance relations. */
1143 if (!pointers_compatible)
1145 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1147 if (!pointers_compatible)
1148 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1150 if (!pointers_compatible && argno == -3)
1151 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1154 /* If the pointers match modulo protocols, check for protocol conformance
1156 if (pointers_compatible)
1158 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1161 if (!pointers_compatible && argno == -3)
1162 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1166 if (!pointers_compatible)
1168 /* NB: For the time being, we shall make our warnings look like their
1169 C counterparts. In the future, we may wish to make them more
1174 warning (0, "comparison of distinct Objective-C types lacks a cast");
1178 warning (0, "initialization from distinct Objective-C type");
1182 warning (0, "assignment from distinct Objective-C type");
1186 warning (0, "distinct Objective-C type in return");
1190 warning (0, "passing argument %d of %qE from distinct "
1191 "Objective-C type", argno, callee);
1199 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1200 lives in the volatilized hash table, ignore the 'volatile' bit when
1201 making the comparison. */
1204 objc_type_quals_match (tree ltyp, tree rtyp)
1206 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1207 struct volatilized_type key;
1211 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1212 lquals &= ~TYPE_QUAL_VOLATILE;
1216 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1217 rquals &= ~TYPE_QUAL_VOLATILE;
1219 return (lquals == rquals);
1223 /* Determine if CHILD is derived from PARENT. The routine assumes that
1224 both parameters are RECORD_TYPEs, and is non-reflexive. */
1227 objc_derived_from_p (tree parent, tree child)
1229 parent = TYPE_MAIN_VARIANT (parent);
1231 for (child = TYPE_MAIN_VARIANT (child);
1232 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1234 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1235 (TYPE_BINFO (child),
1238 if (child == parent)
1247 objc_build_component_ref (tree datum, tree component)
1249 /* If COMPONENT is NULL, the caller is referring to the anonymous
1250 base class field. */
1253 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1255 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1258 /* The 'build_component_ref' routine has been removed from the C++
1259 front-end, but 'finish_class_member_access_expr' seems to be
1260 a worthy substitute. */
1262 return finish_class_member_access_expr (datum, component);
1264 return build_component_ref (datum, component);
1268 /* Recursively copy inheritance information rooted at BINFO. To do this,
1269 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1272 objc_copy_binfo (tree binfo)
1274 tree btype = BINFO_TYPE (binfo);
1275 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1279 BINFO_TYPE (binfo2) = btype;
1280 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1281 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1283 /* Recursively copy base binfos of BINFO. */
1284 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1286 tree base_binfo2 = objc_copy_binfo (base_binfo);
1288 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1289 BINFO_BASE_APPEND (binfo2, base_binfo2);
1295 /* Record superclass information provided in BASETYPE for ObjC class REF.
1296 This is loosely based on cp/decl.c:xref_basetypes(). */
1299 objc_xref_basetypes (tree ref, tree basetype)
1301 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1303 TYPE_BINFO (ref) = binfo;
1304 BINFO_OFFSET (binfo) = size_zero_node;
1305 BINFO_TYPE (binfo) = ref;
1309 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1311 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1312 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1313 BINFO_BASE_APPEND (binfo, base_binfo);
1314 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1319 volatilized_hash (const void *ptr)
1321 tree typ = ((struct volatilized_type *)ptr)->type;
1323 return htab_hash_pointer(typ);
1327 volatilized_eq (const void *ptr1, const void *ptr2)
1329 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1330 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1332 return typ1 == typ2;
1335 /* Called from finish_decl. */
1338 objc_check_decl (tree decl)
1340 tree type = TREE_TYPE (decl);
1342 if (TREE_CODE (type) != RECORD_TYPE)
1344 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1345 error ("statically allocated instance of Objective-C class %qs",
1346 IDENTIFIER_POINTER (type));
1349 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1350 either name an Objective-C class, or refer to the special 'id' or 'Class'
1351 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1354 objc_get_protocol_qualified_type (tree interface, tree protocols)
1356 /* If INTERFACE is not provided, default to 'id'. */
1357 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1358 bool is_ptr = (type != NULL_TREE);
1362 type = objc_is_class_name (interface);
1365 type = xref_tag (RECORD_TYPE, type);
1372 type = build_variant_type_copy (type);
1374 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1378 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1379 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1380 type = TREE_TYPE (type);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1385 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1390 type = TYPE_POINTER_TO (type);
1392 TYPE_OBJC_INTERFACE (type)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1404 check_protocol_recursively (tree proto, tree list)
1408 for (p = list; p; p = TREE_CHAIN (p))
1410 tree pp = TREE_VALUE (p);
1412 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1413 pp = lookup_protocol (pp);
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1419 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1427 lookup_and_install_protocols (tree protocols)
1430 tree return_value = NULL_TREE;
1432 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1434 tree ident = TREE_VALUE (proto);
1435 tree p = lookup_protocol (ident);
1438 error ("cannot find protocol declaration for %qs",
1439 IDENTIFIER_POINTER (ident));
1441 return_value = chainon (return_value,
1442 build_tree_list (NULL_TREE, p));
1445 return return_value;
1448 /* Create a declaration for field NAME of a given TYPE. */
1451 create_field_decl (tree type, const char *name)
1453 return build_decl (FIELD_DECL, get_identifier (name), type);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1460 start_var_decl (tree type, const char *name)
1462 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1464 TREE_STATIC (var) = 1;
1465 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var) = 1;
1467 DECL_ARTIFICIAL (var) = 1;
1468 DECL_CONTEXT (var) = NULL_TREE;
1470 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1476 /* Finish off the variable declaration created by start_var_decl(). */
1479 finish_var_decl (tree var, tree initializer)
1481 finish_decl (var, initializer, NULL_TREE);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1492 setup_string_decl (void)
1497 /* %s in format will provide room for terminating null */
1498 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1499 + strlen (constant_string_class_name);
1500 name = xmalloc (length);
1501 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1502 constant_string_class_name);
1503 constant_string_global_id = get_identifier (name);
1504 string_class_decl = lookup_name (constant_string_global_id);
1506 return string_class_decl;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1521 synth_module_prologue (void)
1524 enum debug_info_type save_write_symbols = write_symbols;
1525 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn'r been called yet. */
1529 write_symbols = NO_DEBUG;
1530 debug_hooks = &do_nothing_debug_hooks;
1533 push_lang_context (lang_name_c); /* extern "C" */
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id = get_identifier (TAG_OBJECT);
1539 objc_class_id = get_identifier (TAG_CLASS);
1541 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1542 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1544 objc_object_type = build_pointer_type (objc_object_reference);
1545 objc_class_type = build_pointer_type (objc_class_reference);
1547 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1548 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1555 DECL_IN_SYSTEM_HEADER (type) = 1;
1556 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1559 DECL_IN_SYSTEM_HEADER (type) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1564 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1565 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime)
1571 /* `struct objc_selector *' */
1573 = build_pointer_type (xref_tag (RECORD_TYPE,
1574 get_identifier (TAG_SELECTOR)));
1576 /* `const struct objc_selector *' */
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE,
1580 get_identifier (TAG_SELECTOR)),
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1587 get_identifier (TAG_SUPER)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr = build_pointer_type
1591 (xref_tag (RECORD_TYPE,
1592 get_identifier (UTAG_METHOD_LIST)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1596 objc_ivar_list_ptr = build_pointer_type
1597 (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_IVAR_LIST)));
1600 if (flag_next_runtime)
1602 /* NB: In order to call one of the ..._stret (struct-returning)
1603 functions, the function *MUST* first be cast to a signature that
1604 corresponds to the actual ObjC method being invoked. This is
1605 what is done by the build_objc_method_call() routine below. */
1607 /* id objc_msgSend (id, SEL, ...); */
1608 /* id objc_msgSendNonNil (id, SEL, ...); */
1609 /* id objc_msgSend_stret (id, SEL, ...); */
1610 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1612 = build_function_type (objc_object_type,
1613 tree_cons (NULL_TREE, objc_object_type,
1614 tree_cons (NULL_TREE, objc_selector_type,
1616 umsg_decl = builtin_function (TAG_MSGSEND,
1617 type, 0, NOT_BUILT_IN,
1619 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1620 type, 0, NOT_BUILT_IN,
1622 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1623 type, 0, NOT_BUILT_IN,
1625 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1626 type, 0, NOT_BUILT_IN,
1629 /* id objc_msgSend_Fast (id, SEL, ...)
1630 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1631 #ifdef OFFS_MSGSEND_FAST
1632 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1633 type, 0, NOT_BUILT_IN,
1635 DECL_ATTRIBUTES (umsg_fast_decl)
1636 = tree_cons (get_identifier ("hard_coded_address"),
1637 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1640 /* No direct dispatch availible. */
1641 umsg_fast_decl = umsg_decl;
1644 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1645 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1647 = build_function_type (objc_object_type,
1648 tree_cons (NULL_TREE, objc_super_type,
1649 tree_cons (NULL_TREE, objc_selector_type,
1651 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1652 type, 0, NOT_BUILT_IN,
1654 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1655 type, 0, NOT_BUILT_IN, 0,
1660 /* GNU runtime messenger entry points. */
1662 /* typedef id (*IMP)(id, SEL, ...); */
1664 = build_pointer_type
1665 (build_function_type (objc_object_type,
1666 tree_cons (NULL_TREE, objc_object_type,
1667 tree_cons (NULL_TREE, objc_selector_type,
1670 /* IMP objc_msg_lookup (id, SEL); */
1672 = build_function_type (IMP_type,
1673 tree_cons (NULL_TREE, objc_object_type,
1674 tree_cons (NULL_TREE, objc_selector_type,
1675 OBJC_VOID_AT_END)));
1676 umsg_decl = builtin_function (TAG_MSGSEND,
1677 type, 0, NOT_BUILT_IN,
1680 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1682 = build_function_type (IMP_type,
1683 tree_cons (NULL_TREE, objc_super_type,
1684 tree_cons (NULL_TREE, objc_selector_type,
1685 OBJC_VOID_AT_END)));
1686 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1687 type, 0, NOT_BUILT_IN,
1690 /* The following GNU runtime entry point is called to initialize
1693 __objc_exec_class (void *); */
1695 = build_function_type (void_type_node,
1696 tree_cons (NULL_TREE, ptr_type_node,
1698 execclass_decl = builtin_function (TAG_EXECCLASS,
1699 type, 0, NOT_BUILT_IN,
1703 /* id objc_getClass (const char *); */
1705 type = build_function_type (objc_object_type,
1706 tree_cons (NULL_TREE,
1707 const_string_type_node,
1711 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1714 /* id objc_getMetaClass (const char *); */
1716 objc_get_meta_class_decl
1717 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1719 build_class_template ();
1720 build_super_template ();
1721 build_protocol_template ();
1722 build_category_template ();
1723 build_objc_exception_stuff ();
1725 if (flag_next_runtime)
1726 build_next_objc_exception_stuff ();
1728 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1730 if (! flag_next_runtime)
1731 build_selector_table_decl ();
1733 /* Forward declare constant_string_id and constant_string_type. */
1734 if (!constant_string_class_name)
1735 constant_string_class_name = default_constant_string_class_name;
1737 constant_string_id = get_identifier (constant_string_class_name);
1738 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1740 /* Pre-build the following entities - for speed/convenience. */
1741 self_id = get_identifier ("self");
1742 ucmd_id = get_identifier ("_cmd");
1745 pop_lang_context ();
1748 write_symbols = save_write_symbols;
1749 debug_hooks = save_hooks;
1752 /* Ensure that the ivar list for NSConstantString/NXConstantString
1753 (or whatever was specified via `-fconstant-string-class')
1754 contains fields at least as large as the following three, so that
1755 the runtime can stomp on them with confidence:
1757 struct STRING_OBJECT_CLASS_NAME
1761 unsigned int length;
1765 check_string_class_template (void)
1767 tree field_decl = objc_get_class_ivars (constant_string_id);
1769 #define AT_LEAST_AS_LARGE_AS(F, T) \
1770 (F && TREE_CODE (F) == FIELD_DECL \
1771 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1772 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1774 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1777 field_decl = TREE_CHAIN (field_decl);
1778 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1781 field_decl = TREE_CHAIN (field_decl);
1782 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1784 #undef AT_LEAST_AS_LARGE_AS
1787 /* Avoid calling `check_string_class_template ()' more than once. */
1788 static GTY(()) int string_layout_checked;
1790 /* Construct an internal string layout to be used as a template for
1791 creating NSConstantString/NXConstantString instances. */
1794 objc_build_internal_const_str_type (void)
1796 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1797 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1798 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1800 TREE_CHAIN (field) = fields; fields = field;
1801 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1802 TREE_CHAIN (field) = fields; fields = field;
1803 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1805 finish_builtin_struct (type, "__builtin_ObjCString",
1811 /* Custom build_string which sets TREE_TYPE! */
1814 my_build_string (int len, const char *str)
1816 return fix_string_type (build_string (len, str));
1819 /* Build a string with contents STR and length LEN and convert it to a
1823 my_build_string_pointer (int len, const char *str)
1825 tree string = my_build_string (len, str);
1826 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1827 return build1 (ADDR_EXPR, ptrtype, string);
1831 string_hash (const void *ptr)
1833 tree str = ((struct string_descriptor *)ptr)->literal;
1834 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1835 int i, len = TREE_STRING_LENGTH (str);
1838 for (i = 0; i < len; i++)
1839 h = ((h * 613) + p[i]);
1845 string_eq (const void *ptr1, const void *ptr2)
1847 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1848 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1849 int len1 = TREE_STRING_LENGTH (str1);
1851 return (len1 == TREE_STRING_LENGTH (str2)
1852 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1856 /* Given a chain of STRING_CST's, build a static instance of
1857 NXConstantString which points at the concatenation of those
1858 strings. We place the string object in the __string_objects
1859 section of the __OBJC segment. The Objective-C runtime will
1860 initialize the isa pointers of the string objects to point at the
1861 NXConstantString class object. */
1864 objc_build_string_object (tree string)
1866 tree initlist, constructor, constant_string_class;
1869 struct string_descriptor *desc, key;
1872 /* Prep the string argument. */
1873 string = fix_string_type (string);
1874 TREE_SET_CODE (string, STRING_CST);
1875 length = TREE_STRING_LENGTH (string) - 1;
1877 /* Check whether the string class being used actually exists and has the
1878 correct ivar layout. */
1879 if (!string_layout_checked)
1881 string_layout_checked = -1;
1882 constant_string_class = lookup_interface (constant_string_id);
1883 internal_const_str_type = objc_build_internal_const_str_type ();
1885 if (!constant_string_class
1886 || !(constant_string_type
1887 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1888 error ("cannot find interface declaration for %qs",
1889 IDENTIFIER_POINTER (constant_string_id));
1890 /* The NSConstantString/NXConstantString ivar layout is now known. */
1891 else if (!check_string_class_template ())
1892 error ("interface %qs does not have valid constant string layout",
1893 IDENTIFIER_POINTER (constant_string_id));
1894 /* For the NeXT runtime, we can generate a literal reference
1895 to the string class, don't need to run a constructor. */
1896 else if (flag_next_runtime && !setup_string_decl ())
1897 error ("cannot find reference tag for class %qs",
1898 IDENTIFIER_POINTER (constant_string_id));
1901 string_layout_checked = 1; /* Success! */
1902 add_class_reference (constant_string_id);
1906 if (string_layout_checked == -1)
1907 return error_mark_node;
1909 /* Perhaps we already constructed a constant string just like this one? */
1910 key.literal = string;
1911 loc = htab_find_slot (string_htab, &key, INSERT);
1917 *loc = desc = ggc_alloc (sizeof (*desc));
1918 desc->literal = string;
1920 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1921 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1922 fields = TYPE_FIELDS (internal_const_str_type);
1924 = build_tree_list (fields,
1926 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1927 : build_int_cst (NULL_TREE, 0));
1928 fields = TREE_CHAIN (fields);
1929 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1931 fields = TREE_CHAIN (fields);
1932 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1934 constructor = objc_build_constructor (internal_const_str_type,
1935 nreverse (initlist));
1936 TREE_INVARIANT (constructor) = true;
1938 if (!flag_next_runtime)
1940 = objc_add_static_instance (constructor, constant_string_type);
1943 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1944 DECL_INITIAL (var) = constructor;
1945 TREE_STATIC (var) = 1;
1946 pushdecl_top_level (var);
1949 desc->constructor = constructor;
1952 addr = convert (build_pointer_type (constant_string_type),
1953 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1958 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1960 static GTY(()) int num_static_inst;
1963 objc_add_static_instance (tree constructor, tree class_decl)
1968 /* Find the list of static instances for the CLASS_DECL. Create one if
1970 for (chain = &objc_static_instances;
1971 *chain && TREE_VALUE (*chain) != class_decl;
1972 chain = &TREE_CHAIN (*chain));
1975 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1976 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1979 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1980 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1981 DECL_COMMON (decl) = 1;
1982 TREE_STATIC (decl) = 1;
1983 DECL_ARTIFICIAL (decl) = 1;
1984 DECL_INITIAL (decl) = constructor;
1986 /* We may be writing something else just now.
1987 Postpone till end of input. */
1988 DECL_DEFER_OUTPUT (decl) = 1;
1989 pushdecl_top_level (decl);
1990 rest_of_decl_compilation (decl, 1, 0);
1992 /* Add the DECL to the head of this CLASS' list. */
1993 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1998 /* Build a static constant CONSTRUCTOR
1999 with type TYPE and elements ELTS. */
2002 objc_build_constructor (tree type, tree elts)
2004 tree constructor = build_constructor (type, elts);
2006 TREE_CONSTANT (constructor) = 1;
2007 TREE_STATIC (constructor) = 1;
2008 TREE_READONLY (constructor) = 1;
2011 /* Adjust for impedance mismatch. We should figure out how to build
2012 CONSTRUCTORs that consistently please both the C and C++ gods. */
2013 if (!TREE_PURPOSE (elts))
2014 TREE_TYPE (constructor) = NULL_TREE;
2015 TREE_HAS_CONSTRUCTOR (constructor) = 1;
2021 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2023 /* Predefine the following data type:
2031 void *defs[cls_def_cnt + cat_def_cnt];
2035 build_objc_symtab_template (void)
2037 tree field_decl, field_decl_chain;
2039 objc_symtab_template
2040 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2042 /* long sel_ref_cnt; */
2043 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2044 field_decl_chain = field_decl;
2047 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2049 chainon (field_decl_chain, field_decl);
2051 /* short cls_def_cnt; */
2052 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2053 chainon (field_decl_chain, field_decl);
2055 /* short cat_def_cnt; */
2056 field_decl = create_field_decl (short_integer_type_node,
2058 chainon (field_decl_chain, field_decl);
2060 if (imp_count || cat_count || !flag_next_runtime)
2062 /* void *defs[imp_count + cat_count (+ 1)]; */
2063 /* NB: The index is one less than the size of the array. */
2064 int index = imp_count + cat_count
2065 + (flag_next_runtime? -1: 0);
2066 field_decl = create_field_decl
2069 build_index_type (build_int_cst (NULL_TREE, index))),
2071 chainon (field_decl_chain, field_decl);
2074 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2077 /* Create the initial value for the `defs' field of _objc_symtab.
2078 This is a CONSTRUCTOR. */
2081 init_def_list (tree type)
2083 tree expr, initlist = NULL_TREE;
2084 struct imp_entry *impent;
2087 for (impent = imp_list; impent; impent = impent->next)
2089 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2091 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2092 initlist = tree_cons (NULL_TREE, expr, initlist);
2097 for (impent = imp_list; impent; impent = impent->next)
2099 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2101 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2102 initlist = tree_cons (NULL_TREE, expr, initlist);
2106 if (!flag_next_runtime)
2108 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2111 if (static_instances_decl)
2112 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2114 expr = build_int_cst (NULL_TREE, 0);
2116 initlist = tree_cons (NULL_TREE, expr, initlist);
2119 return objc_build_constructor (type, nreverse (initlist));
2122 /* Construct the initial value for all of _objc_symtab. */
2125 init_objc_symtab (tree type)
2129 /* sel_ref_cnt = { ..., 5, ... } */
2131 initlist = build_tree_list (NULL_TREE,
2132 build_int_cst (long_integer_type_node, 0));
2134 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2136 if (flag_next_runtime || ! sel_ref_chain)
2137 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2140 = tree_cons (NULL_TREE,
2141 convert (build_pointer_type (objc_selector_type),
2142 build_unary_op (ADDR_EXPR,
2143 UOBJC_SELECTOR_TABLE_decl, 1)),
2146 /* cls_def_cnt = { ..., 5, ... } */
2148 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2150 /* cat_def_cnt = { ..., 5, ... } */
2152 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2154 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2156 if (imp_count || cat_count || !flag_next_runtime)
2159 tree field = TYPE_FIELDS (type);
2160 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2162 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2166 return objc_build_constructor (type, nreverse (initlist));
2169 /* Generate forward declarations for metadata such as
2170 'OBJC_CLASS_...'. */
2173 build_metadata_decl (const char *name, tree type)
2177 /* struct TYPE NAME_<name>; */
2178 decl = start_var_decl (type, synth_id_with_class_suffix
2180 objc_implementation_context));
2185 /* Push forward-declarations of all the categories so that
2186 init_def_list can use them in a CONSTRUCTOR. */
2189 forward_declare_categories (void)
2191 struct imp_entry *impent;
2192 tree sav = objc_implementation_context;
2194 for (impent = imp_list; impent; impent = impent->next)
2196 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2198 /* Set an invisible arg to synth_id_with_class_suffix. */
2199 objc_implementation_context = impent->imp_context;
2200 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2201 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2202 objc_category_template);
2205 objc_implementation_context = sav;
2208 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2209 and initialized appropriately. */
2212 generate_objc_symtab_decl (void)
2214 /* forward declare categories */
2216 forward_declare_categories ();
2218 build_objc_symtab_template ();
2219 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2220 finish_var_decl (UOBJC_SYMBOLS_decl,
2221 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2225 init_module_descriptor (tree type)
2227 tree initlist, expr;
2229 /* version = { 1, ... } */
2231 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2232 initlist = build_tree_list (NULL_TREE, expr);
2234 /* size = { ..., sizeof (struct _objc_module), ... } */
2236 expr = convert (long_integer_type_node,
2237 size_in_bytes (objc_module_template));
2238 initlist = tree_cons (NULL_TREE, expr, initlist);
2240 /* name = { ..., "foo.m", ... } */
2242 expr = add_objc_string (get_identifier (input_filename), class_names);
2243 initlist = tree_cons (NULL_TREE, expr, initlist);
2245 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2247 if (UOBJC_SYMBOLS_decl)
2248 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2250 expr = build_int_cst (NULL_TREE, 0);
2251 initlist = tree_cons (NULL_TREE, expr, initlist);
2253 return objc_build_constructor (type, nreverse (initlist));
2256 /* Write out the data structures to describe Objective C classes defined.
2258 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2261 build_module_descriptor (void)
2263 tree field_decl, field_decl_chain;
2266 push_lang_context (lang_name_c); /* extern "C" */
2269 objc_module_template
2270 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2273 field_decl = create_field_decl (long_integer_type_node, "version");
2274 field_decl_chain = field_decl;
2277 field_decl = create_field_decl (long_integer_type_node, "size");
2278 chainon (field_decl_chain, field_decl);
2281 field_decl = create_field_decl (string_type_node, "name");
2282 chainon (field_decl_chain, field_decl);
2284 /* struct _objc_symtab *symtab; */
2286 = create_field_decl (build_pointer_type
2287 (xref_tag (RECORD_TYPE,
2288 get_identifier (UTAG_SYMTAB))),
2290 chainon (field_decl_chain, field_decl);
2292 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2294 /* Create an instance of "_objc_module". */
2295 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2296 finish_var_decl (UOBJC_MODULES_decl,
2297 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2300 pop_lang_context ();
2304 /* The GNU runtime requires us to provide a static initializer function
2307 static void __objc_gnu_init (void) {
2308 __objc_exec_class (&L_OBJC_MODULES);
2312 build_module_initializer_routine (void)
2317 push_lang_context (lang_name_c); /* extern "C" */
2320 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2321 objc_start_function (get_identifier (TAG_GNUINIT),
2322 build_function_type (void_type_node,
2324 NULL_TREE, objc_get_parm_info (0));
2326 body = c_begin_compound_stmt (true);
2327 add_stmt (build_function_call
2331 build_unary_op (ADDR_EXPR,
2332 UOBJC_MODULES_decl, 0))));
2333 add_stmt (c_end_compound_stmt (body, true));
2335 TREE_PUBLIC (current_function_decl) = 0;
2338 /* For Objective-C++, we will need to call __objc_gnu_init
2339 from objc_generate_static_init_call() below. */
2340 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2343 GNU_INIT_decl = current_function_decl;
2347 pop_lang_context ();
2352 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2353 to be called by the module initializer routine. */
2356 objc_static_init_needed_p (void)
2358 return (GNU_INIT_decl != NULL_TREE);
2361 /* Generate a call to the __objc_gnu_init initializer function. */
2364 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2366 add_stmt (build_stmt (EXPR_STMT,
2367 build_function_call (GNU_INIT_decl, NULL_TREE)));
2371 #endif /* OBJCPLUS */
2373 /* Return the DECL of the string IDENT in the SECTION. */
2376 get_objc_string_decl (tree ident, enum string_section section)
2380 if (section == class_names)
2381 chain = class_names_chain;
2382 else if (section == meth_var_names)
2383 chain = meth_var_names_chain;
2384 else if (section == meth_var_types)
2385 chain = meth_var_types_chain;
2389 for (; chain != 0; chain = TREE_CHAIN (chain))
2390 if (TREE_VALUE (chain) == ident)
2391 return (TREE_PURPOSE (chain));
2397 /* Output references to all statically allocated objects. Return the DECL
2398 for the array built. */
2401 generate_static_references (void)
2403 tree decls = NULL_TREE, expr = NULL_TREE;
2404 tree class_name, class, decl, initlist;
2405 tree cl_chain, in_chain, type
2406 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2407 int num_inst, num_class;
2410 if (flag_next_runtime)
2413 for (cl_chain = objc_static_instances, num_class = 0;
2414 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2416 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2417 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2419 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2420 decl = start_var_decl (type, buf);
2422 /* Output {class_name, ...}. */
2423 class = TREE_VALUE (cl_chain);
2424 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2425 initlist = build_tree_list (NULL_TREE,
2426 build_unary_op (ADDR_EXPR, class_name, 1));
2428 /* Output {..., instance, ...}. */
2429 for (in_chain = TREE_PURPOSE (cl_chain);
2430 in_chain; in_chain = TREE_CHAIN (in_chain))
2432 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2433 initlist = tree_cons (NULL_TREE, expr, initlist);
2436 /* Output {..., NULL}. */
2437 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2439 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2440 finish_var_decl (decl, expr);
2442 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2445 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2446 expr = objc_build_constructor (type, nreverse (decls));
2447 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2448 finish_var_decl (static_instances_decl, expr);
2451 /* Output all strings. */
2454 generate_strings (void)
2456 tree chain, string_expr;
2457 tree string, decl, type;
2459 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2461 string = TREE_VALUE (chain);
2462 decl = TREE_PURPOSE (chain);
2463 type = build_array_type
2466 (build_int_cst (NULL_TREE,
2467 IDENTIFIER_LENGTH (string))));
2468 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2469 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2470 IDENTIFIER_POINTER (string));
2471 finish_var_decl (decl, string_expr);
2474 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2476 string = TREE_VALUE (chain);
2477 decl = TREE_PURPOSE (chain);
2478 type = build_array_type
2481 (build_int_cst (NULL_TREE,
2482 IDENTIFIER_LENGTH (string))));
2483 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2484 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2485 IDENTIFIER_POINTER (string));
2486 finish_var_decl (decl, string_expr);
2489 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2491 string = TREE_VALUE (chain);
2492 decl = TREE_PURPOSE (chain);
2493 type = build_array_type
2496 (build_int_cst (NULL_TREE,
2497 IDENTIFIER_LENGTH (string))));
2498 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2499 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2500 IDENTIFIER_POINTER (string));
2501 finish_var_decl (decl, string_expr);
2505 static GTY(()) int selector_reference_idx;
2508 build_selector_reference_decl (void)
2513 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2514 decl = start_var_decl (objc_selector_type, buf);
2520 build_selector_table_decl (void)
2524 if (flag_typed_selectors)
2526 build_selector_template ();
2527 temp = build_array_type (objc_selector_template, NULL_TREE);
2530 temp = build_array_type (objc_selector_type, NULL_TREE);
2532 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2535 /* Just a handy wrapper for add_objc_string. */
2538 build_selector (tree ident)
2540 return convert (objc_selector_type,
2541 add_objc_string (ident, meth_var_names));
2545 build_selector_translation_table (void)
2547 tree chain, initlist = NULL_TREE;
2549 tree decl = NULL_TREE;
2551 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2555 if (warn_selector && objc_implementation_context)
2559 for (method_chain = meth_var_names_chain;
2561 method_chain = TREE_CHAIN (method_chain))
2563 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2572 if (flag_next_runtime && TREE_PURPOSE (chain))
2573 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2575 loc = &input_location;
2576 warning (0, "%Hcreating selector for nonexistent method %qE",
2577 loc, TREE_VALUE (chain));
2581 expr = build_selector (TREE_VALUE (chain));
2582 /* add one for the '\0' character */
2583 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2585 if (flag_next_runtime)
2587 decl = TREE_PURPOSE (chain);
2588 finish_var_decl (decl, expr);
2592 if (flag_typed_selectors)
2594 tree eltlist = NULL_TREE;
2595 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2596 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2597 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2598 expr = objc_build_constructor (objc_selector_template,
2599 nreverse (eltlist));
2602 initlist = tree_cons (NULL_TREE, expr, initlist);
2606 if (! flag_next_runtime)
2608 /* Cause the selector table (previously forward-declared)
2609 to be actually output. */
2610 initlist = tree_cons (NULL_TREE,
2611 flag_typed_selectors
2612 ? objc_build_constructor
2613 (objc_selector_template,
2614 tree_cons (NULL_TREE,
2615 build_int_cst (NULL_TREE, 0),
2616 tree_cons (NULL_TREE,
2617 build_int_cst (NULL_TREE, 0),
2619 : build_int_cst (NULL_TREE, 0), initlist);
2620 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2621 nreverse (initlist));
2622 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2627 get_proto_encoding (tree proto)
2632 if (! METHOD_ENCODING (proto))
2634 encoding = encode_method_prototype (proto);
2635 METHOD_ENCODING (proto) = encoding;
2638 encoding = METHOD_ENCODING (proto);
2640 return add_objc_string (encoding, meth_var_types);
2643 return build_int_cst (NULL_TREE, 0);
2646 /* sel_ref_chain is a list whose "value" fields will be instances of
2647 identifier_node that represent the selector. */
2650 build_typed_selector_reference (tree ident, tree prototype)
2652 tree *chain = &sel_ref_chain;
2658 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2659 goto return_at_index;
2662 chain = &TREE_CHAIN (*chain);
2665 *chain = tree_cons (prototype, ident, NULL_TREE);
2668 expr = build_unary_op (ADDR_EXPR,
2669 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2670 build_int_cst (NULL_TREE, index)),
2672 return convert (objc_selector_type, expr);
2676 build_selector_reference (tree ident)
2678 tree *chain = &sel_ref_chain;
2684 if (TREE_VALUE (*chain) == ident)
2685 return (flag_next_runtime
2686 ? TREE_PURPOSE (*chain)
2687 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2688 build_int_cst (NULL_TREE, index)));
2691 chain = &TREE_CHAIN (*chain);
2694 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2696 *chain = tree_cons (expr, ident, NULL_TREE);
2698 return (flag_next_runtime
2700 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2701 build_int_cst (NULL_TREE, index)));
2704 static GTY(()) int class_reference_idx;
2707 build_class_reference_decl (void)
2712 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2713 decl = start_var_decl (objc_class_type, buf);
2718 /* Create a class reference, but don't create a variable to reference
2722 add_class_reference (tree ident)
2726 if ((chain = cls_ref_chain))
2731 if (ident == TREE_VALUE (chain))
2735 chain = TREE_CHAIN (chain);
2739 /* Append to the end of the list */
2740 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2743 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2746 /* Get a class reference, creating it if necessary. Also create the
2747 reference variable. */
2750 objc_get_class_reference (tree ident)
2752 tree orig_ident = (DECL_P (ident)
2755 ? OBJC_TYPE_NAME (ident)
2757 bool local_scope = false;
2760 if (processing_template_decl)
2761 /* Must wait until template instantiation time. */
2762 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2765 if (TREE_CODE (ident) == TYPE_DECL)
2766 ident = (DECL_ORIGINAL_TYPE (ident)
2767 ? DECL_ORIGINAL_TYPE (ident)
2768 : TREE_TYPE (ident));
2771 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2772 && TYPE_CONTEXT (ident) != global_namespace)
2776 if (local_scope || !(ident = objc_is_class_name (ident)))
2778 error ("%qs is not an Objective-C class name or alias",
2779 IDENTIFIER_POINTER (orig_ident));
2780 return error_mark_node;
2783 if (flag_next_runtime && !flag_zero_link)
2788 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2789 if (TREE_VALUE (*chain) == ident)
2791 if (! TREE_PURPOSE (*chain))
2792 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2794 return TREE_PURPOSE (*chain);
2797 decl = build_class_reference_decl ();
2798 *chain = tree_cons (decl, ident, NULL_TREE);
2805 add_class_reference (ident);
2807 params = build_tree_list (NULL_TREE,
2808 my_build_string_pointer
2809 (IDENTIFIER_LENGTH (ident) + 1,
2810 IDENTIFIER_POINTER (ident)));
2812 assemble_external (objc_get_class_decl);
2813 return build_function_call (objc_get_class_decl, params);
2817 /* For each string section we have a chain which maps identifier nodes
2818 to decls for the strings. */
2821 add_objc_string (tree ident, enum string_section section)
2825 if (section == class_names)
2826 chain = &class_names_chain;
2827 else if (section == meth_var_names)
2828 chain = &meth_var_names_chain;
2829 else if (section == meth_var_types)
2830 chain = &meth_var_types_chain;
2836 if (TREE_VALUE (*chain) == ident)
2837 return convert (string_type_node,
2838 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2840 chain = &TREE_CHAIN (*chain);
2843 decl = build_objc_string_decl (section);
2845 *chain = tree_cons (decl, ident, NULL_TREE);
2847 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2850 static GTY(()) int class_names_idx;
2851 static GTY(()) int meth_var_names_idx;
2852 static GTY(()) int meth_var_types_idx;
2855 build_objc_string_decl (enum string_section section)
2860 if (section == class_names)
2861 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2862 else if (section == meth_var_names)
2863 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2864 else if (section == meth_var_types)
2865 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2867 ident = get_identifier (buf);
2869 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2870 DECL_EXTERNAL (decl) = 1;
2871 TREE_PUBLIC (decl) = 0;
2872 TREE_USED (decl) = 1;
2873 TREE_CONSTANT (decl) = 1;
2874 DECL_CONTEXT (decl) = 0;
2875 DECL_ARTIFICIAL (decl) = 1;
2877 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2880 make_decl_rtl (decl);
2881 pushdecl_top_level (decl);
2888 objc_declare_alias (tree alias_ident, tree class_ident)
2890 tree underlying_class;
2893 if (current_namespace != global_namespace) {
2894 error ("Objective-C declarations may only appear in global scope");
2896 #endif /* OBJCPLUS */
2898 if (!(underlying_class = objc_is_class_name (class_ident)))
2899 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2900 else if (objc_is_class_name (alias_ident))
2901 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2904 /* Implement @compatibility_alias as a typedef. */
2906 push_lang_context (lang_name_c); /* extern "C" */
2908 lang_hooks.decls.pushdecl (build_decl
2911 xref_tag (RECORD_TYPE, underlying_class)));
2913 pop_lang_context ();
2915 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2920 objc_declare_class (tree ident_list)
2924 if (current_namespace != global_namespace) {
2925 error ("Objective-C declarations may only appear in global scope");
2927 #endif /* OBJCPLUS */
2929 for (list = ident_list; list; list = TREE_CHAIN (list))
2931 tree ident = TREE_VALUE (list);
2933 if (! objc_is_class_name (ident))
2935 tree record = lookup_name (ident), type = record;
2939 if (TREE_CODE (record) == TYPE_DECL)
2940 type = DECL_ORIGINAL_TYPE (record);
2942 if (!TYPE_HAS_OBJC_INFO (type)
2943 || !TYPE_OBJC_INTERFACE (type))
2945 error ("%qs redeclared as different kind of symbol",
2946 IDENTIFIER_POINTER (ident));
2947 error ("previous declaration of %q+D",
2952 record = xref_tag (RECORD_TYPE, ident);
2953 INIT_TYPE_OBJC_INFO (record);
2954 TYPE_OBJC_INTERFACE (record) = ident;
2955 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2961 objc_is_class_name (tree ident)
2965 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2966 && identifier_global_value (ident))
2967 ident = identifier_global_value (ident);
2968 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2969 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2971 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2972 ident = OBJC_TYPE_NAME (ident);
2974 if (ident && TREE_CODE (ident) == TYPE_DECL)
2975 ident = DECL_NAME (ident);
2977 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2980 if (lookup_interface (ident))
2983 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2985 if (ident == TREE_VALUE (chain))
2989 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2991 if (ident == TREE_VALUE (chain))
2992 return TREE_PURPOSE (chain);
2998 /* Check whether TYPE is either 'id' or 'Class'. */
3001 objc_is_id (tree type)
3003 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3004 && identifier_global_value (type))
3005 type = identifier_global_value (type);
3007 if (type && TREE_CODE (type) == TYPE_DECL)
3008 type = TREE_TYPE (type);
3010 /* NB: This function may be called before the ObjC front-end has
3011 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3012 return (objc_object_type && type
3013 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3018 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3019 class instance. This is needed by other parts of the compiler to
3020 handle ObjC types gracefully. */
3023 objc_is_object_ptr (tree type)
3027 type = TYPE_MAIN_VARIANT (type);
3028 if (!POINTER_TYPE_P (type))
3031 ret = objc_is_id (type);
3033 ret = objc_is_class_name (TREE_TYPE (type));
3039 objc_is_gcable_type (tree type, int or_strong_p)
3045 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3047 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3049 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3051 type = TREE_TYPE (type);
3052 if (TREE_CODE (type) != RECORD_TYPE)
3054 name = TYPE_NAME (type);
3055 return (objc_is_class_name (name) != NULL_TREE);
3059 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3061 if (expr == oldexpr)
3064 switch (TREE_CODE (expr))
3067 return objc_build_component_ref
3068 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3071 DECL_NAME (TREE_OPERAND (expr, 1)));
3073 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3076 TREE_OPERAND (expr, 1));
3078 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3087 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3090 /* The LHS parameter contains the expression 'outervar->memberspec';
3091 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3092 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3095 = objc_substitute_decl
3096 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3098 = (flag_objc_direct_dispatch
3099 ? objc_assign_ivar_fast_decl
3100 : objc_assign_ivar_decl);
3102 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3104 func_params = tree_cons (NULL_TREE,
3105 convert (objc_object_type, rhs),
3106 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3107 tree_cons (NULL_TREE, offs,
3110 assemble_external (func);
3111 return build_function_call (func, func_params);
3115 objc_build_global_assignment (tree lhs, tree rhs)
3117 tree func_params = tree_cons (NULL_TREE,
3118 convert (objc_object_type, rhs),
3119 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3120 build_unary_op (ADDR_EXPR, lhs, 0)),
3123 assemble_external (objc_assign_global_decl);
3124 return build_function_call (objc_assign_global_decl, func_params);
3128 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3130 tree func_params = tree_cons (NULL_TREE,
3131 convert (objc_object_type, rhs),
3132 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3133 build_unary_op (ADDR_EXPR, lhs, 0)),
3136 assemble_external (objc_assign_strong_cast_decl);
3137 return build_function_call (objc_assign_strong_cast_decl, func_params);
3141 objc_is_gcable_p (tree expr)
3143 return (TREE_CODE (expr) == COMPONENT_REF
3144 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3145 : TREE_CODE (expr) == ARRAY_REF
3146 ? (objc_is_gcable_p (TREE_TYPE (expr))
3147 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3148 : TREE_CODE (expr) == ARRAY_TYPE
3149 ? objc_is_gcable_p (TREE_TYPE (expr))
3151 ? objc_is_gcable_type (expr, 1)
3152 : (objc_is_gcable_p (TREE_TYPE (expr))
3154 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3158 objc_is_ivar_reference_p (tree expr)
3160 return (TREE_CODE (expr) == ARRAY_REF
3161 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3162 : TREE_CODE (expr) == COMPONENT_REF
3163 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3168 objc_is_global_reference_p (tree expr)
3170 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3171 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3173 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3178 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3180 tree result = NULL_TREE, outer;
3181 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3183 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3184 will have been transformed to the form '*(type *)&expr'. */
3185 if (TREE_CODE (lhs) == INDIRECT_REF)
3187 outer = TREE_OPERAND (lhs, 0);
3189 while (!strong_cast_p
3190 && (TREE_CODE (outer) == CONVERT_EXPR
3191 || TREE_CODE (outer) == NOP_EXPR
3192 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3194 tree lhstype = TREE_TYPE (outer);
3196 /* Descend down the cast chain, and record the first objc_gc
3198 if (POINTER_TYPE_P (lhstype))
3201 = lookup_attribute ("objc_gc",
3202 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3208 outer = TREE_OPERAND (outer, 0);
3212 /* If we have a __strong cast, it trumps all else. */
3215 if (modifycode != NOP_EXPR)
3216 goto invalid_pointer_arithmetic;
3218 if (warn_assign_intercept)
3219 warning (0, "strong-cast assignment has been intercepted");
3221 result = objc_build_strong_cast_assignment (lhs, rhs);
3226 /* the lhs must be of a suitable type, regardless of its underlying
3228 if (!objc_is_gcable_p (lhs))
3234 && (TREE_CODE (outer) == COMPONENT_REF
3235 || TREE_CODE (outer) == ARRAY_REF))
3236 outer = TREE_OPERAND (outer, 0);
3238 if (TREE_CODE (outer) == INDIRECT_REF)
3240 outer = TREE_OPERAND (outer, 0);
3244 outer_gc_p = objc_is_gcable_p (outer);
3246 /* Handle ivar assignments. */
3247 if (objc_is_ivar_reference_p (lhs))
3249 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3250 doesn't cut it here), the best we can do here is suggest a cast. */
3251 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3253 /* We may still be able to use the global write barrier... */
3254 if (!indirect_p && objc_is_global_reference_p (outer))
3255 goto global_reference;
3258 if (modifycode == NOP_EXPR)
3260 if (warn_assign_intercept)
3261 warning (0, "strong-cast may possibly be needed");
3267 if (modifycode != NOP_EXPR)
3268 goto invalid_pointer_arithmetic;
3270 if (warn_assign_intercept)
3271 warning (0, "instance variable assignment has been intercepted");
3273 result = objc_build_ivar_assignment (outer, lhs, rhs);
3278 /* Likewise, intercept assignment to global/static variables if their type is
3280 if (objc_is_global_reference_p (outer))
3286 if (modifycode != NOP_EXPR)
3288 invalid_pointer_arithmetic:
3290 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3295 if (warn_assign_intercept)
3296 warning (0, "global/static variable assignment has been intercepted");
3298 result = objc_build_global_assignment (lhs, rhs);
3301 /* In all other cases, fall back to the normal mechanism. */
3306 struct interface_tuple GTY(())
3312 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3315 hash_interface (const void *p)
3317 const struct interface_tuple *d = p;
3318 return htab_hash_pointer (d->id);
3322 eq_interface (const void *p1, const void *p2)
3324 const struct interface_tuple *d = p1;
3329 lookup_interface (tree ident)
3332 if (ident && TREE_CODE (ident) == TYPE_DECL)
3333 ident = DECL_NAME (ident);
3336 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3340 struct interface_tuple **slot;
3345 slot = (struct interface_tuple **)
3346 htab_find_slot_with_hash (interface_htab, ident,
3347 htab_hash_pointer (ident),
3350 i = (*slot)->class_name;
3356 /* Implement @defs (<classname>) within struct bodies. */
3359 objc_get_class_ivars (tree class_name)
3361 tree interface = lookup_interface (class_name);
3364 return get_class_ivars (interface, true);
3366 error ("cannot find interface declaration for %qs",
3367 IDENTIFIER_POINTER (class_name));
3369 return error_mark_node;
3372 /* Used by: build_private_template, continue_class,
3373 and for @defs constructs. */
3376 get_class_ivars (tree interface, bool inherited)
3378 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3380 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3381 by the current class (i.e., they do not include super-class ivars).
3382 However, the CLASS_IVARS list will be side-effected by a call to
3383 finish_struct(), which will fill in field offsets. */
3384 if (!CLASS_IVARS (interface))
3385 CLASS_IVARS (interface) = ivar_chain;
3390 while (CLASS_SUPER_NAME (interface))
3392 /* Prepend super-class ivars. */
3393 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3394 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3402 objc_create_temporary_var (tree type)
3406 decl = build_decl (VAR_DECL, NULL_TREE, type);
3407 TREE_USED (decl) = 1;
3408 DECL_ARTIFICIAL (decl) = 1;
3409 DECL_IGNORED_P (decl) = 1;
3410 DECL_CONTEXT (decl) = current_function_decl;
3415 /* Exception handling constructs. We begin by having the parser do most
3416 of the work and passing us blocks. What we do next depends on whether
3417 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3418 We abstract all of this in a handful of appropriately named routines. */
3420 /* Stack of open try blocks. */
3422 struct objc_try_context
3424 struct objc_try_context *outer;
3426 /* Statements (or statement lists) as processed by the parser. */
3430 /* Some file position locations. */
3431 location_t try_locus;
3432 location_t end_try_locus;
3433 location_t end_catch_locus;
3434 location_t finally_locus;
3435 location_t end_finally_locus;
3437 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3438 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3441 /* The CATCH_EXPR of an open @catch clause. */
3444 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3450 static struct objc_try_context *cur_try_context;
3452 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3453 that represents TYPE. For Objective-C, this is just the class name. */
3454 /* ??? Isn't there a class object or some such? Is it easy to get? */
3458 objc_eh_runtime_type (tree type)
3460 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3464 /* Initialize exception handling. */
3467 objc_init_exceptions (void)
3469 static bool done = false;
3474 if (flag_objc_sjlj_exceptions)
3476 /* On Darwin, ObjC exceptions require a sufficiently recent
3477 version of the runtime, so the user must ask for them explicitly. */
3478 if (!flag_objc_exceptions)
3479 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3480 "exception syntax");
3485 c_eh_initialized_p = true;
3486 eh_personality_libfunc
3487 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3488 ? "__gnu_objc_personality_sj0"
3489 : "__gnu_objc_personality_v0");
3490 default_init_unwind_resume_libfunc ();
3491 using_eh_for_cleanups ();
3492 lang_eh_runtime_type = objc_eh_runtime_type;
3497 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3498 we'll arrange for it to be initialized (and associated with a binding)
3502 objc_build_exc_ptr (void)
3504 if (flag_objc_sjlj_exceptions)
3506 tree var = cur_try_context->caught_decl;
3509 var = objc_create_temporary_var (objc_object_type);
3510 cur_try_context->caught_decl = var;
3515 return build (EXC_PTR_EXPR, objc_object_type);
3518 /* Build "objc_exception_try_exit(&_stack)". */
3521 next_sjlj_build_try_exit (void)
3524 t = build_fold_addr_expr (cur_try_context->stack_decl);
3525 t = tree_cons (NULL, t, NULL);
3526 t = build_function_call (objc_exception_try_exit_decl, t);
3531 objc_exception_try_enter (&_stack);
3532 if (_setjmp(&_stack.buf))
3536 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3537 empty, ready for the caller to fill them in. */
3540 next_sjlj_build_enter_and_setjmp (void)
3542 tree t, enter, sj, cond;
3544 t = build_fold_addr_expr (cur_try_context->stack_decl);
3545 t = tree_cons (NULL, t, NULL);
3546 enter = build_function_call (objc_exception_try_enter_decl, t);
3548 t = objc_build_component_ref (cur_try_context->stack_decl,
3549 get_identifier ("buf"));
3550 t = build_fold_addr_expr (t);
3552 /* Convert _setjmp argument to type that is expected. */
3553 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3554 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3556 t = convert (ptr_type_node, t);
3558 t = convert (ptr_type_node, t);
3560 t = tree_cons (NULL, t, NULL);
3561 sj = build_function_call (objc_setjmp_decl, t);
3563 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3564 cond = c_common_truthvalue_conversion (cond);
3566 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3570 DECL = objc_exception_extract(&_stack);
3574 next_sjlj_build_exc_extract (tree decl)
3578 t = build_fold_addr_expr (cur_try_context->stack_decl);
3579 t = tree_cons (NULL, t, NULL);
3580 t = build_function_call (objc_exception_extract_decl, t);
3581 t = convert (TREE_TYPE (decl), t);
3582 t = build (MODIFY_EXPR, void_type_node, decl, t);
3588 if (objc_exception_match(obj_get_class(TYPE), _caught)
3595 objc_exception_try_exit(&_stack);
3597 from the sequence of CATCH_EXPRs in the current try context. */
3600 next_sjlj_build_catch_list (void)