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, 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"
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 static void build_class_template (void);
173 static void build_selector_template (void);
174 static void build_category_template (void);
175 static void build_super_template (void);
176 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
177 static tree get_class_ivars (tree);
178 static tree generate_protocol_list (tree);
179 static void build_protocol_reference (tree);
182 static void objc_generate_cxx_cdtors (void);
185 static const char *synth_id_with_class_suffix (const char *, tree);
187 /* Hash tables to manage the global pool of method prototypes. */
189 hash *nst_method_hash_list = 0;
190 hash *cls_method_hash_list = 0;
192 static hash hash_lookup (hash *, tree);
193 static tree lookup_method (tree, tree);
194 static tree lookup_method_static (tree, tree, int);
198 class_names, /* class, category, protocol, module names */
199 meth_var_names, /* method and variable names */
200 meth_var_types /* method and variable type descriptors */
203 static tree add_objc_string (tree, enum string_section);
204 static tree build_objc_string_decl (enum string_section);
205 static void build_selector_table_decl (void);
207 /* Protocol additions. */
209 static tree lookup_protocol (tree);
210 static tree lookup_and_install_protocols (tree);
214 static void encode_type_qualifiers (tree);
215 static void encode_type (tree, int, int);
216 static void encode_field_decl (tree, int, int);
219 static void really_start_method (tree, tree);
221 static void really_start_method (tree, struct c_arg_info *);
223 static int comp_proto_with_proto (tree, tree, int);
224 static void objc_push_parm (tree);
226 static tree objc_get_parm_info (int);
228 static struct c_arg_info *objc_get_parm_info (int);
231 /* Utilities for debugging and error diagnostics. */
233 static void warn_with_method (const char *, int, tree);
234 static char *gen_type_name (tree);
235 static char *gen_type_name_0 (tree);
236 static char *gen_method_decl (tree);
237 static char *gen_declaration (tree);
239 /* Everything else. */
241 static tree create_field_decl (tree, const char *);
242 static void add_class_reference (tree);
243 static void build_protocol_template (void);
244 static tree encode_method_prototype (tree);
245 static void generate_classref_translation_entry (tree);
246 static void handle_class_ref (tree);
247 static void generate_struct_by_value_array (void)
249 static void mark_referenced_methods (void);
250 static void generate_objc_image_info (void);
252 /*** Private Interface (data) ***/
254 /* Reserved tag definitions. */
256 #define OBJECT_TYPEDEF_NAME "id"
257 #define CLASS_TYPEDEF_NAME "Class"
259 #define TAG_OBJECT "objc_object"
260 #define TAG_CLASS "objc_class"
261 #define TAG_SUPER "objc_super"
262 #define TAG_SELECTOR "objc_selector"
264 #define UTAG_CLASS "_objc_class"
265 #define UTAG_IVAR "_objc_ivar"
266 #define UTAG_IVAR_LIST "_objc_ivar_list"
267 #define UTAG_METHOD "_objc_method"
268 #define UTAG_METHOD_LIST "_objc_method_list"
269 #define UTAG_CATEGORY "_objc_category"
270 #define UTAG_MODULE "_objc_module"
271 #define UTAG_SYMTAB "_objc_symtab"
272 #define UTAG_SUPER "_objc_super"
273 #define UTAG_SELECTOR "_objc_selector"
275 #define UTAG_PROTOCOL "_objc_protocol"
276 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
277 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
279 /* Note that the string object global name is only needed for the
281 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
283 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
285 static const char *TAG_GETCLASS;
286 static const char *TAG_GETMETACLASS;
287 static const char *TAG_MSGSEND;
288 static const char *TAG_MSGSENDSUPER;
289 /* The NeXT Objective-C messenger may have two extra entry points, for use
290 when returning a structure. */
291 static const char *TAG_MSGSEND_STRET;
292 static const char *TAG_MSGSENDSUPER_STRET;
293 static const char *default_constant_string_class_name;
295 /* Runtime metadata flags. */
296 #define CLS_FACTORY 0x0001L
297 #define CLS_META 0x0002L
298 #define CLS_HAS_CXX_STRUCTORS 0x2000L
300 #define OBJC_MODIFIER_STATIC 0x00000001
301 #define OBJC_MODIFIER_FINAL 0x00000002
302 #define OBJC_MODIFIER_PUBLIC 0x00000004
303 #define OBJC_MODIFIER_PRIVATE 0x00000008
304 #define OBJC_MODIFIER_PROTECTED 0x00000010
305 #define OBJC_MODIFIER_NATIVE 0x00000020
306 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
307 #define OBJC_MODIFIER_ABSTRACT 0x00000080
308 #define OBJC_MODIFIER_VOLATILE 0x00000100
309 #define OBJC_MODIFIER_TRANSIENT 0x00000200
310 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
312 /* NeXT-specific tags. */
314 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
315 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
316 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
317 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
318 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
319 #define TAG_EXCEPTIONMATCH "objc_exception_match"
320 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
321 #define TAG_SYNCENTER "objc_sync_enter"
322 #define TAG_SYNCEXIT "objc_sync_exit"
323 #define TAG_SETJMP "_setjmp"
324 #define UTAG_EXCDATA "_objc_exception_data"
326 #define TAG_ASSIGNIVAR "objc_assign_ivar"
327 #define TAG_ASSIGNGLOBAL "objc_assign_global"
328 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
330 /* Branch entry points. All that matters here are the addresses;
331 functions with these names do not really exist in libobjc. */
333 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
334 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
336 #define TAG_CXX_CONSTRUCT ".cxx_construct"
337 #define TAG_CXX_DESTRUCT ".cxx_destruct"
339 /* GNU-specific tags. */
341 #define TAG_EXECCLASS "__objc_exec_class"
342 #define TAG_GNUINIT "__objc_gnu_init"
344 /* Flags for lookup_method_static(). */
345 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
346 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
348 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
349 tree objc_global_trees[OCTI_MAX];
351 static void handle_impent (struct imp_entry *);
353 struct imp_entry *imp_list = 0;
354 int imp_count = 0; /* `@implementation' */
355 int cat_count = 0; /* `@category' */
357 enum tree_code objc_inherit_code;
358 int objc_public_flag;
360 /* Use to generate method labels. */
361 static int method_slot = 0;
365 static char *errbuf; /* Buffer for error diagnostics */
367 /* Data imported from tree.c. */
369 extern enum debug_info_type write_symbols;
371 /* Data imported from toplev.c. */
373 extern const char *dump_base_name;
375 static int flag_typed_selectors;
377 /* Store all constructed constant strings in a hash table so that
378 they get uniqued properly. */
380 struct string_descriptor GTY(())
382 /* The literal argument . */
385 /* The resulting constant string. */
389 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
391 FILE *gen_declaration_file;
393 /* Tells "encode_pointer/encode_aggregate" whether we are generating
394 type descriptors for instance variables (as opposed to methods).
395 Type descriptors for instance variables contain more information
396 than methods (for static typing and embedded structures). */
398 static int generating_instance_variables = 0;
400 /* Some platforms pass small structures through registers versus
401 through an invisible pointer. Determine at what size structure is
402 the transition point between the two possibilities. */
405 generate_struct_by_value_array (void)
408 tree field_decl, field_decl_chain;
410 int aggregate_in_mem[32];
413 /* Presumably no platform passes 32 byte structures in a register. */
414 for (i = 1; i < 32; i++)
418 /* Create an unnamed struct that has `i' character components */
419 type = start_struct (RECORD_TYPE, NULL_TREE);
421 strcpy (buffer, "c1");
422 field_decl = create_field_decl (char_type_node,
424 field_decl_chain = field_decl;
426 for (j = 1; j < i; j++)
428 sprintf (buffer, "c%d", j + 1);
429 field_decl = create_field_decl (char_type_node,
431 chainon (field_decl_chain, field_decl);
433 finish_struct (type, field_decl_chain, NULL_TREE);
435 aggregate_in_mem[i] = aggregate_value_p (type, 0);
436 if (!aggregate_in_mem[i])
440 /* We found some structures that are returned in registers instead of memory
441 so output the necessary data. */
444 for (i = 31; i >= 0; i--)
445 if (!aggregate_in_mem[i])
447 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
449 /* The first member of the structure is always 0 because we don't handle
450 structures with 0 members */
451 printf ("static int struct_forward_array[] = {\n 0");
453 for (j = 1; j <= i; j++)
454 printf (", %d", aggregate_in_mem[j]);
465 if (cxx_init () == false)
467 if (c_objc_common_init () == false)
471 #ifndef USE_MAPPED_LOCATION
472 /* Force the line number back to 0; check_newline will have
473 raised it to 1, which will make the builtin functions appear
474 not to be built in. */
478 /* If gen_declaration desired, open the output file. */
479 if (flag_gen_declaration)
481 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
482 gen_declaration_file = fopen (dumpname, "w");
483 if (gen_declaration_file == 0)
484 fatal_error ("can't open %s: %m", dumpname);
488 if (flag_next_runtime)
490 TAG_GETCLASS = "objc_getClass";
491 TAG_GETMETACLASS = "objc_getMetaClass";
492 TAG_MSGSEND = "objc_msgSend";
493 TAG_MSGSENDSUPER = "objc_msgSendSuper";
494 TAG_MSGSEND_STRET = "objc_msgSend_stret";
495 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
496 default_constant_string_class_name = "NSConstantString";
500 TAG_GETCLASS = "objc_get_class";
501 TAG_GETMETACLASS = "objc_get_meta_class";
502 TAG_MSGSEND = "objc_msg_lookup";
503 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
504 /* GNU runtime does not provide special functions to support
505 structure-returning methods. */
506 default_constant_string_class_name = "NXConstantString";
507 flag_typed_selectors = 1;
512 if (print_struct_values)
513 generate_struct_by_value_array ();
519 objc_finish_file (void)
521 mark_referenced_methods ();
524 /* We need to instantiate templates _before_ we emit ObjC metadata;
525 if we do not, some metadata (such as selectors) may go missing. */
527 instantiate_pending_templates (0);
530 /* Finalize Objective-C runtime data. No need to generate tables
531 and code if only checking syntax, or if generating a PCH file. */
532 if (!flag_syntax_only && !pch_file)
535 if (gen_declaration_file)
536 fclose (gen_declaration_file);
543 /* Return the first occurrence of a method declaration corresponding
544 to sel_name in rproto_list. Search rproto_list recursively.
545 If is_class is 0, search for instance methods, otherwise for class
548 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
554 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
556 p = TREE_VALUE (rproto);
558 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
560 if ((fnd = lookup_method (is_class
561 ? PROTOCOL_CLS_METHODS (p)
562 : PROTOCOL_NST_METHODS (p), sel_name)))
564 else if (PROTOCOL_LIST (p))
565 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
570 ; /* An identifier...if we could not find a protocol. */
581 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
585 /* Make sure the protocol is supported by the object on the rhs. */
586 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
589 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
591 p = TREE_VALUE (rproto);
593 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
598 else if (PROTOCOL_LIST (p))
599 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
608 ; /* An identifier...if we could not find a protocol. */
615 objc_start_class_interface (tree class, tree super_class, tree protos)
617 objc_interface_context
619 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
620 objc_public_flag = 0;
624 objc_start_category_interface (tree class, tree categ, tree protos)
626 objc_interface_context
627 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
629 = continue_class (objc_interface_context);
633 objc_start_protocol (tree name, tree protos)
635 objc_interface_context
636 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
640 objc_continue_interface (void)
643 = continue_class (objc_interface_context);
647 objc_finish_interface (void)
649 finish_class (objc_interface_context);
650 objc_interface_context = NULL_TREE;
654 objc_start_class_implementation (tree class, tree super_class)
656 objc_implementation_context
658 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
659 objc_public_flag = 0;
663 objc_start_category_implementation (tree class, tree categ)
665 objc_implementation_context
666 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
668 = continue_class (objc_implementation_context);
672 objc_continue_implementation (void)
675 = continue_class (objc_implementation_context);
679 objc_finish_implementation (void)
682 if (flag_objc_call_cxx_cdtors)
683 objc_generate_cxx_cdtors ();
686 if (objc_implementation_context)
688 finish_class (objc_implementation_context);
689 objc_ivar_chain = NULL_TREE;
690 objc_implementation_context = NULL_TREE;
693 warning (0, "%<@end%> must appear in an @implementation context");
697 objc_set_visibility (int visibility)
699 objc_public_flag = visibility;
703 objc_set_method_type (enum tree_code type)
705 objc_inherit_code = (type == PLUS_EXPR
707 : INSTANCE_METHOD_DECL);
711 objc_build_method_signature (tree rettype, tree selector,
712 tree optparms, bool ellipsis)
714 return build_method_decl (objc_inherit_code, rettype, selector,
719 objc_add_method_declaration (tree decl)
721 if (!objc_interface_context)
722 fatal_error ("method declaration not in @interface context");
724 objc_add_method (objc_interface_context,
726 objc_inherit_code == CLASS_METHOD_DECL);
730 objc_start_method_definition (tree decl)
732 if (!objc_implementation_context)
733 fatal_error ("method definition not in @implementation context");
735 objc_add_method (objc_implementation_context,
737 objc_inherit_code == CLASS_METHOD_DECL);
738 start_method_def (decl);
742 objc_add_instance_variable (tree decl)
744 (void) add_instance_variable (objc_ivar_context,
749 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
753 objc_is_reserved_word (tree ident)
755 unsigned char code = C_RID_CODE (ident);
757 return (OBJC_IS_AT_KEYWORD (code)
759 || code == RID_CLASS || code == RID_PUBLIC
760 || code == RID_PROTECTED || code == RID_PRIVATE
761 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
766 /* Return true if TYPE is 'id'. */
769 objc_is_object_id (tree type)
771 return OBJC_TYPE_NAME (type) == objc_object_id;
775 objc_is_class_id (tree type)
777 return OBJC_TYPE_NAME (type) == objc_class_id;
782 objc_types_compatible_p (tree type1, tree type2)
785 if (objc_is_object_ptr (type1) || objc_is_object_ptr (type2)
786 || objc_is_class_name (type1) || objc_is_class_name (type2))
788 return lhd_types_compatible_p (type1, type2);
793 return cxx_types_compatible_p (type1, type2);
795 return c_types_compatible_p (type1, type2);
801 /* Return 1 if LHS and RHS are compatible types for assignment or
802 various other operations. Return 0 if they are incompatible, and
803 return -1 if we choose to not decide (because the types are really
804 just C types, not ObjC specific ones). When the operation is
805 REFLEXIVE (typically comparisons), check for compatibility in
806 either direction; when it's not (typically assignments), don't.
808 This function is called in two cases: when both lhs and rhs are
809 pointers to records (in which case we check protocols too), and
810 when both lhs and rhs are records (in which case we check class
813 Warnings about classes/protocols not implementing a protocol are
814 emitted here (multiple of those warnings might be emitted for a
815 single line!); generic warnings about incompatible assignments and
816 lacks of casts in comparisons are/must be emitted by the caller if
821 objc_comptypes (tree lhs, tree rhs, int reflexive)
823 /* New clause for protocols. */
825 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
826 manage the ObjC ones, and leave the rest to the C code. */
827 if (TREE_CODE (lhs) == POINTER_TYPE
828 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
829 && TREE_CODE (rhs) == POINTER_TYPE
830 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
832 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (lhs);
833 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (rhs);
837 tree lproto, lproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (lhs));
838 tree rproto, rproto_list;
841 /* <Protocol> = <Protocol> */
844 /* Class <Protocol> != id <Protocol>;
845 id <Protocol> != Class <Protocol> */
846 if (IS_ID (lhs) != IS_ID (rhs))
849 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
853 /* An assignment between objects of type 'id
854 <Protocol>'; make sure the protocol on the lhs is
855 supported by the object on the rhs. */
856 for (lproto = lproto_list; lproto;
857 lproto = TREE_CHAIN (lproto))
859 p = TREE_VALUE (lproto);
860 rproto = lookup_protocol_in_reflist (rproto_list, p);
864 (0, "object does not conform to the %qs protocol",
865 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
871 /* Obscure case - a comparison between two objects
872 of type 'id <Protocol>'. Check that either the
873 protocol on the lhs is supported by the object on
874 the rhs, or viceversa. */
876 /* Check if the protocol on the lhs is supported by the
877 object on the rhs. */
878 for (lproto = lproto_list; lproto;
879 lproto = TREE_CHAIN (lproto))
881 p = TREE_VALUE (lproto);
882 rproto = lookup_protocol_in_reflist (rproto_list, p);
886 /* Check failed - check if the protocol on the rhs
887 is supported by the object on the lhs. */
888 for (rproto = rproto_list; rproto;
889 rproto = TREE_CHAIN (rproto))
891 p = TREE_VALUE (rproto);
892 lproto = lookup_protocol_in_reflist (lproto_list,
897 /* This check failed too: incompatible */
907 /* <Protocol> = <class> * */
908 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
910 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
913 /* Class <Protocol> != <class> * */
917 /* Make sure the protocol is supported by the object on
919 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
921 p = TREE_VALUE (lproto);
923 rinter = lookup_interface (rname);
925 while (rinter && !rproto)
929 rproto_list = CLASS_PROTOCOL_LIST (rinter);
930 rproto = lookup_protocol_in_reflist (rproto_list, p);
931 /* If the underlying ObjC class does not have
932 the protocol we're looking for, check for "one-off"
933 protocols (e.g., `NSObject<MyProt> *foo;') attached
935 if (!rproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (rhs)))
937 rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
938 rproto = lookup_protocol_in_reflist (rproto_list, p);
941 /* Check for protocols adopted by categories. */
942 cat = CLASS_CATEGORY_LIST (rinter);
943 while (cat && !rproto)
945 rproto_list = CLASS_PROTOCOL_LIST (cat);
946 rproto = lookup_protocol_in_reflist (rproto_list, p);
947 cat = CLASS_CATEGORY_LIST (cat);
950 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
954 warning (0, "class %qs does not implement the %qs protocol",
955 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
956 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
960 /* id <Protocol> = id; Class <Protocol> = id */
961 else if (objc_is_object_id (TREE_TYPE (rhs)))
965 /* id <Protocol> != Class; Class <Protocol> = Class */
966 else if (objc_is_class_id (TREE_TYPE (rhs)))
968 return IS_CLASS (lhs);
970 /* <Protocol> = ?? : let comptypes decide. */
973 else if (rhs_is_proto)
975 /* <class> * = <Protocol> */
976 if (TYPED_OBJECT (TREE_TYPE (lhs)))
978 /* <class> * != Class <Protocol> */
984 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
986 tree rproto, rproto_list = TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs));
988 /* Make sure the protocol is supported by the object on
990 for (rproto = rproto_list; rproto;
991 rproto = TREE_CHAIN (rproto))
993 tree p = TREE_VALUE (rproto);
995 rinter = lookup_interface (rname);
997 while (rinter && !lproto)
1001 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1002 lproto = lookup_protocol_in_reflist (lproto_list, p);
1003 /* If the underlying ObjC class does not
1004 have the protocol we're looking for,
1005 check for "one-off" protocols (e.g.,
1006 `NSObject<MyProt> *foo;') attached to the
1008 if (!lproto && TYPE_HAS_OBJC_INFO (TREE_TYPE (lhs)))
1010 lproto_list = TYPE_OBJC_PROTOCOL_LIST
1012 lproto = lookup_protocol_in_reflist
1016 /* Check for protocols adopted by categories. */
1017 cat = CLASS_CATEGORY_LIST (rinter);
1018 while (cat && !lproto)
1020 lproto_list = CLASS_PROTOCOL_LIST (cat);
1021 lproto = lookup_protocol_in_reflist (lproto_list,
1023 cat = CLASS_CATEGORY_LIST (cat);
1026 rinter = lookup_interface (CLASS_SUPER_NAME
1031 warning (0, "class %qs does not implement the %qs protocol",
1032 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1034 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1041 /* id = id <Protocol>; id = Class <Protocol> */
1042 else if (objc_is_object_id (TREE_TYPE (lhs)))
1046 /* Class != id <Protocol>; Class = Class <Protocol> */
1047 else if (objc_is_class_id (TREE_TYPE (lhs)))
1049 return IS_CLASS (rhs);
1051 /* ??? = <Protocol> : let comptypes decide */
1059 /* Attention: we shouldn't defer to comptypes here. One bad
1060 side effect would be that we might loose the REFLEXIVE
1063 lhs = TREE_TYPE (lhs);
1064 rhs = TREE_TYPE (rhs);
1068 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1070 /* Nothing to do with ObjC - let immediately comptypes take
1071 responsibility for checking. */
1075 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1077 'Object *o = [[Object alloc] init]; falls
1078 in the case <class> * = `id'.
1080 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1081 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1084 /* `id' = `Class', `Class' = `id' */
1086 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1087 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1090 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1091 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1092 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1095 /* `<class> *' = `<class> *' */
1097 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1099 tree lname = OBJC_TYPE_NAME (lhs);
1100 tree rname = OBJC_TYPE_NAME (rhs);
1106 /* If the left hand side is a super class of the right hand side,
1108 for (inter = lookup_interface (rname); inter;
1109 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1110 if (lname == CLASS_SUPER_NAME (inter))
1113 /* Allow the reverse when reflexive. */
1115 for (inter = lookup_interface (lname); inter;
1116 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1117 if (rname == CLASS_SUPER_NAME (inter))
1123 /* Not an ObjC type - let comptypes do the check. */
1127 /* Called from finish_decl. */
1130 objc_check_decl (tree decl)
1132 tree type = TREE_TYPE (decl);
1134 if (TREE_CODE (type) != RECORD_TYPE)
1136 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1137 error ("statically allocated instance of Objective-C class %qs",
1138 IDENTIFIER_POINTER (type));
1141 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1142 either name an Objective-C class, or refer to the special 'id' or 'Class'
1143 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1146 objc_get_protocol_qualified_type (tree interface, tree protocols)
1148 /* If INTERFACE is not provided, default to 'id'. */
1149 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1150 bool is_ptr = (type != NULL_TREE);
1154 type = objc_is_class_name (interface);
1157 type = xref_tag (RECORD_TYPE, type);
1164 type = build_variant_type_copy (type);
1166 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1170 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1171 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1172 type = TREE_TYPE (type);
1175 /* Look up protocols and install in lang specific list. */
1176 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1177 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1179 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1180 return the pointer to the new pointee variant. */
1182 type = TYPE_POINTER_TO (type);
1184 TYPE_OBJC_INTERFACE (type)
1185 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1191 /* Check for circular dependencies in protocols. The arguments are
1192 PROTO, the protocol to check, and LIST, a list of protocol it
1196 check_protocol_recursively (tree proto, tree list)
1200 for (p = list; p; p = TREE_CHAIN (p))
1202 tree pp = TREE_VALUE (p);
1204 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1205 pp = lookup_protocol (pp);
1208 fatal_error ("protocol %qs has circular dependency",
1209 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1211 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1215 /* Look up PROTOCOLS, and return a list of those that are found.
1216 If none are found, return NULL. */
1219 lookup_and_install_protocols (tree protocols)
1222 tree return_value = NULL_TREE;
1224 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1226 tree ident = TREE_VALUE (proto);
1227 tree p = lookup_protocol (ident);
1230 error ("cannot find protocol declaration for %qs",
1231 IDENTIFIER_POINTER (ident));
1233 return_value = chainon (return_value,
1234 build_tree_list (NULL_TREE, p));
1237 return return_value;
1240 /* Create a declaration for field NAME of a given TYPE. */
1243 create_field_decl (tree type, const char *name)
1245 return build_decl (FIELD_DECL, get_identifier (name), type);
1248 /* Create a global, static declaration for variable NAME of a given TYPE. The
1249 finish_var_decl() routine will need to be called on it afterwards. */
1252 start_var_decl (tree type, const char *name)
1254 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1256 TREE_STATIC (var) = 1;
1257 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1258 DECL_IGNORED_P (var) = 1;
1259 DECL_ARTIFICIAL (var) = 1;
1260 DECL_CONTEXT (var) = NULL_TREE;
1262 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1268 /* Finish off the variable declaration created by start_var_decl(). */
1271 finish_var_decl (tree var, tree initializer)
1273 finish_decl (var, initializer, NULL_TREE);
1274 /* Ensure that the variable actually gets output. */
1275 mark_decl_referenced (var);
1276 /* Mark the decl to avoid "defined but not used" warning. */
1277 TREE_USED (var) = 1;
1280 /* Find the decl for the constant string class reference. This is only
1281 used for the NeXT runtime. */
1284 setup_string_decl (void)
1289 /* %s in format will provide room for terminating null */
1290 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1291 + strlen (constant_string_class_name);
1292 name = xmalloc (length);
1293 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1294 constant_string_class_name);
1295 constant_string_global_id = get_identifier (name);
1296 string_class_decl = lookup_name (constant_string_global_id);
1298 return string_class_decl;
1301 /* Purpose: "play" parser, creating/installing representations
1302 of the declarations that are required by Objective-C.
1306 type_spec--------->sc_spec
1307 (tree_list) (tree_list)
1310 identifier_node identifier_node */
1313 synth_module_prologue (void)
1316 enum debug_info_type save_write_symbols = write_symbols;
1317 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1319 /* Suppress outputting debug symbols, because
1320 dbxout_init hasn'r been called yet. */
1321 write_symbols = NO_DEBUG;
1322 debug_hooks = &do_nothing_debug_hooks;
1325 push_lang_context (lang_name_c); /* extern "C" */
1328 /* The following are also defined in <objc/objc.h> and friends. */
1330 objc_object_id = get_identifier (TAG_OBJECT);
1331 objc_class_id = get_identifier (TAG_CLASS);
1333 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1334 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1336 objc_object_type = build_pointer_type (objc_object_reference);
1337 objc_class_type = build_pointer_type (objc_class_reference);
1339 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1340 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1342 /* Declare the 'id' and 'Class' typedefs. */
1344 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1347 DECL_IN_SYSTEM_HEADER (type) = 1;
1348 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1351 DECL_IN_SYSTEM_HEADER (type) = 1;
1353 /* Forward-declare '@interface Protocol'. */
1355 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1356 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1357 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1360 /* Declare type of selector-objects that represent an operation name. */
1362 if (flag_next_runtime)
1363 /* `struct objc_selector *' */
1365 = build_pointer_type (xref_tag (RECORD_TYPE,
1366 get_identifier (TAG_SELECTOR)));
1368 /* `const struct objc_selector *' */
1370 = build_pointer_type
1371 (build_qualified_type (xref_tag (RECORD_TYPE,
1372 get_identifier (TAG_SELECTOR)),
1375 /* Declare receiver type used for dispatching messages to 'super'. */
1377 /* `struct objc_super *' */
1378 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1379 get_identifier (TAG_SUPER)));
1381 /* Declare pointers to method and ivar lists. */
1382 objc_method_list_ptr = build_pointer_type
1383 (xref_tag (RECORD_TYPE,
1384 get_identifier (UTAG_METHOD_LIST)));
1385 objc_method_proto_list_ptr
1386 = build_pointer_type (xref_tag (RECORD_TYPE,
1387 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1388 objc_ivar_list_ptr = build_pointer_type
1389 (xref_tag (RECORD_TYPE,
1390 get_identifier (UTAG_IVAR_LIST)));
1392 if (flag_next_runtime)
1394 /* NB: In order to call one of the ..._stret (struct-returning)
1395 functions, the function *MUST* first be cast to a signature that
1396 corresponds to the actual ObjC method being invoked. This is
1397 what is done by the build_objc_method_call() routine below. */
1399 /* id objc_msgSend (id, SEL, ...); */
1400 /* id objc_msgSendNonNil (id, SEL, ...); */
1401 /* id objc_msgSend_stret (id, SEL, ...); */
1402 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1404 = build_function_type (objc_object_type,
1405 tree_cons (NULL_TREE, objc_object_type,
1406 tree_cons (NULL_TREE, objc_selector_type,
1408 umsg_decl = builtin_function (TAG_MSGSEND,
1409 type, 0, NOT_BUILT_IN,
1411 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1412 type, 0, NOT_BUILT_IN,
1414 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1415 type, 0, NOT_BUILT_IN,
1417 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1418 type, 0, NOT_BUILT_IN,
1421 /* id objc_msgSend_Fast (id, SEL, ...)
1422 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1423 #ifdef OFFS_MSGSEND_FAST
1424 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1425 type, 0, NOT_BUILT_IN,
1427 DECL_ATTRIBUTES (umsg_fast_decl)
1428 = tree_cons (get_identifier ("hard_coded_address"),
1429 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1432 /* No direct dispatch availible. */
1433 umsg_fast_decl = umsg_decl;
1436 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1437 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1439 = build_function_type (objc_object_type,
1440 tree_cons (NULL_TREE, objc_super_type,
1441 tree_cons (NULL_TREE, objc_selector_type,
1443 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1444 type, 0, NOT_BUILT_IN,
1446 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1447 type, 0, NOT_BUILT_IN, 0,
1452 /* GNU runtime messenger entry points. */
1454 /* typedef id (*IMP)(id, SEL, ...); */
1456 = build_pointer_type
1457 (build_function_type (objc_object_type,
1458 tree_cons (NULL_TREE, objc_object_type,
1459 tree_cons (NULL_TREE, objc_selector_type,
1462 /* IMP objc_msg_lookup (id, SEL); */
1464 = build_function_type (IMP_type,
1465 tree_cons (NULL_TREE, objc_object_type,
1466 tree_cons (NULL_TREE, objc_selector_type,
1467 OBJC_VOID_AT_END)));
1468 umsg_decl = builtin_function (TAG_MSGSEND,
1469 type, 0, NOT_BUILT_IN,
1472 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1474 = build_function_type (IMP_type,
1475 tree_cons (NULL_TREE, objc_super_type,
1476 tree_cons (NULL_TREE, objc_selector_type,
1477 OBJC_VOID_AT_END)));
1478 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1479 type, 0, NOT_BUILT_IN,
1482 /* The following GNU runtime entry point is called to initialize
1485 __objc_exec_class (void *); */
1487 = build_function_type (void_type_node,
1488 tree_cons (NULL_TREE, ptr_type_node,
1490 execclass_decl = builtin_function (TAG_EXECCLASS,
1491 type, 0, NOT_BUILT_IN,
1495 /* id objc_getClass (const char *); */
1497 type = build_function_type (objc_object_type,
1498 tree_cons (NULL_TREE,
1499 const_string_type_node,
1503 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1506 /* id objc_getMetaClass (const char *); */
1508 objc_get_meta_class_decl
1509 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1511 build_class_template ();
1512 build_super_template ();
1513 build_protocol_template ();
1514 build_category_template ();
1515 build_objc_exception_stuff ();
1517 if (flag_next_runtime)
1518 build_next_objc_exception_stuff ();
1520 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1522 if (! flag_next_runtime)
1523 build_selector_table_decl ();
1525 /* Forward declare constant_string_id and constant_string_type. */
1526 if (!constant_string_class_name)
1527 constant_string_class_name = default_constant_string_class_name;
1529 constant_string_id = get_identifier (constant_string_class_name);
1530 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1532 /* Pre-build the following entities - for speed/convenience. */
1533 self_id = get_identifier ("self");
1534 ucmd_id = get_identifier ("_cmd");
1536 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1537 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1541 pop_lang_context ();
1544 write_symbols = save_write_symbols;
1545 debug_hooks = save_hooks;
1548 /* Ensure that the ivar list for NSConstantString/NXConstantString
1549 (or whatever was specified via `-fconstant-string-class')
1550 contains fields at least as large as the following three, so that
1551 the runtime can stomp on them with confidence:
1553 struct STRING_OBJECT_CLASS_NAME
1557 unsigned int length;
1561 check_string_class_template (void)
1563 tree field_decl = TYPE_FIELDS (constant_string_type);
1565 #define AT_LEAST_AS_LARGE_AS(F, T) \
1566 (F && TREE_CODE (F) == FIELD_DECL \
1567 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1568 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1570 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1573 field_decl = TREE_CHAIN (field_decl);
1574 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1577 field_decl = TREE_CHAIN (field_decl);
1578 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1580 #undef AT_LEAST_AS_LARGE_AS
1583 /* Avoid calling `check_string_class_template ()' more than once. */
1584 static GTY(()) int string_layout_checked;
1586 /* Custom build_string which sets TREE_TYPE! */
1589 my_build_string (int len, const char *str)
1591 return fix_string_type (build_string (len, str));
1596 string_hash (const void *ptr)
1598 tree str = ((struct string_descriptor *)ptr)->literal;
1599 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1600 int i, len = TREE_STRING_LENGTH (str);
1603 for (i = 0; i < len; i++)
1604 h = ((h * 613) + p[i]);
1610 string_eq (const void *ptr1, const void *ptr2)
1612 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1613 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1614 int len1 = TREE_STRING_LENGTH (str1);
1616 return (len1 == TREE_STRING_LENGTH (str2)
1617 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1621 /* Given a chain of STRING_CST's, build a static instance of
1622 NXConstantString which points at the concatenation of those
1623 strings. We place the string object in the __string_objects
1624 section of the __OBJC segment. The Objective-C runtime will
1625 initialize the isa pointers of the string objects to point at the
1626 NXConstantString class object. */
1629 objc_build_string_object (tree string)
1631 tree initlist, constructor, constant_string_class;
1634 struct string_descriptor *desc, key;
1637 /* Prep the string argument. */
1638 string = fix_string_type (string);
1639 TREE_SET_CODE (string, STRING_CST);
1640 length = TREE_STRING_LENGTH (string) - 1;
1642 /* Check whether the string class being used actually exists and has the
1643 correct ivar layout. */
1644 if (!string_layout_checked)
1646 string_layout_checked = -1;
1647 constant_string_class = lookup_interface (constant_string_id);
1649 if (!constant_string_class
1650 || !(constant_string_type
1651 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1652 error ("cannot find interface declaration for %qs",
1653 IDENTIFIER_POINTER (constant_string_id));
1654 /* The NSConstantString/NXConstantString ivar layout is now known. */
1655 else if (!check_string_class_template ())
1656 error ("interface %qs does not have valid constant string layout",
1657 IDENTIFIER_POINTER (constant_string_id));
1658 /* For the NeXT runtime, we can generate a literal reference
1659 to the string class, don't need to run a constructor. */
1660 else if (flag_next_runtime && !setup_string_decl ())
1661 error ("cannot find reference tag for class %qs",
1662 IDENTIFIER_POINTER (constant_string_id));
1665 string_layout_checked = 1; /* Success! */
1666 add_class_reference (constant_string_id);
1670 if (string_layout_checked == -1)
1671 return error_mark_node;
1673 /* Perhaps we already constructed a constant string just like this one? */
1674 key.literal = string;
1675 loc = htab_find_slot (string_htab, &key, INSERT);
1681 *loc = desc = ggc_alloc (sizeof (*desc));
1682 desc->literal = string;
1684 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1685 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1686 fields = TYPE_FIELDS (constant_string_type);
1688 = build_tree_list (fields,
1690 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1691 : build_int_cst (NULL_TREE, 0));
1692 fields = TREE_CHAIN (fields);
1693 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1695 fields = TREE_CHAIN (fields);
1696 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1698 constructor = objc_build_constructor (constant_string_type,
1699 nreverse (initlist));
1700 TREE_INVARIANT (constructor) = true;
1702 if (!flag_next_runtime)
1704 = objc_add_static_instance (constructor, constant_string_type);
1707 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1708 DECL_INITIAL (var) = constructor;
1709 TREE_STATIC (var) = 1;
1710 pushdecl_top_level (var);
1713 desc->constructor = constructor;
1716 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1721 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1723 static GTY(()) int num_static_inst;
1726 objc_add_static_instance (tree constructor, tree class_decl)
1731 /* Find the list of static instances for the CLASS_DECL. Create one if
1733 for (chain = &objc_static_instances;
1734 *chain && TREE_VALUE (*chain) != class_decl;
1735 chain = &TREE_CHAIN (*chain));
1738 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1739 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1742 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1743 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1744 DECL_COMMON (decl) = 1;
1745 TREE_STATIC (decl) = 1;
1746 DECL_ARTIFICIAL (decl) = 1;
1747 DECL_INITIAL (decl) = constructor;
1749 /* We may be writing something else just now.
1750 Postpone till end of input. */
1751 DECL_DEFER_OUTPUT (decl) = 1;
1752 pushdecl_top_level (decl);
1753 rest_of_decl_compilation (decl, 1, 0);
1755 /* Add the DECL to the head of this CLASS' list. */
1756 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1761 /* Build a static constant CONSTRUCTOR
1762 with type TYPE and elements ELTS. */
1765 objc_build_constructor (tree type, tree elts)
1767 tree constructor = build_constructor (type, elts);
1769 TREE_CONSTANT (constructor) = 1;
1770 TREE_STATIC (constructor) = 1;
1771 TREE_READONLY (constructor) = 1;
1774 /* Adjust for impedance mismatch. We should figure out how to build
1775 CONSTRUCTORs that consistently please both the C and C++ gods. */
1776 if (!TREE_PURPOSE (elts))
1777 TREE_TYPE (constructor) = NULL_TREE;
1778 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1784 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1786 /* Predefine the following data type:
1794 void *defs[cls_def_cnt + cat_def_cnt];
1798 build_objc_symtab_template (void)
1800 tree field_decl, field_decl_chain;
1802 objc_symtab_template
1803 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1805 /* long sel_ref_cnt; */
1806 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1807 field_decl_chain = field_decl;
1810 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1812 chainon (field_decl_chain, field_decl);
1814 /* short cls_def_cnt; */
1815 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1816 chainon (field_decl_chain, field_decl);
1818 /* short cat_def_cnt; */
1819 field_decl = create_field_decl (short_integer_type_node,
1821 chainon (field_decl_chain, field_decl);
1823 if (imp_count || cat_count || !flag_next_runtime)
1825 /* void *defs[imp_count + cat_count (+ 1)]; */
1826 /* NB: The index is one less than the size of the array. */
1827 int index = imp_count + cat_count
1828 + (flag_next_runtime? -1: 0);
1829 field_decl = create_field_decl
1832 build_index_type (build_int_cst (NULL_TREE, index))),
1834 chainon (field_decl_chain, field_decl);
1837 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1840 /* Create the initial value for the `defs' field of _objc_symtab.
1841 This is a CONSTRUCTOR. */
1844 init_def_list (tree type)
1846 tree expr, initlist = NULL_TREE;
1847 struct imp_entry *impent;
1850 for (impent = imp_list; impent; impent = impent->next)
1852 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1854 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1855 initlist = tree_cons (NULL_TREE, expr, initlist);
1860 for (impent = imp_list; impent; impent = impent->next)
1862 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1864 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1865 initlist = tree_cons (NULL_TREE, expr, initlist);
1869 if (!flag_next_runtime)
1871 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1874 if (static_instances_decl)
1875 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1877 expr = build_int_cst (NULL_TREE, 0);
1879 initlist = tree_cons (NULL_TREE, expr, initlist);
1882 return objc_build_constructor (type, nreverse (initlist));
1885 /* Construct the initial value for all of _objc_symtab. */
1888 init_objc_symtab (tree type)
1892 /* sel_ref_cnt = { ..., 5, ... } */
1894 initlist = build_tree_list (NULL_TREE,
1895 build_int_cst (long_integer_type_node, 0));
1897 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1899 if (flag_next_runtime || ! sel_ref_chain)
1900 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1903 = tree_cons (NULL_TREE,
1904 convert (build_pointer_type (objc_selector_type),
1905 build_unary_op (ADDR_EXPR,
1906 UOBJC_SELECTOR_TABLE_decl, 1)),
1909 /* cls_def_cnt = { ..., 5, ... } */
1911 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1913 /* cat_def_cnt = { ..., 5, ... } */
1915 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1917 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1919 if (imp_count || cat_count || !flag_next_runtime)
1922 tree field = TYPE_FIELDS (type);
1923 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1925 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1929 return objc_build_constructor (type, nreverse (initlist));
1932 /* Generate forward declarations for metadata such as
1933 'OBJC_CLASS_...'. */
1936 build_metadata_decl (const char *name, tree type)
1940 /* struct TYPE NAME_<name>; */
1941 decl = start_var_decl (type, synth_id_with_class_suffix
1943 objc_implementation_context));
1948 /* Push forward-declarations of all the categories so that
1949 init_def_list can use them in a CONSTRUCTOR. */
1952 forward_declare_categories (void)
1954 struct imp_entry *impent;
1955 tree sav = objc_implementation_context;
1957 for (impent = imp_list; impent; impent = impent->next)
1959 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1961 /* Set an invisible arg to synth_id_with_class_suffix. */
1962 objc_implementation_context = impent->imp_context;
1963 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1964 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1965 objc_category_template);
1968 objc_implementation_context = sav;
1971 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1972 and initialized appropriately. */
1975 generate_objc_symtab_decl (void)
1977 /* forward declare categories */
1979 forward_declare_categories ();
1981 build_objc_symtab_template ();
1982 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1983 finish_var_decl (UOBJC_SYMBOLS_decl,
1984 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
1988 init_module_descriptor (tree type)
1990 tree initlist, expr;
1992 /* version = { 1, ... } */
1994 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
1995 initlist = build_tree_list (NULL_TREE, expr);
1997 /* size = { ..., sizeof (struct _objc_module), ... } */
1999 expr = convert (long_integer_type_node,
2000 size_in_bytes (objc_module_template));
2001 initlist = tree_cons (NULL_TREE, expr, initlist);
2003 /* name = { ..., "foo.m", ... } */
2005 expr = add_objc_string (get_identifier (input_filename), class_names);
2006 initlist = tree_cons (NULL_TREE, expr, initlist);
2008 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2010 if (UOBJC_SYMBOLS_decl)
2011 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2013 expr = build_int_cst (NULL_TREE, 0);
2014 initlist = tree_cons (NULL_TREE, expr, initlist);
2016 return objc_build_constructor (type, nreverse (initlist));
2019 /* Write out the data structures to describe Objective C classes defined.
2021 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2024 build_module_descriptor (void)
2026 tree field_decl, field_decl_chain;
2029 push_lang_context (lang_name_c); /* extern "C" */
2032 objc_module_template
2033 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2036 field_decl = create_field_decl (long_integer_type_node, "version");
2037 field_decl_chain = field_decl;
2040 field_decl = create_field_decl (long_integer_type_node, "size");
2041 chainon (field_decl_chain, field_decl);
2044 field_decl = create_field_decl (string_type_node, "name");
2045 chainon (field_decl_chain, field_decl);
2047 /* struct _objc_symtab *symtab; */
2049 = create_field_decl (build_pointer_type
2050 (xref_tag (RECORD_TYPE,
2051 get_identifier (UTAG_SYMTAB))),
2053 chainon (field_decl_chain, field_decl);
2055 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2057 /* Create an instance of "_objc_module". */
2058 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2059 finish_var_decl (UOBJC_MODULES_decl,
2060 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2063 pop_lang_context ();
2067 /* The GNU runtime requires us to provide a static initializer function
2070 static void __objc_gnu_init (void) {
2071 __objc_exec_class (&L_OBJC_MODULES);
2075 build_module_initializer_routine (void)
2080 push_lang_context (lang_name_c); /* extern "C" */
2083 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2084 objc_start_function (get_identifier (TAG_GNUINIT),
2085 build_function_type (void_type_node,
2087 NULL_TREE, objc_get_parm_info (0));
2089 body = c_begin_compound_stmt (true);
2090 add_stmt (build_function_call
2094 build_unary_op (ADDR_EXPR,
2095 UOBJC_MODULES_decl, 0))));
2096 add_stmt (c_end_compound_stmt (body, true));
2098 TREE_PUBLIC (current_function_decl) = 0;
2101 /* For Objective-C++, we will need to call __objc_gnu_init
2102 from objc_generate_static_init_call() below. */
2103 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2106 GNU_INIT_decl = current_function_decl;
2110 pop_lang_context ();
2115 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2116 to be called by the module initializer routine. */
2119 objc_static_init_needed_p (void)
2121 return (GNU_INIT_decl != NULL_TREE);
2124 /* Generate a call to the __objc_gnu_init initializer function. */
2127 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2129 add_stmt (build_stmt (EXPR_STMT,
2130 build_function_call (GNU_INIT_decl, NULL_TREE)));
2134 #endif /* OBJCPLUS */
2136 /* Return the DECL of the string IDENT in the SECTION. */
2139 get_objc_string_decl (tree ident, enum string_section section)
2143 if (section == class_names)
2144 chain = class_names_chain;
2145 else if (section == meth_var_names)
2146 chain = meth_var_names_chain;
2147 else if (section == meth_var_types)
2148 chain = meth_var_types_chain;
2152 for (; chain != 0; chain = TREE_CHAIN (chain))
2153 if (TREE_VALUE (chain) == ident)
2154 return (TREE_PURPOSE (chain));
2160 /* Output references to all statically allocated objects. Return the DECL
2161 for the array built. */
2164 generate_static_references (void)
2166 tree decls = NULL_TREE, expr = NULL_TREE;
2167 tree class_name, class, decl, initlist;
2168 tree cl_chain, in_chain, type
2169 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2170 int num_inst, num_class;
2173 if (flag_next_runtime)
2176 for (cl_chain = objc_static_instances, num_class = 0;
2177 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2179 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2180 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2182 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2183 decl = start_var_decl (type, buf);
2185 /* Output {class_name, ...}. */
2186 class = TREE_VALUE (cl_chain);
2187 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2188 initlist = build_tree_list (NULL_TREE,
2189 build_unary_op (ADDR_EXPR, class_name, 1));
2191 /* Output {..., instance, ...}. */
2192 for (in_chain = TREE_PURPOSE (cl_chain);
2193 in_chain; in_chain = TREE_CHAIN (in_chain))
2195 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2196 initlist = tree_cons (NULL_TREE, expr, initlist);
2199 /* Output {..., NULL}. */
2200 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2202 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2203 finish_var_decl (decl, expr);
2205 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2208 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2209 expr = objc_build_constructor (type, nreverse (decls));
2210 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2211 finish_var_decl (static_instances_decl, expr);
2214 /* Output all strings. */
2217 generate_strings (void)
2219 tree chain, string_expr;
2220 tree string, decl, type;
2222 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2224 string = TREE_VALUE (chain);
2225 decl = TREE_PURPOSE (chain);
2226 type = build_array_type
2229 (build_int_cst (NULL_TREE,
2230 IDENTIFIER_LENGTH (string))));
2231 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2232 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2233 IDENTIFIER_POINTER (string));
2234 finish_var_decl (decl, string_expr);
2237 for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
2239 string = TREE_VALUE (chain);
2240 decl = TREE_PURPOSE (chain);
2241 type = build_array_type
2244 (build_int_cst (NULL_TREE,
2245 IDENTIFIER_LENGTH (string))));
2246 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2247 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2248 IDENTIFIER_POINTER (string));
2249 finish_var_decl (decl, string_expr);
2252 for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
2254 string = TREE_VALUE (chain);
2255 decl = TREE_PURPOSE (chain);
2256 type = build_array_type
2259 (build_int_cst (NULL_TREE,
2260 IDENTIFIER_LENGTH (string))));
2261 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2262 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2263 IDENTIFIER_POINTER (string));
2264 finish_var_decl (decl, string_expr);
2268 static GTY(()) int selector_reference_idx;
2271 build_selector_reference_decl (void)
2276 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2277 decl = start_var_decl (objc_selector_type, buf);
2283 build_selector_table_decl (void)
2287 if (flag_typed_selectors)
2289 build_selector_template ();
2290 temp = build_array_type (objc_selector_template, NULL_TREE);
2293 temp = build_array_type (objc_selector_type, NULL_TREE);
2295 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2298 /* Just a handy wrapper for add_objc_string. */
2301 build_selector (tree ident)
2303 return convert (objc_selector_type,
2304 add_objc_string (ident, meth_var_names));
2308 build_selector_translation_table (void)
2310 tree chain, initlist = NULL_TREE;
2312 tree decl = NULL_TREE;
2314 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2318 if (warn_selector && objc_implementation_context)
2322 for (method_chain = meth_var_names_chain;
2324 method_chain = TREE_CHAIN (method_chain))
2326 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2335 if (flag_next_runtime && TREE_PURPOSE (chain))
2336 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2338 loc = &input_location;
2339 warning (0, "%Hcreating selector for nonexistent method %qE",
2340 loc, TREE_VALUE (chain));
2344 expr = build_selector (TREE_VALUE (chain));
2345 /* add one for the '\0' character */
2346 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2348 if (flag_next_runtime)
2350 decl = TREE_PURPOSE (chain);
2351 finish_var_decl (decl, expr);
2355 if (flag_typed_selectors)
2357 tree eltlist = NULL_TREE;
2358 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2359 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2360 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2361 expr = objc_build_constructor (objc_selector_template,
2362 nreverse (eltlist));
2365 initlist = tree_cons (NULL_TREE, expr, initlist);
2369 if (! flag_next_runtime)
2371 /* Cause the selector table (previously forward-declared)
2372 to be actually output. */
2373 initlist = tree_cons (NULL_TREE,
2374 flag_typed_selectors
2375 ? objc_build_constructor
2376 (objc_selector_template,
2377 tree_cons (NULL_TREE,
2378 build_int_cst (NULL_TREE, 0),
2379 tree_cons (NULL_TREE,
2380 build_int_cst (NULL_TREE, 0),
2382 : build_int_cst (NULL_TREE, 0), initlist);
2383 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2384 nreverse (initlist));
2385 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2390 get_proto_encoding (tree proto)
2395 if (! METHOD_ENCODING (proto))
2397 encoding = encode_method_prototype (proto);
2398 METHOD_ENCODING (proto) = encoding;
2401 encoding = METHOD_ENCODING (proto);
2403 return add_objc_string (encoding, meth_var_types);
2406 return build_int_cst (NULL_TREE, 0);
2409 /* sel_ref_chain is a list whose "value" fields will be instances of
2410 identifier_node that represent the selector. */
2413 build_typed_selector_reference (tree ident, tree prototype)
2415 tree *chain = &sel_ref_chain;
2421 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2422 goto return_at_index;
2425 chain = &TREE_CHAIN (*chain);
2428 *chain = tree_cons (prototype, ident, NULL_TREE);
2431 expr = build_unary_op (ADDR_EXPR,
2432 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2433 build_int_cst (NULL_TREE, index)),
2435 return convert (objc_selector_type, expr);
2439 build_selector_reference (tree ident)
2441 tree *chain = &sel_ref_chain;
2447 if (TREE_VALUE (*chain) == ident)
2448 return (flag_next_runtime
2449 ? TREE_PURPOSE (*chain)
2450 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2451 build_int_cst (NULL_TREE, index)));
2454 chain = &TREE_CHAIN (*chain);
2457 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2459 *chain = tree_cons (expr, ident, NULL_TREE);
2461 return (flag_next_runtime
2463 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2464 build_int_cst (NULL_TREE, index)));
2467 static GTY(()) int class_reference_idx;
2470 build_class_reference_decl (void)
2475 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2476 decl = start_var_decl (objc_class_type, buf);
2481 /* Create a class reference, but don't create a variable to reference
2485 add_class_reference (tree ident)
2489 if ((chain = cls_ref_chain))
2494 if (ident == TREE_VALUE (chain))
2498 chain = TREE_CHAIN (chain);
2502 /* Append to the end of the list */
2503 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2506 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2509 /* Get a class reference, creating it if necessary. Also create the
2510 reference variable. */
2513 objc_get_class_reference (tree ident)
2516 bool local_scope = false;
2519 if (processing_template_decl)
2520 /* Must wait until template instantiation time. */
2521 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2522 if (TREE_CODE (ident) == TYPE_DECL)
2524 /* The type must exist in the global namespace. */
2525 if (DECL_CONTEXT (ident) && DECL_CONTEXT (ident) != global_namespace)
2528 ident = DECL_NAME (ident);
2533 if (local_scope || !(ident = objc_is_class_name (ident)))
2535 error ("%qs is not an Objective-C class name or alias",
2536 IDENTIFIER_POINTER (orig_ident));
2537 return error_mark_node;
2540 if (flag_next_runtime && !flag_zero_link)
2545 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2546 if (TREE_VALUE (*chain) == ident)
2548 if (! TREE_PURPOSE (*chain))
2549 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2551 return TREE_PURPOSE (*chain);
2554 decl = build_class_reference_decl ();
2555 *chain = tree_cons (decl, ident, NULL_TREE);
2562 add_class_reference (ident);
2564 params = build_tree_list (NULL_TREE,
2565 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2566 IDENTIFIER_POINTER (ident)));
2568 assemble_external (objc_get_class_decl);
2569 return build_function_call (objc_get_class_decl, params);
2573 /* For each string section we have a chain which maps identifier nodes
2574 to decls for the strings. */
2577 add_objc_string (tree ident, enum string_section section)
2581 if (section == class_names)
2582 chain = &class_names_chain;
2583 else if (section == meth_var_names)
2584 chain = &meth_var_names_chain;
2585 else if (section == meth_var_types)
2586 chain = &meth_var_types_chain;
2592 if (TREE_VALUE (*chain) == ident)
2593 return convert (string_type_node,
2594 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2596 chain = &TREE_CHAIN (*chain);
2599 decl = build_objc_string_decl (section);
2601 *chain = tree_cons (decl, ident, NULL_TREE);
2603 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2606 static GTY(()) int class_names_idx;
2607 static GTY(()) int meth_var_names_idx;
2608 static GTY(()) int meth_var_types_idx;
2611 build_objc_string_decl (enum string_section section)
2616 if (section == class_names)
2617 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2618 else if (section == meth_var_names)
2619 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2620 else if (section == meth_var_types)
2621 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2623 ident = get_identifier (buf);
2625 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2626 DECL_EXTERNAL (decl) = 1;
2627 TREE_PUBLIC (decl) = 0;
2628 TREE_USED (decl) = 1;
2629 TREE_CONSTANT (decl) = 1;
2630 DECL_CONTEXT (decl) = 0;
2631 DECL_ARTIFICIAL (decl) = 1;
2633 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2636 make_decl_rtl (decl);
2637 pushdecl_top_level (decl);
2644 objc_declare_alias (tree alias_ident, tree class_ident)
2646 tree underlying_class;
2649 if (current_namespace != global_namespace) {
2650 error ("Objective-C declarations may only appear in global scope");
2652 #endif /* OBJCPLUS */
2654 if (!(underlying_class = objc_is_class_name (class_ident)))
2655 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2656 else if (objc_is_class_name (alias_ident))
2657 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2659 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2663 objc_declare_class (tree ident_list)
2667 if (current_namespace != global_namespace) {
2668 error ("Objective-C declarations may only appear in global scope");
2670 #endif /* OBJCPLUS */
2672 for (list = ident_list; list; list = TREE_CHAIN (list))
2674 tree ident = TREE_VALUE (list);
2676 if (! objc_is_class_name (ident))
2678 tree record = lookup_name (ident), type = record;
2682 if (TREE_CODE (record) == TYPE_DECL)
2683 type = DECL_ORIGINAL_TYPE (record);
2685 if (!TYPE_HAS_OBJC_INFO (type)
2686 || !TYPE_OBJC_INTERFACE (type))
2688 error ("%qs redeclared as different kind of symbol",
2689 IDENTIFIER_POINTER (ident));
2690 error ("%Jprevious declaration of '%D'",
2695 record = xref_tag (RECORD_TYPE, ident);
2696 INIT_TYPE_OBJC_INFO (record);
2697 TYPE_OBJC_INTERFACE (record) = ident;
2698 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2704 objc_is_class_name (tree ident)
2708 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2709 && identifier_global_value (ident))
2710 ident = identifier_global_value (ident);
2711 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2712 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2714 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2715 ident = OBJC_TYPE_NAME (ident);
2717 if (ident && TREE_CODE (ident) == TYPE_DECL)
2718 ident = DECL_NAME (ident);
2720 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2723 if (lookup_interface (ident))
2726 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2728 if (ident == TREE_VALUE (chain))
2732 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2734 if (ident == TREE_VALUE (chain))
2735 return TREE_PURPOSE (chain);
2741 /* Check whether TYPE is either 'id' or 'Class'. */
2744 objc_is_id (tree type)
2746 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2747 && identifier_global_value (type))
2748 type = identifier_global_value (type);
2750 if (type && TREE_CODE (type) == TYPE_DECL)
2751 type = TREE_TYPE (type);
2753 /* NB: This function may be called before the ObjC front-end has
2754 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2755 return (objc_object_type && type
2756 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2761 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2762 class instance. This is needed by other parts of the compiler to
2763 handle ObjC types gracefully. */
2766 objc_is_object_ptr (tree type)
2770 type = TYPE_MAIN_VARIANT (type);
2771 if (!POINTER_TYPE_P (type))
2774 ret = objc_is_id (type);
2776 ret = objc_is_class_name (TREE_TYPE (type));
2782 objc_is_gcable_type (tree type, int or_strong_p)
2788 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
2790 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
2792 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
2794 type = TREE_TYPE (type);
2795 if (TREE_CODE (type) != RECORD_TYPE)
2797 name = TYPE_NAME (type);
2798 return (objc_is_class_name (name) != NULL_TREE);
2802 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
2804 if (expr == oldexpr)
2807 switch (TREE_CODE (expr))
2810 return build_component_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2813 DECL_NAME (TREE_OPERAND (expr, 1)));
2815 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2818 TREE_OPERAND (expr, 1));
2820 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
2829 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
2832 /* The LHS parameter contains the expression 'outervar->memberspec';
2833 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
2834 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
2837 = objc_substitute_decl
2838 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
2840 = (flag_objc_direct_dispatch
2841 ? objc_assign_ivar_fast_decl
2842 : objc_assign_ivar_decl);
2844 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
2846 func_params = tree_cons (NULL_TREE,
2847 convert (objc_object_type, rhs),
2848 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
2849 tree_cons (NULL_TREE, offs,
2852 assemble_external (func);
2853 return build_function_call (func, func_params);
2857 objc_build_global_assignment (tree lhs, tree rhs)
2859 tree func_params = tree_cons (NULL_TREE,
2860 convert (objc_object_type, rhs),
2861 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
2862 build_unary_op (ADDR_EXPR, lhs, 0)),
2865 assemble_external (objc_assign_global_decl);
2866 return build_function_call (objc_assign_global_decl, func_params);
2870 objc_build_strong_cast_assignment (tree lhs, tree rhs)
2872 tree func_params = tree_cons (NULL_TREE,
2873 convert (objc_object_type, rhs),
2874 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
2875 build_unary_op (ADDR_EXPR, lhs, 0)),
2878 assemble_external (objc_assign_strong_cast_decl);
2879 return build_function_call (objc_assign_strong_cast_decl, func_params);
2883 objc_is_gcable_p (tree expr)
2885 return (TREE_CODE (expr) == COMPONENT_REF
2886 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
2887 : TREE_CODE (expr) == ARRAY_REF
2888 ? (objc_is_gcable_p (TREE_TYPE (expr))
2889 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
2890 : TREE_CODE (expr) == ARRAY_TYPE
2891 ? objc_is_gcable_p (TREE_TYPE (expr))
2893 ? objc_is_gcable_type (expr, 1)
2894 : (objc_is_gcable_p (TREE_TYPE (expr))
2896 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
2900 objc_is_ivar_reference_p (tree expr)
2902 return (TREE_CODE (expr) == ARRAY_REF
2903 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
2904 : TREE_CODE (expr) == COMPONENT_REF
2905 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
2910 objc_is_global_reference_p (tree expr)
2912 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
2913 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
2915 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
2920 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
2922 tree result = NULL_TREE, outer;
2923 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
2925 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
2926 will have been transformed to the form '*(type *)&expr'. */
2927 if (TREE_CODE (lhs) == INDIRECT_REF)
2929 outer = TREE_OPERAND (lhs, 0);
2931 while (!strong_cast_p
2932 && (TREE_CODE (outer) == CONVERT_EXPR
2933 || TREE_CODE (outer) == NOP_EXPR
2934 || TREE_CODE (outer) == NON_LVALUE_EXPR))
2936 tree lhstype = TREE_TYPE (outer);
2938 /* Descend down the cast chain, and record the first objc_gc
2940 if (POINTER_TYPE_P (lhstype))
2943 = lookup_attribute ("objc_gc",
2944 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
2950 outer = TREE_OPERAND (outer, 0);
2954 /* If we have a __strong cast, it trumps all else. */
2957 if (modifycode != NOP_EXPR)
2958 goto invalid_pointer_arithmetic;
2960 if (warn_assign_intercept)
2961 warning (0, "strong-cast assignment has been intercepted");
2963 result = objc_build_strong_cast_assignment (lhs, rhs);
2968 /* the lhs must be of a suitable type, regardless of its underlying
2970 if (!objc_is_gcable_p (lhs))
2976 && (TREE_CODE (outer) == COMPONENT_REF
2977 || TREE_CODE (outer) == ARRAY_REF))
2978 outer = TREE_OPERAND (outer, 0);
2980 if (TREE_CODE (outer) == INDIRECT_REF)
2982 outer = TREE_OPERAND (outer, 0);
2986 outer_gc_p = objc_is_gcable_p (outer);
2988 /* Handle ivar assignments. */
2989 if (objc_is_ivar_reference_p (lhs))
2991 /* if the struct to the left of the ivar is not an Objective-C object (__strong
2992 doesn't cut it here), the best we can do here is suggest a cast. */
2993 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
2995 /* We may still be able to use the global write barrier... */
2996 if (!indirect_p && objc_is_global_reference_p (outer))
2997 goto global_reference;
3000 if (modifycode == NOP_EXPR)
3002 if (warn_assign_intercept)
3003 warning (0, "strong-cast may possibly be needed");
3009 if (modifycode != NOP_EXPR)
3010 goto invalid_pointer_arithmetic;
3012 if (warn_assign_intercept)
3013 warning (0, "instance variable assignment has been intercepted");
3015 result = objc_build_ivar_assignment (outer, lhs, rhs);
3020 /* Likewise, intercept assignment to global/static variables if their type is
3022 if (objc_is_global_reference_p (outer))
3028 if (modifycode != NOP_EXPR)
3030 invalid_pointer_arithmetic:
3032 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3037 if (warn_assign_intercept)
3038 warning (0, "global/static variable assignment has been intercepted");
3040 result = objc_build_global_assignment (lhs, rhs);
3043 /* In all other cases, fall back to the normal mechanism. */
3048 struct interface_tuple GTY(())
3054 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3057 hash_interface (const void *p)
3059 const struct interface_tuple *d = p;
3060 return htab_hash_pointer (d->id);
3064 eq_interface (const void *p1, const void *p2)
3066 const struct interface_tuple *d = p1;
3071 lookup_interface (tree ident)
3074 if (ident && TREE_CODE (ident) == TYPE_DECL)
3075 ident = DECL_NAME (ident);
3078 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3082 struct interface_tuple **slot;
3087 slot = (struct interface_tuple **)
3088 htab_find_slot_with_hash (interface_htab, ident,
3089 htab_hash_pointer (ident),
3092 i = (*slot)->class_name;
3098 /* Implement @defs (<classname>) within struct bodies. */
3101 objc_get_class_ivars (tree class_name)
3103 tree interface = lookup_interface (class_name);
3106 return get_class_ivars (interface);
3108 error ("cannot find interface declaration for %qs",
3109 IDENTIFIER_POINTER (class_name));
3111 return error_mark_node;
3114 /* Used by: build_private_template, continue_class,
3115 and for @defs constructs. */
3118 get_class_ivars (tree interface)
3120 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3122 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3123 by the current class (i.e., they do not include super-class ivars).
3124 However, the CLASS_IVARS list will be side-effected by a call to
3125 finish_struct(), which will fill in field offsets. */
3126 if (!CLASS_IVARS (interface))
3127 CLASS_IVARS (interface) = ivar_chain;
3129 while (CLASS_SUPER_NAME (interface))
3131 /* Prepend super-class ivars. */
3132 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3133 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3141 objc_create_temporary_var (tree type)
3145 decl = build_decl (VAR_DECL, NULL_TREE, type);
3146 TREE_USED (decl) = 1;
3147 DECL_ARTIFICIAL (decl) = 1;
3148 DECL_IGNORED_P (decl) = 1;
3149 DECL_CONTEXT (decl) = current_function_decl;
3154 /* Exception handling constructs. We begin by having the parser do most
3155 of the work and passing us blocks. What we do next depends on whether
3156 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3157 We abstract all of this in a handful of appropriately named routines. */
3159 /* Stack of open try blocks. */
3161 struct objc_try_context
3163 struct objc_try_context *outer;
3165 /* Statements (or statement lists) as processed by the parser. */
3169 /* Some file position locations. */
3170 location_t try_locus;
3171 location_t end_try_locus;
3172 location_t end_catch_locus;
3173 location_t finally_locus;
3174 location_t end_finally_locus;
3176 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3177 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3180 /* The CATCH_EXPR of an open @catch clause. */
3183 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3189 static struct objc_try_context *cur_try_context;
3191 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3192 that represents TYPE. For Objective-C, this is just the class name. */
3193 /* ??? Isn't there a class object or some such? Is it easy to get? */
3197 objc_eh_runtime_type (tree type)
3199 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3203 /* Initialize exception handling. */
3206 objc_init_exceptions (void)
3208 static bool done = false;
3213 if (flag_objc_sjlj_exceptions)
3215 /* On Darwin, ObjC exceptions require a sufficiently recent
3216 version of the runtime, so the user must ask for them explicitly. */
3217 if (!flag_objc_exceptions)
3218 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3219 "exception syntax");
3224 c_eh_initialized_p = true;
3225 eh_personality_libfunc
3226 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3227 ? "__gnu_objc_personality_sj0"
3228 : "__gnu_objc_personality_v0");
3229 using_eh_for_cleanups ();
3230 lang_eh_runtime_type = objc_eh_runtime_type;
3235 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3236 we'll arrange for it to be initialized (and associated with a binding)
3240 objc_build_exc_ptr (void)
3242 if (flag_objc_sjlj_exceptions)
3244 tree var = cur_try_context->caught_decl;
3247 var = objc_create_temporary_var (objc_object_type);
3248 cur_try_context->caught_decl = var;
3253 return build (EXC_PTR_EXPR, objc_object_type);
3256 /* Build "objc_exception_try_exit(&_stack)". */
3259 next_sjlj_build_try_exit (void)
3262 t = build_fold_addr_expr (cur_try_context->stack_decl);
3263 t = tree_cons (NULL, t, NULL);
3264 t = build_function_call (objc_exception_try_exit_decl, t);
3269 objc_exception_try_enter (&_stack);
3270 if (_setjmp(&_stack.buf))
3274 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3275 empty, ready for the caller to fill them in. */
3278 next_sjlj_build_enter_and_setjmp (void)
3280 tree t, enter, sj, cond;
3282 t = build_fold_addr_expr (cur_try_context->stack_decl);
3283 t = tree_cons (NULL, t, NULL);
3284 enter = build_function_call (objc_exception_try_enter_decl, t);
3286 t = build_component_ref (cur_try_context->stack_decl,
3287 get_identifier ("buf"));
3288 t = build_fold_addr_expr (t);
3290 /* Convert _setjmp argument to type that is expected. */
3291 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3292 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3294 t = convert (ptr_type_node, t);
3296 t = convert (ptr_type_node, t);
3298 t = tree_cons (NULL, t, NULL);
3299 sj = build_function_call (objc_setjmp_decl, t);
3301 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3302 cond = c_common_truthvalue_conversion (cond);
3304 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
3308 DECL = objc_exception_extract(&_stack);
3312 next_sjlj_build_exc_extract (tree decl)
3316 t = build_fold_addr_expr (cur_try_context->stack_decl);
3317 t = tree_cons (NULL, t, NULL);
3318 t = build_function_call (objc_exception_extract_decl, t);
3319 t = convert (TREE_TYPE (decl), t);
3320 t = build (MODIFY_EXPR, void_type_node, decl, t);
3326 if (objc_exception_match(obj_get_class(TYPE), _caught)
3333 objc_exception_try_exit(&_stack);
3335 from the sequence of CATCH_EXPRs in the current try context. */
3338 next_sjlj_build_catch_list (void)
3340 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3342 tree *last = &catch_seq;
3343 bool saw_id = false;
3345 for (; !tsi_end_p (i); tsi_next (&i))
3347 tree stmt = tsi_stmt (i);
3348 tree type = CATCH_TYPES (stmt);
3349 tree body = CATCH_BODY (stmt);
3361 if (type == error_mark_node)
3362 cond = error_mark_node;
3365 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3366 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3367 args = tree_cons (NULL, t, args);
3368 t = build_function_call (objc_exception_match_decl, args);
3369 cond = c_common_truthvalue_conversion (t);
3371 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3372 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3375 last = &COND_EXPR_ELSE (t);
3381 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3382 cur_try_context->caught_decl);
3383 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3384 append_to_statement_list (t, last);
3386 t = next_sjlj_build_try_exit ();
3387 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3388 append_to_statement_list (t, last);
3394 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3395 exception handling. We aim to build:
3398 struct _objc_exception_data _stack;
3399 id volatile _rethrow = 0;
3402 objc_exception_try_enter (&_stack);
3403 if (_setjmp(&_stack.buf))
3405 id _caught = objc_exception_extract(&_stack);
3406 objc_exception_try_enter (&_stack);
3407 if (_setjmp(&_stack.buf))
3408 _rethrow = objc_exception_extract(&_stack);
3418 objc_exception_try_exit(&_stack);
3421 objc_exception_throw(_rethrow);
3425 If CATCH-LIST is empty, we can omit all of the block containing
3426 "_caught" except for the setting of _rethrow. Note the use of
3427 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3428 but handles goto and other exits from the block. */
3431 next_sjlj_build_try_catch_finally (void)
3433 tree rethrow_decl, stack_decl, t;
3434 tree catch_seq, try_fin, bind;
3436 /* Create the declarations involved. */
3437 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3438 stack_decl = objc_create_temporary_var (t);
3439 cur_try_context->stack_decl = stack_decl;
3441 rethrow_decl = objc_create_temporary_var (objc_object_type);
3442 cur_try_context->rethrow_decl = rethrow_decl;
3443 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3444 TREE_CHAIN (rethrow_decl) = stack_decl;
3446 /* Build the outermost variable binding level. */
3447 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3448 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3449 TREE_SIDE_EFFECTS (bind) = 1;
3451 /* Initialize rethrow_decl. */
3452 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3453 convert (objc_object_type, null_pointer_node));
3454 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3455 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3457 /* Build the outermost TRY_FINALLY_EXPR. */
3458 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3459 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3460 TREE_SIDE_EFFECTS (try_fin) = 1;
3461 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3463 /* Create the complete catch sequence. */
3464 if (cur_try_context->catch_list)
3466 tree caught_decl = objc_build_exc_ptr ();
3467 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3469 t = next_sjlj_build_exc_extract (caught_decl);
3470 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3472 t = next_sjlj_build_enter_and_setjmp ();
3473 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3474 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3475 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3478 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3479 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3481 /* Build the main register-and-try if statement. */
3482 t = next_sjlj_build_enter_and_setjmp ();
3483 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3484 COND_EXPR_THEN (t) = catch_seq;
3485 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3486 TREE_OPERAND (try_fin, 0) = t;
3488 /* Build the complete FINALLY statement list. */
3489 t = next_sjlj_build_try_exit ();
3490 t = build_stmt (COND_EXPR,
3491 c_common_truthvalue_conversion (rethrow_decl),
3493 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3494 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3496 append_to_statement_list (cur_try_context->finally_body,
3497 &TREE_OPERAND (try_fin, 1));
3499 t = tree_cons (NULL, rethrow_decl, NULL);
3500 t = build_function_call (objc_exception_throw_decl, t);
3501 t = build_stmt (COND_EXPR,
3502 c_common_truthvalue_conversion (rethrow_decl),
3504 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3505 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3510 /* Called just after parsing the @try and its associated BODY. We now
3511 must prepare for the tricky bits -- handling the catches and finally. */
3514 objc_begin_try_stmt (location_t try_locus, tree body)
3516 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3517 c->outer = cur_try_context;
3519 c->try_locus = try_locus;
3520 c->end_try_locus = input_location;
3521 cur_try_context = c;
3523 objc_init_exceptions ();
3525 if (flag_objc_sjlj_exceptions)
3526 objc_mark_locals_volatile (NULL);
3529 /* Called just after parsing "@catch (parm)". Open a binding level,
3530 enter DECL into the binding level, and initialize it. Leave the
3531 binding level open while the body of the compound statement is parsed. */
3534 objc_begin_catch_clause (tree decl)
3536 tree compound, type, t;
3538 /* Begin a new scope that the entire catch clause will live in. */
3539 compound = c_begin_compound_stmt (true);
3541 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3542 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3543 lang_hooks.decls.pushdecl (decl);
3545 /* Since a decl is required here by syntax, don't warn if its unused. */
3546 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3547 be what the previous objc implementation did. */
3548 TREE_USED (decl) = 1;
3550 /* Verify that the type of the catch is valid. It must be a pointer
3551 to an Objective-C class, or "id" (which is catch-all). */
3552 type = TREE_TYPE (decl);
3554 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3556 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3558 error ("@catch parameter is not a known Objective-C class type");
3559 type = error_mark_node;
3561 else if (cur_try_context->catch_list)
3563 /* Examine previous @catch clauses and see if we've already
3564 caught the type in question. */
3565 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3566 for (; !tsi_end_p (i); tsi_next (&i))
3568 tree stmt = tsi_stmt (i);
3569 t = CATCH_TYPES (stmt);
3570 if (t == error_mark_node)
3572 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3574 warning (0, "exception of type %<%T%> will be caught",
3576 warning (0, "%H by earlier handler for %<%T%>",
3577 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3583 /* Record the data for the catch in the try context so that we can
3584 finalize it later. */
3585 t = build_stmt (CATCH_EXPR, type, compound);
3586 cur_try_context->current_catch = t;
3588 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3589 t = objc_build_exc_ptr ();
3590 t = convert (TREE_TYPE (decl), t);
3591 t = build (MODIFY_EXPR, void_type_node, decl, t);
3595 /* Called just after parsing the closing brace of a @catch clause. Close
3596 the open binding level, and record a CATCH_EXPR for it. */
3599 objc_finish_catch_clause (void)
3601 tree c = cur_try_context->current_catch;
3602 cur_try_context->current_catch = NULL;
3603 cur_try_context->end_catch_locus = input_location;
3605 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3606 append_to_statement_list (c, &cur_try_context->catch_list);
3609 /* Called after parsing a @finally clause and its associated BODY.
3610 Record the body for later placement. */
3613 objc_build_finally_clause (location_t finally_locus, tree body)
3615 cur_try_context->finally_body = body;
3616 cur_try_context->finally_locus = finally_locus;
3617 cur_try_context->end_finally_locus = input_location;
3620 /* Called to finalize a @try construct. */
3623 objc_finish_try_stmt (void)
3625 struct objc_try_context *c = cur_try_context;
3628 if (c->catch_list == NULL && c->finally_body == NULL)
3629 error ("%<@try%> without %<@catch%> or %<@finally%>");
3631 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3632 if (flag_objc_sjlj_exceptions)
3634 if (!cur_try_context->finally_body)
3636 cur_try_context->finally_locus = input_location;
3637 cur_try_context->end_finally_locus = input_location;
3639 stmt = next_sjlj_build_try_catch_finally ();
3643 /* Otherwise, nest the CATCH inside a FINALLY. */
3647 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3648 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3650 if (c->finally_body)
3652 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3653 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3658 cur_try_context = c->outer;
3664 objc_build_throw_stmt (tree throw_expr)
3668 objc_init_exceptions ();
3670 if (throw_expr == NULL)
3672 /* If we're not inside a @catch block, there is no "current
3673 exception" to be rethrown. */
3674 if (cur_try_context == NULL
3675 || cur_try_context->current_catch == NULL)
3677 error ("%<@throw%> (rethrow) used outside of a @catch block");
3681 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3682 value that we get from the runtime. */
3683 throw_expr = objc_build_exc_ptr ();
3686 /* A throw is just a call to the runtime throw function with the
3687 object as a parameter. */
3688 args = tree_cons (NULL, throw_expr, NULL);
3689 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3693 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3697 /* First lock the mutex. */
3698 mutex = save_expr (mutex);
3699 args = tree_cons (NULL, mutex, NULL);
3700 call = build_function_call (objc_sync_enter_decl, args);
3701 SET_EXPR_LOCATION (call, start_locus);
3704 /* Build the mutex unlock. */
3705 args = tree_cons (NULL, mutex, NULL);
3706 call = build_function_call (objc_sync_exit_decl, args);
3707 SET_EXPR_LOCATION (call, input_location);
3709 /* Put the that and the body in a TRY_FINALLY. */
3710 objc_begin_try_stmt (start_locus, body);
3711 objc_build_finally_clause (input_location, call);
3712 return objc_finish_try_stmt ();
3716 /* Predefine the following data type:
3718 struct _objc_exception_data
3724 /* The following yuckiness should prevent users from having to #include
3725 <setjmp.h> in their code... */
3727 #ifdef TARGET_POWERPC
3728 /* snarfed from /usr/include/ppc/setjmp.h */
3729 #define _JBLEN (26 + 36 + 129 + 1)
3731 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3736 build_next_objc_exception_stuff (void)
3738 tree field_decl, field_decl_chain, index, temp_type;
3740 objc_exception_data_template
3741 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3743 /* int buf[_JBLEN]; */
3745 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3746 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3748 field_decl_chain = field_decl;
3750 /* void *pointers[4]; */
3752 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3753 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3755 chainon (field_decl_chain, field_decl);
3757 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3759 /* int _setjmp(...); */
3760 /* If the user includes <setjmp.h>, this shall be superseded by
3761 'int _setjmp(jmp_buf);' */
3762 temp_type = build_function_type (integer_type_node, NULL_TREE);
3764 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3766 /* id objc_exception_extract(struct _objc_exception_data *); */
3768 = build_function_type (objc_object_type,
3769 tree_cons (NULL_TREE,
3770 build_pointer_type (objc_exception_data_template),
3772 objc_exception_extract_decl
3773 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3774 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3775 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3777 = build_function_type (void_type_node,
3778 tree_cons (NULL_TREE,
3779 build_pointer_type (objc_exception_data_template),
3781 objc_exception_try_enter_decl
3782 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3783 objc_exception_try_exit_decl
3784 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3786 /* int objc_exception_match(id, id); */
3788 = build_function_type (integer_type_node,
3789 tree_cons (NULL_TREE, objc_object_type,
3790 tree_cons (NULL_TREE, objc_object_type,
3791 OBJC_VOID_AT_END)));
3792 objc_exception_match_decl
3793 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3795 /* id objc_assign_ivar (id, id, unsigned int); */
3796 /* id objc_assign_ivar_Fast (id, id, unsigned int)
3797 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
3799 = build_function_type (objc_object_type,
3801 (NULL_TREE, objc_object_type,
3802 tree_cons (NULL_TREE, objc_object_type,
3803 tree_cons (NULL_TREE,
3805 OBJC_VOID_AT_END))));
3806 objc_assign_ivar_decl
3807 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
3809 #ifdef OFFS_ASSIGNIVAR_FAST
3810 objc_assign_ivar_fast_decl
3811 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
3812 NOT_BUILT_IN, NULL, NULL_TREE);
3813 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
3814 = tree_cons (get_identifier ("hard_coded_address"),
3815 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
3818 /* Default to slower ivar method. */
3819 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
3822 /* id objc_assign_global (id, id *); */
3823 /* id objc_assign_strongCast (id, id *); */
3824 temp_type = build_function_type (objc_object_type,
3825 tree_cons (NULL_TREE, objc_object_type,
3826 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
3827 OBJC_VOID_AT_END)));
3828 objc_assign_global_decl
3829 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3830 objc_assign_strong_cast_decl
3831 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3835 build_objc_exception_stuff (void)
3837 tree noreturn_list, nothrow_list, temp_type;
3839 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3840 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3842 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3843 /* void objc_sync_enter(id); */
3844 /* void objc_sync_exit(id); */
3845 temp_type = build_function_type (void_type_node,
3846 tree_cons (NULL_TREE, objc_object_type,
3848 objc_exception_throw_decl
3849 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3851 objc_sync_enter_decl
3852 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3853 NULL, nothrow_list);
3855 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3856 NULL, nothrow_list);
3859 /* Construct a C struct corresponding to ObjC class CLASS, with the same
3862 struct <classname> {
3863 struct _objc_class *isa;
3868 build_private_template (tree class)
3870 if (!CLASS_STATIC_TEMPLATE (class))
3872 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3874 finish_struct (record, get_class_ivars (class), NULL_TREE);
3875 /* mark this record as class template - for class type checking */
3876 INIT_TYPE_OBJC_INFO (record);
3877 TYPE_OBJC_INTERFACE (record) = class;
3878 CLASS_STATIC_TEMPLATE (class) = record;
3880 /* Set the TREE_USED bit for this struct, so that stab generator
3881 can emit stabs for this struct type. */
3882 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
3883 TREE_USED (TYPE_STUB_DECL (record)) = 1;
3887 /* Begin code generation for protocols... */
3889 /* struct _objc_protocol {
3890 struct _objc_class *isa;
3891 char *protocol_name;
3892 struct _objc_protocol **protocol_list;
3893 struct _objc__method_prototype_list *instance_methods;
3894 struct _objc__method_prototype_list *class_methods;
3898 build_protocol_template (void)
3900 tree field_decl, field_decl_chain;
3902 objc_protocol_template = start_struct (RECORD_TYPE,
3903 get_identifier (UTAG_PROTOCOL));
3905 /* struct _objc_class *isa; */
3906 field_decl = create_field_decl (build_pointer_type
3907 (xref_tag (RECORD_TYPE,
3908 get_identifier (UTAG_CLASS))),
3910 field_decl_chain = field_decl;
3912 /* char *protocol_name; */
3913 field_decl = create_field_decl (string_type_node, "protocol_name");
3914 chainon (field_decl_chain, field_decl);
3916 /* struct _objc_protocol **protocol_list; */
3917 field_decl = create_field_decl (build_pointer_type
3919 (objc_protocol_template)),
3921 chainon (field_decl_chain, field_decl);
3923 /* struct _objc__method_prototype_list *instance_methods; */
3924 field_decl = create_field_decl (objc_method_proto_list_ptr,
3925 "instance_methods");
3926 chainon (field_decl_chain, field_decl);
3928 /* struct _objc__method_prototype_list *class_methods; */
3929 field_decl = create_field_decl (objc_method_proto_list_ptr,
3931 chainon (field_decl_chain, field_decl);
3933 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3937 build_descriptor_table_initializer (tree type, tree entries)
3939 tree initlist = NULL_TREE;
3943 tree eltlist = NULL_TREE;
3946 = tree_cons (NULL_TREE,
3947 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3949 = tree_cons (NULL_TREE,
3950 add_objc_string (METHOD_ENCODING (entries),
3955 = tree_cons (NULL_TREE,
3956 objc_build_constructor (type, nreverse (eltlist)),
3959 entries = TREE_CHAIN (entries);
3963 return objc_build_constructor (build_array_type (type, 0),
3964 nreverse (initlist));
3967 /* struct objc_method_prototype_list {
3969 struct objc_method_prototype {
3976 build_method_prototype_list_template (tree list_type, int size)
3978 tree objc_ivar_list_record;
3979 tree field_decl, field_decl_chain;
3981 /* Generate an unnamed struct definition. */
3983 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3985 /* int method_count; */
3986 field_decl = create_field_decl (integer_type_node, "method_count");
3987 field_decl_chain = field_decl;
3989 /* struct objc_method method_list[]; */
3990 field_decl = create_field_decl (build_array_type
3993 (build_int_cst (NULL_TREE, size - 1))),
3995 chainon (field_decl_chain, field_decl);
3997 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3999 return objc_ivar_list_record;
4003 build_method_prototype_template (void)
4006 tree field_decl, field_decl_chain;
4009 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4012 field_decl = create_field_decl (objc_selector_type, "_cmd");
4013 field_decl_chain = field_decl;
4015 /* char *method_types; */
4016 field_decl = create_field_decl (string_type_node, "method_types");
4017 chainon (field_decl_chain, field_decl);
4019 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4021 return proto_record;
4025 objc_method_parm_type (tree type)
4027 type = TREE_VALUE (TREE_TYPE (type));
4028 if (TREE_CODE (type) == TYPE_DECL)
4029 type = TREE_TYPE (type);
4034 objc_encoded_type_size (tree type)
4036 int sz = int_size_in_bytes (type);
4038 /* Make all integer and enum types at least as large
4040 if (sz > 0 && INTEGRAL_TYPE_P (type))
4041 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4042 /* Treat arrays as pointers, since that's how they're
4044 else if (TREE_CODE (type) == ARRAY_TYPE)
4045 sz = int_size_in_bytes (ptr_type_node);
4050 encode_method_prototype (tree method_decl)
4057 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4058 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4060 /* Encode return type. */
4061 encode_type (objc_method_parm_type (method_decl),
4062 obstack_object_size (&util_obstack),
4063 OBJC_ENCODE_INLINE_DEFS);
4066 /* The first two arguments (self and _cmd) are pointers; account for
4068 i = int_size_in_bytes (ptr_type_node);
4069 parm_offset = 2 * i;
4070 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4071 parms = TREE_CHAIN (parms))
4073 tree type = objc_method_parm_type (parms);
4074 int sz = objc_encoded_type_size (type);
4076 /* If a type size is not known, bail out. */
4079 error ("%Jtype '%D' does not have a known size",
4081 /* Pretend that the encoding succeeded; the compilation will
4082 fail nevertheless. */
4083 goto finish_encoding;
4088 sprintf (buf, "%d@0:%d", parm_offset, i);
4089 obstack_grow (&util_obstack, buf, strlen (buf));
4091 /* Argument types. */
4092 parm_offset = 2 * i;
4093 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4094 parms = TREE_CHAIN (parms))
4096 tree type = objc_method_parm_type (parms);
4098 /* Process argument qualifiers for user supplied arguments. */
4099 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4102 encode_type (type, obstack_object_size (&util_obstack),
4103 OBJC_ENCODE_INLINE_DEFS);
4105 /* Compute offset. */
4106 sprintf (buf, "%d", parm_offset);
4107 parm_offset += objc_encoded_type_size (type);
4109 obstack_grow (&util_obstack, buf, strlen (buf));
4113 obstack_1grow (&util_obstack, '\0');
4114 result = get_identifier (obstack_finish (&util_obstack));
4115 obstack_free (&util_obstack, util_firstobj);
4120 generate_descriptor_table (tree type, const char *name, int size, tree list,
4123 tree decl, initlist;
4125 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4127 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4128 initlist = tree_cons (NULL_TREE, list, initlist);
4130 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4136 generate_method_descriptors (tree protocol)
4138 tree initlist, chain, method_list_template;
4141 if (!objc_method_prototype_template)
4142 objc_method_prototype_template = build_method_prototype_template ();
4144 chain = PROTOCOL_CLS_METHODS (protocol);
4147 size = list_length (chain);
4149 method_list_template
4150 = build_method_prototype_list_template (objc_method_prototype_template,
4154 = build_descriptor_table_initializer (objc_method_prototype_template,
4157 UOBJC_CLASS_METHODS_decl
4158 = generate_descriptor_table (method_list_template,
4159 "_OBJC_PROTOCOL_CLASS_METHODS",
4160 size, initlist, protocol);
4163 UOBJC_CLASS_METHODS_decl = 0;