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 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, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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"
59 #include "langhooks.h"
70 #include "diagnostic.h"
72 #include "tree-iterator.h"
76 #define OBJC_VOID_AT_END void_list_node
78 /* When building Objective-C++, we are not linking against the C front-end
79 and so need to replicate the C tree-construction functions in some way. */
81 #define OBJCP_REMAP_FUNCTIONS
82 #include "objcp-decl.h"
85 /* This is the default way of generating a method name. */
86 /* I am not sure it is really correct.
87 Perhaps there's a danger that it will make name conflicts
88 if method names contain underscores. -- rms. */
89 #ifndef OBJC_GEN_METHOD_LABEL
90 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
93 sprintf ((BUF), "_%s_%s_%s_%s", \
94 ((IS_INST) ? "i" : "c"), \
96 ((CAT_NAME)? (CAT_NAME) : ""), \
98 for (temp = (BUF); *temp; temp++) \
99 if (*temp == ':') *temp = '_'; \
103 /* These need specifying. */
104 #ifndef OBJC_FORWARDING_STACK_OFFSET
105 #define OBJC_FORWARDING_STACK_OFFSET 0
108 #ifndef OBJC_FORWARDING_MIN_OFFSET
109 #define OBJC_FORWARDING_MIN_OFFSET 0
112 /* Set up for use of obstacks. */
116 /* This obstack is used to accumulate the encoding of a data type. */
117 static struct obstack util_obstack;
119 /* This points to the beginning of obstack contents, so we can free
120 the whole contents. */
123 /* The version identifies which language generation and runtime
124 the module (file) was compiled for, and is recorded in the
125 module descriptor. */
127 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
128 #define PROTOCOL_VERSION 2
130 /* (Decide if these can ever be validly changed.) */
131 #define OBJC_ENCODE_INLINE_DEFS 0
132 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
134 /*** Private Interface (procedures) ***/
136 /* Used by compile_file. */
138 static void init_objc (void);
139 static void finish_objc (void);
141 /* Code generation. */
143 static void synth_module_prologue (void);
144 static tree objc_build_constructor (tree, tree);
145 static void build_module_descriptor (void);
146 static void build_module_initializer_routine (void);
147 static tree init_module_descriptor (tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static void generate_strings (void);
150 static tree get_proto_encoding (tree);
151 static void build_selector_translation_table (void);
152 static tree lookup_interface (tree);
153 static tree objc_add_static_instance (tree, tree);
155 static tree start_class (enum tree_code, tree, tree, tree);
156 static tree continue_class (tree);
157 static void finish_class (tree);
158 static void start_method_def (tree);
160 static void objc_start_function (tree, tree, tree, tree);
162 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
164 static tree start_protocol (enum tree_code, tree, tree);
165 static tree build_method_decl (enum tree_code, tree, tree, tree);
166 static tree objc_add_method (tree, tree, int);
167 static tree add_instance_variable (tree, int, tree);
168 static tree build_ivar_reference (tree);
169 static tree is_ivar (tree, tree);
170 static int is_private (tree);
171 static tree get_super_receiver (void);
173 static void build_objc_exception_stuff (void);
174 static void build_next_objc_exception_stuff (void);
176 static tree build_ivar_template (void);
177 static tree build_method_template (void);
178 static tree build_private_template (tree);
179 static void build_class_template (void);
180 static void build_selector_template (void);
181 static void build_category_template (void);
182 static tree lookup_method_in_hash_lists (tree, int);
183 static void build_super_template (void);
184 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
185 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
186 static void synth_forward_declarations (void);
187 static int ivar_list_length (tree);
188 static tree get_class_ivars (tree);
189 static void generate_ivar_lists (void);
190 static void generate_dispatch_tables (void);
191 static void generate_shared_structures (void);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
195 static tree build_keyword_selector (tree);
196 static const char *synth_id_with_class_suffix (const char *, tree);
198 static void generate_static_references (void);
199 static int check_methods_accessible (tree, tree, int);
200 static void encode_aggregate_within (tree, int, int, int, int);
201 static const char *objc_demangle (const char *);
203 /* Hash tables to manage the global pool of method prototypes. */
205 hash *nst_method_hash_list = 0;
206 hash *cls_method_hash_list = 0;
208 static size_t hash_func (tree);
209 static void hash_init (void);
210 static void hash_enter (hash *, tree);
211 static hash hash_lookup (hash *, tree);
212 static void hash_add_attr (hash, tree);
213 static tree lookup_method (tree, tree);
214 static tree lookup_method_static (tree, tree, int);
215 static void add_method_to_hash_list (hash *, tree);
216 static tree add_class (tree);
217 static void add_category (tree, tree);
218 static inline tree lookup_category (tree, tree);
222 class_names, /* class, category, protocol, module names */
223 meth_var_names, /* method and variable names */
224 meth_var_types /* method and variable type descriptors */
227 static tree add_objc_string (tree, enum string_section);
228 static tree get_objc_string_decl (tree, enum string_section);
229 static tree build_objc_string_decl (enum string_section);
230 static tree build_selector_reference_decl (void);
231 static void build_selector_table_decl (void);
233 /* Protocol additions. */
235 static tree add_protocol (tree);
236 static tree lookup_protocol (tree);
237 static void check_protocol_recursively (tree, tree);
238 static tree lookup_and_install_protocols (tree);
242 static void encode_type_qualifiers (tree);
243 static void encode_pointer (tree, int, int);
244 static void encode_array (tree, int, int);
245 static void encode_aggregate (tree, int, int);
246 static void encode_next_bitfield (int);
247 static void encode_gnu_bitfield (int, tree, int);
248 static void encode_type (tree, int, int);
249 static void encode_field_decl (tree, int, int);
252 static void really_start_method (tree, tree);
254 static void really_start_method (tree, struct c_arg_info *);
256 static int objc_types_are_equivalent (tree, tree);
257 static int comp_proto_with_proto (tree, tree);
258 static tree get_arg_type_list (tree, int, int);
259 static void objc_push_parm (tree);
261 static tree objc_get_parm_info (int);
263 static struct c_arg_info *objc_get_parm_info (int);
265 static void synth_self_and_ucmd_args (void);
267 /* Utilities for debugging and error diagnostics. */
269 static void warn_with_method (const char *, int, tree);
270 static void error_with_ivar (const char *, tree);
271 static char *gen_type_name (tree);
272 static char *gen_type_name_0 (tree);
273 static char *gen_method_decl (tree);
274 static char *gen_declaration (tree);
275 static void dump_interface (FILE *, tree);
277 /* Everything else. */
279 static tree lookup_method_in_protocol_list (tree, tree, int);
280 static tree lookup_protocol_in_reflist (tree, tree);
281 static tree start_var_decl (tree, const char *);
282 static void finish_var_decl (tree, tree);
283 static tree create_field_decl (tree, const char *);
284 static tree setup_string_decl (void);
285 static int check_string_class_template (void);
286 static tree my_build_string (int, const char *);
287 static void build_objc_symtab_template (void);
288 static tree init_def_list (tree);
289 static tree init_objc_symtab (tree);
290 static tree build_metadata_decl (const char *, tree);
291 static void forward_declare_categories (void);
292 static void generate_objc_symtab_decl (void);
293 static tree build_selector (tree);
294 static tree build_typed_selector_reference (tree, tree);
295 static tree build_selector_reference (tree);
296 static tree build_class_reference_decl (void);
297 static void add_class_reference (tree);
298 static void build_protocol_template (void);
299 static tree build_descriptor_table_initializer (tree, tree);
300 static tree build_method_prototype_list_template (tree, int);
301 static tree build_method_prototype_template (void);
302 static tree objc_method_parm_type (tree);
303 static int objc_encoded_type_size (tree);
304 static tree encode_method_prototype (tree);
305 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
306 static void generate_method_descriptors (tree);
307 static void generate_protocol_references (tree);
308 static void generate_protocols (void);
309 static void check_ivars (tree, tree);
310 static tree build_ivar_list_template (tree, int);
311 static tree build_method_list_template (tree, int);
312 static tree build_ivar_list_initializer (tree, tree);
313 static tree generate_ivars_list (tree, const char *, int, tree);
314 static tree build_dispatch_table_initializer (tree, tree);
315 static tree generate_dispatch_table (tree, const char *, int, tree);
316 static tree build_shared_structure_initializer (tree, tree, tree, tree,
317 tree, int, tree, tree, tree);
318 static void generate_category (tree);
319 static tree adjust_type_for_id_default (tree);
320 static tree check_duplicates (hash, int, int);
321 static tree receiver_is_class_object (tree, int, int);
322 static int check_methods (tree, tree, int);
323 static int conforms_to_protocol (tree, tree);
324 static void check_protocol (tree, const char *, const char *);
325 static void check_protocols (tree, const char *, const char *);
326 static void generate_classref_translation_entry (tree);
327 static void handle_class_ref (tree);
328 static void generate_struct_by_value_array (void)
330 static void mark_referenced_methods (void);
331 static void generate_objc_image_info (void);
333 /*** Private Interface (data) ***/
335 /* Reserved tag definitions. */
337 #define OBJECT_TYPEDEF_NAME "id"
338 #define CLASS_TYPEDEF_NAME "Class"
340 #define TAG_OBJECT "objc_object"
341 #define TAG_CLASS "objc_class"
342 #define TAG_SUPER "objc_super"
343 #define TAG_SELECTOR "objc_selector"
345 #define UTAG_CLASS "_objc_class"
346 #define UTAG_IVAR "_objc_ivar"
347 #define UTAG_IVAR_LIST "_objc_ivar_list"
348 #define UTAG_METHOD "_objc_method"
349 #define UTAG_METHOD_LIST "_objc_method_list"
350 #define UTAG_CATEGORY "_objc_category"
351 #define UTAG_MODULE "_objc_module"
352 #define UTAG_SYMTAB "_objc_symtab"
353 #define UTAG_SUPER "_objc_super"
354 #define UTAG_SELECTOR "_objc_selector"
356 #define UTAG_PROTOCOL "_objc_protocol"
357 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
358 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
360 /* Note that the string object global name is only needed for the
362 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
364 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
366 static const char *TAG_GETCLASS;
367 static const char *TAG_GETMETACLASS;
368 static const char *TAG_MSGSEND;
369 static const char *TAG_MSGSENDSUPER;
370 /* The NeXT Objective-C messenger may have two extra entry points, for use
371 when returning a structure. */
372 static const char *TAG_MSGSEND_STRET;
373 static const char *TAG_MSGSENDSUPER_STRET;
374 static const char *default_constant_string_class_name;
376 /* Runtime metadata flags. */
377 #define CLS_FACTORY 0x0001L
378 #define CLS_META 0x0002L
380 #define OBJC_MODIFIER_STATIC 0x00000001
381 #define OBJC_MODIFIER_FINAL 0x00000002
382 #define OBJC_MODIFIER_PUBLIC 0x00000004
383 #define OBJC_MODIFIER_PRIVATE 0x00000008
384 #define OBJC_MODIFIER_PROTECTED 0x00000010
385 #define OBJC_MODIFIER_NATIVE 0x00000020
386 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
387 #define OBJC_MODIFIER_ABSTRACT 0x00000080
388 #define OBJC_MODIFIER_VOLATILE 0x00000100
389 #define OBJC_MODIFIER_TRANSIENT 0x00000200
390 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
392 /* NeXT-specific tags. */
394 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
395 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
396 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
397 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
398 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
399 #define TAG_EXCEPTIONMATCH "objc_exception_match"
400 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
401 #define TAG_SYNCENTER "objc_sync_enter"
402 #define TAG_SYNCEXIT "objc_sync_exit"
403 #define TAG_SETJMP "_setjmp"
404 #define UTAG_EXCDATA "_objc_exception_data"
406 /* GNU-specific tags. */
408 #define TAG_EXECCLASS "__objc_exec_class"
409 #define TAG_GNUINIT "__objc_gnu_init"
411 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
412 tree objc_global_trees[OCTI_MAX];
414 static void handle_impent (struct imp_entry *);
416 struct imp_entry *imp_list = 0;
417 int imp_count = 0; /* `@implementation' */
418 int cat_count = 0; /* `@category' */
420 enum tree_code objc_inherit_code;
421 int objc_public_flag;
423 /* Use to generate method labels. */
424 static int method_slot = 0;
428 static char *errbuf; /* Buffer for error diagnostics */
430 /* Data imported from tree.c. */
432 extern enum debug_info_type write_symbols;
434 /* Data imported from toplev.c. */
436 extern const char *dump_base_name;
438 static int flag_typed_selectors;
440 /* Store all constructed constant strings in a hash table so that
441 they get uniqued properly. */
443 struct string_descriptor GTY(())
445 /* The literal argument . */
448 /* The resulting constant string. */
452 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
454 static hashval_t string_hash (const void *);
455 static int string_eq (const void *, const void *);
457 FILE *gen_declaration_file;
459 /* Tells "encode_pointer/encode_aggregate" whether we are generating
460 type descriptors for instance variables (as opposed to methods).
461 Type descriptors for instance variables contain more information
462 than methods (for static typing and embedded structures). */
464 static int generating_instance_variables = 0;
466 /* Some platforms pass small structures through registers versus
467 through an invisible pointer. Determine at what size structure is
468 the transition point between the two possibilities. */
471 generate_struct_by_value_array (void)
474 tree field_decl, field_decl_chain;
476 int aggregate_in_mem[32];
479 /* Presumably no platform passes 32 byte structures in a register. */
480 for (i = 1; i < 32; i++)
484 /* Create an unnamed struct that has `i' character components */
485 type = start_struct (RECORD_TYPE, NULL_TREE);
487 strcpy (buffer, "c1");
488 field_decl = create_field_decl (char_type_node,
490 field_decl_chain = field_decl;
492 for (j = 1; j < i; j++)
494 sprintf (buffer, "c%d", j + 1);
495 field_decl = create_field_decl (char_type_node,
497 chainon (field_decl_chain, field_decl);
499 finish_struct (type, field_decl_chain, NULL_TREE);
501 aggregate_in_mem[i] = aggregate_value_p (type, 0);
502 if (!aggregate_in_mem[i])
506 /* We found some structures that are returned in registers instead of memory
507 so output the necessary data. */
510 for (i = 31; i >= 0; i--)
511 if (!aggregate_in_mem[i])
513 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
515 /* The first member of the structure is always 0 because we don't handle
516 structures with 0 members */
517 printf ("static int struct_forward_array[] = {\n 0");
519 for (j = 1; j <= i; j++)
520 printf (", %d", aggregate_in_mem[j]);
531 if (cxx_init () == false)
533 if (c_objc_common_init () == false)
537 /* Force the line number back to 0; check_newline will have
538 raised it to 1, which will make the builtin functions appear
539 not to be built in. */
542 /* If gen_declaration desired, open the output file. */
543 if (flag_gen_declaration)
545 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
546 gen_declaration_file = fopen (dumpname, "w");
547 if (gen_declaration_file == 0)
548 fatal_error ("can't open %s: %m", dumpname);
552 if (flag_next_runtime)
554 TAG_GETCLASS = "objc_getClass";
555 TAG_GETMETACLASS = "objc_getMetaClass";
556 TAG_MSGSEND = "objc_msgSend";
557 TAG_MSGSENDSUPER = "objc_msgSendSuper";
558 TAG_MSGSEND_STRET = "objc_msgSend_stret";
559 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
560 default_constant_string_class_name = "NSConstantString";
564 TAG_GETCLASS = "objc_get_class";
565 TAG_GETMETACLASS = "objc_get_meta_class";
566 TAG_MSGSEND = "objc_msg_lookup";
567 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
568 /* GNU runtime does not provide special functions to support
569 structure-returning methods. */
570 default_constant_string_class_name = "NXConstantString";
571 flag_typed_selectors = 1;
576 if (print_struct_values)
577 generate_struct_by_value_array ();
583 objc_finish_file (void)
585 mark_referenced_methods ();
588 /* We need to instantiate templates _before_ we emit ObjC metadata;
589 if we do not, some metadata (such as selectors) may go missing. */
590 instantiate_pending_templates (0);
593 /* Finalize Objective-C runtime data. No need to generate tables
594 and code if only checking syntax. */
595 if (!flag_syntax_only)
598 if (gen_declaration_file)
599 fclose (gen_declaration_file);
606 /* Return the first occurrence of a method declaration corresponding
607 to sel_name in rproto_list. Search rproto_list recursively.
608 If is_class is 0, search for instance methods, otherwise for class
611 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
617 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
619 p = TREE_VALUE (rproto);
621 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
623 if ((fnd = lookup_method (is_class
624 ? PROTOCOL_CLS_METHODS (p)
625 : PROTOCOL_NST_METHODS (p), sel_name)))
627 else if (PROTOCOL_LIST (p))
628 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
633 ; /* An identifier...if we could not find a protocol. */
644 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
648 /* Make sure the protocol is supported by the object on the rhs. */
649 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
652 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
654 p = TREE_VALUE (rproto);
656 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
661 else if (PROTOCOL_LIST (p))
662 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
671 ; /* An identifier...if we could not find a protocol. */
678 objc_start_class_interface (tree class, tree super_class, tree protos)
680 objc_interface_context
682 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
683 objc_public_flag = 0;
687 objc_start_category_interface (tree class, tree categ, tree protos)
689 objc_interface_context
690 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
692 = continue_class (objc_interface_context);
696 objc_start_protocol (tree name, tree protos)
698 objc_interface_context
699 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
703 objc_continue_interface (void)
706 = continue_class (objc_interface_context);
710 objc_finish_interface (void)
712 finish_class (objc_interface_context);
713 objc_interface_context = NULL_TREE;
717 objc_start_class_implementation (tree class, tree super_class)
719 objc_implementation_context
721 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
722 objc_public_flag = 0;
726 objc_start_category_implementation (tree class, tree categ)
728 objc_implementation_context
729 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
731 = continue_class (objc_implementation_context);
735 objc_continue_implementation (void)
738 = continue_class (objc_implementation_context);
742 objc_finish_implementation (void)
744 if (objc_implementation_context)
746 finish_class (objc_implementation_context);
747 objc_ivar_chain = NULL_TREE;
748 objc_implementation_context = NULL_TREE;
751 warning ("`@end' must appear in an @implementation context");
755 objc_set_visibility (int visibility)
757 objc_public_flag = visibility;
761 objc_set_method_type (enum tree_code type)
763 objc_inherit_code = (type == PLUS_EXPR
765 : INSTANCE_METHOD_DECL);
769 objc_build_method_signature (tree rettype, tree selector, tree optparms)
771 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
775 objc_add_method_declaration (tree decl)
777 if (!objc_interface_context)
778 fatal_error ("method declaration not in @interface context");
780 objc_add_method (objc_interface_context,
782 objc_inherit_code == CLASS_METHOD_DECL);
786 objc_start_method_definition (tree decl)
788 if (!objc_implementation_context)
789 fatal_error ("method definition not in @implementation context");
791 objc_add_method (objc_implementation_context,
793 objc_inherit_code == CLASS_METHOD_DECL);
794 start_method_def (decl);
798 objc_add_instance_variable (tree decl)
800 (void) add_instance_variable (objc_ivar_context,
805 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
809 objc_is_reserved_word (tree ident)
811 unsigned char code = C_RID_CODE (ident);
813 return (OBJC_IS_AT_KEYWORD (code)
815 || code == RID_CLASS || code == RID_PUBLIC
816 || code == RID_PROTECTED || code == RID_PRIVATE
817 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
822 /* Return true if TYPE is 'id'. */
825 objc_is_object_id (tree type)
827 return OBJC_TYPE_NAME (type) == objc_object_id;
831 objc_is_class_id (tree type)
833 return OBJC_TYPE_NAME (type) == objc_class_id;
836 /* Return 1 if LHS and RHS are compatible types for assignment or
837 various other operations. Return 0 if they are incompatible, and
838 return -1 if we choose to not decide (because the types are really
839 just C types, not ObjC specific ones). When the operation is
840 REFLEXIVE (typically comparisons), check for compatibility in
841 either direction; when it's not (typically assignments), don't.
843 This function is called in two cases: when both lhs and rhs are
844 pointers to records (in which case we check protocols too), and
845 when both lhs and rhs are records (in which case we check class
848 Warnings about classes/protocols not implementing a protocol are
849 emitted here (multiple of those warnings might be emitted for a
850 single line!); generic warnings about incompatible assignments and
851 lacks of casts in comparisons are/must be emitted by the caller if
856 objc_comptypes (tree lhs, tree rhs, int reflexive)
858 /* New clause for protocols. */
860 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
861 manage the ObjC ones, and leave the rest to the C code. */
862 if (TREE_CODE (lhs) == POINTER_TYPE
863 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
864 && TREE_CODE (rhs) == POINTER_TYPE
865 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
867 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs);
868 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs);
872 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
873 tree rproto, rproto_list;
876 /* <Protocol> = <Protocol> */
879 rproto_list = TYPE_PROTOCOL_LIST (rhs);
883 /* An assignment between objects of type 'id
884 <Protocol>'; make sure the protocol on the lhs is
885 supported by the object on the rhs. */
886 for (lproto = lproto_list; lproto;
887 lproto = TREE_CHAIN (lproto))
889 p = TREE_VALUE (lproto);
890 rproto = lookup_protocol_in_reflist (rproto_list, p);
894 ("object does not conform to the `%s' protocol",
895 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
901 /* Obscure case - a comparison between two objects
902 of type 'id <Protocol>'. Check that either the
903 protocol on the lhs is supported by the object on
904 the rhs, or viceversa. */
906 /* Check if the protocol on the lhs is supported by the
907 object on the rhs. */
908 for (lproto = lproto_list; lproto;
909 lproto = TREE_CHAIN (lproto))
911 p = TREE_VALUE (lproto);
912 rproto = lookup_protocol_in_reflist (rproto_list, p);
916 /* Check failed - check if the protocol on the rhs
917 is supported by the object on the lhs. */
918 for (rproto = rproto_list; rproto;
919 rproto = TREE_CHAIN (rproto))
921 p = TREE_VALUE (rproto);
922 lproto = lookup_protocol_in_reflist (lproto_list,
927 /* This check failed too: incompatible */
937 /* <Protocol> = <class> * */
938 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
940 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
943 /* Make sure the protocol is supported by the object on
945 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
947 p = TREE_VALUE (lproto);
949 rinter = lookup_interface (rname);
951 while (rinter && !rproto)
955 rproto_list = CLASS_PROTOCOL_LIST (rinter);
956 rproto = lookup_protocol_in_reflist (rproto_list, p);
957 /* If the underlying ObjC class does not have
958 the protocol we're looking for, check for "one-off"
959 protocols (e.g., `NSObject<MyProt> *foo;') attached
963 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
964 rproto = lookup_protocol_in_reflist (rproto_list, p);
967 /* Check for protocols adopted by categories. */
968 cat = CLASS_CATEGORY_LIST (rinter);
969 while (cat && !rproto)
971 rproto_list = CLASS_PROTOCOL_LIST (cat);
972 rproto = lookup_protocol_in_reflist (rproto_list, p);
973 cat = CLASS_CATEGORY_LIST (cat);
976 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
980 warning ("class `%s' does not implement the `%s' protocol",
981 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
982 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
986 /* <Protocol> = id */
987 else if (objc_is_object_id (TREE_TYPE (rhs)))
991 /* <Protocol> = Class */
992 else if (objc_is_class_id (TREE_TYPE (rhs)))
996 /* <Protocol> = ?? : let comptypes decide. */
999 else if (rhs_is_proto)
1001 /* <class> * = <Protocol> */
1002 if (TYPED_OBJECT (TREE_TYPE (lhs)))
1006 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
1008 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
1010 /* Make sure the protocol is supported by the object on
1012 for (rproto = rproto_list; rproto;
1013 rproto = TREE_CHAIN (rproto))
1015 tree p = TREE_VALUE (rproto);
1017 rinter = lookup_interface (rname);
1019 while (rinter && !lproto)
1023 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1024 lproto = lookup_protocol_in_reflist (lproto_list, p);
1025 /* If the underlying ObjC class does not
1026 have the protocol we're looking for,
1027 check for "one-off" protocols (e.g.,
1028 `NSObject<MyProt> *foo;') attached to the
1032 lproto_list = TYPE_PROTOCOL_LIST
1034 lproto = lookup_protocol_in_reflist
1038 /* Check for protocols adopted by categories. */
1039 cat = CLASS_CATEGORY_LIST (rinter);
1040 while (cat && !lproto)
1042 lproto_list = CLASS_PROTOCOL_LIST (cat);
1043 lproto = lookup_protocol_in_reflist (lproto_list,
1045 cat = CLASS_CATEGORY_LIST (cat);
1048 rinter = lookup_interface (CLASS_SUPER_NAME
1053 warning ("class `%s' does not implement the `%s' protocol",
1054 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1056 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1063 /* id = <Protocol> */
1064 else if (objc_is_object_id (TREE_TYPE (lhs)))
1068 /* Class = <Protocol> */
1069 else if (objc_is_class_id (TREE_TYPE (lhs)))
1073 /* ??? = <Protocol> : let comptypes decide */
1081 /* Attention: we shouldn't defer to comptypes here. One bad
1082 side effect would be that we might loose the REFLEXIVE
1085 lhs = TREE_TYPE (lhs);
1086 rhs = TREE_TYPE (rhs);
1090 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1092 /* Nothing to do with ObjC - let immediately comptypes take
1093 responsibility for checking. */
1097 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1099 'Object *o = [[Object alloc] init]; falls
1100 in the case <class> * = `id'.
1102 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1103 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1106 /* `id' = `Class', `Class' = `id' */
1108 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1109 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1112 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1113 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1114 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1117 /* `<class> *' = `<class> *' */
1119 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1121 tree lname = OBJC_TYPE_NAME (lhs);
1122 tree rname = OBJC_TYPE_NAME (rhs);
1128 /* If the left hand side is a super class of the right hand side,
1130 for (inter = lookup_interface (rname); inter;
1131 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1132 if (lname == CLASS_SUPER_NAME (inter))
1135 /* Allow the reverse when reflexive. */
1137 for (inter = lookup_interface (lname); inter;
1138 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1139 if (rname == CLASS_SUPER_NAME (inter))
1145 /* Not an ObjC type - let comptypes do the check. */
1149 /* Called from finish_decl. */
1152 objc_check_decl (tree decl)
1154 tree type = TREE_TYPE (decl);
1156 if (TREE_CODE (type) != RECORD_TYPE)
1158 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1159 error ("statically allocated instance of Objective-C class `%s'",
1160 IDENTIFIER_POINTER (type));
1163 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1164 either name an Objective-C class, or refer to the special 'id' or 'Class'
1165 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1168 objc_get_protocol_qualified_type (tree interface, tree protocols)
1173 type = objc_object_type;
1174 else if (!(type = objc_is_id (interface)))
1176 type = objc_is_class_name (interface);
1179 type = xref_tag (RECORD_TYPE, type);
1186 type = build_variant_type_copy (type);
1187 /* Look up protocols and install in lang specific list. Note
1188 that the protocol list can have a different lifetime than T! */
1189 SET_TYPE_PROTOCOL_LIST (type, lookup_and_install_protocols (protocols));
1191 /* Establish the ObjC-ness of this record. */
1192 if (TREE_CODE (type) == RECORD_TYPE)
1193 TREE_STATIC_TEMPLATE (type) = 1;
1199 /* Check for circular dependencies in protocols. The arguments are
1200 PROTO, the protocol to check, and LIST, a list of protocol it
1204 check_protocol_recursively (tree proto, tree list)
1208 for (p = list; p; p = TREE_CHAIN (p))
1210 tree pp = TREE_VALUE (p);
1212 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1213 pp = lookup_protocol (pp);
1216 fatal_error ("protocol `%s' has circular dependency",
1217 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1219 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1223 /* Look up PROTOCOLS, and return a list of those that are found.
1224 If none are found, return NULL. */
1227 lookup_and_install_protocols (tree protocols)
1230 tree return_value = NULL_TREE;
1232 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1234 tree ident = TREE_VALUE (proto);
1235 tree p = lookup_protocol (ident);
1238 error ("cannot find protocol declaration for `%s'",
1239 IDENTIFIER_POINTER (ident));
1241 return_value = chainon (return_value,
1242 build_tree_list (NULL_TREE, p));
1245 return return_value;
1248 /* Create a declaration for field NAME of a given TYPE. */
1251 create_field_decl (tree type, const char *name)
1253 return build_decl (FIELD_DECL, get_identifier (name), type);
1256 /* Create a global, static declaration for variable NAME of a given TYPE. The
1257 finish_var_decl() routine will need to be called on it afterwards. */
1260 start_var_decl (tree type, const char *name)
1262 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1264 TREE_STATIC (var) = 1;
1265 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1266 DECL_IGNORED_P (var) = 1;
1267 DECL_ARTIFICIAL (var) = 1;
1268 DECL_CONTEXT (var) = NULL_TREE;
1270 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1276 /* Finish off the variable declaration created by start_var_decl(). */
1279 finish_var_decl (tree var, tree initializer)
1281 finish_decl (var, initializer, NULL_TREE);
1282 /* Ensure that the variable actually gets output. */
1283 mark_decl_referenced (var);
1284 /* Mark the decl to avoid "defined but not used" warning. */
1285 TREE_USED (var) = 1;
1288 /* Find the decl for the constant string class refernce. This is only
1289 used for the NeXT runtime. */
1292 setup_string_decl (void)
1297 /* %s in format will provide room for terminating null */
1298 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1299 + strlen (constant_string_class_name);
1300 name = xmalloc (length);
1301 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1302 constant_string_class_name);
1303 constant_string_global_id = get_identifier (name);
1304 string_class_decl = lookup_name (constant_string_global_id);
1306 return string_class_decl;
1309 /* Purpose: "play" parser, creating/installing representations
1310 of the declarations that are required by Objective-C.
1314 type_spec--------->sc_spec
1315 (tree_list) (tree_list)
1318 identifier_node identifier_node */
1321 synth_module_prologue (void)
1324 enum debug_info_type save_write_symbols = write_symbols;
1325 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1327 /* Suppress outputting debug symbols, because
1328 dbxout_init hasn'r been called yet. */
1329 write_symbols = NO_DEBUG;
1330 debug_hooks = &do_nothing_debug_hooks;
1333 push_lang_context (lang_name_c); /* extern "C" */
1336 /* The following are also defined in <objc/objc.h> and friends. */
1338 objc_object_id = get_identifier (TAG_OBJECT);
1339 objc_class_id = get_identifier (TAG_CLASS);
1341 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1342 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1344 objc_object_type = build_pointer_type (objc_object_reference);
1345 objc_class_type = build_pointer_type (objc_class_reference);
1347 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1348 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1350 /* Declare the 'id' and 'Class' typedefs. */
1352 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1355 DECL_IN_SYSTEM_HEADER (type) = 1;
1356 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1359 DECL_IN_SYSTEM_HEADER (type) = 1;
1361 /* Forward-declare '@interface Protocol'. */
1363 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1364 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1365 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1368 /* Declare type of selector-objects that represent an operation name. */
1370 if (flag_next_runtime)
1371 /* `struct objc_selector *' */
1373 = build_pointer_type (xref_tag (RECORD_TYPE,
1374 get_identifier (TAG_SELECTOR)));
1376 /* `const struct objc_selector *' */
1378 = build_pointer_type
1379 (build_qualified_type (xref_tag (RECORD_TYPE,
1380 get_identifier (TAG_SELECTOR)),
1383 /* Declare receiver type used for dispatching messages to 'super'. */
1385 /* `struct objc_super *' */
1386 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1387 get_identifier (TAG_SUPER)));
1389 if (flag_next_runtime)
1391 /* NB: In order to call one of the ..._stret (struct-returning)
1392 functions, the function *MUST* first be cast to a signature that
1393 corresponds to the actual ObjC method being invoked. This is
1394 what is done by the build_objc_method_call() routine below. */
1396 /* id objc_msgSend (id, SEL, ...); */
1397 /* id objc_msgSendNonNil (id, SEL, ...); */
1398 /* id objc_msgSend_stret (id, SEL, ...); */
1399 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1401 = build_function_type (objc_object_type,
1402 tree_cons (NULL_TREE, objc_object_type,
1403 tree_cons (NULL_TREE, objc_selector_type,
1405 umsg_decl = builtin_function (TAG_MSGSEND,
1406 type, 0, NOT_BUILT_IN,
1408 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1409 type, 0, NOT_BUILT_IN,
1411 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1412 type, 0, NOT_BUILT_IN,
1414 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1415 type, 0, NOT_BUILT_IN,
1418 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1419 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1421 = build_function_type (objc_object_type,
1422 tree_cons (NULL_TREE, objc_super_type,
1423 tree_cons (NULL_TREE, objc_selector_type,
1425 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1426 type, 0, NOT_BUILT_IN,
1428 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1429 type, 0, NOT_BUILT_IN, 0,
1434 /* GNU runtime messenger entry points. */
1436 /* typedef id (*IMP)(id, SEL, ...); */
1438 = build_pointer_type
1439 (build_function_type (objc_object_type,
1440 tree_cons (NULL_TREE, objc_object_type,
1441 tree_cons (NULL_TREE, objc_selector_type,
1444 /* IMP objc_msg_lookup (id, SEL); */
1446 = build_function_type (IMP_type,
1447 tree_cons (NULL_TREE, objc_object_type,
1448 tree_cons (NULL_TREE, objc_selector_type,
1449 OBJC_VOID_AT_END)));
1450 umsg_decl = builtin_function (TAG_MSGSEND,
1451 type, 0, NOT_BUILT_IN,
1454 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1456 = build_function_type (IMP_type,
1457 tree_cons (NULL_TREE, objc_super_type,
1458 tree_cons (NULL_TREE, objc_selector_type,
1459 OBJC_VOID_AT_END)));
1460 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1461 type, 0, NOT_BUILT_IN,
1464 /* The following GNU runtime entry point is called to initialize
1467 __objc_exec_class (void *); */
1469 = build_function_type (void_type_node,
1470 tree_cons (NULL_TREE, ptr_type_node,
1472 execclass_decl = builtin_function (TAG_EXECCLASS,
1473 type, 0, NOT_BUILT_IN,
1477 /* id objc_getClass (const char *); */
1479 type = build_function_type (objc_object_type,
1480 tree_cons (NULL_TREE,
1481 const_string_type_node,
1485 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1488 /* id objc_getMetaClass (const char *); */
1490 objc_get_meta_class_decl
1491 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1493 build_class_template ();
1494 build_super_template ();
1495 build_protocol_template ();
1496 build_category_template ();
1497 build_objc_exception_stuff ();
1499 if (flag_next_runtime)
1500 build_next_objc_exception_stuff ();
1502 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1504 if (! flag_next_runtime)
1505 build_selector_table_decl ();
1507 /* Forward declare constant_string_id and constant_string_type. */
1508 if (!constant_string_class_name)
1509 constant_string_class_name = default_constant_string_class_name;
1511 constant_string_id = get_identifier (constant_string_class_name);
1512 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1514 /* Pre-build the following entities - for speed/convenience. */
1515 self_id = get_identifier ("self");
1516 ucmd_id = get_identifier ("_cmd");
1518 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1519 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1523 pop_lang_context ();
1526 write_symbols = save_write_symbols;
1527 debug_hooks = save_hooks;
1530 /* Ensure that the ivar list for NSConstantString/NXConstantString
1531 (or whatever was specified via `-fconstant-string-class')
1532 contains fields at least as large as the following three, so that
1533 the runtime can stomp on them with confidence:
1535 struct STRING_OBJECT_CLASS_NAME
1539 unsigned int length;
1543 check_string_class_template (void)
1545 tree field_decl = TYPE_FIELDS (constant_string_type);
1547 #define AT_LEAST_AS_LARGE_AS(F, T) \
1548 (F && TREE_CODE (F) == FIELD_DECL \
1549 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1550 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1552 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1555 field_decl = TREE_CHAIN (field_decl);
1556 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1559 field_decl = TREE_CHAIN (field_decl);
1560 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1562 #undef AT_LEAST_AS_LARGE_AS
1565 /* Avoid calling `check_string_class_template ()' more than once. */
1566 static GTY(()) int string_layout_checked;
1568 /* Custom build_string which sets TREE_TYPE! */
1571 my_build_string (int len, const char *str)
1573 return fix_string_type (build_string (len, str));
1578 string_hash (const void *ptr)
1580 tree str = ((struct string_descriptor *)ptr)->literal;
1581 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1582 int i, len = TREE_STRING_LENGTH (str);
1585 for (i = 0; i < len; i++)
1586 h = ((h * 613) + p[i]);
1592 string_eq (const void *ptr1, const void *ptr2)
1594 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1595 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1596 int len1 = TREE_STRING_LENGTH (str1);
1598 return (len1 == TREE_STRING_LENGTH (str2)
1599 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1603 /* Given a chain of STRING_CST's, build a static instance of
1604 NXConstantString which points at the concatenation of those
1605 strings. We place the string object in the __string_objects
1606 section of the __OBJC segment. The Objective-C runtime will
1607 initialize the isa pointers of the string objects to point at the
1608 NXConstantString class object. */
1611 objc_build_string_object (tree string)
1613 tree initlist, constructor, constant_string_class;
1616 struct string_descriptor *desc, key;
1619 /* Prep the string argument. */
1620 string = fix_string_type (string);
1621 TREE_SET_CODE (string, STRING_CST);
1622 length = TREE_STRING_LENGTH (string) - 1;
1624 /* Check whether the string class being used actually exists and has the
1625 correct ivar layout. */
1626 if (!string_layout_checked)
1628 string_layout_checked = -1;
1629 constant_string_class = lookup_interface (constant_string_id);
1631 if (!constant_string_class
1632 || !(constant_string_type
1633 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1634 error ("cannot find interface declaration for `%s'",
1635 IDENTIFIER_POINTER (constant_string_id));
1636 /* The NSConstantString/NXConstantString ivar layout is now known. */
1637 else if (!check_string_class_template ())
1638 error ("interface `%s' does not have valid constant string layout",
1639 IDENTIFIER_POINTER (constant_string_id));
1640 /* For the NeXT runtime, we can generate a literal reference
1641 to the string class, don't need to run a constructor. */
1642 else if (flag_next_runtime && !setup_string_decl ())
1643 error ("cannot find reference tag for class `%s'",
1644 IDENTIFIER_POINTER (constant_string_id));
1647 string_layout_checked = 1; /* Success! */
1648 add_class_reference (constant_string_id);
1652 if (string_layout_checked == -1)
1653 return error_mark_node;
1655 /* Perhaps we already constructed a constant string just like this one? */
1656 key.literal = string;
1657 loc = htab_find_slot (string_htab, &key, INSERT);
1662 *loc = desc = ggc_alloc (sizeof (*desc));
1663 desc->literal = string;
1665 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1666 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1667 fields = TYPE_FIELDS (constant_string_type);
1669 = build_tree_list (fields,
1671 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1672 : build_int_cst (NULL_TREE, 0));
1673 fields = TREE_CHAIN (fields);
1674 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1676 fields = TREE_CHAIN (fields);
1677 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1679 constructor = objc_build_constructor (constant_string_type,
1680 nreverse (initlist));
1681 TREE_INVARIANT (constructor) = true;
1683 if (!flag_next_runtime)
1685 = objc_add_static_instance (constructor, constant_string_type);
1687 desc->constructor = constructor;
1690 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1691 TREE_CONSTANT (addr) = true;
1692 TREE_INVARIANT (addr) = true;
1693 TREE_STATIC (addr) = true;
1698 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1700 static GTY(()) int num_static_inst;
1703 objc_add_static_instance (tree constructor, tree class_decl)
1708 /* Find the list of static instances for the CLASS_DECL. Create one if
1710 for (chain = &objc_static_instances;
1711 *chain && TREE_VALUE (*chain) != class_decl;
1712 chain = &TREE_CHAIN (*chain));
1715 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1716 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1719 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1720 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1721 DECL_COMMON (decl) = 1;
1722 TREE_STATIC (decl) = 1;
1723 DECL_ARTIFICIAL (decl) = 1;
1724 DECL_INITIAL (decl) = constructor;
1726 /* We may be writing something else just now.
1727 Postpone till end of input. */
1728 DECL_DEFER_OUTPUT (decl) = 1;
1729 pushdecl_top_level (decl);
1730 rest_of_decl_compilation (decl, 1, 0);
1732 /* Add the DECL to the head of this CLASS' list. */
1733 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1738 /* Build a static constant CONSTRUCTOR
1739 with type TYPE and elements ELTS. */
1742 objc_build_constructor (tree type, tree elts)
1744 tree constructor = build_constructor (type, elts);
1746 TREE_CONSTANT (constructor) = 1;
1747 TREE_STATIC (constructor) = 1;
1748 TREE_READONLY (constructor) = 1;
1751 /* Adjust for impedance mismatch. We should figure out how to build
1752 CONSTRUCTORs that consistently please both the C and C++ gods. */
1753 if (!TREE_PURPOSE (elts))
1754 TREE_TYPE (constructor) = NULL_TREE;
1755 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1761 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1763 /* Predefine the following data type:
1771 void *defs[cls_def_cnt + cat_def_cnt];
1775 build_objc_symtab_template (void)
1777 tree field_decl, field_decl_chain;
1779 objc_symtab_template
1780 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1782 /* long sel_ref_cnt; */
1783 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1784 field_decl_chain = field_decl;
1787 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1789 chainon (field_decl_chain, field_decl);
1791 /* short cls_def_cnt; */
1792 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1793 chainon (field_decl_chain, field_decl);
1795 /* short cat_def_cnt; */
1796 field_decl = create_field_decl (short_integer_type_node,
1798 chainon (field_decl_chain, field_decl);
1800 if (imp_count || cat_count || !flag_next_runtime)
1802 /* void *defs[imp_count + cat_count (+ 1)]; */
1803 /* NB: The index is one less than the size of the array. */
1804 int index = imp_count + cat_count
1805 + (flag_next_runtime? -1: 0);
1806 field_decl = create_field_decl
1809 build_index_type (build_int_cst (NULL_TREE, index))),
1811 chainon (field_decl_chain, field_decl);
1814 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1817 /* Create the initial value for the `defs' field of _objc_symtab.
1818 This is a CONSTRUCTOR. */
1821 init_def_list (tree type)
1823 tree expr, initlist = NULL_TREE;
1824 struct imp_entry *impent;
1827 for (impent = imp_list; impent; impent = impent->next)
1829 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1831 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1832 initlist = tree_cons (NULL_TREE, expr, initlist);
1837 for (impent = imp_list; impent; impent = impent->next)
1839 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1841 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1842 initlist = tree_cons (NULL_TREE, expr, initlist);
1846 if (!flag_next_runtime)
1848 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1851 if (static_instances_decl)
1852 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1854 expr = build_int_cst (NULL_TREE, 0);
1856 initlist = tree_cons (NULL_TREE, expr, initlist);
1859 return objc_build_constructor (type, nreverse (initlist));
1862 /* Construct the initial value for all of _objc_symtab. */
1865 init_objc_symtab (tree type)
1869 /* sel_ref_cnt = { ..., 5, ... } */
1871 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
1873 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1875 if (flag_next_runtime || ! sel_ref_chain)
1876 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1879 = tree_cons (NULL_TREE,
1880 convert (build_pointer_type (objc_selector_type),
1881 build_unary_op (ADDR_EXPR,
1882 UOBJC_SELECTOR_TABLE_decl, 1)),
1885 /* cls_def_cnt = { ..., 5, ... } */
1887 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1889 /* cat_def_cnt = { ..., 5, ... } */
1891 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1893 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1895 if (imp_count || cat_count || !flag_next_runtime)
1898 tree field = TYPE_FIELDS (type);
1899 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1901 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1905 return objc_build_constructor (type, nreverse (initlist));
1908 /* Generate forward declarations for metadata such as
1909 'OBJC_CLASS_...'. */
1912 build_metadata_decl (const char *name, tree type)
1916 /* struct TYPE NAME_<name>; */
1917 decl = start_var_decl (type, synth_id_with_class_suffix
1919 objc_implementation_context));
1924 /* Push forward-declarations of all the categories so that
1925 init_def_list can use them in a CONSTRUCTOR. */
1928 forward_declare_categories (void)
1930 struct imp_entry *impent;
1931 tree sav = objc_implementation_context;
1933 for (impent = imp_list; impent; impent = impent->next)
1935 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1937 /* Set an invisible arg to synth_id_with_class_suffix. */
1938 objc_implementation_context = impent->imp_context;
1939 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1940 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1941 objc_category_template);
1944 objc_implementation_context = sav;
1947 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1948 and initialized appropriately. */
1951 generate_objc_symtab_decl (void)
1953 /* forward declare categories */
1955 forward_declare_categories ();
1957 build_objc_symtab_template ();
1958 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1959 finish_var_decl (UOBJC_SYMBOLS_decl,
1960 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
1964 init_module_descriptor (tree type)
1966 tree initlist, expr;
1968 /* version = { 1, ... } */
1970 expr = build_int_cst (NULL_TREE, OBJC_VERSION);
1971 initlist = build_tree_list (NULL_TREE, expr);
1973 /* size = { ..., sizeof (struct _objc_module), ... } */
1975 expr = size_in_bytes (objc_module_template);
1976 initlist = tree_cons (NULL_TREE, expr, initlist);
1978 /* name = { ..., "foo.m", ... } */
1980 expr = add_objc_string (get_identifier (input_filename), class_names);
1981 initlist = tree_cons (NULL_TREE, expr, initlist);
1983 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1985 if (UOBJC_SYMBOLS_decl)
1986 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
1988 expr = build_int_cst (NULL_TREE, 0);
1989 initlist = tree_cons (NULL_TREE, expr, initlist);
1991 return objc_build_constructor (type, nreverse (initlist));
1994 /* Write out the data structures to describe Objective C classes defined.
1996 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
1999 build_module_descriptor (void)
2001 tree field_decl, field_decl_chain;
2004 push_lang_context (lang_name_c); /* extern "C" */
2007 objc_module_template
2008 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2011 field_decl = create_field_decl (long_integer_type_node, "version");
2012 field_decl_chain = field_decl;
2015 field_decl = create_field_decl (long_integer_type_node, "size");
2016 chainon (field_decl_chain, field_decl);
2019 field_decl = create_field_decl (string_type_node, "name");
2020 chainon (field_decl_chain, field_decl);
2022 /* struct _objc_symtab *symtab; */
2024 = create_field_decl (build_pointer_type
2025 (xref_tag (RECORD_TYPE,
2026 get_identifier (UTAG_SYMTAB))),
2028 chainon (field_decl_chain, field_decl);
2030 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2032 /* Create an instance of "_objc_module". */
2033 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2034 finish_var_decl (UOBJC_MODULES_decl,
2035 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2038 pop_lang_context ();
2042 /* The GNU runtime requires us to provide a static initializer function
2045 static void __objc_gnu_init (void) {
2046 __objc_exec_class (&L_OBJC_MODULES);
2050 build_module_initializer_routine (void)
2055 push_lang_context (lang_name_c); /* extern "C" */
2058 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2059 objc_start_function (get_identifier (TAG_GNUINIT),
2060 build_function_type (void_type_node,
2062 NULL_TREE, objc_get_parm_info (0));
2064 body = c_begin_compound_stmt (true);
2065 add_stmt (build_function_call
2069 build_unary_op (ADDR_EXPR,
2070 UOBJC_MODULES_decl, 0))));
2071 add_stmt (c_end_compound_stmt (body, true));
2073 TREE_PUBLIC (current_function_decl) = 0;
2076 /* For Objective-C++, we will need to call __objc_gnu_init
2077 from objc_generate_static_init_call() below. */
2078 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2081 GNU_INIT_decl = current_function_decl;
2085 pop_lang_context ();
2090 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2091 to be called by the module initializer routine. */
2094 objc_static_init_needed_p (void)
2096 return (GNU_INIT_decl != NULL_TREE);
2099 /* Generate a call to the __objc_gnu_init initializer function. */
2102 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2104 add_stmt (build_stmt (EXPR_STMT,
2105 build_function_call (GNU_INIT_decl, NULL_TREE)));
2109 #endif /* OBJCPLUS */
2111 /* Return the DECL of the string IDENT in the SECTION. */
2114 get_objc_string_decl (tree ident, enum string_section section)
2118 if (section == class_names)
2119 chain = class_names_chain;
2120 else if (section == meth_var_names)
2121 chain = meth_var_names_chain;
2122 else if (section == meth_var_types)
2123 chain = meth_var_types_chain;
2127 for (; chain != 0; chain = TREE_CHAIN (chain))
2128 if (TREE_VALUE (chain) == ident)
2129 return (TREE_PURPOSE (chain));
2135 /* Output references to all statically allocated objects. Return the DECL
2136 for the array built. */
2139 generate_static_references (void)
2141 tree decls = NULL_TREE, expr = NULL_TREE;
2142 tree class_name, class, decl, initlist;
2143 tree cl_chain, in_chain, type
2144 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2145 int num_inst, num_class;
2148 if (flag_next_runtime)
2151 for (cl_chain = objc_static_instances, num_class = 0;
2152 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2154 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2155 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2157 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2158 decl = start_var_decl (type, buf);
2160 /* Output {class_name, ...}. */
2161 class = TREE_VALUE (cl_chain);
2162 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2163 initlist = build_tree_list (NULL_TREE,
2164 build_unary_op (ADDR_EXPR, class_name, 1));
2166 /* Output {..., instance, ...}. */
2167 for (in_chain = TREE_PURPOSE (cl_chain);
2168 in_chain; in_chain = TREE_CHAIN (in_chain))
2170 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2171 initlist = tree_cons (NULL_TREE, expr, initlist);
2174 /* Output {..., NULL}. */
2175 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2177 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2178 finish_var_decl (decl, expr);
2180 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2183 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2184 expr = objc_build_constructor (type, nreverse (decls));
2185 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2186 finish_var_decl (static_instances_decl, expr);
2189 /* Output all strings. */
2192 generate_strings (void)
2194 tree chain, string_expr;
2195 tree string, decl, type;
2197 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2199 string = TREE_VALUE (chain);
2200 decl = TREE_PURPOSE (chain);
2201 type = build_array_type
2204 (build_int_cst (NULL_TREE,
2205 IDENTIFIER_LENGTH (string))));
2206 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2207 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2208 IDENTIFIER_POINTER (string));
2209 finish_var_decl (decl, string_expr);
2212 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2214 string = TREE_VALUE (chain);
2215 decl = TREE_PURPOSE (chain);
2216 type = build_array_type
2219 (build_int_cst (NULL_TREE,
2220 IDENTIFIER_LENGTH (string))));
2221 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2222 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2223 IDENTIFIER_POINTER (string));
2224 finish_var_decl (decl, string_expr);
2227 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2229 string = TREE_VALUE (chain);
2230 decl = TREE_PURPOSE (chain);
2231 type = build_array_type
2234 (build_int_cst (NULL_TREE,
2235 IDENTIFIER_LENGTH (string))));
2236 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2237 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2238 IDENTIFIER_POINTER (string));
2239 finish_var_decl (decl, string_expr);
2243 static GTY(()) int selector_reference_idx;
2246 build_selector_reference_decl (void)
2251 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2252 decl = start_var_decl (objc_selector_type, buf);
2258 build_selector_table_decl (void)
2262 if (flag_typed_selectors)
2264 build_selector_template ();
2265 temp = build_array_type (objc_selector_template, NULL_TREE);
2268 temp = build_array_type (objc_selector_type, NULL_TREE);
2270 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2273 /* Just a handy wrapper for add_objc_string. */
2276 build_selector (tree ident)
2278 return convert (objc_selector_type,
2279 add_objc_string (ident, meth_var_names));
2283 build_selector_translation_table (void)
2285 tree chain, initlist = NULL_TREE;
2287 tree decl = NULL_TREE;
2289 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2293 if (warn_selector && objc_implementation_context)
2297 for (method_chain = meth_var_names_chain;
2299 method_chain = TREE_CHAIN (method_chain))
2301 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2309 /* Adjust line number for warning message. */
2310 int save_lineno = input_line;
2311 if (flag_next_runtime && TREE_PURPOSE (chain))
2312 input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
2313 warning ("creating selector for non existant method %s",
2314 IDENTIFIER_POINTER (TREE_VALUE (chain)));
2315 input_line = save_lineno;
2319 expr = build_selector (TREE_VALUE (chain));
2320 /* add one for the '\0' character */
2321 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2323 if (flag_next_runtime)
2325 decl = TREE_PURPOSE (chain);
2326 finish_var_decl (decl, expr);
2330 if (flag_typed_selectors)
2332 tree eltlist = NULL_TREE;
2333 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2334 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2335 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2336 expr = objc_build_constructor (objc_selector_template,
2337 nreverse (eltlist));
2340 initlist = tree_cons (NULL_TREE, expr, initlist);
2344 if (! flag_next_runtime)
2346 /* Cause the selector table (previously forward-declared)
2347 to be actually output. */
2348 initlist = tree_cons (NULL_TREE,
2349 flag_typed_selectors
2350 ? objc_build_constructor
2351 (objc_selector_template,
2352 tree_cons (NULL_TREE,
2353 build_int_cst (NULL_TREE, 0),
2354 tree_cons (NULL_TREE,
2355 build_int_cst (NULL_TREE, 0),
2357 : build_int_cst (NULL_TREE, 0), initlist);
2358 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2359 nreverse (initlist));
2360 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2365 get_proto_encoding (tree proto)
2370 if (! METHOD_ENCODING (proto))
2372 encoding = encode_method_prototype (proto);
2373 METHOD_ENCODING (proto) = encoding;
2376 encoding = METHOD_ENCODING (proto);
2378 return add_objc_string (encoding, meth_var_types);
2381 return build_int_cst (NULL_TREE, 0);
2384 /* sel_ref_chain is a list whose "value" fields will be instances of
2385 identifier_node that represent the selector. */
2388 build_typed_selector_reference (tree ident, tree prototype)
2390 tree *chain = &sel_ref_chain;
2396 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2397 goto return_at_index;
2400 chain = &TREE_CHAIN (*chain);
2403 *chain = tree_cons (prototype, ident, NULL_TREE);
2406 expr = build_unary_op (ADDR_EXPR,
2407 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2408 build_int_cst (NULL_TREE, index)),
2410 return convert (objc_selector_type, expr);
2414 build_selector_reference (tree ident)
2416 tree *chain = &sel_ref_chain;
2422 if (TREE_VALUE (*chain) == ident)
2423 return (flag_next_runtime
2424 ? TREE_PURPOSE (*chain)
2425 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2426 build_int_cst (NULL_TREE, index)));
2429 chain = &TREE_CHAIN (*chain);
2432 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2434 *chain = tree_cons (expr, ident, NULL_TREE);
2436 return (flag_next_runtime
2438 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2439 build_int_cst (NULL_TREE, index)));
2442 static GTY(()) int class_reference_idx;
2445 build_class_reference_decl (void)
2450 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2451 decl = start_var_decl (objc_class_type, buf);
2456 /* Create a class reference, but don't create a variable to reference
2460 add_class_reference (tree ident)
2464 if ((chain = cls_ref_chain))
2469 if (ident == TREE_VALUE (chain))
2473 chain = TREE_CHAIN (chain);
2477 /* Append to the end of the list */
2478 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2481 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2484 /* Get a class reference, creating it if necessary. Also create the
2485 reference variable. */
2488 objc_get_class_reference (tree ident)
2493 if (processing_template_decl)
2494 /* Must wait until template instantiation time. */
2495 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2496 if (TREE_CODE (ident) == TYPE_DECL)
2497 ident = DECL_NAME (ident);
2501 if (!(ident = objc_is_class_name (ident)))
2503 error ("`%s' is not an Objective-C class name or alias",
2504 IDENTIFIER_POINTER (orig_ident));
2505 return error_mark_node;
2508 if (flag_next_runtime && !flag_zero_link)
2513 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2514 if (TREE_VALUE (*chain) == ident)
2516 if (! TREE_PURPOSE (*chain))
2517 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2519 return TREE_PURPOSE (*chain);
2522 decl = build_class_reference_decl ();
2523 *chain = tree_cons (decl, ident, NULL_TREE);
2530 add_class_reference (ident);
2532 params = build_tree_list (NULL_TREE,
2533 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2534 IDENTIFIER_POINTER (ident)));
2536 assemble_external (objc_get_class_decl);
2537 return build_function_call (objc_get_class_decl, params);
2541 /* For each string section we have a chain which maps identifier nodes
2542 to decls for the strings. */
2545 add_objc_string (tree ident, enum string_section section)
2549 if (section == class_names)
2550 chain = &class_names_chain;
2551 else if (section == meth_var_names)
2552 chain = &meth_var_names_chain;
2553 else if (section == meth_var_types)
2554 chain = &meth_var_types_chain;
2560 if (TREE_VALUE (*chain) == ident)
2561 return convert (string_type_node,
2562 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2564 chain = &TREE_CHAIN (*chain);
2567 decl = build_objc_string_decl (section);
2569 *chain = tree_cons (decl, ident, NULL_TREE);
2571 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2574 static GTY(()) int class_names_idx;
2575 static GTY(()) int meth_var_names_idx;
2576 static GTY(()) int meth_var_types_idx;
2579 build_objc_string_decl (enum string_section section)
2584 if (section == class_names)
2585 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2586 else if (section == meth_var_names)
2587 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2588 else if (section == meth_var_types)
2589 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2591 ident = get_identifier (buf);
2593 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2594 DECL_EXTERNAL (decl) = 1;
2595 TREE_PUBLIC (decl) = 0;
2596 TREE_USED (decl) = 1;
2597 TREE_CONSTANT (decl) = 1;
2598 DECL_CONTEXT (decl) = 0;
2599 DECL_ARTIFICIAL (decl) = 1;
2601 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2604 make_decl_rtl (decl);
2605 pushdecl_top_level (decl);
2612 objc_declare_alias (tree alias_ident, tree class_ident)
2614 tree underlying_class;
2617 if (current_namespace != global_namespace) {
2618 error ("Objective-C declarations may only appear in global scope");
2620 #endif /* OBJCPLUS */
2622 if (!(underlying_class = objc_is_class_name (class_ident)))
2623 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2624 else if (objc_is_class_name (alias_ident))
2625 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2627 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2631 objc_declare_class (tree ident_list)
2635 if (current_namespace != global_namespace) {
2636 error ("Objective-C declarations may only appear in global scope");
2638 #endif /* OBJCPLUS */
2640 for (list = ident_list; list; list = TREE_CHAIN (list))
2642 tree ident = TREE_VALUE (list);
2644 if (! objc_is_class_name (ident))
2646 tree record = lookup_name (ident);
2648 if (record && ! TREE_STATIC_TEMPLATE (record))
2650 error ("`%s' redeclared as different kind of symbol",
2651 IDENTIFIER_POINTER (ident));
2652 error ("%Jprevious declaration of '%D'",
2656 record = xref_tag (RECORD_TYPE, ident);
2657 TREE_STATIC_TEMPLATE (record) = 1;
2658 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2664 objc_is_class_name (tree ident)
2668 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2669 && identifier_global_value (ident))
2670 ident = identifier_global_value (ident);
2671 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2672 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2674 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2675 ident = OBJC_TYPE_NAME (ident);
2677 if (ident && TREE_CODE (ident) == TYPE_DECL)
2678 ident = DECL_NAME (ident);
2680 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2683 if (lookup_interface (ident))
2686 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2688 if (ident == TREE_VALUE (chain))
2692 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2694 if (ident == TREE_VALUE (chain))
2695 return TREE_PURPOSE (chain);
2701 /* Check whether TYPE is either 'id' or 'Class'. */
2704 objc_is_id (tree type)
2706 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2707 && identifier_global_value (type))
2708 type = identifier_global_value (type);
2710 if (type && TREE_CODE (type) == TYPE_DECL)
2711 type = TREE_TYPE (type);
2713 /* NB: This function may be called before the ObjC front-end has
2714 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2715 return (objc_object_type && type && (IS_ID (type) || IS_CLASS (type))
2720 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2721 class instance. This is needed by other parts of the compiler to
2722 handle ObjC types gracefully. */
2725 objc_is_object_ptr (tree type)
2729 type = TYPE_MAIN_VARIANT (type);
2730 if (!POINTER_TYPE_P (type))
2733 ret = objc_is_id (type);
2735 ret = objc_is_class_name (TREE_TYPE (type));
2741 lookup_interface (tree ident)
2746 if (ident && TREE_CODE (ident) == TYPE_DECL)
2747 ident = DECL_NAME (ident);
2749 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2751 if (ident == CLASS_NAME (chain))
2757 /* Implement @defs (<classname>) within struct bodies. */
2760 objc_get_class_ivars (tree class_name)
2762 tree interface = lookup_interface (class_name);
2765 return get_class_ivars (interface);
2767 error ("cannot find interface declaration for `%s'",
2768 IDENTIFIER_POINTER (class_name));
2770 return error_mark_node;
2773 /* Used by: build_private_template, continue_class,
2774 and for @defs constructs. */
2777 get_class_ivars (tree interface)
2779 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2781 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2782 by the current class (i.e., they do not include super-class ivars).
2783 However, the CLASS_IVARS list will be side-effected by a call to
2784 finish_struct(), which will fill in field offsets. */
2785 if (!CLASS_IVARS (interface))
2786 CLASS_IVARS (interface) = ivar_chain;
2788 while (CLASS_SUPER_NAME (interface))
2790 /* Prepend super-class ivars. */
2791 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2792 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2800 objc_create_temporary_var (tree type)
2804 decl = build_decl (VAR_DECL, NULL_TREE, type);
2805 TREE_USED (decl) = 1;
2806 DECL_ARTIFICIAL (decl) = 1;
2807 DECL_IGNORED_P (decl) = 1;
2808 DECL_CONTEXT (decl) = current_function_decl;
2813 /* Exception handling constructs. We begin by having the parser do most
2814 of the work and passing us blocks. What we do next depends on whether
2815 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2816 We abstract all of this in a handful of appropriately named routines. */
2818 /* Stack of open try blocks. */
2820 struct objc_try_context
2822 struct objc_try_context *outer;
2824 /* Statements (or statement lists) as processed by the parser. */
2828 /* Some file position locations. */
2829 location_t try_locus;
2830 location_t end_try_locus;
2831 location_t end_catch_locus;
2832 location_t finally_locus;
2833 location_t end_finally_locus;
2835 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2836 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2839 /* The CATCH_EXPR of an open @catch clause. */
2842 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2848 static struct objc_try_context *cur_try_context;
2850 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2851 that represents TYPE. For Objective-C, this is just the class name. */
2852 /* ??? Isn't there a class object or some such? Is it easy to get? */
2856 objc_eh_runtime_type (tree type)
2858 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2862 /* Initialize exception handling. */
2865 objc_init_exceptions (void)
2867 static bool done = false;
2872 if (flag_objc_sjlj_exceptions)
2874 /* On Darwin, ObjC exceptions require a sufficiently recent
2875 version of the runtime, so the user must ask for them explicitly. */
2876 if (!flag_objc_exceptions)
2877 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2878 "exception syntax");
2883 c_eh_initialized_p = true;
2884 eh_personality_libfunc
2885 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2886 ? "__gnu_objc_personality_sj0"
2887 : "__gnu_objc_personality_v0");
2888 using_eh_for_cleanups ();
2889 lang_eh_runtime_type = objc_eh_runtime_type;
2894 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2895 we'll arrange for it to be initialized (and associated with a binding)
2899 objc_build_exc_ptr (void)
2901 if (flag_objc_sjlj_exceptions)
2903 tree var = cur_try_context->caught_decl;
2906 var = objc_create_temporary_var (objc_object_type);
2907 cur_try_context->caught_decl = var;
2912 return build (EXC_PTR_EXPR, objc_object_type);
2915 /* Build "objc_exception_try_exit(&_stack)". */
2918 next_sjlj_build_try_exit (void)
2921 t = build_fold_addr_expr (cur_try_context->stack_decl);
2922 t = tree_cons (NULL, t, NULL);
2923 t = build_function_call (objc_exception_try_exit_decl, t);
2928 objc_exception_try_enter (&_stack);
2929 if (_setjmp(&_stack.buf))
2933 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2934 empty, ready for the caller to fill them in. */
2937 next_sjlj_build_enter_and_setjmp (void)
2939 tree t, enter, sj, cond;
2941 t = build_fold_addr_expr (cur_try_context->stack_decl);
2942 t = tree_cons (NULL, t, NULL);
2943 enter = build_function_call (objc_exception_try_enter_decl, t);
2945 t = build_component_ref (cur_try_context->stack_decl,
2946 get_identifier ("buf"));
2947 t = build_fold_addr_expr (t);
2948 t = convert (ptr_type_node, t);
2949 t = tree_cons (NULL, t, NULL);
2950 sj = build_function_call (objc_setjmp_decl, t);
2952 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2953 cond = lang_hooks.truthvalue_conversion (cond);
2955 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2959 DECL = objc_exception_extract(&_stack);
2963 next_sjlj_build_exc_extract (tree decl)
2967 t = build_fold_addr_expr (cur_try_context->stack_decl);
2968 t = tree_cons (NULL, t, NULL);
2969 t = build_function_call (objc_exception_extract_decl, t);
2970 t = convert (TREE_TYPE (decl), t);
2971 t = build (MODIFY_EXPR, void_type_node, decl, t);
2977 if (objc_exception_match(obj_get_class(TYPE), _caught)
2984 objc_exception_try_exit(&_stack);
2986 from the sequence of CATCH_EXPRs in the current try context. */
2989 next_sjlj_build_catch_list (void)
2991 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
2993 tree *last = &catch_seq;
2994 bool saw_id = false;
2996 for (; !tsi_end_p (i); tsi_next (&i))
2998 tree stmt = tsi_stmt (i);
2999 tree type = CATCH_TYPES (stmt);
3000 tree body = CATCH_BODY (stmt);
3012 if (type == error_mark_node)
3013 cond = error_mark_node;
3016 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3017 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3018 args = tree_cons (NULL, t, args);
3019 t = build_function_call (objc_exception_match_decl, args);
3020 cond = lang_hooks.truthvalue_conversion (t);
3022 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3023 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3026 last = &COND_EXPR_ELSE (t);
3032 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3033 cur_try_context->caught_decl);
3034 annotate_with_locus (t, cur_try_context->end_catch_locus);
3035 append_to_statement_list (t, last);
3037 t = next_sjlj_build_try_exit ();
3038 annotate_with_locus (t, cur_try_context->end_catch_locus);
3039 append_to_statement_list (t, last);
3045 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3046 exception handling. We aim to build:
3049 struct _objc_exception_data _stack;
3050 id volatile _rethrow = 0;
3053 objc_exception_try_enter (&_stack);
3054 if (_setjmp(&_stack.buf))
3056 id _caught = objc_exception_extract(&_stack);
3057 objc_exception_try_enter (&_stack);
3058 if (_setjmp(&_stack.buf))
3059 _rethrow = objc_exception_extract(&_stack);
3069 objc_exception_try_exit(&_stack);
3072 objc_exception_throw(_rethrow);
3076 If CATCH-LIST is empty, we can omit all of the block containing
3077 "_caught" except for the setting of _rethrow. Note the use of
3078 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3079 but handles goto and other exits from the block. */
3082 next_sjlj_build_try_catch_finally (void)
3084 tree rethrow_decl, stack_decl, t;
3085 tree catch_seq, try_fin, bind;
3087 /* Create the declarations involved. */
3088 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3089 stack_decl = objc_create_temporary_var (t);
3090 cur_try_context->stack_decl = stack_decl;
3092 rethrow_decl = objc_create_temporary_var (objc_object_type);
3093 cur_try_context->rethrow_decl = rethrow_decl;
3094 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3095 TREE_CHAIN (rethrow_decl) = stack_decl;
3097 /* Build the outermost varible binding level. */
3098 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3099 annotate_with_locus (bind, cur_try_context->try_locus);
3100 TREE_SIDE_EFFECTS (bind) = 1;
3102 /* Initialize rethrow_decl. */
3103 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3104 convert (objc_object_type, null_pointer_node));
3105 annotate_with_locus (t, cur_try_context->try_locus);
3106 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3108 /* Build the outermost TRY_FINALLY_EXPR. */
3109 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3110 annotate_with_locus (try_fin, cur_try_context->try_locus);
3111 TREE_SIDE_EFFECTS (try_fin) = 1;
3112 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3114 /* Create the complete catch sequence. */
3115 if (cur_try_context->catch_list)
3117 tree caught_decl = objc_build_exc_ptr ();
3118 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3120 t = next_sjlj_build_exc_extract (caught_decl);
3121 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3123 t = next_sjlj_build_enter_and_setjmp ();
3124 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3125 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3126 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3129 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3130 annotate_with_locus (catch_seq, cur_try_context->end_try_locus);
3132 /* Build the main register-and-try if statement. */
3133 t = next_sjlj_build_enter_and_setjmp ();
3134 annotate_with_locus (t, cur_try_context->try_locus);
3135 COND_EXPR_THEN (t) = catch_seq;
3136 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3137 TREE_OPERAND (try_fin, 0) = t;
3139 /* Build the complete FINALLY statement list. */
3140 t = next_sjlj_build_try_exit ();
3141 t = build_stmt (COND_EXPR,
3142 lang_hooks.truthvalue_conversion (rethrow_decl),
3144 annotate_with_locus (t, cur_try_context->finally_locus);
3145 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3147 append_to_statement_list (cur_try_context->finally_body,
3148 &TREE_OPERAND (try_fin, 1));
3150 t = tree_cons (NULL, rethrow_decl, NULL);
3151 t = build_function_call (objc_exception_throw_decl, t);
3152 t = build_stmt (COND_EXPR,
3153 lang_hooks.truthvalue_conversion (rethrow_decl),
3155 annotate_with_locus (t, cur_try_context->end_finally_locus);
3156 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3161 /* Called just after parsing the @try and its associated BODY. We now
3162 must prepare for the tricky bits -- handling the catches and finally. */
3165 objc_begin_try_stmt (location_t try_locus, tree body)
3167 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3168 c->outer = cur_try_context;
3170 c->try_locus = try_locus;
3171 c->end_try_locus = input_location;
3172 cur_try_context = c;
3174 objc_init_exceptions ();
3177 /* Called just after parsing "@catch (parm)". Open a binding level,
3178 enter DECL into the binding level, and initialize it. Leave the
3179 binding level open while the body of the compound statement is parsed. */
3182 objc_begin_catch_clause (tree decl)
3184 tree compound, type, t;
3186 /* Begin a new scope that the entire catch clause will live in. */
3187 compound = c_begin_compound_stmt (true);
3189 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3190 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3191 lang_hooks.decls.pushdecl (decl);
3193 /* Since a decl is required here by syntax, don't warn if its unused. */
3194 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3195 be what the previous objc implementation did. */
3196 TREE_USED (decl) = 1;
3198 /* Verify that the type of the catch is valid. It must be a pointer
3199 to an Objective-C class, or "id" (which is catch-all). */
3200 type = TREE_TYPE (decl);
3202 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3204 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3206 error ("@catch parameter is not a known Objective-C class type");
3207 type = error_mark_node;
3209 else if (cur_try_context->catch_list)
3211 /* Examine previous @catch clauses and see if we've already
3212 caught the type in question. */
3213 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3214 for (; !tsi_end_p (i); tsi_next (&i))
3216 tree stmt = tsi_stmt (i);
3217 t = CATCH_TYPES (stmt);
3218 if (t == error_mark_node)
3220 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3222 warning ("exception of type %<%T%> will be caught",
3224 warning ("%H by earlier handler for %<%T%>",
3225 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3231 /* Record the data for the catch in the try context so that we can
3232 finalize it later. */
3233 t = build_stmt (CATCH_EXPR, type, compound);
3234 cur_try_context->current_catch = t;
3236 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3237 t = objc_build_exc_ptr ();
3238 t = convert (TREE_TYPE (decl), t);
3239 t = build (MODIFY_EXPR, void_type_node, decl, t);
3243 /* Called just after parsing the closing brace of a @catch clause. Close
3244 the open binding level, and record a CATCH_EXPR for it. */
3247 objc_finish_catch_clause (void)
3249 tree c = cur_try_context->current_catch;
3250 cur_try_context->current_catch = NULL;
3251 cur_try_context->end_catch_locus = input_location;
3253 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3254 append_to_statement_list (c, &cur_try_context->catch_list);
3257 /* Called after parsing a @finally clause and its associated BODY.
3258 Record the body for later placement. */
3261 objc_build_finally_clause (location_t finally_locus, tree body)
3263 cur_try_context->finally_body = body;
3264 cur_try_context->finally_locus = finally_locus;
3265 cur_try_context->end_finally_locus = input_location;
3268 /* Called to finalize a @try construct. */
3271 objc_finish_try_stmt (void)
3273 struct objc_try_context *c = cur_try_context;
3276 if (c->catch_list == NULL && c->finally_body == NULL)
3277 error ("`@try' without `@catch' or `@finally'");
3279 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3280 if (flag_objc_sjlj_exceptions)
3282 if (!cur_try_context->finally_body)
3284 cur_try_context->finally_locus = input_location;
3285 cur_try_context->end_finally_locus = input_location;
3287 stmt = next_sjlj_build_try_catch_finally ();
3291 /* Otherwise, nest the CATCH inside a FINALLY. */
3295 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3296 annotate_with_locus (stmt, cur_try_context->try_locus);
3298 if (c->finally_body)
3300 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3301 annotate_with_locus (stmt, cur_try_context->try_locus);
3306 cur_try_context = c->outer;
3311 objc_build_throw_stmt (tree throw_expr)
3315 objc_init_exceptions ();
3317 if (throw_expr == NULL)
3319 /* If we're not inside a @catch block, there is no "current
3320 exception" to be rethrown. */
3321 if (cur_try_context == NULL
3322 || cur_try_context->current_catch == NULL)
3324 error ("%<@throw%> (rethrow) used outside of a @catch block");
3328 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3329 value that we get from the runtime. */
3330 throw_expr = objc_build_exc_ptr ();
3333 /* A throw is just a call to the runtime throw function with the
3334 object as a parameter. */
3335 args = tree_cons (NULL, throw_expr, NULL);
3336 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3340 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3344 /* First lock the mutex. */
3345 mutex = save_expr (mutex);
3346 args = tree_cons (NULL, mutex, NULL);
3347 call = build_function_call (objc_sync_enter_decl, args);
3348 annotate_with_locus (call, start_locus);
3351 /* Build the mutex unlock. */
3352 args = tree_cons (NULL, mutex, NULL);
3353 call = build_function_call (objc_sync_exit_decl, args);
3354 annotate_with_locus (call, input_location);
3356 /* Put the that and the body in a TRY_FINALLY. */
3357 objc_begin_try_stmt (start_locus, body);
3358 objc_build_finally_clause (input_location, call);
3359 objc_finish_try_stmt ();
3363 /* Predefine the following data type:
3365 struct _objc_exception_data
3371 /* The following yuckiness should prevent users from having to #include
3372 <setjmp.h> in their code... */
3374 #ifdef TARGET_POWERPC
3375 /* snarfed from /usr/include/ppc/setjmp.h */
3376 #define _JBLEN (26 + 36 + 129 + 1)
3378 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3383 build_next_objc_exception_stuff (void)
3385 tree field_decl, field_decl_chain, index, temp_type;
3387 objc_exception_data_template
3388 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3390 /* int buf[_JBLEN]; */
3392 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3393 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3395 field_decl_chain = field_decl;
3397 /* void *pointers[4]; */
3399 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3400 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3402 chainon (field_decl_chain, field_decl);
3404 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3406 /* int _setjmp(...); */
3407 /* If the user includes <setjmp.h>, this shall be superseded by
3408 'int _setjmp(jmp_buf);' */
3409 temp_type = build_function_type (integer_type_node, NULL_TREE);
3411 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3413 /* id objc_exception_extract(struct _objc_exception_data *); */
3415 = build_function_type (objc_object_type,
3416 tree_cons (NULL_TREE,
3417 build_pointer_type (objc_exception_data_template),
3419 objc_exception_extract_decl
3420 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3421 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3422 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3424 = build_function_type (void_type_node,
3425 tree_cons (NULL_TREE,
3426 build_pointer_type (objc_exception_data_template),
3428 objc_exception_try_enter_decl
3429 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3430 objc_exception_try_exit_decl
3431 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3433 /* int objc_exception_match(id, id); */
3435 = build_function_type (integer_type_node,
3436 tree_cons (NULL_TREE, objc_object_type,
3437 tree_cons (NULL_TREE, objc_object_type,
3438 OBJC_VOID_AT_END)));
3439 objc_exception_match_decl
3440 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3444 build_objc_exception_stuff (void)
3446 tree noreturn_list, nothrow_list, temp_type;
3448 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3449 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3451 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3452 /* void objc_sync_enter(id); */
3453 /* void objc_sync_exit(id); */
3454 temp_type = build_function_type (void_type_node,
3455 tree_cons (NULL_TREE, objc_object_type,
3457 objc_exception_throw_decl
3458 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3460 objc_sync_enter_decl
3461 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3462 NULL, nothrow_list);
3464 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3465 NULL, nothrow_list);
3469 /* struct <classname> {
3470 struct _objc_class *isa;
3475 build_private_template (tree class)
3479 if (CLASS_STATIC_TEMPLATE (class))
3481 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3482 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3486 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3487 ivar_context = get_class_ivars (class);
3489 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3491 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3493 /* mark this record as class template - for class type checking */
3494 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3497 objc_instance_type = build_pointer_type (uprivate_record);
3499 return ivar_context;
3502 /* Begin code generation for protocols... */
3504 /* struct _objc_protocol {
3505 struct _objc_class *isa;
3506 char *protocol_name;
3507 struct _objc_protocol **protocol_list;
3508 struct _objc__method_prototype_list *instance_methods;
3509 struct _objc__method_prototype_list *class_methods;
3513 build_protocol_template (void)
3515 tree field_decl, field_decl_chain;
3517 objc_protocol_template = start_struct (RECORD_TYPE,
3518 get_identifier (UTAG_PROTOCOL));
3520 /* struct _objc_class *isa; */
3521 field_decl = create_field_decl (build_pointer_type
3522 (xref_tag (RECORD_TYPE,
3523 get_identifier (UTAG_CLASS))),
3525 field_decl_chain = field_decl;
3527 /* char *protocol_name; */
3528 field_decl = create_field_decl (string_type_node, "protocol_name");
3529 chainon (field_decl_chain, field_decl);
3531 /* struct _objc_protocol **protocol_list; */
3532 field_decl = create_field_decl (build_pointer_type
3534 (objc_protocol_template)),
3536 chainon (field_decl_chain, field_decl);
3538 /* struct objc_method_list *instance_methods; */
3539 field_decl = create_field_decl (build_pointer_type
3540 (xref_tag (RECORD_TYPE,
3542 (UTAG_METHOD_PROTOTYPE_LIST))),
3543 "instance_methods");
3544 chainon (field_decl_chain, field_decl);
3546 /* struct objc_method_list *class_methods