* c-tree.h: Add argument to c_objc_common_truthvalue_conversion,
[official-gcc.git] / gcc / objc / objc-act.c
blob9ea40eafbec39ad81517c0b1bf224d17293bf75b
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
57 #include "c-common.h"
58 #include "c-pragma.h"
59 #include "flags.h"
60 #include "langhooks.h"
61 #include "objc-act.h"
62 #include "input.h"
63 #include "except.h"
64 #include "function.h"
65 #include "output.h"
66 #include "toplev.h"
67 #include "ggc.h"
68 #include "varray.h"
69 #include "debug.h"
70 #include "target.h"
71 #include "diagnostic.h"
72 #include "cgraph.h"
73 #include "tree-iterator.h"
74 #include "libfuncs.h"
75 #include "hashtab.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. */
84 #ifdef OBJCPLUS
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
87 #endif /* OBJCPLUS */
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) \
95 do { \
96 char *temp; \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
99 (CLASS_NAME), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
101 (SEL_NAME)); \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
104 } while (0)
105 #endif
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
110 #endif
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
114 #endif
116 /* Set up for use of obstacks. */
118 #include "obstack.h"
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. */
125 char *util_firstobj;
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);
157 #ifdef OBJCPLUS
158 static void objc_start_function (tree, tree, tree, tree);
159 #else
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
161 #endif
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
174 #ifndef OBJCPLUS
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
177 #endif
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
189 #ifdef OBJCPLUS
190 static void objc_generate_cxx_cdtors (void);
191 #endif
193 static const char *synth_id_with_class_suffix (const char *, tree);
195 /* Hash tables to manage the global pool of method prototypes. */
197 hash *nst_method_hash_list = 0;
198 hash *cls_method_hash_list = 0;
200 static hash hash_lookup (hash *, tree);
201 static tree lookup_method (tree, tree);
202 static tree lookup_method_static (tree, tree, int);
204 enum string_section
206 class_names, /* class, category, protocol, module names */
207 meth_var_names, /* method and variable names */
208 meth_var_types /* method and variable type descriptors */
211 static tree add_objc_string (tree, enum string_section);
212 static tree build_objc_string_decl (enum string_section);
213 static void build_selector_table_decl (void);
215 /* Protocol additions. */
217 static tree lookup_protocol (tree);
218 static tree lookup_and_install_protocols (tree);
220 /* Type encoding. */
222 static void encode_type_qualifiers (tree);
223 static void encode_type (tree, int, int);
224 static void encode_field_decl (tree, int, int);
226 #ifdef OBJCPLUS
227 static void really_start_method (tree, tree);
228 #else
229 static void really_start_method (tree, struct c_arg_info *);
230 #endif
231 static int comp_proto_with_proto (tree, tree, int);
232 static void objc_push_parm (tree);
233 #ifdef OBJCPLUS
234 static tree objc_get_parm_info (int);
235 #else
236 static struct c_arg_info *objc_get_parm_info (int);
237 #endif
239 /* Utilities for debugging and error diagnostics. */
241 static void warn_with_method (const char *, int, tree);
242 static char *gen_type_name (tree);
243 static char *gen_type_name_0 (tree);
244 static char *gen_method_decl (tree);
245 static char *gen_declaration (tree);
247 /* Everything else. */
249 static tree create_field_decl (tree, const char *);
250 static void add_class_reference (tree);
251 static void build_protocol_template (void);
252 static tree encode_method_prototype (tree);
253 static void generate_classref_translation_entry (tree);
254 static void handle_class_ref (tree);
255 static void generate_struct_by_value_array (void)
256 ATTRIBUTE_NORETURN;
257 static void mark_referenced_methods (void);
258 static void generate_objc_image_info (void);
260 /*** Private Interface (data) ***/
262 /* Reserved tag definitions. */
264 #define OBJECT_TYPEDEF_NAME "id"
265 #define CLASS_TYPEDEF_NAME "Class"
267 #define TAG_OBJECT "objc_object"
268 #define TAG_CLASS "objc_class"
269 #define TAG_SUPER "objc_super"
270 #define TAG_SELECTOR "objc_selector"
272 #define UTAG_CLASS "_objc_class"
273 #define UTAG_IVAR "_objc_ivar"
274 #define UTAG_IVAR_LIST "_objc_ivar_list"
275 #define UTAG_METHOD "_objc_method"
276 #define UTAG_METHOD_LIST "_objc_method_list"
277 #define UTAG_CATEGORY "_objc_category"
278 #define UTAG_MODULE "_objc_module"
279 #define UTAG_SYMTAB "_objc_symtab"
280 #define UTAG_SUPER "_objc_super"
281 #define UTAG_SELECTOR "_objc_selector"
283 #define UTAG_PROTOCOL "_objc_protocol"
284 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
285 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
287 /* Note that the string object global name is only needed for the
288 NeXT runtime. */
289 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
291 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
293 static const char *TAG_GETCLASS;
294 static const char *TAG_GETMETACLASS;
295 static const char *TAG_MSGSEND;
296 static const char *TAG_MSGSENDSUPER;
297 /* The NeXT Objective-C messenger may have two extra entry points, for use
298 when returning a structure. */
299 static const char *TAG_MSGSEND_STRET;
300 static const char *TAG_MSGSENDSUPER_STRET;
301 static const char *default_constant_string_class_name;
303 /* Runtime metadata flags. */
304 #define CLS_FACTORY 0x0001L
305 #define CLS_META 0x0002L
306 #define CLS_HAS_CXX_STRUCTORS 0x2000L
308 #define OBJC_MODIFIER_STATIC 0x00000001
309 #define OBJC_MODIFIER_FINAL 0x00000002
310 #define OBJC_MODIFIER_PUBLIC 0x00000004
311 #define OBJC_MODIFIER_PRIVATE 0x00000008
312 #define OBJC_MODIFIER_PROTECTED 0x00000010
313 #define OBJC_MODIFIER_NATIVE 0x00000020
314 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
315 #define OBJC_MODIFIER_ABSTRACT 0x00000080
316 #define OBJC_MODIFIER_VOLATILE 0x00000100
317 #define OBJC_MODIFIER_TRANSIENT 0x00000200
318 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
320 /* NeXT-specific tags. */
322 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
323 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
324 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
325 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
326 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
327 #define TAG_EXCEPTIONMATCH "objc_exception_match"
328 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
329 #define TAG_SYNCENTER "objc_sync_enter"
330 #define TAG_SYNCEXIT "objc_sync_exit"
331 #define TAG_SETJMP "_setjmp"
332 #define UTAG_EXCDATA "_objc_exception_data"
334 #define TAG_ASSIGNIVAR "objc_assign_ivar"
335 #define TAG_ASSIGNGLOBAL "objc_assign_global"
336 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
338 /* Branch entry points. All that matters here are the addresses;
339 functions with these names do not really exist in libobjc. */
341 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
342 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
344 #define TAG_CXX_CONSTRUCT ".cxx_construct"
345 #define TAG_CXX_DESTRUCT ".cxx_destruct"
347 /* GNU-specific tags. */
349 #define TAG_EXECCLASS "__objc_exec_class"
350 #define TAG_GNUINIT "__objc_gnu_init"
352 /* Flags for lookup_method_static(). */
353 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
354 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
356 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
357 tree objc_global_trees[OCTI_MAX];
359 static void handle_impent (struct imp_entry *);
361 struct imp_entry *imp_list = 0;
362 int imp_count = 0; /* `@implementation' */
363 int cat_count = 0; /* `@category' */
365 enum tree_code objc_inherit_code;
366 int objc_public_flag;
368 /* Use to generate method labels. */
369 static int method_slot = 0;
371 #define BUFSIZE 1024
373 static char *errbuf; /* Buffer for error diagnostics */
375 /* Data imported from tree.c. */
377 extern enum debug_info_type write_symbols;
379 /* Data imported from toplev.c. */
381 extern const char *dump_base_name;
383 static int flag_typed_selectors;
385 /* Store all constructed constant strings in a hash table so that
386 they get uniqued properly. */
388 struct string_descriptor GTY(())
390 /* The literal argument . */
391 tree literal;
393 /* The resulting constant string. */
394 tree constructor;
397 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
399 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
400 struct volatilized_type GTY(())
402 tree type;
405 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
407 FILE *gen_declaration_file;
409 /* Tells "encode_pointer/encode_aggregate" whether we are generating
410 type descriptors for instance variables (as opposed to methods).
411 Type descriptors for instance variables contain more information
412 than methods (for static typing and embedded structures). */
414 static int generating_instance_variables = 0;
416 /* Some platforms pass small structures through registers versus
417 through an invisible pointer. Determine at what size structure is
418 the transition point between the two possibilities. */
420 static void
421 generate_struct_by_value_array (void)
423 tree type;
424 tree field_decl, field_decl_chain;
425 int i, j;
426 int aggregate_in_mem[32];
427 int found = 0;
429 /* Presumably no platform passes 32 byte structures in a register. */
430 for (i = 1; i < 32; i++)
432 char buffer[5];
434 /* Create an unnamed struct that has `i' character components */
435 type = start_struct (RECORD_TYPE, NULL_TREE);
437 strcpy (buffer, "c1");
438 field_decl = create_field_decl (char_type_node,
439 buffer);
440 field_decl_chain = field_decl;
442 for (j = 1; j < i; j++)
444 sprintf (buffer, "c%d", j + 1);
445 field_decl = create_field_decl (char_type_node,
446 buffer);
447 chainon (field_decl_chain, field_decl);
449 finish_struct (type, field_decl_chain, NULL_TREE);
451 aggregate_in_mem[i] = aggregate_value_p (type, 0);
452 if (!aggregate_in_mem[i])
453 found = 1;
456 /* We found some structures that are returned in registers instead of memory
457 so output the necessary data. */
458 if (found)
460 for (i = 31; i >= 0; i--)
461 if (!aggregate_in_mem[i])
462 break;
463 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
465 /* The first member of the structure is always 0 because we don't handle
466 structures with 0 members */
467 printf ("static int struct_forward_array[] = {\n 0");
469 for (j = 1; j <= i; j++)
470 printf (", %d", aggregate_in_mem[j]);
471 printf ("\n};\n");
474 exit (0);
477 bool
478 objc_init (void)
480 #ifdef OBJCPLUS
481 if (cxx_init () == false)
482 #else
483 if (c_objc_common_init () == false)
484 #endif
485 return false;
487 /* If gen_declaration desired, open the output file. */
488 if (flag_gen_declaration)
490 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
491 gen_declaration_file = fopen (dumpname, "w");
492 if (gen_declaration_file == 0)
493 fatal_error ("can't open %s: %m", dumpname);
494 free (dumpname);
497 if (flag_next_runtime)
499 TAG_GETCLASS = "objc_getClass";
500 TAG_GETMETACLASS = "objc_getMetaClass";
501 TAG_MSGSEND = "objc_msgSend";
502 TAG_MSGSENDSUPER = "objc_msgSendSuper";
503 TAG_MSGSEND_STRET = "objc_msgSend_stret";
504 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
505 default_constant_string_class_name = "NSConstantString";
507 else
509 TAG_GETCLASS = "objc_get_class";
510 TAG_GETMETACLASS = "objc_get_meta_class";
511 TAG_MSGSEND = "objc_msg_lookup";
512 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
513 /* GNU runtime does not provide special functions to support
514 structure-returning methods. */
515 default_constant_string_class_name = "NXConstantString";
516 flag_typed_selectors = 1;
519 init_objc ();
521 if (print_struct_values)
522 generate_struct_by_value_array ();
524 return true;
527 void
528 objc_finish_file (void)
530 mark_referenced_methods ();
532 #ifdef OBJCPLUS
533 /* We need to instantiate templates _before_ we emit ObjC metadata;
534 if we do not, some metadata (such as selectors) may go missing. */
535 at_eof = 1;
536 instantiate_pending_templates (0);
537 #endif
539 /* Finalize Objective-C runtime data. No need to generate tables
540 and code if only checking syntax, or if generating a PCH file. */
541 if (!flag_syntax_only && !pch_file)
542 finish_objc ();
544 if (gen_declaration_file)
545 fclose (gen_declaration_file);
548 /* Return the first occurrence of a method declaration corresponding
549 to sel_name in rproto_list. Search rproto_list recursively.
550 If is_class is 0, search for instance methods, otherwise for class
551 methods. */
552 static tree
553 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
554 int is_class)
556 tree rproto, p;
557 tree fnd = 0;
559 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
561 p = TREE_VALUE (rproto);
563 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
565 if ((fnd = lookup_method (is_class
566 ? PROTOCOL_CLS_METHODS (p)
567 : PROTOCOL_NST_METHODS (p), sel_name)))
569 else if (PROTOCOL_LIST (p))
570 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
571 sel_name, is_class);
573 else
575 ; /* An identifier...if we could not find a protocol. */
578 if (fnd)
579 return fnd;
582 return 0;
585 static tree
586 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
588 tree rproto, p;
590 /* Make sure the protocol is supported by the object on the rhs. */
591 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
593 tree fnd = 0;
594 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
596 p = TREE_VALUE (rproto);
598 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
600 if (lproto == p)
601 fnd = lproto;
603 else if (PROTOCOL_LIST (p))
604 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
607 if (fnd)
608 return fnd;
611 else
613 ; /* An identifier...if we could not find a protocol. */
616 return 0;
619 void
620 objc_start_class_interface (tree klass, tree super_class, tree protos)
622 objc_interface_context
623 = objc_ivar_context
624 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
625 objc_public_flag = 0;
628 void
629 objc_start_category_interface (tree klass, tree categ, tree protos)
631 objc_interface_context
632 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
633 objc_ivar_chain
634 = continue_class (objc_interface_context);
637 void
638 objc_start_protocol (tree name, tree protos)
640 objc_interface_context
641 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
644 void
645 objc_continue_interface (void)
647 objc_ivar_chain
648 = continue_class (objc_interface_context);
651 void
652 objc_finish_interface (void)
654 finish_class (objc_interface_context);
655 objc_interface_context = NULL_TREE;
658 void
659 objc_start_class_implementation (tree klass, tree super_class)
661 objc_implementation_context
662 = objc_ivar_context
663 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
664 objc_public_flag = 0;
667 void
668 objc_start_category_implementation (tree klass, tree categ)
670 objc_implementation_context
671 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
672 objc_ivar_chain
673 = continue_class (objc_implementation_context);
676 void
677 objc_continue_implementation (void)
679 objc_ivar_chain
680 = continue_class (objc_implementation_context);
683 void
684 objc_finish_implementation (void)
686 #ifdef OBJCPLUS
687 if (flag_objc_call_cxx_cdtors)
688 objc_generate_cxx_cdtors ();
689 #endif
691 if (objc_implementation_context)
693 finish_class (objc_implementation_context);
694 objc_ivar_chain = NULL_TREE;
695 objc_implementation_context = NULL_TREE;
697 else
698 warning (0, "%<@end%> must appear in an @implementation context");
701 void
702 objc_set_visibility (int visibility)
704 objc_public_flag = visibility;
707 void
708 objc_set_method_type (enum tree_code type)
710 objc_inherit_code = (type == PLUS_EXPR
711 ? CLASS_METHOD_DECL
712 : INSTANCE_METHOD_DECL);
715 tree
716 objc_build_method_signature (tree rettype, tree selector,
717 tree optparms, bool ellipsis)
719 return build_method_decl (objc_inherit_code, rettype, selector,
720 optparms, ellipsis);
723 void
724 objc_add_method_declaration (tree decl)
726 if (!objc_interface_context)
727 fatal_error ("method declaration not in @interface context");
729 objc_add_method (objc_interface_context,
730 decl,
731 objc_inherit_code == CLASS_METHOD_DECL);
734 void
735 objc_start_method_definition (tree decl)
737 if (!objc_implementation_context)
738 fatal_error ("method definition not in @implementation context");
740 objc_add_method (objc_implementation_context,
741 decl,
742 objc_inherit_code == CLASS_METHOD_DECL);
743 start_method_def (decl);
746 void
747 objc_add_instance_variable (tree decl)
749 (void) add_instance_variable (objc_ivar_context,
750 objc_public_flag,
751 decl);
754 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
755 an '@'. */
758 objc_is_reserved_word (tree ident)
760 unsigned char code = C_RID_CODE (ident);
762 return (OBJC_IS_AT_KEYWORD (code)
763 || code == RID_CLASS || code == RID_PUBLIC
764 || code == RID_PROTECTED || code == RID_PRIVATE
765 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
768 /* Return true if TYPE is 'id'. */
770 static bool
771 objc_is_object_id (tree type)
773 return OBJC_TYPE_NAME (type) == objc_object_id;
776 static bool
777 objc_is_class_id (tree type)
779 return OBJC_TYPE_NAME (type) == objc_class_id;
782 /* Construct a C struct with same name as KLASS, a base struct with tag
783 SUPER_NAME (if any), and FIELDS indicated. */
785 static tree
786 objc_build_struct (tree klass, tree fields, tree super_name)
788 tree name = CLASS_NAME (klass);
789 tree s = start_struct (RECORD_TYPE, name);
790 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
791 tree t, objc_info = NULL_TREE;
793 if (super)
795 /* Prepend a packed variant of the base class into the layout. This
796 is necessary to preserve ObjC ABI compatibility. */
797 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
798 tree field = TYPE_FIELDS (super);
800 while (field && TREE_CHAIN (field)
801 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
802 field = TREE_CHAIN (field);
804 /* For ObjC ABI purposes, the "packed" size of a base class is
805 the sum of the offset and the size (in bits) of the last field
806 in the class. */
807 DECL_SIZE (base)
808 = (field && TREE_CODE (field) == FIELD_DECL
809 ? size_binop (PLUS_EXPR,
810 size_binop (PLUS_EXPR,
811 size_binop
812 (MULT_EXPR,
813 convert (bitsizetype,
814 DECL_FIELD_OFFSET (field)),
815 bitsize_int (BITS_PER_UNIT)),
816 DECL_FIELD_BIT_OFFSET (field)),
817 DECL_SIZE (field))
818 : bitsize_zero_node);
819 DECL_SIZE_UNIT (base)
820 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
821 size_int (BITS_PER_UNIT));
822 DECL_ARTIFICIAL (base) = 1;
823 DECL_ALIGN (base) = 1;
824 DECL_FIELD_CONTEXT (base) = s;
825 #ifdef OBJCPLUS
826 DECL_FIELD_IS_BASE (base) = 1;
828 if (fields)
829 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
830 #endif /* are following the ObjC ABI here. */
831 TREE_CHAIN (base) = fields;
832 fields = base;
835 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
836 in all variants of this RECORD_TYPE to be clobbered, but it is therein
837 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
838 Hence, we must squirrel away the ObjC-specific information before calling
839 finish_struct(), and then reinstate it afterwards. */
841 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
842 objc_info
843 = chainon (objc_info,
844 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
846 /* Point the struct at its related Objective-C class. */
847 INIT_TYPE_OBJC_INFO (s);
848 TYPE_OBJC_INTERFACE (s) = klass;
850 s = finish_struct (s, fields, NULL_TREE);
852 for (t = TYPE_NEXT_VARIANT (s); t;
853 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
855 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
856 /* Replace the IDENTIFIER_NODE with an actual @interface. */
857 TYPE_OBJC_INTERFACE (t) = klass;
860 /* Use TYPE_BINFO structures to point at the super class, if any. */
861 objc_xref_basetypes (s, super);
863 /* Mark this struct as a class template. */
864 CLASS_STATIC_TEMPLATE (klass) = s;
866 return s;
869 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
870 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
871 process. */
872 static tree
873 objc_build_volatilized_type (tree type)
875 tree t;
877 /* Check if we have not constructed the desired variant already. */
878 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
880 /* The type qualifiers must (obviously) match up. */
881 if (!TYPE_VOLATILE (t)
882 || (TYPE_READONLY (t) != TYPE_READONLY (type))
883 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
884 continue;
886 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
887 info, if any) must match up. */
888 if (POINTER_TYPE_P (t)
889 && (TREE_TYPE (t) != TREE_TYPE (type)))
890 continue;
892 /* Everything matches up! */
893 return t;
896 /* Ok, we could not re-use any of the pre-existing variants. Create
897 a new one. */
898 t = build_variant_type_copy (type);
899 TYPE_VOLATILE (t) = 1;
901 /* Set up the canonical type information. */
902 if (TYPE_STRUCTURAL_EQUALITY_P (type))
903 SET_TYPE_STRUCTURAL_EQUALITY (t);
904 else if (TYPE_CANONICAL (type) != type)
905 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
906 else
907 TYPE_CANONICAL (t) = t;
909 return t;
912 /* Mark DECL as being 'volatile' for purposes of Darwin
913 _setjmp()/_longjmp() exception handling. Called from
914 objc_mark_locals_volatile(). */
915 void
916 objc_volatilize_decl (tree decl)
918 /* Do not mess with variables that are 'static' or (already)
919 'volatile'. */
920 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
921 && (TREE_CODE (decl) == VAR_DECL
922 || TREE_CODE (decl) == PARM_DECL))
924 tree t = TREE_TYPE (decl);
925 struct volatilized_type key;
926 void **loc;
928 t = objc_build_volatilized_type (t);
929 key.type = t;
930 loc = htab_find_slot (volatilized_htab, &key, INSERT);
932 if (!*loc)
934 *loc = ggc_alloc (sizeof (key));
935 ((struct volatilized_type *) *loc)->type = t;
938 TREE_TYPE (decl) = t;
939 TREE_THIS_VOLATILE (decl) = 1;
940 TREE_SIDE_EFFECTS (decl) = 1;
941 DECL_REGISTER (decl) = 0;
942 #ifndef OBJCPLUS
943 C_DECL_REGISTER (decl) = 0;
944 #endif
948 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
949 (including its categories and superclasses) or by object type TYP.
950 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
952 static bool
953 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
955 bool class_type = (cls != NULL_TREE);
957 while (cls)
959 tree c;
961 /* Check protocols adopted by the class and its categories. */
962 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
964 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
965 return true;
968 /* Repeat for superclasses. */
969 cls = lookup_interface (CLASS_SUPER_NAME (cls));
972 /* Check for any protocols attached directly to the object type. */
973 if (TYPE_HAS_OBJC_INFO (typ))
975 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
976 return true;
979 if (warn)
981 strcpy (errbuf, class_type ? "class \'" : "type \'");
982 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
983 strcat (errbuf, "\' does not ");
984 /* NB: Types 'id' and 'Class' cannot reasonably be described as
985 "implementing" a given protocol, since they do not have an
986 implementation. */
987 strcat (errbuf, class_type ? "implement" : "conform to");
988 strcat (errbuf, " the \'");
989 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
990 strcat (errbuf, "\' protocol");
991 warning (0, errbuf);
994 return false;
997 /* Check if class RCLS and instance struct type RTYP conform to at least the
998 same protocols that LCLS and LTYP conform to. */
1000 static bool
1001 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1003 tree p;
1004 bool have_lproto = false;
1006 while (lcls)
1008 /* NB: We do _not_ look at categories defined for LCLS; these may or
1009 may not get loaded in, and therefore it is unreasonable to require
1010 that RCLS/RTYP must implement any of their protocols. */
1011 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1013 have_lproto = true;
1015 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1016 return warn;
1019 /* Repeat for superclasses. */
1020 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1023 /* Check for any protocols attached directly to the object type. */
1024 if (TYPE_HAS_OBJC_INFO (ltyp))
1026 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1028 have_lproto = true;
1030 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1031 return warn;
1035 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1036 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1037 away with simply checking for 'id' or 'Class' (!RCLS), since this
1038 routine will not get called in other cases. */
1039 return have_lproto || (rcls != NULL_TREE);
1042 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1043 an instance of RTYP to an instance of LTYP or to compare the two
1044 (if ARGNO is equal to -3), per ObjC type system rules. Before
1045 returning 'true', this routine may issue warnings related to, e.g.,
1046 protocol conformance. When returning 'false', the routine must
1047 produce absolutely no warnings; the C or C++ front-end will do so
1048 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1049 the routine must return 'false'.
1051 The ARGNO parameter is encoded as follows:
1052 >= 1 Parameter number (CALLEE contains function being called);
1053 0 Return value;
1054 -1 Assignment;
1055 -2 Initialization;
1056 -3 Comparison (LTYP and RTYP may match in either direction). */
1058 bool
1059 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1061 tree lcls, rcls, lproto, rproto;
1062 bool pointers_compatible;
1064 /* We must be dealing with pointer types */
1065 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1066 return false;
1070 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1071 rtyp = TREE_TYPE (rtyp);
1073 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1075 /* Past this point, we are only interested in ObjC class instances,
1076 or 'id' or 'Class'. */
1077 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1078 return false;
1080 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1081 && !TYPE_HAS_OBJC_INFO (ltyp))
1082 return false;
1084 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1085 && !TYPE_HAS_OBJC_INFO (rtyp))
1086 return false;
1088 /* Past this point, we are committed to returning 'true' to the caller.
1089 However, we can still warn about type and/or protocol mismatches. */
1091 if (TYPE_HAS_OBJC_INFO (ltyp))
1093 lcls = TYPE_OBJC_INTERFACE (ltyp);
1094 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1096 else
1097 lcls = lproto = NULL_TREE;
1099 if (TYPE_HAS_OBJC_INFO (rtyp))
1101 rcls = TYPE_OBJC_INTERFACE (rtyp);
1102 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1104 else
1105 rcls = rproto = NULL_TREE;
1107 /* If we could not find an @interface declaration, we must have
1108 only seen a @class declaration; for purposes of type comparison,
1109 treat it as a stand-alone (root) class. */
1111 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1112 lcls = NULL_TREE;
1114 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1115 rcls = NULL_TREE;
1117 /* If either type is an unqualified 'id', we're done. */
1118 if ((!lproto && objc_is_object_id (ltyp))
1119 || (!rproto && objc_is_object_id (rtyp)))
1120 return true;
1122 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1124 /* If the underlying types are the same, and at most one of them has
1125 a protocol list, we do not need to issue any diagnostics. */
1126 if (pointers_compatible && (!lproto || !rproto))
1127 return true;
1129 /* If exactly one of the types is 'Class', issue a diagnostic; any
1130 exceptions of this rule have already been handled. */
1131 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1132 pointers_compatible = false;
1133 /* Otherwise, check for inheritance relations. */
1134 else
1136 if (!pointers_compatible)
1137 pointers_compatible
1138 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1140 if (!pointers_compatible)
1141 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1143 if (!pointers_compatible && argno == -3)
1144 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1147 /* If the pointers match modulo protocols, check for protocol conformance
1148 mismatches. */
1149 if (pointers_compatible)
1151 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1152 argno != -3);
1154 if (!pointers_compatible && argno == -3)
1155 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1156 argno != -3);
1159 if (!pointers_compatible)
1161 /* NB: For the time being, we shall make our warnings look like their
1162 C counterparts. In the future, we may wish to make them more
1163 ObjC-specific. */
1164 switch (argno)
1166 case -3:
1167 warning (0, "comparison of distinct Objective-C types lacks a cast");
1168 break;
1170 case -2:
1171 warning (0, "initialization from distinct Objective-C type");
1172 break;
1174 case -1:
1175 warning (0, "assignment from distinct Objective-C type");
1176 break;
1178 case 0:
1179 warning (0, "distinct Objective-C type in return");
1180 break;
1182 default:
1183 warning (0, "passing argument %d of %qE from distinct "
1184 "Objective-C type", argno, callee);
1185 break;
1189 return true;
1192 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1193 lives in the volatilized hash table, ignore the 'volatile' bit when
1194 making the comparison. */
1196 bool
1197 objc_type_quals_match (tree ltyp, tree rtyp)
1199 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1200 struct volatilized_type key;
1202 key.type = ltyp;
1204 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1205 lquals &= ~TYPE_QUAL_VOLATILE;
1207 key.type = rtyp;
1209 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1210 rquals &= ~TYPE_QUAL_VOLATILE;
1212 return (lquals == rquals);
1215 #ifndef OBJCPLUS
1216 /* Determine if CHILD is derived from PARENT. The routine assumes that
1217 both parameters are RECORD_TYPEs, and is non-reflexive. */
1219 static bool
1220 objc_derived_from_p (tree parent, tree child)
1222 parent = TYPE_MAIN_VARIANT (parent);
1224 for (child = TYPE_MAIN_VARIANT (child);
1225 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1227 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1228 (TYPE_BINFO (child),
1229 0)));
1231 if (child == parent)
1232 return true;
1235 return false;
1237 #endif
1239 static tree
1240 objc_build_component_ref (tree datum, tree component)
1242 /* If COMPONENT is NULL, the caller is referring to the anonymous
1243 base class field. */
1244 if (!component)
1246 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1248 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1251 /* The 'build_component_ref' routine has been removed from the C++
1252 front-end, but 'finish_class_member_access_expr' seems to be
1253 a worthy substitute. */
1254 #ifdef OBJCPLUS
1255 return finish_class_member_access_expr (datum, component, false,
1256 tf_warning_or_error);
1257 #else
1258 return build_component_ref (datum, component);
1259 #endif
1262 /* Recursively copy inheritance information rooted at BINFO. To do this,
1263 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1265 static tree
1266 objc_copy_binfo (tree binfo)
1268 tree btype = BINFO_TYPE (binfo);
1269 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1270 tree base_binfo;
1271 int ix;
1273 BINFO_TYPE (binfo2) = btype;
1274 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1275 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1277 /* Recursively copy base binfos of BINFO. */
1278 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1280 tree base_binfo2 = objc_copy_binfo (base_binfo);
1282 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1283 BINFO_BASE_APPEND (binfo2, base_binfo2);
1286 return binfo2;
1289 /* Record superclass information provided in BASETYPE for ObjC class REF.
1290 This is loosely based on cp/decl.c:xref_basetypes(). */
1292 static void
1293 objc_xref_basetypes (tree ref, tree basetype)
1295 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1297 TYPE_BINFO (ref) = binfo;
1298 BINFO_OFFSET (binfo) = size_zero_node;
1299 BINFO_TYPE (binfo) = ref;
1301 if (basetype)
1303 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1305 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1306 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1307 BINFO_BASE_APPEND (binfo, base_binfo);
1308 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1312 static hashval_t
1313 volatilized_hash (const void *ptr)
1315 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1317 return htab_hash_pointer(typ);
1320 static int
1321 volatilized_eq (const void *ptr1, const void *ptr2)
1323 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1324 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1326 return typ1 == typ2;
1329 /* Called from finish_decl. */
1331 void
1332 objc_check_decl (tree decl)
1334 tree type = TREE_TYPE (decl);
1336 if (TREE_CODE (type) != RECORD_TYPE)
1337 return;
1338 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1339 error ("statically allocated instance of Objective-C class %qs",
1340 IDENTIFIER_POINTER (type));
1343 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1344 either name an Objective-C class, or refer to the special 'id' or 'Class'
1345 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1347 tree
1348 objc_get_protocol_qualified_type (tree interface, tree protocols)
1350 /* If INTERFACE is not provided, default to 'id'. */
1351 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1352 bool is_ptr = (type != NULL_TREE);
1354 if (!is_ptr)
1356 type = objc_is_class_name (interface);
1358 if (type)
1359 type = xref_tag (RECORD_TYPE, type);
1360 else
1361 return interface;
1364 if (protocols)
1366 type = build_variant_type_copy (type);
1368 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1369 to the pointee. */
1370 if (is_ptr)
1372 tree orig_pointee_type = TREE_TYPE (type);
1373 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1375 /* Set up the canonical type information. */
1376 TYPE_CANONICAL (type)
1377 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1379 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1380 type = TREE_TYPE (type);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1385 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1389 if (is_ptr)
1390 type = TYPE_POINTER_TO (type);
1391 else
1392 TYPE_OBJC_INTERFACE (type)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1396 return type;
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1401 conforms to. */
1403 static void
1404 check_protocol_recursively (tree proto, tree list)
1406 tree p;
1408 for (p = list; p; p = TREE_CHAIN (p))
1410 tree pp = TREE_VALUE (p);
1412 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1413 pp = lookup_protocol (pp);
1415 if (pp == proto)
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1418 if (pp)
1419 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1426 static tree
1427 lookup_and_install_protocols (tree protocols)
1429 tree proto;
1430 tree return_value = NULL_TREE;
1432 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1434 tree ident = TREE_VALUE (proto);
1435 tree p = lookup_protocol (ident);
1437 if (p)
1438 return_value = chainon (return_value,
1439 build_tree_list (NULL_TREE, p));
1440 else if (ident != error_mark_node)
1441 error ("cannot find protocol declaration for %qs",
1442 IDENTIFIER_POINTER (ident));
1445 return return_value;
1448 /* Create a declaration for field NAME of a given TYPE. */
1450 static tree
1451 create_field_decl (tree type, const char *name)
1453 return build_decl (FIELD_DECL, get_identifier (name), type);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1459 static tree
1460 start_var_decl (tree type, const char *name)
1462 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1464 TREE_STATIC (var) = 1;
1465 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var) = 1;
1467 DECL_ARTIFICIAL (var) = 1;
1468 DECL_CONTEXT (var) = NULL_TREE;
1469 #ifdef OBJCPLUS
1470 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1471 #endif
1473 return var;
1476 /* Finish off the variable declaration created by start_var_decl(). */
1478 static void
1479 finish_var_decl (tree var, tree initializer)
1481 finish_decl (var, initializer, NULL_TREE);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1491 static tree
1492 setup_string_decl (void)
1494 char *name;
1495 size_t length;
1497 /* %s in format will provide room for terminating null */
1498 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1499 + strlen (constant_string_class_name);
1500 name = XNEWVEC (char, length);
1501 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1502 constant_string_class_name);
1503 constant_string_global_id = get_identifier (name);
1504 string_class_decl = lookup_name (constant_string_global_id);
1506 return string_class_decl;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1512 Model:
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1520 static void
1521 synth_module_prologue (void)
1523 tree type;
1524 enum debug_info_type save_write_symbols = write_symbols;
1525 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn't been called yet. */
1529 write_symbols = NO_DEBUG;
1530 debug_hooks = &do_nothing_debug_hooks;
1532 #ifdef OBJCPLUS
1533 push_lang_context (lang_name_c); /* extern "C" */
1534 #endif
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id = get_identifier (TAG_OBJECT);
1539 objc_class_id = get_identifier (TAG_CLASS);
1541 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1542 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1544 objc_object_type = build_pointer_type (objc_object_reference);
1545 objc_class_type = build_pointer_type (objc_class_reference);
1547 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1548 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1553 objc_object_name,
1554 objc_object_type));
1555 TREE_NO_WARNING (type) = 1;
1556 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1557 objc_class_name,
1558 objc_class_type));
1559 TREE_NO_WARNING (type) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1564 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1565 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1566 type));
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime)
1571 /* `struct objc_selector *' */
1572 objc_selector_type
1573 = build_pointer_type (xref_tag (RECORD_TYPE,
1574 get_identifier (TAG_SELECTOR)));
1575 else
1576 /* `const struct objc_selector *' */
1577 objc_selector_type
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE,
1580 get_identifier (TAG_SELECTOR)),
1581 TYPE_QUAL_CONST));
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1587 get_identifier (TAG_SUPER)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr = build_pointer_type
1591 (xref_tag (RECORD_TYPE,
1592 get_identifier (UTAG_METHOD_LIST)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1596 objc_ivar_list_ptr = build_pointer_type
1597 (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_IVAR_LIST)));
1600 /* TREE_NOTHROW is cleared for the message-sending functions,
1601 because the function that gets called can throw in Obj-C++, or
1602 could itself call something that can throw even in Obj-C. */
1604 if (flag_next_runtime)
1606 /* NB: In order to call one of the ..._stret (struct-returning)
1607 functions, the function *MUST* first be cast to a signature that
1608 corresponds to the actual ObjC method being invoked. This is
1609 what is done by the build_objc_method_call() routine below. */
1611 /* id objc_msgSend (id, SEL, ...); */
1612 /* id objc_msgSendNonNil (id, SEL, ...); */
1613 /* id objc_msgSend_stret (id, SEL, ...); */
1614 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1615 type
1616 = build_function_type (objc_object_type,
1617 tree_cons (NULL_TREE, objc_object_type,
1618 tree_cons (NULL_TREE, objc_selector_type,
1619 NULL_TREE)));
1620 umsg_decl = add_builtin_function (TAG_MSGSEND,
1621 type, 0, NOT_BUILT_IN,
1622 NULL, NULL_TREE);
1623 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1624 type, 0, NOT_BUILT_IN,
1625 NULL, NULL_TREE);
1626 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1627 type, 0, NOT_BUILT_IN,
1628 NULL, NULL_TREE);
1629 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1630 type, 0, NOT_BUILT_IN,
1631 NULL, NULL_TREE);
1633 /* These can throw, because the function that gets called can throw
1634 in Obj-C++, or could itself call something that can throw even
1635 in Obj-C. */
1636 TREE_NOTHROW (umsg_decl) = 0;
1637 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1638 TREE_NOTHROW (umsg_stret_decl) = 0;
1639 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1641 /* id objc_msgSend_Fast (id, SEL, ...)
1642 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1643 #ifdef OFFS_MSGSEND_FAST
1644 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1645 type, 0, NOT_BUILT_IN,
1646 NULL, NULL_TREE);
1647 TREE_NOTHROW (umsg_fast_decl) = 0;
1648 DECL_ATTRIBUTES (umsg_fast_decl)
1649 = tree_cons (get_identifier ("hard_coded_address"),
1650 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1651 NULL_TREE);
1652 #else
1653 /* No direct dispatch available. */
1654 umsg_fast_decl = umsg_decl;
1655 #endif
1657 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1658 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1659 type
1660 = build_function_type (objc_object_type,
1661 tree_cons (NULL_TREE, objc_super_type,
1662 tree_cons (NULL_TREE, objc_selector_type,
1663 NULL_TREE)));
1664 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1665 type, 0, NOT_BUILT_IN,
1666 NULL, NULL_TREE);
1667 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1668 type, 0, NOT_BUILT_IN, 0,
1669 NULL_TREE);
1670 TREE_NOTHROW (umsg_super_decl) = 0;
1671 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1673 else
1675 /* GNU runtime messenger entry points. */
1677 /* typedef id (*IMP)(id, SEL, ...); */
1678 tree IMP_type
1679 = build_pointer_type
1680 (build_function_type (objc_object_type,
1681 tree_cons (NULL_TREE, objc_object_type,
1682 tree_cons (NULL_TREE, objc_selector_type,
1683 NULL_TREE))));
1685 /* IMP objc_msg_lookup (id, SEL); */
1686 type
1687 = build_function_type (IMP_type,
1688 tree_cons (NULL_TREE, objc_object_type,
1689 tree_cons (NULL_TREE, objc_selector_type,
1690 OBJC_VOID_AT_END)));
1691 umsg_decl = add_builtin_function (TAG_MSGSEND,
1692 type, 0, NOT_BUILT_IN,
1693 NULL, NULL_TREE);
1694 TREE_NOTHROW (umsg_decl) = 0;
1696 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1697 type
1698 = build_function_type (IMP_type,
1699 tree_cons (NULL_TREE, objc_super_type,
1700 tree_cons (NULL_TREE, objc_selector_type,
1701 OBJC_VOID_AT_END)));
1702 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1703 type, 0, NOT_BUILT_IN,
1704 NULL, NULL_TREE);
1705 TREE_NOTHROW (umsg_super_decl) = 0;
1707 /* The following GNU runtime entry point is called to initialize
1708 each module:
1710 __objc_exec_class (void *); */
1711 type
1712 = build_function_type (void_type_node,
1713 tree_cons (NULL_TREE, ptr_type_node,
1714 OBJC_VOID_AT_END));
1715 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1716 type, 0, NOT_BUILT_IN,
1717 NULL, NULL_TREE);
1720 /* id objc_getClass (const char *); */
1722 type = build_function_type (objc_object_type,
1723 tree_cons (NULL_TREE,
1724 const_string_type_node,
1725 OBJC_VOID_AT_END));
1727 objc_get_class_decl
1728 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1729 NULL, NULL_TREE);
1731 /* id objc_getMetaClass (const char *); */
1733 objc_get_meta_class_decl
1734 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1736 build_class_template ();
1737 build_super_template ();
1738 build_protocol_template ();
1739 build_category_template ();
1740 build_objc_exception_stuff ();
1742 if (flag_next_runtime)
1743 build_next_objc_exception_stuff ();
1745 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1747 if (! flag_next_runtime)
1748 build_selector_table_decl ();
1750 /* Forward declare constant_string_id and constant_string_type. */
1751 if (!constant_string_class_name)
1752 constant_string_class_name = default_constant_string_class_name;
1754 constant_string_id = get_identifier (constant_string_class_name);
1755 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1757 /* Pre-build the following entities - for speed/convenience. */
1758 self_id = get_identifier ("self");
1759 ucmd_id = get_identifier ("_cmd");
1761 #ifdef OBJCPLUS
1762 pop_lang_context ();
1763 #endif
1765 write_symbols = save_write_symbols;
1766 debug_hooks = save_hooks;
1769 /* Ensure that the ivar list for NSConstantString/NXConstantString
1770 (or whatever was specified via `-fconstant-string-class')
1771 contains fields at least as large as the following three, so that
1772 the runtime can stomp on them with confidence:
1774 struct STRING_OBJECT_CLASS_NAME
1776 Object isa;
1777 char *cString;
1778 unsigned int length;
1779 }; */
1781 static int
1782 check_string_class_template (void)
1784 tree field_decl = objc_get_class_ivars (constant_string_id);
1786 #define AT_LEAST_AS_LARGE_AS(F, T) \
1787 (F && TREE_CODE (F) == FIELD_DECL \
1788 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1789 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1791 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1792 return 0;
1794 field_decl = TREE_CHAIN (field_decl);
1795 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1796 return 0;
1798 field_decl = TREE_CHAIN (field_decl);
1799 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1801 #undef AT_LEAST_AS_LARGE_AS
1804 /* Avoid calling `check_string_class_template ()' more than once. */
1805 static GTY(()) int string_layout_checked;
1807 /* Construct an internal string layout to be used as a template for
1808 creating NSConstantString/NXConstantString instances. */
1810 static tree
1811 objc_build_internal_const_str_type (void)
1813 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1814 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1815 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1817 TREE_CHAIN (field) = fields; fields = field;
1818 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1819 TREE_CHAIN (field) = fields; fields = field;
1820 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1821 reverse order! */
1822 finish_builtin_struct (type, "__builtin_ObjCString",
1823 fields, NULL_TREE);
1825 return type;
1828 /* Custom build_string which sets TREE_TYPE! */
1830 static tree
1831 my_build_string (int len, const char *str)
1833 return fix_string_type (build_string (len, str));
1836 /* Build a string with contents STR and length LEN and convert it to a
1837 pointer. */
1839 static tree
1840 my_build_string_pointer (int len, const char *str)
1842 tree string = my_build_string (len, str);
1843 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1844 return build1 (ADDR_EXPR, ptrtype, string);
1847 static hashval_t
1848 string_hash (const void *ptr)
1850 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1851 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1852 int i, len = TREE_STRING_LENGTH (str);
1853 hashval_t h = len;
1855 for (i = 0; i < len; i++)
1856 h = ((h * 613) + p[i]);
1858 return h;
1861 static int
1862 string_eq (const void *ptr1, const void *ptr2)
1864 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1865 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1866 int len1 = TREE_STRING_LENGTH (str1);
1868 return (len1 == TREE_STRING_LENGTH (str2)
1869 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1870 len1));
1873 /* Given a chain of STRING_CST's, build a static instance of
1874 NXConstantString which points at the concatenation of those
1875 strings. We place the string object in the __string_objects
1876 section of the __OBJC segment. The Objective-C runtime will
1877 initialize the isa pointers of the string objects to point at the
1878 NXConstantString class object. */
1880 tree
1881 objc_build_string_object (tree string)
1883 tree initlist, constructor, constant_string_class;
1884 int length;
1885 tree fields, addr;
1886 struct string_descriptor *desc, key;
1887 void **loc;
1889 /* Prep the string argument. */
1890 string = fix_string_type (string);
1891 TREE_SET_CODE (string, STRING_CST);
1892 length = TREE_STRING_LENGTH (string) - 1;
1894 /* Check whether the string class being used actually exists and has the
1895 correct ivar layout. */
1896 if (!string_layout_checked)
1898 string_layout_checked = -1;
1899 constant_string_class = lookup_interface (constant_string_id);
1900 internal_const_str_type = objc_build_internal_const_str_type ();
1902 if (!constant_string_class
1903 || !(constant_string_type
1904 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1905 error ("cannot find interface declaration for %qs",
1906 IDENTIFIER_POINTER (constant_string_id));
1907 /* The NSConstantString/NXConstantString ivar layout is now known. */
1908 else if (!check_string_class_template ())
1909 error ("interface %qs does not have valid constant string layout",
1910 IDENTIFIER_POINTER (constant_string_id));
1911 /* For the NeXT runtime, we can generate a literal reference
1912 to the string class, don't need to run a constructor. */
1913 else if (flag_next_runtime && !setup_string_decl ())
1914 error ("cannot find reference tag for class %qs",
1915 IDENTIFIER_POINTER (constant_string_id));
1916 else
1918 string_layout_checked = 1; /* Success! */
1919 add_class_reference (constant_string_id);
1923 if (string_layout_checked == -1)
1924 return error_mark_node;
1926 /* Perhaps we already constructed a constant string just like this one? */
1927 key.literal = string;
1928 loc = htab_find_slot (string_htab, &key, INSERT);
1929 desc = (struct string_descriptor *) *loc;
1931 if (!desc)
1933 tree var;
1934 *loc = desc = GGC_NEW (struct string_descriptor);
1935 desc->literal = string;
1937 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1938 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1939 fields = TYPE_FIELDS (internal_const_str_type);
1940 initlist
1941 = build_tree_list (fields,
1942 flag_next_runtime
1943 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1944 : build_int_cst (NULL_TREE, 0));
1945 fields = TREE_CHAIN (fields);
1946 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1947 initlist);
1948 fields = TREE_CHAIN (fields);
1949 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1950 initlist);
1951 constructor = objc_build_constructor (internal_const_str_type,
1952 nreverse (initlist));
1954 if (!flag_next_runtime)
1955 constructor
1956 = objc_add_static_instance (constructor, constant_string_type);
1957 else
1959 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1960 DECL_INITIAL (var) = constructor;
1961 TREE_STATIC (var) = 1;
1962 pushdecl_top_level (var);
1963 constructor = var;
1965 desc->constructor = constructor;
1968 addr = convert (build_pointer_type (constant_string_type),
1969 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1971 return addr;
1974 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1976 static GTY(()) int num_static_inst;
1978 static tree
1979 objc_add_static_instance (tree constructor, tree class_decl)
1981 tree *chain, decl;
1982 char buf[256];
1984 /* Find the list of static instances for the CLASS_DECL. Create one if
1985 not found. */
1986 for (chain = &objc_static_instances;
1987 *chain && TREE_VALUE (*chain) != class_decl;
1988 chain = &TREE_CHAIN (*chain));
1989 if (!*chain)
1991 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1992 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1995 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1996 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1997 DECL_COMMON (decl) = 1;
1998 TREE_STATIC (decl) = 1;
1999 DECL_ARTIFICIAL (decl) = 1;
2000 TREE_USED (decl) = 1;
2001 DECL_INITIAL (decl) = constructor;
2003 /* We may be writing something else just now.
2004 Postpone till end of input. */
2005 DECL_DEFER_OUTPUT (decl) = 1;
2006 pushdecl_top_level (decl);
2007 rest_of_decl_compilation (decl, 1, 0);
2009 /* Add the DECL to the head of this CLASS' list. */
2010 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2012 return decl;
2015 /* Build a static constant CONSTRUCTOR
2016 with type TYPE and elements ELTS. */
2018 static tree
2019 objc_build_constructor (tree type, tree elts)
2021 tree constructor = build_constructor_from_list (type, elts);
2023 TREE_CONSTANT (constructor) = 1;
2024 TREE_STATIC (constructor) = 1;
2025 TREE_READONLY (constructor) = 1;
2027 #ifdef OBJCPLUS
2028 /* Adjust for impedance mismatch. We should figure out how to build
2029 CONSTRUCTORs that consistently please both the C and C++ gods. */
2030 if (!TREE_PURPOSE (elts))
2031 TREE_TYPE (constructor) = init_list_type_node;
2032 #endif
2034 return constructor;
2037 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2039 /* Predefine the following data type:
2041 struct _objc_symtab
2043 long sel_ref_cnt;
2044 SEL *refs;
2045 short cls_def_cnt;
2046 short cat_def_cnt;
2047 void *defs[cls_def_cnt + cat_def_cnt];
2048 }; */
2050 static void
2051 build_objc_symtab_template (void)
2053 tree field_decl, field_decl_chain;
2055 objc_symtab_template
2056 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2058 /* long sel_ref_cnt; */
2059 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2060 field_decl_chain = field_decl;
2062 /* SEL *refs; */
2063 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2064 "refs");
2065 chainon (field_decl_chain, field_decl);
2067 /* short cls_def_cnt; */
2068 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2069 chainon (field_decl_chain, field_decl);
2071 /* short cat_def_cnt; */
2072 field_decl = create_field_decl (short_integer_type_node,
2073 "cat_def_cnt");
2074 chainon (field_decl_chain, field_decl);
2076 if (imp_count || cat_count || !flag_next_runtime)
2078 /* void *defs[imp_count + cat_count (+ 1)]; */
2079 /* NB: The index is one less than the size of the array. */
2080 int index = imp_count + cat_count
2081 + (flag_next_runtime? -1: 0);
2082 field_decl = create_field_decl
2083 (build_array_type
2084 (ptr_type_node,
2085 build_index_type (build_int_cst (NULL_TREE, index))),
2086 "defs");
2087 chainon (field_decl_chain, field_decl);
2090 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2093 /* Create the initial value for the `defs' field of _objc_symtab.
2094 This is a CONSTRUCTOR. */
2096 static tree
2097 init_def_list (tree type)
2099 tree expr, initlist = NULL_TREE;
2100 struct imp_entry *impent;
2102 if (imp_count)
2103 for (impent = imp_list; impent; impent = impent->next)
2105 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2107 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2108 initlist = tree_cons (NULL_TREE, expr, initlist);
2112 if (cat_count)
2113 for (impent = imp_list; impent; impent = impent->next)
2115 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2117 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2118 initlist = tree_cons (NULL_TREE, expr, initlist);
2122 if (!flag_next_runtime)
2124 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2125 tree expr;
2127 if (static_instances_decl)
2128 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2129 else
2130 expr = build_int_cst (NULL_TREE, 0);
2132 initlist = tree_cons (NULL_TREE, expr, initlist);
2135 return objc_build_constructor (type, nreverse (initlist));
2138 /* Construct the initial value for all of _objc_symtab. */
2140 static tree
2141 init_objc_symtab (tree type)
2143 tree initlist;
2145 /* sel_ref_cnt = { ..., 5, ... } */
2147 initlist = build_tree_list (NULL_TREE,
2148 build_int_cst (long_integer_type_node, 0));
2150 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2152 if (flag_next_runtime || ! sel_ref_chain)
2153 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2154 else
2155 initlist
2156 = tree_cons (NULL_TREE,
2157 convert (build_pointer_type (objc_selector_type),
2158 build_unary_op (ADDR_EXPR,
2159 UOBJC_SELECTOR_TABLE_decl, 1)),
2160 initlist);
2162 /* cls_def_cnt = { ..., 5, ... } */
2164 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2166 /* cat_def_cnt = { ..., 5, ... } */
2168 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2170 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2172 if (imp_count || cat_count || !flag_next_runtime)
2175 tree field = TYPE_FIELDS (type);
2176 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2178 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2179 initlist);
2182 return objc_build_constructor (type, nreverse (initlist));
2185 /* Generate forward declarations for metadata such as
2186 'OBJC_CLASS_...'. */
2188 static tree
2189 build_metadata_decl (const char *name, tree type)
2191 tree decl;
2193 /* struct TYPE NAME_<name>; */
2194 decl = start_var_decl (type, synth_id_with_class_suffix
2195 (name,
2196 objc_implementation_context));
2198 return decl;
2201 /* Push forward-declarations of all the categories so that
2202 init_def_list can use them in a CONSTRUCTOR. */
2204 static void
2205 forward_declare_categories (void)
2207 struct imp_entry *impent;
2208 tree sav = objc_implementation_context;
2210 for (impent = imp_list; impent; impent = impent->next)
2212 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2214 /* Set an invisible arg to synth_id_with_class_suffix. */
2215 objc_implementation_context = impent->imp_context;
2216 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2217 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2218 objc_category_template);
2221 objc_implementation_context = sav;
2224 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2225 and initialized appropriately. */
2227 static void
2228 generate_objc_symtab_decl (void)
2230 /* forward declare categories */
2231 if (cat_count)
2232 forward_declare_categories ();
2234 build_objc_symtab_template ();
2235 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2236 finish_var_decl (UOBJC_SYMBOLS_decl,
2237 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2240 static tree
2241 init_module_descriptor (tree type)
2243 tree initlist, expr;
2245 /* version = { 1, ... } */
2247 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2248 initlist = build_tree_list (NULL_TREE, expr);
2250 /* size = { ..., sizeof (struct _objc_module), ... } */
2252 expr = convert (long_integer_type_node,
2253 size_in_bytes (objc_module_template));
2254 initlist = tree_cons (NULL_TREE, expr, initlist);
2256 /* Don't provide any file name for security reasons. */
2257 /* name = { ..., "", ... } */
2259 expr = add_objc_string (get_identifier (""), class_names);
2260 initlist = tree_cons (NULL_TREE, expr, initlist);
2262 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2264 if (UOBJC_SYMBOLS_decl)
2265 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2266 else
2267 expr = build_int_cst (NULL_TREE, 0);
2268 initlist = tree_cons (NULL_TREE, expr, initlist);
2270 return objc_build_constructor (type, nreverse (initlist));
2273 /* Write out the data structures to describe Objective C classes defined.
2275 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2277 static void
2278 build_module_descriptor (void)
2280 tree field_decl, field_decl_chain;
2282 #ifdef OBJCPLUS
2283 push_lang_context (lang_name_c); /* extern "C" */
2284 #endif
2286 objc_module_template
2287 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2289 /* long version; */
2290 field_decl = create_field_decl (long_integer_type_node, "version");
2291 field_decl_chain = field_decl;
2293 /* long size; */
2294 field_decl = create_field_decl (long_integer_type_node, "size");
2295 chainon (field_decl_chain, field_decl);
2297 /* char *name; */
2298 field_decl = create_field_decl (string_type_node, "name");
2299 chainon (field_decl_chain, field_decl);
2301 /* struct _objc_symtab *symtab; */
2302 field_decl
2303 = create_field_decl (build_pointer_type
2304 (xref_tag (RECORD_TYPE,
2305 get_identifier (UTAG_SYMTAB))),
2306 "symtab");
2307 chainon (field_decl_chain, field_decl);
2309 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2311 /* Create an instance of "_objc_module". */
2312 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2313 finish_var_decl (UOBJC_MODULES_decl,
2314 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2316 #ifdef OBJCPLUS
2317 pop_lang_context ();
2318 #endif
2321 /* The GNU runtime requires us to provide a static initializer function
2322 for each module:
2324 static void __objc_gnu_init (void) {
2325 __objc_exec_class (&L_OBJC_MODULES);
2326 } */
2328 static void
2329 build_module_initializer_routine (void)
2331 tree body;
2333 #ifdef OBJCPLUS
2334 push_lang_context (lang_name_c); /* extern "C" */
2335 #endif
2337 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2338 objc_start_function (get_identifier (TAG_GNUINIT),
2339 build_function_type (void_type_node,
2340 OBJC_VOID_AT_END),
2341 NULL_TREE, objc_get_parm_info (0));
2343 body = c_begin_compound_stmt (true);
2344 add_stmt (build_function_call
2345 (execclass_decl,
2346 build_tree_list
2347 (NULL_TREE,
2348 build_unary_op (ADDR_EXPR,
2349 UOBJC_MODULES_decl, 0))));
2350 add_stmt (c_end_compound_stmt (body, true));
2352 TREE_PUBLIC (current_function_decl) = 0;
2354 #ifndef OBJCPLUS
2355 /* For Objective-C++, we will need to call __objc_gnu_init
2356 from objc_generate_static_init_call() below. */
2357 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2358 #endif
2360 GNU_INIT_decl = current_function_decl;
2361 finish_function ();
2363 #ifdef OBJCPLUS
2364 pop_lang_context ();
2365 #endif
2368 #ifdef OBJCPLUS
2369 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2370 to be called by the module initializer routine. */
2373 objc_static_init_needed_p (void)
2375 return (GNU_INIT_decl != NULL_TREE);
2378 /* Generate a call to the __objc_gnu_init initializer function. */
2380 tree
2381 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2383 add_stmt (build_stmt (EXPR_STMT,
2384 build_function_call (GNU_INIT_decl, NULL_TREE)));
2386 return ctors;
2388 #endif /* OBJCPLUS */
2390 /* Return the DECL of the string IDENT in the SECTION. */
2392 static tree
2393 get_objc_string_decl (tree ident, enum string_section section)
2395 tree chain;
2397 if (section == class_names)
2398 chain = class_names_chain;
2399 else if (section == meth_var_names)
2400 chain = meth_var_names_chain;
2401 else if (section == meth_var_types)
2402 chain = meth_var_types_chain;
2403 else
2404 abort ();
2406 for (; chain != 0; chain = TREE_CHAIN (chain))
2407 if (TREE_VALUE (chain) == ident)
2408 return (TREE_PURPOSE (chain));
2410 abort ();
2411 return NULL_TREE;
2414 /* Output references to all statically allocated objects. Return the DECL
2415 for the array built. */
2417 static void
2418 generate_static_references (void)
2420 tree decls = NULL_TREE, expr = NULL_TREE;
2421 tree class_name, klass, decl, initlist;
2422 tree cl_chain, in_chain, type
2423 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2424 int num_inst, num_class;
2425 char buf[256];
2427 if (flag_next_runtime)
2428 abort ();
2430 for (cl_chain = objc_static_instances, num_class = 0;
2431 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2433 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2434 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2436 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2437 decl = start_var_decl (type, buf);
2439 /* Output {class_name, ...}. */
2440 klass = TREE_VALUE (cl_chain);
2441 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2442 initlist = build_tree_list (NULL_TREE,
2443 build_unary_op (ADDR_EXPR, class_name, 1));
2445 /* Output {..., instance, ...}. */
2446 for (in_chain = TREE_PURPOSE (cl_chain);
2447 in_chain; in_chain = TREE_CHAIN (in_chain))
2449 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2450 initlist = tree_cons (NULL_TREE, expr, initlist);
2453 /* Output {..., NULL}. */
2454 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2456 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2457 finish_var_decl (decl, expr);
2458 decls
2459 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2462 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2463 expr = objc_build_constructor (type, nreverse (decls));
2464 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2465 finish_var_decl (static_instances_decl, expr);
2468 static GTY(()) int selector_reference_idx;
2470 static tree
2471 build_selector_reference_decl (void)
2473 tree decl;
2474 char buf[256];
2476 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2477 decl = start_var_decl (objc_selector_type, buf);
2479 return decl;
2482 static void
2483 build_selector_table_decl (void)
2485 tree temp;
2487 if (flag_typed_selectors)
2489 build_selector_template ();
2490 temp = build_array_type (objc_selector_template, NULL_TREE);
2492 else
2493 temp = build_array_type (objc_selector_type, NULL_TREE);
2495 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2498 /* Just a handy wrapper for add_objc_string. */
2500 static tree
2501 build_selector (tree ident)
2503 return convert (objc_selector_type,
2504 add_objc_string (ident, meth_var_names));
2507 static void
2508 build_selector_translation_table (void)
2510 tree chain, initlist = NULL_TREE;
2511 int offset = 0;
2512 tree decl = NULL_TREE;
2514 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2516 tree expr;
2518 if (warn_selector && objc_implementation_context)
2520 tree method_chain;
2521 bool found = false;
2522 for (method_chain = meth_var_names_chain;
2523 method_chain;
2524 method_chain = TREE_CHAIN (method_chain))
2526 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2528 found = true;
2529 break;
2532 if (!found)
2534 location_t *loc;
2535 if (flag_next_runtime && TREE_PURPOSE (chain))
2536 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2537 else
2538 loc = &input_location;
2539 warning (0, "%Hcreating selector for nonexistent method %qE",
2540 loc, TREE_VALUE (chain));
2544 expr = build_selector (TREE_VALUE (chain));
2545 /* add one for the '\0' character */
2546 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2548 if (flag_next_runtime)
2550 decl = TREE_PURPOSE (chain);
2551 finish_var_decl (decl, expr);
2553 else
2555 if (flag_typed_selectors)
2557 tree eltlist = NULL_TREE;
2558 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2559 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2560 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2561 expr = objc_build_constructor (objc_selector_template,
2562 nreverse (eltlist));
2565 initlist = tree_cons (NULL_TREE, expr, initlist);
2569 if (! flag_next_runtime)
2571 /* Cause the selector table (previously forward-declared)
2572 to be actually output. */
2573 initlist = tree_cons (NULL_TREE,
2574 flag_typed_selectors
2575 ? objc_build_constructor
2576 (objc_selector_template,
2577 tree_cons (NULL_TREE,
2578 build_int_cst (NULL_TREE, 0),
2579 tree_cons (NULL_TREE,
2580 build_int_cst (NULL_TREE, 0),
2581 NULL_TREE)))
2582 : build_int_cst (NULL_TREE, 0), initlist);
2583 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2584 nreverse (initlist));
2585 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2589 static tree
2590 get_proto_encoding (tree proto)
2592 tree encoding;
2593 if (proto)
2595 if (! METHOD_ENCODING (proto))
2597 encoding = encode_method_prototype (proto);
2598 METHOD_ENCODING (proto) = encoding;
2600 else
2601 encoding = METHOD_ENCODING (proto);
2603 return add_objc_string (encoding, meth_var_types);
2605 else
2606 return build_int_cst (NULL_TREE, 0);
2609 /* sel_ref_chain is a list whose "value" fields will be instances of
2610 identifier_node that represent the selector. */
2612 static tree
2613 build_typed_selector_reference (tree ident, tree prototype)
2615 tree *chain = &sel_ref_chain;
2616 tree expr;
2617 int index = 0;
2619 while (*chain)
2621 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2622 goto return_at_index;
2624 index++;
2625 chain = &TREE_CHAIN (*chain);
2628 *chain = tree_cons (prototype, ident, NULL_TREE);
2630 return_at_index:
2631 expr = build_unary_op (ADDR_EXPR,
2632 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2633 build_int_cst (NULL_TREE, index),
2634 input_location),
2636 return convert (objc_selector_type, expr);
2639 static tree
2640 build_selector_reference (tree ident)
2642 tree *chain = &sel_ref_chain;
2643 tree expr;
2644 int index = 0;
2646 while (*chain)
2648 if (TREE_VALUE (*chain) == ident)
2649 return (flag_next_runtime
2650 ? TREE_PURPOSE (*chain)
2651 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2652 build_int_cst (NULL_TREE, index),
2653 input_location));
2655 index++;
2656 chain = &TREE_CHAIN (*chain);
2659 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2661 *chain = tree_cons (expr, ident, NULL_TREE);
2663 return (flag_next_runtime
2664 ? expr
2665 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2666 build_int_cst (NULL_TREE, index),
2667 input_location));
2670 static GTY(()) int class_reference_idx;
2672 static tree
2673 build_class_reference_decl (void)
2675 tree decl;
2676 char buf[256];
2678 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2679 decl = start_var_decl (objc_class_type, buf);
2681 return decl;
2684 /* Create a class reference, but don't create a variable to reference
2685 it. */
2687 static void
2688 add_class_reference (tree ident)
2690 tree chain;
2692 if ((chain = cls_ref_chain))
2694 tree tail;
2697 if (ident == TREE_VALUE (chain))
2698 return;
2700 tail = chain;
2701 chain = TREE_CHAIN (chain);
2703 while (chain);
2705 /* Append to the end of the list */
2706 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2708 else
2709 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2712 /* Get a class reference, creating it if necessary. Also create the
2713 reference variable. */
2715 tree
2716 objc_get_class_reference (tree ident)
2718 tree orig_ident = (DECL_P (ident)
2719 ? DECL_NAME (ident)
2720 : TYPE_P (ident)
2721 ? OBJC_TYPE_NAME (ident)
2722 : ident);
2723 bool local_scope = false;
2725 #ifdef OBJCPLUS
2726 if (processing_template_decl)
2727 /* Must wait until template instantiation time. */
2728 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2729 #endif
2731 if (TREE_CODE (ident) == TYPE_DECL)
2732 ident = (DECL_ORIGINAL_TYPE (ident)
2733 ? DECL_ORIGINAL_TYPE (ident)
2734 : TREE_TYPE (ident));
2736 #ifdef OBJCPLUS
2737 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2738 && TYPE_CONTEXT (ident) != global_namespace)
2739 local_scope = true;
2740 #endif
2742 if (local_scope || !(ident = objc_is_class_name (ident)))
2744 error ("%qs is not an Objective-C class name or alias",
2745 IDENTIFIER_POINTER (orig_ident));
2746 return error_mark_node;
2749 if (flag_next_runtime && !flag_zero_link)
2751 tree *chain;
2752 tree decl;
2754 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2755 if (TREE_VALUE (*chain) == ident)
2757 if (! TREE_PURPOSE (*chain))
2758 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2760 return TREE_PURPOSE (*chain);
2763 decl = build_class_reference_decl ();
2764 *chain = tree_cons (decl, ident, NULL_TREE);
2765 return decl;
2767 else
2769 tree params;
2771 add_class_reference (ident);
2773 params = build_tree_list (NULL_TREE,
2774 my_build_string_pointer
2775 (IDENTIFIER_LENGTH (ident) + 1,
2776 IDENTIFIER_POINTER (ident)));
2778 assemble_external (objc_get_class_decl);
2779 return build_function_call (objc_get_class_decl, params);
2783 /* For each string section we have a chain which maps identifier nodes
2784 to decls for the strings. */
2786 static tree
2787 add_objc_string (tree ident, enum string_section section)
2789 tree *chain, decl, type, string_expr;
2791 if (section == class_names)
2792 chain = &class_names_chain;
2793 else if (section == meth_var_names)
2794 chain = &meth_var_names_chain;
2795 else if (section == meth_var_types)
2796 chain = &meth_var_types_chain;
2797 else
2798 abort ();
2800 while (*chain)
2802 if (TREE_VALUE (*chain) == ident)
2803 return convert (string_type_node,
2804 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2806 chain = &TREE_CHAIN (*chain);
2809 decl = build_objc_string_decl (section);
2811 type = build_array_type
2812 (char_type_node,
2813 build_index_type
2814 (build_int_cst (NULL_TREE,
2815 IDENTIFIER_LENGTH (ident))));
2816 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2817 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2818 IDENTIFIER_POINTER (ident));
2819 finish_var_decl (decl, string_expr);
2821 *chain = tree_cons (decl, ident, NULL_TREE);
2823 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2826 static GTY(()) int class_names_idx;
2827 static GTY(()) int meth_var_names_idx;
2828 static GTY(()) int meth_var_types_idx;
2830 static tree
2831 build_objc_string_decl (enum string_section section)
2833 tree decl, ident;
2834 char buf[256];
2836 if (section == class_names)
2837 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2838 else if (section == meth_var_names)
2839 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2840 else if (section == meth_var_types)
2841 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2843 ident = get_identifier (buf);
2845 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2846 DECL_EXTERNAL (decl) = 1;
2847 TREE_PUBLIC (decl) = 0;
2848 TREE_USED (decl) = 1;
2849 TREE_CONSTANT (decl) = 1;
2850 DECL_CONTEXT (decl) = 0;
2851 DECL_ARTIFICIAL (decl) = 1;
2852 #ifdef OBJCPLUS
2853 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2854 #endif
2856 make_decl_rtl (decl);
2857 pushdecl_top_level (decl);
2859 return decl;
2863 void
2864 objc_declare_alias (tree alias_ident, tree class_ident)
2866 tree underlying_class;
2868 #ifdef OBJCPLUS
2869 if (current_namespace != global_namespace) {
2870 error ("Objective-C declarations may only appear in global scope");
2872 #endif /* OBJCPLUS */
2874 if (!(underlying_class = objc_is_class_name (class_ident)))
2875 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2876 else if (objc_is_class_name (alias_ident))
2877 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2878 else
2880 /* Implement @compatibility_alias as a typedef. */
2881 #ifdef OBJCPLUS
2882 push_lang_context (lang_name_c); /* extern "C" */
2883 #endif
2884 lang_hooks.decls.pushdecl (build_decl
2885 (TYPE_DECL,
2886 alias_ident,
2887 xref_tag (RECORD_TYPE, underlying_class)));
2888 #ifdef OBJCPLUS
2889 pop_lang_context ();
2890 #endif
2891 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2895 void
2896 objc_declare_class (tree ident_list)
2898 tree list;
2899 #ifdef OBJCPLUS
2900 if (current_namespace != global_namespace) {
2901 error ("Objective-C declarations may only appear in global scope");
2903 #endif /* OBJCPLUS */
2905 for (list = ident_list; list; list = TREE_CHAIN (list))
2907 tree ident = TREE_VALUE (list);
2909 if (! objc_is_class_name (ident))
2911 tree record = lookup_name (ident), type = record;
2913 if (record)
2915 if (TREE_CODE (record) == TYPE_DECL)
2916 type = DECL_ORIGINAL_TYPE (record);
2918 if (!TYPE_HAS_OBJC_INFO (type)
2919 || !TYPE_OBJC_INTERFACE (type))
2921 error ("%qs redeclared as different kind of symbol",
2922 IDENTIFIER_POINTER (ident));
2923 error ("previous declaration of %q+D",
2924 record);
2928 record = xref_tag (RECORD_TYPE, ident);
2929 INIT_TYPE_OBJC_INFO (record);
2930 TYPE_OBJC_INTERFACE (record) = ident;
2931 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2936 tree
2937 objc_is_class_name (tree ident)
2939 tree chain;
2941 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2942 && identifier_global_value (ident))
2943 ident = identifier_global_value (ident);
2944 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2945 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2947 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2948 ident = OBJC_TYPE_NAME (ident);
2949 #ifdef OBJCPLUS
2950 if (ident && TREE_CODE (ident) == TYPE_DECL)
2951 ident = DECL_NAME (ident);
2952 #endif
2953 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2954 return NULL_TREE;
2956 if (lookup_interface (ident))
2957 return ident;
2959 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2961 if (ident == TREE_VALUE (chain))
2962 return ident;
2965 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2967 if (ident == TREE_VALUE (chain))
2968 return TREE_PURPOSE (chain);
2971 return 0;
2974 /* Check whether TYPE is either 'id' or 'Class'. */
2976 tree
2977 objc_is_id (tree type)
2979 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2980 && identifier_global_value (type))
2981 type = identifier_global_value (type);
2983 if (type && TREE_CODE (type) == TYPE_DECL)
2984 type = TREE_TYPE (type);
2986 /* NB: This function may be called before the ObjC front-end has
2987 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2988 return (objc_object_type && type
2989 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2990 ? type
2991 : NULL_TREE);
2994 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2995 class instance. This is needed by other parts of the compiler to
2996 handle ObjC types gracefully. */
2998 tree
2999 objc_is_object_ptr (tree type)
3001 tree ret;
3003 type = TYPE_MAIN_VARIANT (type);
3004 if (!POINTER_TYPE_P (type))
3005 return 0;
3007 ret = objc_is_id (type);
3008 if (!ret)
3009 ret = objc_is_class_name (TREE_TYPE (type));
3011 return ret;
3014 static int
3015 objc_is_gcable_type (tree type, int or_strong_p)
3017 tree name;
3019 if (!TYPE_P (type))
3020 return 0;
3021 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3022 return 1;
3023 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3024 return 1;
3025 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3026 return 0;
3027 type = TREE_TYPE (type);
3028 if (TREE_CODE (type) != RECORD_TYPE)
3029 return 0;
3030 name = TYPE_NAME (type);
3031 return (objc_is_class_name (name) != NULL_TREE);
3034 static tree
3035 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3037 if (expr == oldexpr)
3038 return newexpr;
3040 switch (TREE_CODE (expr))
3042 case COMPONENT_REF:
3043 return objc_build_component_ref
3044 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3045 oldexpr,
3046 newexpr),
3047 DECL_NAME (TREE_OPERAND (expr, 1)));
3048 case ARRAY_REF:
3049 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3050 oldexpr,
3051 newexpr),
3052 TREE_OPERAND (expr, 1),
3053 input_location);
3054 case INDIRECT_REF:
3055 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3056 oldexpr,
3057 newexpr), "->",
3058 input_location);
3059 default:
3060 return expr;
3064 static tree
3065 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3067 tree func_params;
3068 /* The LHS parameter contains the expression 'outervar->memberspec';
3069 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3070 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3072 tree offs
3073 = objc_substitute_decl
3074 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3075 tree func
3076 = (flag_objc_direct_dispatch
3077 ? objc_assign_ivar_fast_decl
3078 : objc_assign_ivar_decl);
3080 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3081 offs = fold (offs);
3082 func_params = tree_cons (NULL_TREE,
3083 convert (objc_object_type, rhs),
3084 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3085 tree_cons (NULL_TREE, offs,
3086 NULL_TREE)));
3088 assemble_external (func);
3089 return build_function_call (func, func_params);
3092 static tree
3093 objc_build_global_assignment (tree lhs, tree rhs)
3095 tree func_params = tree_cons (NULL_TREE,
3096 convert (objc_object_type, rhs),
3097 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3098 build_unary_op (ADDR_EXPR, lhs, 0)),
3099 NULL_TREE));
3101 assemble_external (objc_assign_global_decl);
3102 return build_function_call (objc_assign_global_decl, func_params);
3105 static tree
3106 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3108 tree func_params = tree_cons (NULL_TREE,
3109 convert (objc_object_type, rhs),
3110 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3111 build_unary_op (ADDR_EXPR, lhs, 0)),
3112 NULL_TREE));
3114 assemble_external (objc_assign_strong_cast_decl);
3115 return build_function_call (objc_assign_strong_cast_decl, func_params);
3118 static int
3119 objc_is_gcable_p (tree expr)
3121 return (TREE_CODE (expr) == COMPONENT_REF
3122 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3123 : TREE_CODE (expr) == ARRAY_REF
3124 ? (objc_is_gcable_p (TREE_TYPE (expr))
3125 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3126 : TREE_CODE (expr) == ARRAY_TYPE
3127 ? objc_is_gcable_p (TREE_TYPE (expr))
3128 : TYPE_P (expr)
3129 ? objc_is_gcable_type (expr, 1)
3130 : (objc_is_gcable_p (TREE_TYPE (expr))
3131 || (DECL_P (expr)
3132 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3135 static int
3136 objc_is_ivar_reference_p (tree expr)
3138 return (TREE_CODE (expr) == ARRAY_REF
3139 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3140 : TREE_CODE (expr) == COMPONENT_REF
3141 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3142 : 0);
3145 static int
3146 objc_is_global_reference_p (tree expr)
3148 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3149 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3150 : DECL_P (expr)
3151 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3152 : 0);
3155 tree
3156 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3158 tree result = NULL_TREE, outer;
3159 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3161 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3162 will have been transformed to the form '*(type *)&expr'. */
3163 if (TREE_CODE (lhs) == INDIRECT_REF)
3165 outer = TREE_OPERAND (lhs, 0);
3167 while (!strong_cast_p
3168 && (CONVERT_EXPR_P (outer)
3169 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3171 tree lhstype = TREE_TYPE (outer);
3173 /* Descend down the cast chain, and record the first objc_gc
3174 attribute found. */
3175 if (POINTER_TYPE_P (lhstype))
3177 tree attr
3178 = lookup_attribute ("objc_gc",
3179 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3181 if (attr)
3182 strong_cast_p = 1;
3185 outer = TREE_OPERAND (outer, 0);
3189 /* If we have a __strong cast, it trumps all else. */
3190 if (strong_cast_p)
3192 if (modifycode != NOP_EXPR)
3193 goto invalid_pointer_arithmetic;
3195 if (warn_assign_intercept)
3196 warning (0, "strong-cast assignment has been intercepted");
3198 result = objc_build_strong_cast_assignment (lhs, rhs);
3200 goto exit_point;
3203 /* the lhs must be of a suitable type, regardless of its underlying
3204 structure. */
3205 if (!objc_is_gcable_p (lhs))
3206 goto exit_point;
3208 outer = lhs;
3210 while (outer
3211 && (TREE_CODE (outer) == COMPONENT_REF
3212 || TREE_CODE (outer) == ARRAY_REF))
3213 outer = TREE_OPERAND (outer, 0);
3215 if (TREE_CODE (outer) == INDIRECT_REF)
3217 outer = TREE_OPERAND (outer, 0);
3218 indirect_p = 1;
3221 outer_gc_p = objc_is_gcable_p (outer);
3223 /* Handle ivar assignments. */
3224 if (objc_is_ivar_reference_p (lhs))
3226 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3227 doesn't cut it here), the best we can do here is suggest a cast. */
3228 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3230 /* We may still be able to use the global write barrier... */
3231 if (!indirect_p && objc_is_global_reference_p (outer))
3232 goto global_reference;
3234 suggest_cast:
3235 if (modifycode == NOP_EXPR)
3237 if (warn_assign_intercept)
3238 warning (0, "strong-cast may possibly be needed");
3241 goto exit_point;
3244 if (modifycode != NOP_EXPR)
3245 goto invalid_pointer_arithmetic;
3247 if (warn_assign_intercept)
3248 warning (0, "instance variable assignment has been intercepted");
3250 result = objc_build_ivar_assignment (outer, lhs, rhs);
3252 goto exit_point;
3255 /* Likewise, intercept assignment to global/static variables if their type is
3256 GC-marked. */
3257 if (objc_is_global_reference_p (outer))
3259 if (indirect_p)
3260 goto suggest_cast;
3262 global_reference:
3263 if (modifycode != NOP_EXPR)
3265 invalid_pointer_arithmetic:
3266 if (outer_gc_p)
3267 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3269 goto exit_point;
3272 if (warn_assign_intercept)
3273 warning (0, "global/static variable assignment has been intercepted");
3275 result = objc_build_global_assignment (lhs, rhs);
3278 /* In all other cases, fall back to the normal mechanism. */
3279 exit_point:
3280 return result;
3283 struct interface_tuple GTY(())
3285 tree id;
3286 tree class_name;
3289 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3291 static hashval_t
3292 hash_interface (const void *p)
3294 const struct interface_tuple *d = (const struct interface_tuple *) p;
3295 return IDENTIFIER_HASH_VALUE (d->id);
3298 static int
3299 eq_interface (const void *p1, const void *p2)
3301 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3302 return d->id == p2;
3305 static tree
3306 lookup_interface (tree ident)
3308 #ifdef OBJCPLUS
3309 if (ident && TREE_CODE (ident) == TYPE_DECL)
3310 ident = DECL_NAME (ident);
3311 #endif
3313 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3314 return NULL_TREE;
3317 struct interface_tuple **slot;
3318 tree i = NULL_TREE;
3320 if (interface_htab)
3322 slot = (struct interface_tuple **)
3323 htab_find_slot_with_hash (interface_htab, ident,
3324 IDENTIFIER_HASH_VALUE (ident),
3325 NO_INSERT);
3326 if (slot && *slot)
3327 i = (*slot)->class_name;
3329 return i;
3333 /* Implement @defs (<classname>) within struct bodies. */
3335 tree
3336 objc_get_class_ivars (tree class_name)
3338 tree interface = lookup_interface (class_name);
3340 if (interface)
3341 return get_class_ivars (interface, true);
3343 error ("cannot find interface declaration for %qs",
3344 IDENTIFIER_POINTER (class_name));
3346 return error_mark_node;
3349 /* Used by: build_private_template, continue_class,
3350 and for @defs constructs. */
3352 static tree
3353 get_class_ivars (tree interface, bool inherited)
3355 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3357 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3358 by the current class (i.e., they do not include super-class ivars).
3359 However, the CLASS_IVARS list will be side-effected by a call to
3360 finish_struct(), which will fill in field offsets. */
3361 if (!CLASS_IVARS (interface))
3362 CLASS_IVARS (interface) = ivar_chain;
3364 if (!inherited)
3365 return ivar_chain;
3367 while (CLASS_SUPER_NAME (interface))
3369 /* Prepend super-class ivars. */
3370 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3371 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3372 ivar_chain);
3375 return ivar_chain;
3378 static tree
3379 objc_create_temporary_var (tree type)
3381 tree decl;
3383 decl = build_decl (VAR_DECL, NULL_TREE, type);
3384 TREE_USED (decl) = 1;
3385 DECL_ARTIFICIAL (decl) = 1;
3386 DECL_IGNORED_P (decl) = 1;
3387 DECL_CONTEXT (decl) = current_function_decl;
3389 return decl;
3392 /* Exception handling constructs. We begin by having the parser do most
3393 of the work and passing us blocks. What we do next depends on whether
3394 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3395 We abstract all of this in a handful of appropriately named routines. */
3397 /* Stack of open try blocks. */
3399 struct objc_try_context
3401 struct objc_try_context *outer;
3403 /* Statements (or statement lists) as processed by the parser. */
3404 tree try_body;
3405 tree finally_body;
3407 /* Some file position locations. */
3408 location_t try_locus;
3409 location_t end_try_locus;
3410 location_t end_catch_locus;
3411 location_t finally_locus;
3412 location_t end_finally_locus;
3414 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3415 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3416 tree catch_list;
3418 /* The CATCH_EXPR of an open @catch clause. */
3419 tree current_catch;
3421 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3422 tree caught_decl;
3423 tree stack_decl;
3424 tree rethrow_decl;
3427 static struct objc_try_context *cur_try_context;
3429 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3430 that represents TYPE. For Objective-C, this is just the class name. */
3431 /* ??? Isn't there a class object or some such? Is it easy to get? */
3433 #ifndef OBJCPLUS
3434 static tree
3435 objc_eh_runtime_type (tree type)
3437 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3439 #endif
3441 /* Initialize exception handling. */
3443 static void
3444 objc_init_exceptions (void)
3446 static bool done = false;
3447 if (done)
3448 return;
3449 done = true;
3451 if (flag_objc_sjlj_exceptions)
3453 /* On Darwin, ObjC exceptions require a sufficiently recent
3454 version of the runtime, so the user must ask for them explicitly. */
3455 if (!flag_objc_exceptions)
3456 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3457 "exception syntax");
3459 #ifndef OBJCPLUS
3460 else
3462 c_eh_initialized_p = true;
3463 eh_personality_libfunc
3464 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3465 ? "__gnu_objc_personality_sj0"
3466 : "__gnu_objc_personality_v0");
3467 default_init_unwind_resume_libfunc ();
3468 using_eh_for_cleanups ();
3469 lang_eh_runtime_type = objc_eh_runtime_type;
3471 #endif
3474 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3475 we'll arrange for it to be initialized (and associated with a binding)
3476 later. */
3478 static tree
3479 objc_build_exc_ptr (void)
3481 if (flag_objc_sjlj_exceptions)
3483 tree var = cur_try_context->caught_decl;
3484 if (!var)
3486 var = objc_create_temporary_var (objc_object_type);
3487 cur_try_context->caught_decl = var;
3489 return var;
3491 else
3492 return build0 (EXC_PTR_EXPR, objc_object_type);
3495 /* Build "objc_exception_try_exit(&_stack)". */
3497 static tree
3498 next_sjlj_build_try_exit (void)
3500 tree t;
3501 t = build_fold_addr_expr (cur_try_context->stack_decl);
3502 t = tree_cons (NULL, t, NULL);
3503 t = build_function_call (objc_exception_try_exit_decl, t);
3504 return t;
3507 /* Build
3508 objc_exception_try_enter (&_stack);
3509 if (_setjmp(&_stack.buf))
3511 else
3513 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3514 empty, ready for the caller to fill them in. */
3516 static tree
3517 next_sjlj_build_enter_and_setjmp (void)
3519 tree t, enter, sj, cond;
3521 t = build_fold_addr_expr (cur_try_context->stack_decl);
3522 t = tree_cons (NULL, t, NULL);
3523 enter = build_function_call (objc_exception_try_enter_decl, t);
3525 t = objc_build_component_ref (cur_try_context->stack_decl,
3526 get_identifier ("buf"));
3527 t = build_fold_addr_expr (t);
3528 #ifdef OBJCPLUS
3529 /* Convert _setjmp argument to type that is expected. */
3530 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3531 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3532 else
3533 t = convert (ptr_type_node, t);
3534 #else
3535 t = convert (ptr_type_node, t);
3536 #endif
3537 t = tree_cons (NULL, t, NULL);
3538 sj = build_function_call (objc_setjmp_decl, t);
3540 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3541 cond = c_common_truthvalue_conversion (input_location, cond);
3543 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3546 /* Build:
3548 DECL = objc_exception_extract(&_stack); */
3550 static tree
3551 next_sjlj_build_exc_extract (tree decl)
3553 tree t;
3555 t = build_fold_addr_expr (cur_try_context->stack_decl);
3556 t = tree_cons (NULL, t, NULL);
3557 t = build_function_call (objc_exception_extract_decl, t);
3558 t = convert (TREE_TYPE (decl), t);
3559 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3561 return t;
3564 /* Build
3565 if (objc_exception_match(obj_get_class(TYPE), _caught)
3566 BODY
3567 else if (...)
3569 else
3571 _rethrow = _caught;
3572 objc_exception_try_exit(&_stack);
3574 from the sequence of CATCH_EXPRs in the current try context. */
3576 static tree
3577 next_sjlj_build_catch_list (void)
3579 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3580 tree catch_seq, t;
3581 tree *last = &catch_seq;
3582 bool saw_id = false;
3584 for (; !tsi_end_p (i); tsi_next (&i))
3586 tree stmt = tsi_stmt (i);
3587 tree type = CATCH_TYPES (stmt);
3588 tree body = CATCH_BODY (stmt);
3590 if (type == NULL)
3592 *last = body;
3593 saw_id = true;
3594 break;
3596 else
3598 tree args, cond;
3600 if (type == error_mark_node)
3601 cond = error_mark_node;
3602 else
3604 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3605 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3606 args = tree_cons (NULL, t, args);
3607 t = build_function_call (objc_exception_match_decl, args);
3608 cond = c_common_truthvalue_conversion (input_location, t);
3610 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3611 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3613 *last = t;
3614 last = &COND_EXPR_ELSE (t);
3618 if (!saw_id)
3620 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3621 cur_try_context->caught_decl);
3622 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3623 append_to_statement_list (t, last);
3625 t = next_sjlj_build_try_exit ();
3626 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3627 append_to_statement_list (t, last);
3630 return catch_seq;
3633 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3634 exception handling. We aim to build:
3637 struct _objc_exception_data _stack;
3638 id _rethrow = 0;
3641 objc_exception_try_enter (&_stack);
3642 if (_setjmp(&_stack.buf))
3644 id _caught = objc_exception_extract(&_stack);
3645 objc_exception_try_enter (&_stack);
3646 if (_setjmp(&_stack.buf))
3647 _rethrow = objc_exception_extract(&_stack);
3648 else
3649 CATCH-LIST
3651 else
3652 TRY-BLOCK
3654 finally
3656 if (!_rethrow)
3657 objc_exception_try_exit(&_stack);
3658 FINALLY-BLOCK
3659 if (_rethrow)
3660 objc_exception_throw(_rethrow);
3664 If CATCH-LIST is empty, we can omit all of the block containing
3665 "_caught" except for the setting of _rethrow. Note the use of
3666 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3667 but handles goto and other exits from the block. */
3669 static tree
3670 next_sjlj_build_try_catch_finally (void)
3672 tree rethrow_decl, stack_decl, t;
3673 tree catch_seq, try_fin, bind;
3675 /* Create the declarations involved. */
3676 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3677 stack_decl = objc_create_temporary_var (t);
3678 cur_try_context->stack_decl = stack_decl;
3680 rethrow_decl = objc_create_temporary_var (objc_object_type);
3681 cur_try_context->rethrow_decl = rethrow_decl;
3682 TREE_CHAIN (rethrow_decl) = stack_decl;
3684 /* Build the outermost variable binding level. */
3685 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3686 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3687 TREE_SIDE_EFFECTS (bind) = 1;
3689 /* Initialize rethrow_decl. */
3690 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3691 convert (objc_object_type, null_pointer_node));
3692 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3693 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3695 /* Build the outermost TRY_FINALLY_EXPR. */
3696 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3697 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3698 TREE_SIDE_EFFECTS (try_fin) = 1;
3699 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3701 /* Create the complete catch sequence. */
3702 if (cur_try_context->catch_list)
3704 tree caught_decl = objc_build_exc_ptr ();
3705 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3706 TREE_SIDE_EFFECTS (catch_seq) = 1;
3708 t = next_sjlj_build_exc_extract (caught_decl);
3709 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3711 t = next_sjlj_build_enter_and_setjmp ();
3712 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3713 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3714 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3716 else
3717 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3718 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3720 /* Build the main register-and-try if statement. */
3721 t = next_sjlj_build_enter_and_setjmp ();
3722 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3723 COND_EXPR_THEN (t) = catch_seq;
3724 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3725 TREE_OPERAND (try_fin, 0) = t;
3727 /* Build the complete FINALLY statement list. */
3728 t = next_sjlj_build_try_exit ();
3729 t = build_stmt (COND_EXPR,
3730 c_common_truthvalue_conversion
3731 (input_location, rethrow_decl),
3732 NULL, t);
3733 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3734 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3736 append_to_statement_list (cur_try_context->finally_body,
3737 &TREE_OPERAND (try_fin, 1));
3739 t = tree_cons (NULL, rethrow_decl, NULL);
3740 t = build_function_call (objc_exception_throw_decl, t);
3741 t = build_stmt (COND_EXPR,
3742 c_common_truthvalue_conversion (input_location,
3743 rethrow_decl),
3744 t, NULL);
3745 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3746 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3748 return bind;
3751 /* Called just after parsing the @try and its associated BODY. We now
3752 must prepare for the tricky bits -- handling the catches and finally. */
3754 void
3755 objc_begin_try_stmt (location_t try_locus, tree body)
3757 struct objc_try_context *c = XCNEW (struct objc_try_context);
3758 c->outer = cur_try_context;
3759 c->try_body = body;
3760 c->try_locus = try_locus;
3761 c->end_try_locus = input_location;
3762 cur_try_context = c;
3764 objc_init_exceptions ();
3766 if (flag_objc_sjlj_exceptions)
3767 objc_mark_locals_volatile (NULL);
3770 /* Called just after parsing "@catch (parm)". Open a binding level,
3771 enter DECL into the binding level, and initialize it. Leave the
3772 binding level open while the body of the compound statement is parsed. */
3774 void
3775 objc_begin_catch_clause (tree decl)
3777 tree compound, type, t;
3779 /* Begin a new scope that the entire catch clause will live in. */
3780 compound = c_begin_compound_stmt (true);
3782 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3783 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3784 lang_hooks.decls.pushdecl (decl);
3786 /* Since a decl is required here by syntax, don't warn if its unused. */
3787 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3788 be what the previous objc implementation did. */
3789 TREE_USED (decl) = 1;
3791 /* Verify that the type of the catch is valid. It must be a pointer
3792 to an Objective-C class, or "id" (which is catch-all). */
3793 type = TREE_TYPE (decl);
3795 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3796 type = NULL;
3797 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3799 error ("@catch parameter is not a known Objective-C class type");
3800 type = error_mark_node;
3802 else if (cur_try_context->catch_list)
3804 /* Examine previous @catch clauses and see if we've already
3805 caught the type in question. */
3806 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3807 for (; !tsi_end_p (i); tsi_next (&i))
3809 tree stmt = tsi_stmt (i);
3810 t = CATCH_TYPES (stmt);
3811 if (t == error_mark_node)
3812 continue;
3813 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3815 warning (0, "exception of type %<%T%> will be caught",
3816 TREE_TYPE (type));
3817 warning (0, "%H by earlier handler for %<%T%>",
3818 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3819 break;
3824 /* Record the data for the catch in the try context so that we can
3825 finalize it later. */
3826 t = build_stmt (CATCH_EXPR, type, compound);
3827 cur_try_context->current_catch = t;
3829 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3830 t = objc_build_exc_ptr ();
3831 t = convert (TREE_TYPE (decl), t);
3832 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3833 add_stmt (t);
3836 /* Called just after parsing the closing brace of a @catch clause. Close
3837 the open binding level, and record a CATCH_EXPR for it. */
3839 void
3840 objc_finish_catch_clause (void)
3842 tree c = cur_try_context->current_catch;
3843 cur_try_context->current_catch = NULL;
3844 cur_try_context->end_catch_locus = input_location;
3846 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3847 append_to_statement_list (c, &cur_try_context->catch_list);
3850 /* Called after parsing a @finally clause and its associated BODY.
3851 Record the body for later placement. */
3853 void
3854 objc_build_finally_clause (location_t finally_locus, tree body)
3856 cur_try_context->finally_body = body;
3857 cur_try_context->finally_locus = finally_locus;
3858 cur_try_context->end_finally_locus = input_location;
3861 /* Called to finalize a @try construct. */
3863 tree
3864 objc_finish_try_stmt (void)
3866 struct objc_try_context *c = cur_try_context;
3867 tree stmt;
3869 if (c->catch_list == NULL && c->finally_body == NULL)
3870 error ("%<@try%> without %<@catch%> or %<@finally%>");
3872 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3873 if (flag_objc_sjlj_exceptions)
3875 if (!cur_try_context->finally_body)
3877 cur_try_context->finally_locus = input_location;
3878 cur_try_context->end_finally_locus = input_location;
3880 stmt = next_sjlj_build_try_catch_finally ();
3882 else
3884 /* Otherwise, nest the CATCH inside a FINALLY. */
3885 stmt = c->try_body;
3886 if (c->catch_list)
3888 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3889 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3891 if (c->finally_body)
3893 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3894 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3897 add_stmt (stmt);
3899 cur_try_context = c->outer;
3900 free (c);
3901 return stmt;
3904 tree
3905 objc_build_throw_stmt (tree throw_expr)
3907 tree args;
3909 objc_init_exceptions ();
3911 if (throw_expr == NULL)
3913 /* If we're not inside a @catch block, there is no "current
3914 exception" to be rethrown. */
3915 if (cur_try_context == NULL
3916 || cur_try_context->current_catch == NULL)
3918 error ("%<@throw%> (rethrow) used outside of a @catch block");
3919 return NULL_TREE;
3922 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3923 value that we get from the runtime. */
3924 throw_expr = objc_build_exc_ptr ();
3927 /* A throw is just a call to the runtime throw function with the
3928 object as a parameter. */
3929 args = tree_cons (NULL, throw_expr, NULL);
3930 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3933 tree
3934 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3936 tree args, call;
3938 /* First lock the mutex. */
3939 mutex = save_expr (mutex);
3940 args = tree_cons (NULL, mutex, NULL);
3941 call = build_function_call (objc_sync_enter_decl, args);
3942 SET_EXPR_LOCATION (call, start_locus);
3943 add_stmt (call);
3945 /* Build the mutex unlock. */
3946 args = tree_cons (NULL, mutex, NULL);
3947 call = build_function_call (objc_sync_exit_decl, args);
3948 SET_EXPR_LOCATION (call, input_location);
3950 /* Put the that and the body in a TRY_FINALLY. */
3951 objc_begin_try_stmt (start_locus, body);
3952 objc_build_finally_clause (input_location, call);
3953 return objc_finish_try_stmt ();
3957 /* Predefine the following data type:
3959 struct _objc_exception_data
3961 int buf[OBJC_JBLEN];
3962 void *pointers[4];
3963 }; */
3965 /* The following yuckiness should prevent users from having to #include
3966 <setjmp.h> in their code... */
3968 /* Define to a harmless positive value so the below code doesn't die. */
3969 #ifndef OBJC_JBLEN
3970 #define OBJC_JBLEN 18
3971 #endif
3973 static void
3974 build_next_objc_exception_stuff (void)
3976 tree field_decl, field_decl_chain, index, temp_type;
3978 objc_exception_data_template
3979 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3981 /* int buf[OBJC_JBLEN]; */
3983 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
3984 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3985 "buf");
3986 field_decl_chain = field_decl;
3988 /* void *pointers[4]; */
3990 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3991 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3992 "pointers");
3993 chainon (field_decl_chain, field_decl);
3995 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3997 /* int _setjmp(...); */
3998 /* If the user includes <setjmp.h>, this shall be superseded by
3999 'int _setjmp(jmp_buf);' */
4000 temp_type = build_function_type (integer_type_node, NULL_TREE);
4001 objc_setjmp_decl
4002 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4004 /* id objc_exception_extract(struct _objc_exception_data *); */
4005 temp_type
4006 = build_function_type (objc_object_type,
4007 tree_cons (NULL_TREE,
4008 build_pointer_type (objc_exception_data_template),
4009 OBJC_VOID_AT_END));
4010 objc_exception_extract_decl
4011 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4012 NULL_TREE);
4013 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4014 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4015 temp_type
4016 = build_function_type (void_type_node,
4017 tree_cons (NULL_TREE,
4018 build_pointer_type (objc_exception_data_template),
4019 OBJC_VOID_AT_END));
4020 objc_exception_try_enter_decl
4021 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4022 NULL_TREE);
4023 objc_exception_try_exit_decl
4024 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4025 NULL_TREE);
4027 /* int objc_exception_match(id, id); */
4028 temp_type
4029 = build_function_type (integer_type_node,
4030 tree_cons (NULL_TREE, objc_object_type,
4031 tree_cons (NULL_TREE, objc_object_type,
4032 OBJC_VOID_AT_END)));
4033 objc_exception_match_decl
4034 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4035 NULL_TREE);
4037 /* id objc_assign_ivar (id, id, unsigned int); */
4038 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4039 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4040 temp_type
4041 = build_function_type (objc_object_type,
4042 tree_cons
4043 (NULL_TREE, objc_object_type,
4044 tree_cons (NULL_TREE, objc_object_type,
4045 tree_cons (NULL_TREE,
4046 unsigned_type_node,
4047 OBJC_VOID_AT_END))));
4048 objc_assign_ivar_decl
4049 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4050 NULL, NULL_TREE);
4051 #ifdef OFFS_ASSIGNIVAR_FAST
4052 objc_assign_ivar_fast_decl
4053 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4054 NOT_BUILT_IN, NULL, NULL_TREE);
4055 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4056 = tree_cons (get_identifier ("hard_coded_address"),
4057 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4058 NULL_TREE);
4059 #else
4060 /* Default to slower ivar method. */
4061 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4062 #endif
4064 /* id objc_assign_global (id, id *); */
4065 /* id objc_assign_strongCast (id, id *); */
4066 temp_type = build_function_type (objc_object_type,
4067 tree_cons (NULL_TREE, objc_object_type,
4068 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4069 OBJC_VOID_AT_END)));
4070 objc_assign_global_decl
4071 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4072 NULL_TREE);
4073 objc_assign_strong_cast_decl
4074 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4075 NULL_TREE);
4078 static void
4079 build_objc_exception_stuff (void)
4081 tree noreturn_list, nothrow_list, temp_type;
4083 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4084 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4086 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4087 /* void objc_sync_enter(id); */
4088 /* void objc_sync_exit(id); */
4089 temp_type = build_function_type (void_type_node,
4090 tree_cons (NULL_TREE, objc_object_type,
4091 OBJC_VOID_AT_END));
4092 objc_exception_throw_decl
4093 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4094 noreturn_list);
4095 objc_sync_enter_decl
4096 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4097 NULL, nothrow_list);
4098 objc_sync_exit_decl
4099 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4100 NULL, nothrow_list);
4103 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4104 name as the class:
4106 struct <classname> {
4107 struct _objc_class *isa;
4109 }; */
4111 static void
4112 build_private_template (tree klass)
4114 if (!CLASS_STATIC_TEMPLATE (klass))
4116 tree record = objc_build_struct (klass,
4117 get_class_ivars (klass, false),
4118 CLASS_SUPER_NAME (klass));
4120 /* Set the TREE_USED bit for this struct, so that stab generator
4121 can emit stabs for this struct type. */
4122 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4123 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4127 /* Begin code generation for protocols... */
4129 /* struct _objc_protocol {
4130 struct _objc_class *isa;
4131 char *protocol_name;
4132 struct _objc_protocol **protocol_list;
4133 struct _objc__method_prototype_list *instance_methods;
4134 struct _objc__method_prototype_list *class_methods;
4135 }; */
4137 static void
4138 build_protocol_template (void)
4140 tree field_decl, field_decl_chain;
4142 objc_protocol_template = start_struct (RECORD_TYPE,
4143 get_identifier (UTAG_PROTOCOL));
4145 /* struct _objc_class *isa; */
4146 field_decl = create_field_decl (build_pointer_type
4147 (xref_tag (RECORD_TYPE,
4148 get_identifier (UTAG_CLASS))),
4149 "isa");
4150 field_decl_chain = field_decl;
4152 /* char *protocol_name; */
4153 field_decl = create_field_decl (string_type_node, "protocol_name");
4154 chainon (field_decl_chain, field_decl);
4156 /* struct _objc_protocol **protocol_list; */
4157 field_decl = create_field_decl (build_pointer_type
4158 (build_pointer_type
4159 (objc_protocol_template)),
4160 "protocol_list");
4161 chainon (field_decl_chain, field_decl);
4163 /* struct _objc__method_prototype_list *instance_methods; */
4164 field_decl = create_field_decl (objc_method_proto_list_ptr,
4165 "instance_methods");
4166 chainon (field_decl_chain, field_decl);
4168 /* struct _objc__method_prototype_list *class_methods; */
4169 field_decl = create_field_decl (objc_method_proto_list_ptr,
4170 "class_methods");
4171 chainon (field_decl_chain, field_decl);
4173 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4176 static tree
4177 build_descriptor_table_initializer (tree type, tree entries)
4179 tree initlist = NULL_TREE;
4183 tree eltlist = NULL_TREE;
4185 eltlist
4186 = tree_cons (NULL_TREE,
4187 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4188 eltlist
4189 = tree_cons (NULL_TREE,
4190 add_objc_string (METHOD_ENCODING (entries),
4191 meth_var_types),
4192 eltlist);
4194 initlist
4195 = tree_cons (NULL_TREE,
4196 objc_build_constructor (type, nreverse (eltlist)),
4197 initlist);
4199 entries = TREE_CHAIN (entries);
4201 while (entries);
4203 return objc_build_constructor (build_array_type (type, 0),
4204 nreverse (initlist));
4207 /* struct objc_method_prototype_list {
4208 int count;
4209 struct objc_method_prototype {
4210 SEL name;
4211 char *types;
4212 } list[1];
4213 }; */
4215 static tree
4216 build_method_prototype_list_template (tree list_type, int size)
4218 tree objc_ivar_list_record;
4219 tree field_decl, field_decl_chain;
4221 /* Generate an unnamed struct definition. */
4223 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4225 /* int method_count; */
4226 field_decl = create_field_decl (integer_type_node, "method_count");
4227 field_decl_chain = field_decl;
4229 /* struct objc_method method_list[]; */
4230 field_decl = create_field_decl (build_array_type
4231 (list_type,
4232 build_index_type
4233 (build_int_cst (NULL_TREE, size - 1))),
4234 "method_list");
4235 chainon (field_decl_chain, field_decl);
4237 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4239 return objc_ivar_list_record;
4242 static tree
4243 build_method_prototype_template (void)
4245 tree proto_record;
4246 tree field_decl, field_decl_chain;
4248 proto_record
4249 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4251 /* SEL _cmd; */
4252 field_decl = create_field_decl (objc_selector_type, "_cmd");
4253 field_decl_chain = field_decl;
4255 /* char *method_types; */
4256 field_decl = create_field_decl (string_type_node, "method_types");
4257 chainon (field_decl_chain, field_decl);
4259 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4261 return proto_record;
4264 static tree
4265 objc_method_parm_type (tree type)
4267 type = TREE_VALUE (TREE_TYPE (type));
4268 if (TREE_CODE (type) == TYPE_DECL)
4269 type = TREE_TYPE (type);
4270 return type;
4273 static int
4274 objc_encoded_type_size (tree type)
4276 int sz = int_size_in_bytes (type);
4278 /* Make all integer and enum types at least as large
4279 as an int. */
4280 if (sz > 0 && INTEGRAL_TYPE_P (type))
4281 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4282 /* Treat arrays as pointers, since that's how they're
4283 passed in. */
4284 else if (TREE_CODE (type) == ARRAY_TYPE)
4285 sz = int_size_in_bytes (ptr_type_node);
4286 return sz;
4289 static tree
4290 encode_method_prototype (tree method_decl)
4292 tree parms;
4293 int parm_offset, i;
4294 char buf[40];
4295 tree result;
4297 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4298 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4300 /* Encode return type. */
4301 encode_type (objc_method_parm_type (method_decl),
4302 obstack_object_size (&util_obstack),
4303 OBJC_ENCODE_INLINE_DEFS);
4305 /* Stack size. */
4306 /* The first two arguments (self and _cmd) are pointers; account for
4307 their size. */
4308 i = int_size_in_bytes (ptr_type_node);
4309 parm_offset = 2 * i;
4310 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4311 parms = TREE_CHAIN (parms))
4313 tree type = objc_method_parm_type (parms);
4314 int sz = objc_encoded_type_size (type);
4316 /* If a type size is not known, bail out. */
4317 if (sz < 0)
4319 error ("type %q+D does not have a known size",
4320 type);
4321 /* Pretend that the encoding succeeded; the compilation will
4322 fail nevertheless. */
4323 goto finish_encoding;
4325 parm_offset += sz;
4328 sprintf (buf, "%d@0:%d", parm_offset, i);
4329 obstack_grow (&util_obstack, buf, strlen (buf));
4331 /* Argument types. */
4332 parm_offset = 2 * i;
4333 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4334 parms = TREE_CHAIN (parms))
4336 tree type = objc_method_parm_type (parms);
4338 /* Process argument qualifiers for user supplied arguments. */
4339 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4341 /* Type. */
4342 encode_type (type, obstack_object_size (&util_obstack),
4343 OBJC_ENCODE_INLINE_DEFS);
4345 /* Compute offset. */
4346 sprintf (buf, "%d", parm_offset);
4347 parm_offset += objc_encoded_type_size (type);
4349 obstack_grow (&util_obstack, buf, strlen (buf));
4352 finish_encoding:
4353 obstack_1grow (&util_obstack, '\0');
4354 result = get_identifier (XOBFINISH (&util_obstack, char *));
4355 obstack_free (&util_obstack, util_firstobj);
4356 return result;
4359 static tree
4360 generate_descriptor_table (tree type, const char *name, int size, tree list,
4361 tree proto)
4363 tree decl, initlist;
4365 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4367 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4368 initlist = tree_cons (NULL_TREE, list, initlist);
4370 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4372 return decl;
4375 static void
4376 generate_method_descriptors (tree protocol)
4378 tree initlist, chain, method_list_template;
4379 int size;
4381 if (!objc_method_prototype_template)
4382 objc_method_prototype_template = build_method_prototype_template ();
4384 chain = PROTOCOL_CLS_METHODS (protocol);
4385 if (chain)
4387 size = list_length (chain);
4389 method_list_template
4390 = build_method_prototype_list_template (objc_method_prototype_template,
4391 size);
4393 initlist
4394 = build_descriptor_table_initializer (objc_method_prototype_template,
4395 chain);
4397 UOBJC_CLASS_METHODS_decl
4398 = generate_descriptor_table (method_list_template,
4399 "_OBJC_PROTOCOL_CLASS_METHODS",
4400 size, initlist, protocol);
4402 else
4403 UOBJC_CLASS_METHODS_decl = 0;
4405 chain = PROTOCOL_NST_METHODS (protocol);
4406 if (chain)
4408 size = list_length (chain);
4410 method_list_template
4411 = build_method_prototype_list_template (objc_method_prototype_template,
4412 size);
4413 initlist
4414 = build_descriptor_table_initializer (objc_method_prototype_template,
4415 chain);
4417 UOBJC_INSTANCE_METHODS_decl
4418 = generate_descriptor_table (method_list_template,
4419 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4420 size, initlist, protocol);
4422 else
4423 UOBJC_INSTANCE_METHODS_decl = 0;
4426 static void
4427 generate_protocol_references (tree plist)
4429 tree lproto;
4431 /* Forward declare protocols referenced. */
4432 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4434 tree proto = TREE_VALUE (lproto);
4436 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4437 && PROTOCOL_NAME (proto))
4439 if (! PROTOCOL_FORWARD_DECL (proto))
4440 build_protocol_reference (proto);
4442 if (PROTOCOL_LIST (proto))
4443 generate_protocol_references (PROTOCOL_LIST (proto));
4448 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4449 current class. */
4450 #ifdef OBJCPLUS
4451 static void
4452 objc_generate_cxx_ctor_or_dtor (bool dtor)
4454 tree fn, body, compound_stmt, ivar;
4456 /* - (id) .cxx_construct { ... return self; } */
4457 /* - (void) .cxx_construct { ... } */
4459 objc_set_method_type (MINUS_EXPR);
4460 objc_start_method_definition
4461 (objc_build_method_signature (build_tree_list (NULL_TREE,
4462 dtor
4463 ? void_type_node
4464 : objc_object_type),
4465 get_identifier (dtor
4466 ? TAG_CXX_DESTRUCT
4467 : TAG_CXX_CONSTRUCT),
4468 make_node (TREE_LIST),
4469 false));
4470 body = begin_function_body ();
4471 compound_stmt = begin_compound_stmt (0);
4473 ivar = CLASS_IVARS (implementation_template);
4474 /* Destroy ivars in reverse order. */
4475 if (dtor)
4476 ivar = nreverse (copy_list (ivar));
4478 for (; ivar; ivar = TREE_CHAIN (ivar))
4480 if (TREE_CODE (ivar) == FIELD_DECL)
4482 tree type = TREE_TYPE (ivar);
4484 /* Call the ivar's default constructor or destructor. Do not
4485 call the destructor unless a corresponding constructor call
4486 has also been made (or is not needed). */
4487 if (MAYBE_CLASS_TYPE_P (type)
4488 && (dtor
4489 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4490 && (!TYPE_NEEDS_CONSTRUCTING (type)
4491 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4492 : (TYPE_NEEDS_CONSTRUCTING (type)
4493 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4494 finish_expr_stmt
4495 (build_special_member_call
4496 (build_ivar_reference (DECL_NAME (ivar)),
4497 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4498 NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
4502 /* The constructor returns 'self'. */
4503 if (!dtor)
4504 finish_return_stmt (self_decl);
4506 finish_compound_stmt (compound_stmt);
4507 finish_function_body (body);
4508 fn = current_function_decl;
4509 finish_function ();
4510 objc_finish_method_definition (fn);
4513 /* The following routine will examine the current @interface for any
4514 non-POD C++ ivars requiring non-trivial construction and/or
4515 destruction, and then synthesize special '- .cxx_construct' and/or
4516 '- .cxx_destruct' methods which will run the appropriate
4517 construction or destruction code. Note that ivars inherited from
4518 super-classes are _not_ considered. */
4519 static void
4520 objc_generate_cxx_cdtors (void)
4522 bool need_ctor = false, need_dtor = false;
4523 tree ivar;
4525 /* We do not want to do this for categories, since they do not have
4526 their own ivars. */
4528 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4529 return;
4531 /* First, determine if we even need a constructor and/or destructor. */
4533 for (ivar = CLASS_IVARS (implementation_template); ivar;
4534 ivar = TREE_CHAIN (ivar))
4536 if (TREE_CODE (ivar) == FIELD_DECL)
4538 tree type = TREE_TYPE (ivar);
4540 if (MAYBE_CLASS_TYPE_P (type))
4542 if (TYPE_NEEDS_CONSTRUCTING (type)
4543 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4544 /* NB: If a default constructor is not available, we will not
4545 be able to initialize this ivar; the add_instance_variable()
4546 routine will already have warned about this. */
4547 need_ctor = true;
4549 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4550 && (!TYPE_NEEDS_CONSTRUCTING (type)
4551 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4552 /* NB: If a default constructor is not available, we will not
4553 call the destructor either, for symmetry. */
4554 need_dtor = true;
4559 /* Generate '- .cxx_construct' if needed. */
4561 if (need_ctor)
4562 objc_generate_cxx_ctor_or_dtor (false);
4564 /* Generate '- .cxx_destruct' if needed. */
4566 if (need_dtor)
4567 objc_generate_cxx_ctor_or_dtor (true);
4569 /* The 'imp_list' variable points at an imp_entry record for the current
4570 @implementation. Record the existence of '- .cxx_construct' and/or
4571 '- .cxx_destruct' methods therein; it will be included in the
4572 metadata for the class. */
4573 if (flag_next_runtime)
4574 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4576 #endif
4578 /* For each protocol which was referenced either from a @protocol()
4579 expression, or because a class/category implements it (then a
4580 pointer to the protocol is stored in the struct describing the
4581 class/category), we create a statically allocated instance of the
4582 Protocol class. The code is written in such a way as to generate
4583 as few Protocol objects as possible; we generate a unique Protocol
4584 instance for each protocol, and we don't generate a Protocol
4585 instance if the protocol is never referenced (either from a
4586 @protocol() or from a class/category implementation). These
4587 statically allocated objects can be referred to via the static
4588 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4590 The statically allocated Protocol objects that we generate here
4591 need to be fixed up at runtime in order to be used: the 'isa'
4592 pointer of the objects need to be set up to point to the 'Protocol'
4593 class, as known at runtime.
4595 The NeXT runtime fixes up all protocols at program startup time,
4596 before main() is entered. It uses a low-level trick to look up all
4597 those symbols, then loops on them and fixes them up.
4599 The GNU runtime as well fixes up all protocols before user code
4600 from the module is executed; it requires pointers to those symbols
4601 to be put in the objc_symtab (which is then passed as argument to
4602 the function __objc_exec_class() which the compiler sets up to be
4603 executed automatically when the module is loaded); setup of those
4604 Protocol objects happen in two ways in the GNU runtime: all
4605 Protocol objects referred to by a class or category implementation
4606 are fixed up when the class/category is loaded; all Protocol
4607 objects referred to by a @protocol() expression are added by the
4608 compiler to the list of statically allocated instances to fixup
4609 (the same list holding the statically allocated constant string
4610 objects). Because, as explained above, the compiler generates as
4611 few Protocol objects as possible, some Protocol object might end up
4612 being referenced multiple times when compiled with the GNU runtime,
4613 and end up being fixed up multiple times at runtime initialization.
4614 But that doesn't hurt, it's just a little inefficient. */
4616 static void
4617 generate_protocols (void)
4619 tree p, encoding;
4620 tree decl;
4621 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4623 /* If a protocol was directly referenced, pull in indirect references. */
4624 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4625 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4626 generate_protocol_references (PROTOCOL_LIST (p));
4628 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4630 tree nst_methods = PROTOCOL_NST_METHODS (p);
4631 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4633 /* If protocol wasn't referenced, don't generate any code. */
4634 decl = PROTOCOL_FORWARD_DECL (p);
4636 if (!decl)
4637 continue;
4639 /* Make sure we link in the Protocol class. */
4640 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4642 while (nst_methods)
4644 if (! METHOD_ENCODING (nst_methods))
4646 encoding = encode_method_prototype (nst_methods);
4647 METHOD_ENCODING (nst_methods) = encoding;
4649 nst_methods = TREE_CHAIN (nst_methods);
4652 while (cls_methods)
4654 if (! METHOD_ENCODING (cls_methods))
4656 encoding = encode_method_prototype (cls_methods);
4657 METHOD_ENCODING (cls_methods) = encoding;
4660 cls_methods = TREE_CHAIN (cls_methods);
4662 generate_method_descriptors (p);
4664 if (PROTOCOL_LIST (p))
4665 refs_decl = generate_protocol_list (p);
4666 else
4667 refs_decl = 0;
4669 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4670 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4672 if (refs_decl)
4673 refs_expr = convert (build_pointer_type (build_pointer_type
4674 (objc_protocol_template)),
4675 build_unary_op (ADDR_EXPR, refs_decl, 0));
4676 else
4677 refs_expr = build_int_cst (NULL_TREE, 0);
4679 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4680 by generate_method_descriptors, which is called above. */
4681 initlist = build_protocol_initializer (TREE_TYPE (decl),
4682 protocol_name_expr, refs_expr,
4683 UOBJC_INSTANCE_METHODS_decl,
4684 UOBJC_CLASS_METHODS_decl);
4685 finish_var_decl (decl, initlist);
4689 static tree
4690 build_protocol_initializer (tree type, tree protocol_name,
4691 tree protocol_list, tree instance_methods,
4692 tree class_methods)
4694 tree initlist = NULL_TREE, expr;
4695 tree cast_type = build_pointer_type
4696 (xref_tag (RECORD_TYPE,
4697 get_identifier (UTAG_CLASS)));
4699 /* Filling the "isa" in with one allows the runtime system to
4700 detect that the version change...should remove before final release. */
4702 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4703 initlist = tree_cons (NULL_TREE, expr, initlist);
4704 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4705 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4707 if (!instance_methods)
4708 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4709 else
4711 expr = convert (objc_method_proto_list_ptr,
4712 build_unary_op (ADDR_EXPR, instance_methods, 0));
4713 initlist = tree_cons (NULL_TREE, expr, initlist);
4716 if (!class_methods)
4717 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4718 else
4720 expr = convert (objc_method_proto_list_ptr,
4721 build_unary_op (ADDR_EXPR, class_methods, 0));
4722 initlist = tree_cons (NULL_TREE, expr, initlist);
4725 return objc_build_constructor (type, nreverse (initlist));
4728 /* struct _objc_category {
4729 char *category_name;
4730 char *class_name;
4731 struct _objc_method_list *instance_methods;
4732 struct _objc_method_list *class_methods;
4733 struct _objc_protocol_list *protocols;
4734 }; */
4736 static void
4737 build_category_template (void)
4739 tree field_decl, field_decl_chain;
4741 objc_category_template = start_struct (RECORD_TYPE,
4742 get_identifier (UTAG_CATEGORY));
4744 /* char *category_name; */
4745 field_decl = create_field_decl (string_type_node, "category_name");
4746 field_decl_chain = field_decl;
4748 /* char *class_name; */
4749 field_decl = create_field_decl (string_type_node, "class_name");
4750 chainon (field_decl_chain, field_decl);
4752 /* struct _objc_method_list *instance_methods; */
4753 field_decl = create_field_decl (objc_method_list_ptr,
4754 "instance_methods");
4755 chainon (field_decl_chain, field_decl);
4757 /* struct _objc_method_list *class_methods; */
4758 field_decl = create_field_decl (objc_method_list_ptr,
4759 "class_methods");
4760 chainon (field_decl_chain, field_decl);
4762 /* struct _objc_protocol **protocol_list; */
4763 field_decl = create_field_decl (build_pointer_type
4764 (build_pointer_type
4765 (objc_protocol_template)),
4766 "protocol_list");
4767 chainon (field_decl_chain, field_decl);
4769 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4772 /* struct _objc_selector {
4773 SEL sel_id;
4774 char *sel_type;
4775 }; */
4777 static void
4778 build_selector_template (void)
4781 tree field_decl, field_decl_chain;
4783 objc_selector_template
4784 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4786 /* SEL sel_id; */
4787 field_decl = create_field_decl (objc_selector_type, "sel_id");
4788 field_decl_chain = field_decl;
4790 /* char *sel_type; */
4791 field_decl = create_field_decl (string_type_node, "sel_type");
4792 chainon (field_decl_chain, field_decl);
4794 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4797 /* struct _objc_class {
4798 struct _objc_class *isa;
4799 struct _objc_class *super_class;
4800 char *name;
4801 long version;
4802 long info;
4803 long instance_size;
4804 struct _objc_ivar_list *ivars;
4805 struct _objc_method_list *methods;
4806 #ifdef __NEXT_RUNTIME__
4807 struct objc_cache *cache;
4808 #else
4809 struct sarray *dtable;
4810 struct _objc_class *subclass_list;
4811 struct _objc_class *sibling_class;
4812 #endif
4813 struct _objc_protocol_list *protocols;
4814 #ifdef __NEXT_RUNTIME__
4815 void *sel_id;
4816 #endif
4817 void *gc_object_type;
4818 }; */
4820 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4821 the NeXT/Apple runtime; still, the compiler must generate them to
4822 maintain backward binary compatibility (and to allow for future
4823 expansion). */
4825 static void
4826 build_class_template (void)
4828 tree field_decl, field_decl_chain;
4830 objc_class_template
4831 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4833 /* struct _objc_class *isa; */
4834 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4835 "isa");
4836 field_decl_chain = field_decl;
4838 /* struct _objc_class *super_class; */
4839 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4840 "super_class");
4841 chainon (field_decl_chain, field_decl);
4843 /* char *name; */
4844 field_decl = create_field_decl (string_type_node, "name");
4845 chainon (field_decl_chain, field_decl);
4847 /* long version; */
4848 field_decl = create_field_decl (long_integer_type_node, "version");
4849 chainon (field_decl_chain, field_decl);
4851 /* long info; */
4852 field_decl = create_field_decl (long_integer_type_node, "info");
4853 chainon (field_decl_chain, field_decl);
4855 /* long instance_size; */
4856 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4857 chainon (field_decl_chain, field_decl);
4859 /* struct _objc_ivar_list *ivars; */
4860 field_decl = create_field_decl (objc_ivar_list_ptr,
4861 "ivars");
4862 chainon (field_decl_chain, field_decl);
4864 /* struct _objc_method_list *methods; */
4865 field_decl = create_field_decl (objc_method_list_ptr,
4866 "methods");
4867 chainon (field_decl_chain, field_decl);
4869 if (flag_next_runtime)
4871 /* struct objc_cache *cache; */
4872 field_decl = create_field_decl (build_pointer_type
4873 (xref_tag (RECORD_TYPE,
4874 get_identifier
4875 ("objc_cache"))),
4876 "cache");
4877 chainon (field_decl_chain, field_decl);
4879 else
4881 /* struct sarray *dtable; */
4882 field_decl = create_field_decl (build_pointer_type
4883 (xref_tag (RECORD_TYPE,
4884 get_identifier
4885 ("sarray"))),
4886 "dtable");
4887 chainon (field_decl_chain, field_decl);
4889 /* struct objc_class *subclass_list; */
4890 field_decl = create_field_decl (build_pointer_type
4891 (objc_class_template),
4892 "subclass_list");
4893 chainon (field_decl_chain, field_decl);
4895 /* struct objc_class *sibling_class; */
4896 field_decl = create_field_decl (build_pointer_type
4897 (objc_class_template),
4898 "sibling_class");
4899 chainon (field_decl_chain, field_decl);
4902 /* struct _objc_protocol **protocol_list; */
4903 field_decl = create_field_decl (build_pointer_type
4904 (build_pointer_type
4905 (xref_tag (RECORD_TYPE,
4906 get_identifier
4907 (UTAG_PROTOCOL)))),
4908 "protocol_list");
4909 chainon (field_decl_chain, field_decl);
4911 if (flag_next_runtime)
4913 /* void *sel_id; */
4914 field_decl = create_field_decl (build_pointer_type (void_type_node),
4915 "sel_id");
4916 chainon (field_decl_chain, field_decl);
4919 /* void *gc_object_type; */
4920 field_decl = create_field_decl (build_pointer_type (void_type_node),
4921 "gc_object_type");
4922 chainon (field_decl_chain, field_decl);
4924 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4927 /* Generate appropriate forward declarations for an implementation. */
4929 static void
4930 synth_forward_declarations (void)
4932 tree an_id;
4934 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4935 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4936 objc_class_template);
4938 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4939 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4940 objc_class_template);
4942 /* Pre-build the following entities - for speed/convenience. */
4944 an_id = get_identifier ("super_class");
4945 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4946 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4949 static void
4950 error_with_ivar (const char *message, tree decl)
4952 error ("%J%s %qs", decl,
4953 message, gen_declaration (decl));
4957 static void
4958 check_ivars (tree inter, tree imp)
4960 tree intdecls = CLASS_RAW_IVARS (inter);
4961 tree impdecls = CLASS_RAW_IVARS (imp);
4963 while (1)
4965 tree t1, t2;
4967 #ifdef OBJCPLUS
4968 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4969 intdecls = TREE_CHAIN (intdecls);
4970 #endif
4971 if (intdecls == 0 && impdecls == 0)
4972 break;
4973 if (intdecls == 0 || impdecls == 0)
4975 error ("inconsistent instance variable specification");
4976 break;
4979 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4981 if (!comptypes (t1, t2)
4982 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4983 DECL_INITIAL (impdecls)))
4985 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4987 error_with_ivar ("conflicting instance variable type",
4988 impdecls);
4989 error_with_ivar ("previous declaration of",
4990 intdecls);
4992 else /* both the type and the name don't match */
4994 error ("inconsistent instance variable specification");
4995 break;
4999 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5001 error_with_ivar ("conflicting instance variable name",
5002 impdecls);
5003 error_with_ivar ("previous declaration of",
5004 intdecls);
5007 intdecls = TREE_CHAIN (intdecls);
5008 impdecls = TREE_CHAIN (impdecls);
5012 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5013 This needs to be done just once per compilation. */
5015 /* struct _objc_super {
5016 struct _objc_object *self;
5017 struct _objc_class *super_class;
5018 }; */
5020 static void
5021 build_super_template (void)
5023 tree field_decl, field_decl_chain;
5025 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5027 /* struct _objc_object *self; */
5028 field_decl = create_field_decl (objc_object_type, "self");
5029 field_decl_chain = field_decl;
5031 /* struct _objc_class *super_class; */
5032 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5033 "super_class");
5034 chainon (field_decl_chain, field_decl);
5036 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5039 /* struct _objc_ivar {
5040 char *ivar_name;
5041 char *ivar_type;
5042 int ivar_offset;
5043 }; */
5045 static tree
5046 build_ivar_template (void)
5048 tree objc_ivar_id, objc_ivar_record;
5049 tree field_decl, field_decl_chain;
5051 objc_ivar_id = get_identifier (UTAG_IVAR);
5052 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5054 /* char *ivar_name; */
5055 field_decl = create_field_decl (string_type_node, "ivar_name");
5056 field_decl_chain = field_decl;
5058 /* char *ivar_type; */
5059 field_decl = create_field_decl (string_type_node, "ivar_type");
5060 chainon (field_decl_chain, field_decl);
5062 /* int ivar_offset; */
5063 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5064 chainon (field_decl_chain, field_decl);
5066 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5068 return objc_ivar_record;
5071 /* struct {
5072 int ivar_count;
5073 struct objc_ivar ivar_list[ivar_count];
5074 }; */
5076 static tree
5077 build_ivar_list_template (tree list_type, int size)
5079 tree objc_ivar_list_record;
5080 tree field_decl, field_decl_chain;
5082 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5084 /* int ivar_count; */
5085 field_decl = create_field_decl (integer_type_node, "ivar_count");
5086 field_decl_chain = field_decl;
5088 /* struct objc_ivar ivar_list[]; */
5089 field_decl = create_field_decl (build_array_type
5090 (list_type,
5091 build_index_type
5092 (build_int_cst (NULL_TREE, size - 1))),
5093 "ivar_list");
5094 chainon (field_decl_chain, field_decl);
5096 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5098 return objc_ivar_list_record;
5101 /* struct {
5102 struct _objc__method_prototype_list *method_next;
5103 int method_count;
5104 struct objc_method method_list[method_count];
5105 }; */
5107 static tree
5108 build_method_list_template (tree list_type, int size)
5110 tree objc_ivar_list_record;
5111 tree field_decl, field_decl_chain;
5113 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5115 /* struct _objc__method_prototype_list *method_next; */
5116 field_decl = create_field_decl (objc_method_proto_list_ptr,
5117 "method_next");
5118 field_decl_chain = field_decl;
5120 /* int method_count; */
5121 field_decl = create_field_decl (integer_type_node, "method_count");
5122 chainon (field_decl_chain, field_decl);
5124 /* struct objc_method method_list[]; */
5125 field_decl = create_field_decl (build_array_type
5126 (list_type,
5127 build_index_type
5128 (build_int_cst (NULL_TREE, size - 1))),
5129 "method_list");
5130 chainon (field_decl_chain, field_decl);
5132 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5134 return objc_ivar_list_record;
5137 static tree
5138 build_ivar_list_initializer (tree type, tree field_decl)
5140 tree initlist = NULL_TREE;
5144 tree ivar = NULL_TREE;
5146 /* Set name. */
5147 if (DECL_NAME (field_decl))
5148 ivar = tree_cons (NULL_TREE,
5149 add_objc_string (DECL_NAME (field_decl),
5150 meth_var_names),
5151 ivar);
5152 else
5153 /* Unnamed bit-field ivar (yuck). */
5154 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5156 /* Set type. */
5157 encode_field_decl (field_decl,
5158 obstack_object_size (&util_obstack),
5159 OBJC_ENCODE_DONT_INLINE_DEFS);
5161 /* Null terminate string. */
5162 obstack_1grow (&util_obstack, 0);
5163 ivar
5164 = tree_cons
5165 (NULL_TREE,
5166 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5167 meth_var_types),
5168 ivar);
5169 obstack_free (&util_obstack, util_firstobj);
5171 /* Set offset. */
5172 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5173 initlist = tree_cons (NULL_TREE,
5174 objc_build_constructor (type, nreverse (ivar)),
5175 initlist);
5177 field_decl = TREE_CHAIN (field_decl);
5178 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5180 while (field_decl);
5182 return objc_build_constructor (build_array_type (type, 0),
5183 nreverse (initlist));
5186 static tree
5187 generate_ivars_list (tree type, const char *name, int size, tree list)
5189 tree decl, initlist;
5191 decl = start_var_decl (type, synth_id_with_class_suffix
5192 (name, objc_implementation_context));
5194 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5195 initlist = tree_cons (NULL_TREE, list, initlist);
5197 finish_var_decl (decl,
5198 objc_build_constructor (TREE_TYPE (decl),
5199 nreverse (initlist)));
5201 return decl;
5204 /* Count only the fields occurring in T. */
5206 static int
5207 ivar_list_length (tree t)
5209 int count = 0;
5211 for (; t; t = TREE_CHAIN (t))
5212 if (TREE_CODE (t) == FIELD_DECL)
5213 ++count;
5215 return count;
5218 static void
5219 generate_ivar_lists (void)
5221 tree initlist, ivar_list_template, chain;
5222 int size;
5224 generating_instance_variables = 1;
5226 if (!objc_ivar_template)
5227 objc_ivar_template = build_ivar_template ();
5229 /* Only generate class variables for the root of the inheritance
5230 hierarchy since these will be the same for every class. */
5232 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5233 && (chain = TYPE_FIELDS (objc_class_template)))
5235 size = ivar_list_length (chain);
5237 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5238 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5240 UOBJC_CLASS_VARIABLES_decl
5241 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5242 size, initlist);
5244 else
5245 UOBJC_CLASS_VARIABLES_decl = 0;
5247 chain = CLASS_IVARS (implementation_template);
5248 if (chain)
5250 size = ivar_list_length (chain);
5251 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5252 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5254 UOBJC_INSTANCE_VARIABLES_decl
5255 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5256 size, initlist);
5258 else
5259 UOBJC_INSTANCE_VARIABLES_decl = 0;
5261 generating_instance_variables = 0;
5264 static tree
5265 build_dispatch_table_initializer (tree type, tree entries)
5267 tree initlist = NULL_TREE;
5271 tree elemlist = NULL_TREE;
5273 elemlist = tree_cons (NULL_TREE,
5274 build_selector (METHOD_SEL_NAME (entries)),
5275 NULL_TREE);
5277 /* Generate the method encoding if we don't have one already. */
5278 if (! METHOD_ENCODING (entries))
5279 METHOD_ENCODING (entries) =
5280 encode_method_prototype (entries);
5282 elemlist = tree_cons (NULL_TREE,
5283 add_objc_string (METHOD_ENCODING (entries),
5284 meth_var_types),
5285 elemlist);
5287 elemlist
5288 = tree_cons (NULL_TREE,
5289 convert (ptr_type_node,
5290 build_unary_op (ADDR_EXPR,
5291 METHOD_DEFINITION (entries), 1)),
5292 elemlist);
5294 initlist = tree_cons (NULL_TREE,
5295 objc_build_constructor (type, nreverse (elemlist)),
5296 initlist);
5298 entries = TREE_CHAIN (entries);
5300 while (entries);
5302 return objc_build_constructor (build_array_type (type, 0),
5303 nreverse (initlist));
5306 /* To accomplish method prototyping without generating all kinds of
5307 inane warnings, the definition of the dispatch table entries were
5308 changed from:
5310 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5312 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5314 static tree
5315 build_method_template (void)
5317 tree _SLT_record;
5318 tree field_decl, field_decl_chain;
5320 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5322 /* SEL _cmd; */
5323 field_decl = create_field_decl (objc_selector_type, "_cmd");
5324 field_decl_chain = field_decl;
5326 /* char *method_types; */
5327 field_decl = create_field_decl (string_type_node, "method_types");
5328 chainon (field_decl_chain, field_decl);
5330 /* void *_imp; */
5331 field_decl = create_field_decl (build_pointer_type (void_type_node),
5332 "_imp");
5333 chainon (field_decl_chain, field_decl);
5335 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5337 return _SLT_record;
5341 static tree
5342 generate_dispatch_table (tree type, const char *name, int size, tree list)
5344 tree decl, initlist;
5346 decl = start_var_decl (type, synth_id_with_class_suffix
5347 (name, objc_implementation_context));
5349 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5350 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5351 initlist = tree_cons (NULL_TREE, list, initlist);
5353 finish_var_decl (decl,
5354 objc_build_constructor (TREE_TYPE (decl),
5355 nreverse (initlist)));
5357 return decl;
5360 static void
5361 mark_referenced_methods (void)
5363 struct imp_entry *impent;
5364 tree chain;
5366 for (impent = imp_list; impent; impent = impent->next)
5368 chain = CLASS_CLS_METHODS (impent->imp_context);
5369 while (chain)
5371 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5372 chain = TREE_CHAIN (chain);
5375 chain = CLASS_NST_METHODS (impent->imp_context);
5376 while (chain)
5378 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5379 chain = TREE_CHAIN (chain);
5384 static void
5385 generate_dispatch_tables (void)
5387 tree initlist, chain, method_list_template;
5388 int size;
5390 if (!objc_method_template)
5391 objc_method_template = build_method_template ();
5393 chain = CLASS_CLS_METHODS (objc_implementation_context);
5394 if (chain)
5396 size = list_length (chain);
5398 method_list_template
5399 = build_method_list_template (objc_method_template, size);
5400 initlist
5401 = build_dispatch_table_initializer (objc_method_template, chain);
5403 UOBJC_CLASS_METHODS_decl
5404 = generate_dispatch_table (method_list_template,
5405 ((TREE_CODE (objc_implementation_context)
5406 == CLASS_IMPLEMENTATION_TYPE)
5407 ? "_OBJC_CLASS_METHODS"
5408 : "_OBJC_CATEGORY_CLASS_METHODS"),
5409 size, initlist);
5411 else
5412 UOBJC_CLASS_METHODS_decl = 0;
5414 chain = CLASS_NST_METHODS (objc_implementation_context);
5415 if (chain)
5417 size = list_length (chain);
5419 method_list_template
5420 = build_method_list_template (objc_method_template, size);
5421 initlist
5422 = build_dispatch_table_initializer (objc_method_template, chain);
5424 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5425 UOBJC_INSTANCE_METHODS_decl
5426 = generate_dispatch_table (method_list_template,
5427 "_OBJC_INSTANCE_METHODS",
5428 size, initlist);
5429 else
5430 /* We have a category. */
5431 UOBJC_INSTANCE_METHODS_decl
5432 = generate_dispatch_table (method_list_template,
5433 "_OBJC_CATEGORY_INSTANCE_METHODS",
5434 size, initlist);
5436 else
5437 UOBJC_INSTANCE_METHODS_decl = 0;
5440 static tree
5441 generate_protocol_list (tree i_or_p)
5443 tree initlist;
5444 tree refs_decl, lproto, e, plist;
5445 int size = 0;
5446 const char *ref_name;
5448 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5449 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5450 plist = CLASS_PROTOCOL_LIST (i_or_p);
5451 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5452 plist = PROTOCOL_LIST (i_or_p);
5453 else
5454 abort ();
5456 /* Compute size. */
5457 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5458 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5459 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5460 size++;
5462 /* Build initializer. */
5463 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5464 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5465 initlist = tree_cons (NULL_TREE, e, initlist);
5467 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5469 tree pval = TREE_VALUE (lproto);
5471 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5472 && PROTOCOL_FORWARD_DECL (pval))
5474 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5475 initlist = tree_cons (NULL_TREE, e, initlist);
5479 /* static struct objc_protocol *refs[n]; */
5481 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5482 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5483 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5484 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5485 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5486 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5487 else
5488 abort ();
5490 refs_decl = start_var_decl
5491 (build_array_type
5492 (build_pointer_type (objc_protocol_template),
5493 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5494 ref_name);
5496 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5497 nreverse (initlist)));
5499 return refs_decl;
5502 static tree
5503 build_category_initializer (tree type, tree cat_name, tree class_name,
5504 tree instance_methods, tree class_methods,
5505 tree protocol_list)
5507 tree initlist = NULL_TREE, expr;
5509 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5510 initlist = tree_cons (NULL_TREE, class_name, initlist);
5512 if (!instance_methods)
5513 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5514 else
5516 expr = convert (objc_method_list_ptr,
5517 build_unary_op (ADDR_EXPR, instance_methods, 0));
5518 initlist = tree_cons (NULL_TREE, expr, initlist);
5520 if (!class_methods)
5521 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5522 else
5524 expr = convert (objc_method_list_ptr,
5525 build_unary_op (ADDR_EXPR, class_methods, 0));
5526 initlist = tree_cons (NULL_TREE, expr, initlist);
5529 /* protocol_list = */
5530 if (!protocol_list)
5531 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5532 else
5534 expr = convert (build_pointer_type
5535 (build_pointer_type
5536 (objc_protocol_template)),
5537 build_unary_op (ADDR_EXPR, protocol_list, 0));
5538 initlist = tree_cons (NULL_TREE, expr, initlist);
5541 return objc_build_constructor (type, nreverse (initlist));
5544 /* struct _objc_class {
5545 struct objc_class *isa;
5546 struct objc_class *super_class;
5547 char *name;
5548 long version;
5549 long info;
5550 long instance_size;
5551 struct objc_ivar_list *ivars;
5552 struct objc_method_list *methods;
5553 if (flag_next_runtime)
5554 struct objc_cache *cache;
5555 else {
5556 struct sarray *dtable;
5557 struct objc_class *subclass_list;
5558 struct objc_class *sibling_class;
5560 struct objc_protocol_list *protocols;
5561 if (flag_next_runtime)
5562 void *sel_id;
5563 void *gc_object_type;
5564 }; */
5566 static tree
5567 build_shared_structure_initializer (tree type, tree isa, tree super,
5568 tree name, tree size, int status,
5569 tree dispatch_table, tree ivar_list,
5570 tree protocol_list)
5572 tree initlist = NULL_TREE, expr;
5574 /* isa = */
5575 initlist = tree_cons (NULL_TREE, isa, initlist);
5577 /* super_class = */
5578 initlist = tree_cons (NULL_TREE, super, initlist);
5580 /* name = */
5581 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5583 /* version = */
5584 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5585 initlist);
5587 /* info = */
5588 initlist = tree_cons (NULL_TREE,
5589 build_int_cst (long_integer_type_node, status),
5590 initlist);
5592 /* instance_size = */
5593 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5594 initlist);
5596 /* objc_ivar_list = */
5597 if (!ivar_list)
5598 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5599 else
5601 expr = convert (objc_ivar_list_ptr,
5602 build_unary_op (ADDR_EXPR, ivar_list, 0));
5603 initlist = tree_cons (NULL_TREE, expr, initlist);
5606 /* objc_method_list = */
5607 if (!dispatch_table)
5608 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5609 else
5611 expr = convert (objc_method_list_ptr,
5612 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5613 initlist = tree_cons (NULL_TREE, expr, initlist);
5616 if (flag_next_runtime)
5617 /* method_cache = */
5618 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5619 else
5621 /* dtable = */
5622 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5624 /* subclass_list = */
5625 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5627 /* sibling_class = */
5628 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5631 /* protocol_list = */
5632 if (! protocol_list)
5633 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5634 else
5636 expr = convert (build_pointer_type
5637 (build_pointer_type
5638 (objc_protocol_template)),
5639 build_unary_op (ADDR_EXPR, protocol_list, 0));
5640 initlist = tree_cons (NULL_TREE, expr, initlist);
5643 if (flag_next_runtime)
5644 /* sel_id = NULL */
5645 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5647 /* gc_object_type = NULL */
5648 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5650 return objc_build_constructor (type, nreverse (initlist));
5653 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5655 static inline tree
5656 lookup_category (tree klass, tree cat_name)
5658 tree category = CLASS_CATEGORY_LIST (klass);
5660 while (category && CLASS_SUPER_NAME (category) != cat_name)
5661 category = CLASS_CATEGORY_LIST (category);
5662 return category;
5665 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5667 static void
5668 generate_category (tree cat)
5670 tree decl;
5671 tree initlist, cat_name_expr, class_name_expr;
5672 tree protocol_decl, category;
5674 add_class_reference (CLASS_NAME (cat));
5675 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5677 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5679 category = lookup_category (implementation_template,
5680 CLASS_SUPER_NAME (cat));
5682 if (category && CLASS_PROTOCOL_LIST (category))
5684 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5685 protocol_decl = generate_protocol_list (category);
5687 else
5688 protocol_decl = 0;
5690 decl = start_var_decl (objc_category_template,
5691 synth_id_with_class_suffix
5692 ("_OBJC_CATEGORY", objc_implementation_context));
5694 initlist = build_category_initializer (TREE_TYPE (decl),
5695 cat_name_expr, class_name_expr,
5696 UOBJC_INSTANCE_METHODS_decl,
5697 UOBJC_CLASS_METHODS_decl,
5698 protocol_decl);
5700 finish_var_decl (decl, initlist);
5703 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5704 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5706 static void
5707 generate_shared_structures (int cls_flags)
5709 tree sc_spec, decl_specs, decl;
5710 tree name_expr, super_expr, root_expr;
5711 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5712 tree cast_type, initlist, protocol_decl;
5714 my_super_id = CLASS_SUPER_NAME (implementation_template);
5715 if (my_super_id)
5717 add_class_reference (my_super_id);
5719 /* Compute "my_root_id" - this is required for code generation.
5720 the "isa" for all meta class structures points to the root of
5721 the inheritance hierarchy (e.g. "__Object")... */
5722 my_root_id = my_super_id;
5725 tree my_root_int = lookup_interface (my_root_id);
5727 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5728 my_root_id = CLASS_SUPER_NAME (my_root_int);
5729 else
5730 break;
5732 while (1);
5734 else
5735 /* No super class. */
5736 my_root_id = CLASS_NAME (implementation_template);
5738 cast_type = build_pointer_type (objc_class_template);
5739 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5740 class_names);
5742 /* Install class `isa' and `super' pointers at runtime. */
5743 if (my_super_id)
5745 super_expr = add_objc_string (my_super_id, class_names);
5746 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5748 else
5749 super_expr = build_int_cst (NULL_TREE, 0);
5751 root_expr = add_objc_string (my_root_id, class_names);
5752 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5754 if (CLASS_PROTOCOL_LIST (implementation_template))
5756 generate_protocol_references
5757 (CLASS_PROTOCOL_LIST (implementation_template));
5758 protocol_decl = generate_protocol_list (implementation_template);
5760 else
5761 protocol_decl = 0;
5763 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5765 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5766 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5768 decl = start_var_decl (objc_class_template,
5769 IDENTIFIER_POINTER
5770 (DECL_NAME (UOBJC_METACLASS_decl)));
5772 initlist
5773 = build_shared_structure_initializer
5774 (TREE_TYPE (decl),
5775 root_expr, super_expr, name_expr,
5776 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5777 2 /*CLS_META*/,
5778 UOBJC_CLASS_METHODS_decl,
5779 UOBJC_CLASS_VARIABLES_decl,
5780 protocol_decl);
5782 finish_var_decl (decl, initlist);
5784 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5786 decl = start_var_decl (objc_class_template,
5787 IDENTIFIER_POINTER
5788 (DECL_NAME (UOBJC_CLASS_decl)));
5790 initlist
5791 = build_shared_structure_initializer
5792 (TREE_TYPE (decl),
5793 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5794 super_expr, name_expr,
5795 convert (integer_type_node,
5796 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5797 (implementation_template))),
5798 1 /*CLS_FACTORY*/ | cls_flags,
5799 UOBJC_INSTANCE_METHODS_decl,
5800 UOBJC_INSTANCE_VARIABLES_decl,
5801 protocol_decl);
5803 finish_var_decl (decl, initlist);
5807 static const char *
5808 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5810 static char string[BUFSIZE];
5812 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5813 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5815 sprintf (string, "%s_%s", preamble,
5816 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5818 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5819 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5821 /* We have a category. */
5822 const char *const class_name
5823 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5824 const char *const class_super_name
5825 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5826 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5828 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5830 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5831 sprintf (string, "%s_%s", preamble, protocol_name);
5833 else
5834 abort ();
5836 return string;
5839 /* If type is empty or only type qualifiers are present, add default
5840 type of id (otherwise grokdeclarator will default to int). */
5842 static tree
5843 adjust_type_for_id_default (tree type)
5845 if (!type)
5846 type = make_node (TREE_LIST);
5848 if (!TREE_VALUE (type))
5849 TREE_VALUE (type) = objc_object_type;
5850 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5851 && TYPED_OBJECT (TREE_VALUE (type)))
5852 error ("can not use an object as parameter to a method");
5854 return type;
5857 /* Usage:
5858 keyworddecl:
5859 selector ':' '(' typename ')' identifier
5861 Purpose:
5862 Transform an Objective-C keyword argument into
5863 the C equivalent parameter declarator.
5865 In: key_name, an "identifier_node" (optional).
5866 arg_type, a "tree_list" (optional).
5867 arg_name, an "identifier_node".
5869 Note: It would be really nice to strongly type the preceding
5870 arguments in the function prototype; however, then I
5871 could not use the "accessor" macros defined in "tree.h".
5873 Out: an instance of "keyword_decl". */
5875 tree
5876 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5878 tree keyword_decl;
5880 /* If no type is specified, default to "id". */
5881 arg_type = adjust_type_for_id_default (arg_type);
5883 keyword_decl = make_node (KEYWORD_DECL);
5885 TREE_TYPE (keyword_decl) = arg_type;
5886 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5887 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5889 return keyword_decl;
5892 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5894 static tree
5895 build_keyword_selector (tree selector)
5897 int len = 0;
5898 tree key_chain, key_name;
5899 char *buf;
5901 /* Scan the selector to see how much space we'll need. */
5902 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5904 if (TREE_CODE (selector) == KEYWORD_DECL)
5905 key_name = KEYWORD_KEY_NAME (key_chain);
5906 else if (TREE_CODE (selector) == TREE_LIST)
5907 key_name = TREE_PURPOSE (key_chain);
5908 else
5909 abort ();
5911 if (key_name)
5912 len += IDENTIFIER_LENGTH (key_name) + 1;
5913 else
5914 /* Just a ':' arg. */
5915 len++;
5918 buf = (char *) alloca (len + 1);
5919 /* Start the buffer out as an empty string. */
5920 buf[0] = '\0';
5922 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5924 if (TREE_CODE (selector) == KEYWORD_DECL)
5925 key_name = KEYWORD_KEY_NAME (key_chain);
5926 else if (TREE_CODE (selector) == TREE_LIST)
5928 key_name = TREE_PURPOSE (key_chain);
5929 /* The keyword decl chain will later be used as a function argument
5930 chain. Unhook the selector itself so as to not confuse other
5931 parts of the compiler. */
5932 TREE_PURPOSE (key_chain) = NULL_TREE;
5934 else
5935 abort ();
5937 if (key_name)
5938 strcat (buf, IDENTIFIER_POINTER (key_name));
5939 strcat (buf, ":");
5942 return get_identifier (buf);
5945 /* Used for declarations and definitions. */
5947 static tree
5948 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5949 tree add_args, bool ellipsis)
5951 tree method_decl;
5953 /* If no type is specified, default to "id". */
5954 ret_type = adjust_type_for_id_default (ret_type);
5956 method_decl = make_node (code);
5957 TREE_TYPE (method_decl) = ret_type;
5959 /* If we have a keyword selector, create an identifier_node that
5960 represents the full selector name (`:' included)... */
5961 if (TREE_CODE (selector) == KEYWORD_DECL)
5963 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5964 METHOD_SEL_ARGS (method_decl) = selector;
5965 METHOD_ADD_ARGS (method_decl) = add_args;
5966 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5968 else
5970 METHOD_SEL_NAME (method_decl) = selector;
5971 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5972 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5975 return method_decl;
5978 #define METHOD_DEF 0
5979 #define METHOD_REF 1
5981 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5982 an argument list for method METH. CONTEXT is either METHOD_DEF or
5983 METHOD_REF, saying whether we are trying to define a method or call
5984 one. SUPERFLAG says this is for a send to super; this makes a
5985 difference for the NeXT calling sequence in which the lookup and
5986 the method call are done together. If METH is null, user-defined
5987 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5989 static tree
5990 get_arg_type_list (tree meth, int context, int superflag)
5992 tree arglist, akey;
5994 /* Receiver type. */
5995 if (flag_next_runtime && superflag)
5996 arglist = build_tree_list (NULL_TREE, objc_super_type);
5997 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5998 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5999 else
6000 arglist = build_tree_list (NULL_TREE, objc_object_type);
6002 /* Selector type - will eventually change to `int'. */
6003 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6005 /* No actual method prototype given -- assume that remaining arguments
6006 are `...'. */
6007 if (!meth)
6008 return arglist;
6010 /* Build a list of argument types. */
6011 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6013 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6015 /* Decay arrays and functions into pointers. */
6016 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6017 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6018 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6019 arg_type = build_pointer_type (arg_type);
6021 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6024 if (METHOD_ADD_ARGS (meth))
6026 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6027 akey; akey = TREE_CHAIN (akey))
6029 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6031 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6034 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6035 goto lack_of_ellipsis;
6037 else
6039 lack_of_ellipsis:
6040 chainon (arglist, OBJC_VOID_AT_END);
6043 return arglist;
6046 static tree
6047 check_duplicates (hash hsh, int methods, int is_class)
6049 tree meth = NULL_TREE;
6051 if (hsh)
6053 meth = hsh->key;
6055 if (hsh->list)
6057 /* We have two or more methods with the same name but
6058 different types. */
6059 attr loop;
6061 /* But just how different are those types? If
6062 -Wno-strict-selector-match is specified, we shall not
6063 complain if the differences are solely among types with
6064 identical size and alignment. */
6065 if (!warn_strict_selector_match)
6067 for (loop = hsh->list; loop; loop = loop->next)
6068 if (!comp_proto_with_proto (meth, loop->value, 0))
6069 goto issue_warning;
6071 return meth;
6074 issue_warning:
6075 warning (0, "multiple %s named %<%c%s%> found",
6076 methods ? "methods" : "selectors",
6077 (is_class ? '+' : '-'),
6078 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6080 warn_with_method (methods ? "using" : "found",
6081 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6082 ? '-'
6083 : '+'),
6084 meth);
6085 for (loop = hsh->list; loop; loop = loop->next)
6086 warn_with_method ("also found",
6087 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6088 ? '-'
6089 : '+'),
6090 loop->value);
6093 return meth;
6096 /* If RECEIVER is a class reference, return the identifier node for
6097 the referenced class. RECEIVER is created by objc_get_class_reference,
6098 so we check the exact form created depending on which runtimes are
6099 used. */
6101 static tree
6102 receiver_is_class_object (tree receiver, int self, int super)
6104 tree chain, exp, arg;
6106 /* The receiver is 'self' or 'super' in the context of a class method. */
6107 if (objc_method_context
6108 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6109 && (self || super))
6110 return (super
6111 ? CLASS_SUPER_NAME (implementation_template)
6112 : CLASS_NAME (implementation_template));
6114 if (flag_next_runtime)
6116 /* The receiver is a variable created by
6117 build_class_reference_decl. */
6118 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6119 /* Look up the identifier. */
6120 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6121 if (TREE_PURPOSE (chain) == receiver)
6122 return TREE_VALUE (chain);
6125 /* The receiver is a function call that returns an id. Check if
6126 it is a call to objc_getClass, if so, pick up the class name. */
6127 if (TREE_CODE (receiver) == CALL_EXPR
6128 && (exp = CALL_EXPR_FN (receiver))
6129 && TREE_CODE (exp) == ADDR_EXPR
6130 && (exp = TREE_OPERAND (exp, 0))
6131 && TREE_CODE (exp) == FUNCTION_DECL
6132 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6133 prototypes for objc_get_class(). Thankfully, they seem to share the
6134 same function type. */
6135 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6136 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6137 /* We have a call to objc_get_class/objc_getClass! */
6138 && (arg = CALL_EXPR_ARG (receiver, 0)))
6140 STRIP_NOPS (arg);
6141 if (TREE_CODE (arg) == ADDR_EXPR
6142 && (arg = TREE_OPERAND (arg, 0))
6143 && TREE_CODE (arg) == STRING_CST)
6144 /* Finally, we have the class name. */
6145 return get_identifier (TREE_STRING_POINTER (arg));
6147 return 0;
6150 /* If we are currently building a message expr, this holds
6151 the identifier of the selector of the message. This is
6152 used when printing warnings about argument mismatches. */
6154 static tree current_objc_message_selector = 0;
6156 tree
6157 objc_message_selector (void)
6159 return current_objc_message_selector;
6162 /* Construct an expression for sending a message.
6163 MESS has the object to send to in TREE_PURPOSE
6164 and the argument list (including selector) in TREE_VALUE.
6166 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6167 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6169 tree
6170 objc_build_message_expr (tree mess)
6172 tree receiver = TREE_PURPOSE (mess);
6173 tree sel_name;
6174 #ifdef OBJCPLUS
6175 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6176 #else
6177 tree args = TREE_VALUE (mess);
6178 #endif
6179 tree method_params = NULL_TREE;
6181 if (TREE_CODE (receiver) == ERROR_MARK)
6182 return error_mark_node;
6184 /* Obtain the full selector name. */
6185 if (TREE_CODE (args) == IDENTIFIER_NODE)
6186 /* A unary selector. */
6187 sel_name = args;
6188 else if (TREE_CODE (args) == TREE_LIST)
6189 sel_name = build_keyword_selector (args);
6190 else
6191 abort ();
6193 /* Build the parameter list to give to the method. */
6194 if (TREE_CODE (args) == TREE_LIST)
6195 #ifdef OBJCPLUS
6196 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6197 #else
6199 tree chain = args, prev = NULL_TREE;
6201 /* We have a keyword selector--check for comma expressions. */
6202 while (chain)
6204 tree element = TREE_VALUE (chain);
6206 /* We have a comma expression, must collapse... */
6207 if (TREE_CODE (element) == TREE_LIST)
6209 if (prev)
6210 TREE_CHAIN (prev) = element;
6211 else
6212 args = element;
6214 prev = chain;
6215 chain = TREE_CHAIN (chain);
6217 method_params = args;
6219 #endif
6221 #ifdef OBJCPLUS
6222 if (processing_template_decl)
6223 /* Must wait until template instantiation time. */
6224 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6225 method_params);
6226 #endif
6228 return objc_finish_message_expr (receiver, sel_name, method_params);
6231 /* Look up method SEL_NAME that would be suitable for receiver
6232 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6233 nonzero), and report on any duplicates. */
6235 static tree
6236 lookup_method_in_hash_lists (tree sel_name, int is_class)
6238 hash method_prototype = NULL;
6240 if (!is_class)
6241 method_prototype = hash_lookup (nst_method_hash_list,
6242 sel_name);
6244 if (!method_prototype)
6246 method_prototype = hash_lookup (cls_method_hash_list,
6247 sel_name);
6248 is_class = 1;
6251 return check_duplicates (method_prototype, 1, is_class);
6254 /* The 'objc_finish_message_expr' routine is called from within
6255 'objc_build_message_expr' for non-template functions. In the case of
6256 C++ template functions, it is called from 'build_expr_from_tree'
6257 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6259 tree
6260 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6262 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6263 tree selector, retval, class_tree;
6264 int self, super, have_cast;
6266 /* Extract the receiver of the message, as well as its type
6267 (where the latter may take the form of a cast or be inferred
6268 from the implementation context). */
6269 rtype = receiver;
6270 while (TREE_CODE (rtype) == COMPOUND_EXPR
6271 || TREE_CODE (rtype) == MODIFY_EXPR
6272 || CONVERT_EXPR_P (rtype)
6273 || TREE_CODE (rtype) == COMPONENT_REF)
6274 rtype = TREE_OPERAND (rtype, 0);
6275 self = (rtype == self_decl);
6276 super = (rtype == UOBJC_SUPER_decl);
6277 rtype = TREE_TYPE (receiver);
6278 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6279 || (TREE_CODE (receiver) == COMPOUND_EXPR
6280 && !IS_SUPER (rtype)));
6282 /* If we are calling [super dealloc], reset our warning flag. */
6283 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6284 should_call_super_dealloc = 0;
6286 /* If the receiver is a class object, retrieve the corresponding
6287 @interface, if one exists. */
6288 class_tree = receiver_is_class_object (receiver, self, super);
6290 /* Now determine the receiver type (if an explicit cast has not been
6291 provided). */
6292 if (!have_cast)
6294 if (class_tree)
6295 rtype = lookup_interface (class_tree);
6296 /* Handle `self' and `super'. */
6297 else if (super)
6299 if (!CLASS_SUPER_NAME (implementation_template))
6301 error ("no super class declared in @interface for %qs",
6302 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6303 return error_mark_node;
6305 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6307 else if (self)
6308 rtype = lookup_interface (CLASS_NAME (implementation_template));
6311 /* If receiver is of type `id' or `Class' (or if the @interface for a
6312 class is not visible), we shall be satisfied with the existence of
6313 any instance or class method. */
6314 if (objc_is_id (rtype))
6316 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6317 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6318 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6319 : NULL_TREE);
6320 rtype = NULL_TREE;
6322 if (rprotos)
6324 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6325 in protocols themselves for the method prototype. */
6326 method_prototype
6327 = lookup_method_in_protocol_list (rprotos, sel_name,
6328 class_tree != NULL_TREE);
6330 /* If messaging 'Class <Proto>' but did not find a class method
6331 prototype, search for an instance method instead, and warn
6332 about having done so. */
6333 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6335 method_prototype
6336 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6338 if (method_prototype)
6339 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6340 IDENTIFIER_POINTER (sel_name),
6341 IDENTIFIER_POINTER (sel_name));
6345 else if (rtype)
6347 tree orig_rtype = rtype, saved_rtype;
6349 if (TREE_CODE (rtype) == POINTER_TYPE)
6350 rtype = TREE_TYPE (rtype);
6351 /* Traverse typedef aliases */
6352 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6353 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6354 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6355 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6356 saved_rtype = rtype;
6357 if (TYPED_OBJECT (rtype))
6359 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6360 rtype = TYPE_OBJC_INTERFACE (rtype);
6362 /* If we could not find an @interface declaration, we must have
6363 only seen a @class declaration; so, we cannot say anything
6364 more intelligent about which methods the receiver will
6365 understand. */
6366 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6367 rtype = NULL_TREE;
6368 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6369 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6371 /* We have a valid ObjC class name. Look up the method name
6372 in the published @interface for the class (and its
6373 superclasses). */
6374 method_prototype
6375 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6377 /* If the method was not found in the @interface, it may still
6378 exist locally as part of the @implementation. */
6379 if (!method_prototype && objc_implementation_context
6380 && CLASS_NAME (objc_implementation_context)
6381 == OBJC_TYPE_NAME (rtype))
6382 method_prototype
6383 = lookup_method
6384 ((class_tree
6385 ? CLASS_CLS_METHODS (objc_implementation_context)
6386 : CLASS_NST_METHODS (objc_implementation_context)),
6387 sel_name);
6389 /* If we haven't found a candidate method by now, try looking for
6390 it in the protocol list. */
6391 if (!method_prototype && rprotos)
6392 method_prototype
6393 = lookup_method_in_protocol_list (rprotos, sel_name,
6394 class_tree != NULL_TREE);
6396 else
6398 warning (0, "invalid receiver type %qs",
6399 gen_type_name (orig_rtype));
6400 /* After issuing the "invalid receiver" warning, perform method
6401 lookup as if we were messaging 'id'. */
6402 rtype = rprotos = NULL_TREE;
6407 /* For 'id' or 'Class' receivers, search in the global hash table
6408 as a last resort. For all receivers, warn if protocol searches
6409 have failed. */
6410 if (!method_prototype)
6412 if (rprotos)
6413 warning (0, "%<%c%s%> not found in protocol(s)",
6414 (class_tree ? '+' : '-'),
6415 IDENTIFIER_POINTER (sel_name));
6417 if (!rtype)
6418 method_prototype
6419 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6422 if (!method_prototype)
6424 static bool warn_missing_methods = false;
6426 if (rtype)
6427 warning (0, "%qs may not respond to %<%c%s%>",
6428 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6429 (class_tree ? '+' : '-'),
6430 IDENTIFIER_POINTER (sel_name));
6431 /* If we are messaging an 'id' or 'Class' object and made it here,
6432 then we have failed to find _any_ instance or class method,
6433 respectively. */
6434 else
6435 warning (0, "no %<%c%s%> method found",
6436 (class_tree ? '+' : '-'),
6437 IDENTIFIER_POINTER (sel_name));
6439 if (!warn_missing_methods)
6441 warning (0, "(Messages without a matching method signature");
6442 warning (0, "will be assumed to return %<id%> and accept");
6443 warning (0, "%<...%> as arguments.)");
6444 warn_missing_methods = true;
6448 /* Save the selector name for printing error messages. */
6449 current_objc_message_selector = sel_name;
6451 /* Build the parameters list for looking up the method.
6452 These are the object itself and the selector. */
6454 if (flag_typed_selectors)
6455 selector = build_typed_selector_reference (sel_name, method_prototype);
6456 else
6457 selector = build_selector_reference (sel_name);
6459 retval = build_objc_method_call (super, method_prototype,
6460 receiver,
6461 selector, method_params);
6463 current_objc_message_selector = 0;
6465 return retval;
6468 /* Build a tree expression to send OBJECT the operation SELECTOR,
6469 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6470 assuming the method has prototype METHOD_PROTOTYPE.
6471 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6472 Use METHOD_PARAMS as list of args to pass to the method.
6473 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6475 static tree
6476 build_objc_method_call (int super_flag, tree method_prototype,
6477 tree lookup_object, tree selector,
6478 tree method_params)
6480 tree sender = (super_flag ? umsg_super_decl :
6481 (!flag_next_runtime || flag_nil_receivers
6482 ? (flag_objc_direct_dispatch
6483 ? umsg_fast_decl
6484 : umsg_decl)
6485 : umsg_nonnil_decl));
6486 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6488 /* If a prototype for the method to be called exists, then cast
6489 the sender's return type and arguments to match that of the method.
6490 Otherwise, leave sender as is. */
6491 tree ret_type
6492 = (method_prototype
6493 ? TREE_VALUE (TREE_TYPE (method_prototype))
6494 : objc_object_type);
6495 tree sender_cast
6496 = build_pointer_type
6497 (build_function_type
6498 (ret_type,
6499 get_arg_type_list
6500 (method_prototype, METHOD_REF, super_flag)));
6501 tree method, t;
6503 lookup_object = build_c_cast (rcv_p, lookup_object);
6505 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6506 lookup_object = save_expr (lookup_object);
6508 if (flag_next_runtime)
6510 /* If we are returning a struct in memory, and the address
6511 of that memory location is passed as a hidden first
6512 argument, then change which messenger entry point this
6513 expr will call. NB: Note that sender_cast remains
6514 unchanged (it already has a struct return type). */
6515 if (!targetm.calls.struct_value_rtx (0, 0)
6516 && (TREE_CODE (ret_type) == RECORD_TYPE
6517 || TREE_CODE (ret_type) == UNION_TYPE)
6518 && targetm.calls.return_in_memory (ret_type, 0))
6519 sender = (super_flag ? umsg_super_stret_decl :
6520 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6522 method_params = tree_cons (NULL_TREE, lookup_object,
6523 tree_cons (NULL_TREE, selector,
6524 method_params));
6525 method = build_fold_addr_expr (sender);
6527 else
6529 /* This is the portable (GNU) way. */
6530 tree object;
6532 /* First, call the lookup function to get a pointer to the method,
6533 then cast the pointer, then call it with the method arguments. */
6535 object = (super_flag ? self_decl : lookup_object);
6537 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6538 t = tree_cons (NULL_TREE, lookup_object, t);
6539 method = build_function_call (sender, t);
6541 /* Pass the object to the method. */
6542 method_params = tree_cons (NULL_TREE, object,
6543 tree_cons (NULL_TREE, selector,
6544 method_params));
6547 /* ??? Selector is not at this point something we can use inside
6548 the compiler itself. Set it to garbage for the nonce. */
6549 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6550 return build_function_call (t, method_params);
6553 static void
6554 build_protocol_reference (tree p)
6556 tree decl;
6557 const char *proto_name;
6559 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6561 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6562 decl = start_var_decl (objc_protocol_template, proto_name);
6564 PROTOCOL_FORWARD_DECL (p) = decl;
6567 /* This function is called by the parser when (and only when) a
6568 @protocol() expression is found, in order to compile it. */
6569 tree
6570 objc_build_protocol_expr (tree protoname)
6572 tree expr;
6573 tree p = lookup_protocol (protoname);
6575 if (!p)
6577 error ("cannot find protocol declaration for %qs",
6578 IDENTIFIER_POINTER (protoname));
6579 return error_mark_node;
6582 if (!PROTOCOL_FORWARD_DECL (p))
6583 build_protocol_reference (p);
6585 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6587 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6588 if we have it, rather than converting it here. */
6589 expr = convert (objc_protocol_type, expr);
6591 /* The @protocol() expression is being compiled into a pointer to a
6592 statically allocated instance of the Protocol class. To become
6593 usable at runtime, the 'isa' pointer of the instance need to be
6594 fixed up at runtime by the runtime library, to point to the
6595 actual 'Protocol' class. */
6597 /* For the GNU runtime, put the static Protocol instance in the list
6598 of statically allocated instances, so that we make sure that its
6599 'isa' pointer is fixed up at runtime by the GNU runtime library
6600 to point to the Protocol class (at runtime, when loading the
6601 module, the GNU runtime library loops on the statically allocated
6602 instances (as found in the defs field in objc_symtab) and fixups
6603 all the 'isa' pointers of those objects). */
6604 if (! flag_next_runtime)
6606 /* This type is a struct containing the fields of a Protocol
6607 object. (Cfr. objc_protocol_type instead is the type of a pointer
6608 to such a struct). */
6609 tree protocol_struct_type = xref_tag
6610 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6611 tree *chain;
6613 /* Look for the list of Protocol statically allocated instances
6614 to fixup at runtime. Create a new list to hold Protocol
6615 statically allocated instances, if the list is not found. At
6616 present there is only another list, holding NSConstantString
6617 static instances to be fixed up at runtime. */
6618 for (chain = &objc_static_instances;
6619 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6620 chain = &TREE_CHAIN (*chain));
6621 if (!*chain)
6623 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6624 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6625 class_names);
6628 /* Add this statically allocated instance to the Protocol list. */
6629 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6630 PROTOCOL_FORWARD_DECL (p),
6631 TREE_PURPOSE (*chain));
6635 return expr;
6638 /* This function is called by the parser when a @selector() expression
6639 is found, in order to compile it. It is only called by the parser
6640 and only to compile a @selector(). */
6641 tree
6642 objc_build_selector_expr (tree selnamelist)
6644 tree selname;
6646 /* Obtain the full selector name. */
6647 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6648 /* A unary selector. */
6649 selname = selnamelist;
6650 else if (TREE_CODE (selnamelist) == TREE_LIST)
6651 selname = build_keyword_selector (selnamelist);
6652 else
6653 abort ();
6655 /* If we are required to check @selector() expressions as they
6656 are found, check that the selector has been declared. */
6657 if (warn_undeclared_selector)
6659 /* Look the selector up in the list of all known class and
6660 instance methods (up to this line) to check that the selector
6661 exists. */
6662 hash hsh;
6664 /* First try with instance methods. */
6665 hsh = hash_lookup (nst_method_hash_list, selname);
6667 /* If not found, try with class methods. */
6668 if (!hsh)
6670 hsh = hash_lookup (cls_method_hash_list, selname);
6673 /* If still not found, print out a warning. */
6674 if (!hsh)
6676 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6681 if (flag_typed_selectors)
6682 return build_typed_selector_reference (selname, 0);
6683 else
6684 return build_selector_reference (selname);
6687 tree
6688 objc_build_encode_expr (tree type)
6690 tree result;
6691 const char *string;
6693 encode_type (type, obstack_object_size (&util_obstack),
6694 OBJC_ENCODE_INLINE_DEFS);
6695 obstack_1grow (&util_obstack, 0); /* null terminate string */
6696 string = XOBFINISH (&util_obstack, const char *);
6698 /* Synthesize a string that represents the encoded struct/union. */
6699 result = my_build_string (strlen (string) + 1, string);
6700 obstack_free (&util_obstack, util_firstobj);
6701 return result;
6704 static tree
6705 build_ivar_reference (tree id)
6707 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6709 /* Historically, a class method that produced objects (factory
6710 method) would assign `self' to the instance that it
6711 allocated. This would effectively turn the class method into
6712 an instance method. Following this assignment, the instance
6713 variables could be accessed. That practice, while safe,
6714 violates the simple rule that a class method should not refer
6715 to an instance variable. It's better to catch the cases
6716 where this is done unknowingly than to support the above
6717 paradigm. */
6718 warning (0, "instance variable %qs accessed in class method",
6719 IDENTIFIER_POINTER (id));
6720 self_decl = convert (objc_instance_type, self_decl); /* cast */
6723 return objc_build_component_ref (build_indirect_ref (self_decl, "->",
6724 input_location), id);
6727 /* Compute a hash value for a given method SEL_NAME. */
6729 static size_t
6730 hash_func (tree sel_name)
6732 const unsigned char *s
6733 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6734 size_t h = 0;
6736 while (*s)
6737 h = h * 67 + *s++ - 113;
6738 return h;
6741 static void
6742 hash_init (void)
6744 nst_method_hash_list
6745 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6746 cls_method_hash_list
6747 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6749 /* Initialize the hash table used to hold the constant string objects. */
6750 string_htab = htab_create_ggc (31, string_hash,
6751 string_eq, NULL);
6753 /* Initialize the hash table used to hold EH-volatilized types. */
6754 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6755 volatilized_eq, NULL);
6758 /* WARNING!!!! hash_enter is called with a method, and will peek
6759 inside to find its selector! But hash_lookup is given a selector
6760 directly, and looks for the selector that's inside the found
6761 entry's key (method) for comparison. */
6763 static void
6764 hash_enter (hash *hashlist, tree method)
6766 hash obj;
6767 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6769 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6770 obj->list = 0;
6771 obj->next = hashlist[slot];
6772 obj->key = method;
6774 hashlist[slot] = obj; /* append to front */
6777 static hash
6778 hash_lookup (hash *hashlist, tree sel_name)
6780 hash target;
6782 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6784 while (target)
6786 if (sel_name == METHOD_SEL_NAME (target->key))
6787 return target;
6789 target = target->next;
6791 return 0;
6794 static void
6795 hash_add_attr (hash entry, tree value)
6797 attr obj;
6799 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6800 obj->next = entry->list;
6801 obj->value = value;
6803 entry->list = obj; /* append to front */
6806 static tree
6807 lookup_method (tree mchain, tree method)
6809 tree key;
6811 if (TREE_CODE (method) == IDENTIFIER_NODE)
6812 key = method;
6813 else
6814 key = METHOD_SEL_NAME (method);
6816 while (mchain)
6818 if (METHOD_SEL_NAME (mchain) == key)
6819 return mchain;
6821 mchain = TREE_CHAIN (mchain);
6823 return NULL_TREE;
6826 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6827 in INTERFACE, along with any categories and protocols attached thereto.
6828 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6829 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6830 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6831 be found in INTERFACE or any of its superclasses, look for an _instance_
6832 method of the same name in the root class as a last resort.
6834 If a suitable method cannot be found, return NULL_TREE. */
6836 static tree
6837 lookup_method_static (tree interface, tree ident, int flags)
6839 tree meth = NULL_TREE, root_inter = NULL_TREE;
6840 tree inter = interface;
6841 int is_class = (flags & OBJC_LOOKUP_CLASS);
6842 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6844 while (inter)
6846 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6847 tree category = inter;
6849 /* First, look up the method in the class itself. */
6850 if ((meth = lookup_method (chain, ident)))
6851 return meth;
6853 /* Failing that, look for the method in each category of the class. */
6854 while ((category = CLASS_CATEGORY_LIST (category)))
6856 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6858 /* Check directly in each category. */
6859 if ((meth = lookup_method (chain, ident)))
6860 return meth;
6862 /* Failing that, check in each category's protocols. */
6863 if (CLASS_PROTOCOL_LIST (category))
6865 if ((meth = (lookup_method_in_protocol_list
6866 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6867 return meth;
6871 /* If not found in categories, check in protocols of the main class. */
6872 if (CLASS_PROTOCOL_LIST (inter))
6874 if ((meth = (lookup_method_in_protocol_list
6875 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6876 return meth;
6879 /* If we were instructed not to look in superclasses, don't. */
6880 if (no_superclasses)
6881 return NULL_TREE;
6883 /* Failing that, climb up the inheritance hierarchy. */
6884 root_inter = inter;
6885 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6887 while (inter);
6889 /* If no class (factory) method was found, check if an _instance_
6890 method of the same name exists in the root class. This is what
6891 the Objective-C runtime will do. If an instance method was not
6892 found, return 0. */
6893 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6896 /* Add the method to the hash list if it doesn't contain an identical
6897 method already. */
6899 static void
6900 add_method_to_hash_list (hash *hash_list, tree method)
6902 hash hsh;
6904 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6906 /* Install on a global chain. */
6907 hash_enter (hash_list, method);
6909 else
6911 /* Check types against those; if different, add to a list. */
6912 attr loop;
6913 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6914 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6915 already_there |= comp_proto_with_proto (method, loop->value, 1);
6916 if (!already_there)
6917 hash_add_attr (hsh, method);
6921 static tree
6922 objc_add_method (tree klass, tree method, int is_class)
6924 tree mth;
6926 if (!(mth = lookup_method (is_class
6927 ? CLASS_CLS_METHODS (klass)
6928 : CLASS_NST_METHODS (klass), method)))
6930 /* put method on list in reverse order */
6931 if (is_class)
6933 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
6934 CLASS_CLS_METHODS (klass) = method;
6936 else
6938 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
6939 CLASS_NST_METHODS (klass) = method;
6942 else
6944 /* When processing an @interface for a class or category, give hard
6945 errors on methods with identical selectors but differing argument
6946 and/or return types. We do not do this for @implementations, because
6947 C/C++ will do it for us (i.e., there will be duplicate function
6948 definition errors). */
6949 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
6950 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
6951 && !comp_proto_with_proto (method, mth, 1))
6952 error ("duplicate declaration of method %<%c%s%>",
6953 is_class ? '+' : '-',
6954 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6957 if (is_class)
6958 add_method_to_hash_list (cls_method_hash_list, method);
6959 else
6961 add_method_to_hash_list (nst_method_hash_list, method);
6963 /* Instance methods in root classes (and categories thereof)
6964 may act as class methods as a last resort. We also add
6965 instance methods listed in @protocol declarations to
6966 the class hash table, on the assumption that @protocols
6967 may be adopted by root classes or categories. */
6968 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
6969 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
6970 klass = lookup_interface (CLASS_NAME (klass));
6972 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
6973 || !CLASS_SUPER_NAME (klass))
6974 add_method_to_hash_list (cls_method_hash_list, method);
6977 return method;
6980 static tree
6981 add_class (tree class_name, tree name)
6983 struct interface_tuple **slot;
6985 /* Put interfaces on list in reverse order. */
6986 TREE_CHAIN (class_name) = interface_chain;
6987 interface_chain = class_name;
6989 if (interface_htab == NULL)
6990 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6991 slot = (struct interface_tuple **)
6992 htab_find_slot_with_hash (interface_htab, name,
6993 IDENTIFIER_HASH_VALUE (name),
6994 INSERT);
6995 if (!*slot)
6997 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6998 (*slot)->id = name;
7000 (*slot)->class_name = class_name;
7002 return interface_chain;
7005 static void
7006 add_category (tree klass, tree category)
7008 /* Put categories on list in reverse order. */
7009 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7011 if (cat)
7013 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7014 IDENTIFIER_POINTER (CLASS_NAME (klass)),
7015 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7017 else
7019 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7020 CLASS_CATEGORY_LIST (klass) = category;
7024 /* Called after parsing each instance variable declaration. Necessary to
7025 preserve typedefs and implement public/private...
7027 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7029 static tree
7030 add_instance_variable (tree klass, int visibility, tree field_decl)
7032 tree field_type = TREE_TYPE (field_decl);
7033 const char *ivar_name = DECL_NAME (field_decl)
7034 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7035 : "<unnamed>";
7037 #ifdef OBJCPLUS
7038 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7040 error ("illegal reference type specified for instance variable %qs",
7041 ivar_name);
7042 /* Return class as is without adding this ivar. */
7043 return klass;
7045 #endif
7047 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7048 || TYPE_SIZE (field_type) == error_mark_node)
7049 /* 'type[0]' is allowed, but 'type[]' is not! */
7051 error ("instance variable %qs has unknown size", ivar_name);
7052 /* Return class as is without adding this ivar. */
7053 return klass;
7056 #ifdef OBJCPLUS
7057 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7058 need to either (1) warn the user about it or (2) generate suitable
7059 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7060 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7061 if (MAYBE_CLASS_TYPE_P (field_type)
7062 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7063 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7064 || TYPE_POLYMORPHIC_P (field_type)))
7066 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7068 if (flag_objc_call_cxx_cdtors)
7070 /* Since the ObjC runtime will be calling the constructors and
7071 destructors for us, the only thing we can't handle is the lack
7072 of a default constructor. */
7073 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7074 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7076 warning (0, "type %qs has no default constructor to call",
7077 type_name);
7079 /* If we cannot call a constructor, we should also avoid
7080 calling the destructor, for symmetry. */
7081 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7082 warning (0, "destructor for %qs shall not be run either",
7083 type_name);
7086 else
7088 static bool warn_cxx_ivars = false;
7090 if (TYPE_POLYMORPHIC_P (field_type))
7092 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7093 initialize them. */
7094 error ("type %qs has virtual member functions", type_name);
7095 error ("illegal aggregate type %qs specified "
7096 "for instance variable %qs",
7097 type_name, ivar_name);
7098 /* Return class as is without adding this ivar. */
7099 return klass;
7102 /* User-defined constructors and destructors are not known to Obj-C
7103 and hence will not be called. This may or may not be a problem. */
7104 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7105 warning (0, "type %qs has a user-defined constructor", type_name);
7106 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7107 warning (0, "type %qs has a user-defined destructor", type_name);
7109 if (!warn_cxx_ivars)
7111 warning (0, "C++ constructors and destructors will not "
7112 "be invoked for Objective-C fields");
7113 warn_cxx_ivars = true;
7117 #endif
7119 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7120 switch (visibility)
7122 case 0:
7123 TREE_PUBLIC (field_decl) = 0;
7124 TREE_PRIVATE (field_decl) = 0;
7125 TREE_PROTECTED (field_decl) = 1;
7126 break;
7128 case 1:
7129 TREE_PUBLIC (field_decl) = 1;
7130 TREE_PRIVATE (field_decl) = 0;
7131 TREE_PROTECTED (field_decl) = 0;
7132 break;
7134 case 2:
7135 TREE_PUBLIC (field_decl) = 0;
7136 TREE_PRIVATE (field_decl) = 1;
7137 TREE_PROTECTED (field_decl) = 0;
7138 break;
7142 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7144 return klass;
7147 static tree
7148 is_ivar (tree decl_chain, tree ident)
7150 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7151 if (DECL_NAME (decl_chain) == ident)
7152 return decl_chain;
7153 return NULL_TREE;
7156 /* True if the ivar is private and we are not in its implementation. */
7158 static int
7159 is_private (tree decl)
7161 return (TREE_PRIVATE (decl)
7162 && ! is_ivar (CLASS_IVARS (implementation_template),
7163 DECL_NAME (decl)));
7166 /* We have an instance variable reference;, check to see if it is public. */
7169 objc_is_public (tree expr, tree identifier)
7171 tree basetype, decl;
7173 #ifdef OBJCPLUS
7174 if (processing_template_decl)
7175 return 1;
7176 #endif
7178 if (TREE_TYPE (expr) == error_mark_node)
7179 return 1;
7181 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7183 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7185 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7187 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7189 if (!klass)
7191 error ("cannot find interface declaration for %qs",
7192 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7193 return 0;
7196 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7198 if (TREE_PUBLIC (decl))
7199 return 1;
7201 /* Important difference between the Stepstone translator:
7202 all instance variables should be public within the context
7203 of the implementation. */
7204 if (objc_implementation_context
7205 && ((TREE_CODE (objc_implementation_context)
7206 == CLASS_IMPLEMENTATION_TYPE)
7207 || (TREE_CODE (objc_implementation_context)
7208 == CATEGORY_IMPLEMENTATION_TYPE)))
7210 tree curtype = TYPE_MAIN_VARIANT
7211 (CLASS_STATIC_TEMPLATE
7212 (implementation_template));
7214 if (basetype == curtype
7215 || DERIVED_FROM_P (basetype, curtype))
7217 int priv = is_private (decl);
7219 if (priv)
7220 error ("instance variable %qs is declared private",
7221 IDENTIFIER_POINTER (DECL_NAME (decl)));
7223 return !priv;
7227 /* The 2.95.2 compiler sometimes allowed C functions to access
7228 non-@public ivars. We will let this slide for now... */
7229 if (!objc_method_context)
7231 warning (0, "instance variable %qs is %s; "
7232 "this will be a hard error in the future",
7233 IDENTIFIER_POINTER (identifier),
7234 TREE_PRIVATE (decl) ? "@private" : "@protected");
7235 return 1;
7238 error ("instance variable %qs is declared %s",
7239 IDENTIFIER_POINTER (identifier),
7240 TREE_PRIVATE (decl) ? "private" : "protected");
7241 return 0;
7246 return 1;
7249 /* Make sure all entries in CHAIN are also in LIST. */
7251 static int
7252 check_methods (tree chain, tree list, int mtype)
7254 int first = 1;
7256 while (chain)
7258 if (!lookup_method (list, chain))
7260 if (first)
7262 if (TREE_CODE (objc_implementation_context)
7263 == CLASS_IMPLEMENTATION_TYPE)
7264 warning (0, "incomplete implementation of class %qs",
7265 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7266 else if (TREE_CODE (objc_implementation_context)
7267 == CATEGORY_IMPLEMENTATION_TYPE)
7268 warning (0, "incomplete implementation of category %qs",
7269 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7270 first = 0;
7273 warning (0, "method definition for %<%c%s%> not found",
7274 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7277 chain = TREE_CHAIN (chain);
7280 return first;
7283 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7285 static int
7286 conforms_to_protocol (tree klass, tree protocol)
7288 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7290 tree p = CLASS_PROTOCOL_LIST (klass);
7291 while (p && TREE_VALUE (p) != protocol)
7292 p = TREE_CHAIN (p);
7294 if (!p)
7296 tree super = (CLASS_SUPER_NAME (klass)
7297 ? lookup_interface (CLASS_SUPER_NAME (klass))
7298 : NULL_TREE);
7299 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7300 if (!tmp)
7301 return 0;
7305 return 1;
7308 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7309 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7311 static int
7312 check_methods_accessible (tree chain, tree context, int mtype)
7314 int first = 1;
7315 tree list;
7316 tree base_context = context;
7318 while (chain)
7320 context = base_context;
7321 while (context)
7323 if (mtype == '+')
7324 list = CLASS_CLS_METHODS (context);
7325 else
7326 list = CLASS_NST_METHODS (context);
7328 if (lookup_method (list, chain))
7329 break;
7331 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7332 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7333 context = (CLASS_SUPER_NAME (context)
7334 ? lookup_interface (CLASS_SUPER_NAME (context))
7335 : NULL_TREE);
7337 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7338 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7339 context = (CLASS_NAME (context)
7340 ? lookup_interface (CLASS_NAME (context))
7341 : NULL_TREE);
7342 else
7343 abort ();
7346 if (context == NULL_TREE)
7348 if (first)
7350 if (TREE_CODE (objc_implementation_context)
7351 == CLASS_IMPLEMENTATION_TYPE)
7352 warning (0, "incomplete implementation of class %qs",
7353 IDENTIFIER_POINTER
7354 (CLASS_NAME (objc_implementation_context)));
7355 else if (TREE_CODE (objc_implementation_context)
7356 == CATEGORY_IMPLEMENTATION_TYPE)
7357 warning (0, "incomplete implementation of category %qs",
7358 IDENTIFIER_POINTER
7359 (CLASS_SUPER_NAME (objc_implementation_context)));
7360 first = 0;
7362 warning (0, "method definition for %<%c%s%> not found",
7363 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7366 chain = TREE_CHAIN (chain); /* next method... */
7368 return first;
7371 /* Check whether the current interface (accessible via
7372 'objc_implementation_context') actually implements protocol P, along
7373 with any protocols that P inherits. */
7375 static void
7376 check_protocol (tree p, const char *type, const char *name)
7378 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7380 int f1, f2;
7382 /* Ensure that all protocols have bodies! */
7383 if (warn_protocol)
7385 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7386 CLASS_CLS_METHODS (objc_implementation_context),
7387 '+');
7388 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7389 CLASS_NST_METHODS (objc_implementation_context),
7390 '-');
7392 else
7394 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7395 objc_implementation_context,
7396 '+');
7397 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7398 objc_implementation_context,
7399 '-');
7402 if (!f1 || !f2)
7403 warning (0, "%s %qs does not fully implement the %qs protocol",
7404 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7407 /* Check protocols recursively. */
7408 if (PROTOCOL_LIST (p))
7410 tree subs = PROTOCOL_LIST (p);
7411 tree super_class =
7412 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7414 while (subs)
7416 tree sub = TREE_VALUE (subs);
7418 /* If the superclass does not conform to the protocols
7419 inherited by P, then we must! */
7420 if (!super_class || !conforms_to_protocol (super_class, sub))
7421 check_protocol (sub, type, name);
7422 subs = TREE_CHAIN (subs);
7427 /* Check whether the current interface (accessible via
7428 'objc_implementation_context') actually implements the protocols listed
7429 in PROTO_LIST. */
7431 static void
7432 check_protocols (tree proto_list, const char *type, const char *name)
7434 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7436 tree p = TREE_VALUE (proto_list);
7438 check_protocol (p, type, name);
7442 /* Make sure that the class CLASS_NAME is defined
7443 CODE says which kind of thing CLASS_NAME ought to be.
7444 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7445 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7447 static tree
7448 start_class (enum tree_code code, tree class_name, tree super_name,
7449 tree protocol_list)
7451 tree klass, decl;
7453 #ifdef OBJCPLUS
7454 if (current_namespace != global_namespace) {
7455 error ("Objective-C declarations may only appear in global scope");
7457 #endif /* OBJCPLUS */
7459 if (objc_implementation_context)
7461 warning (0, "%<@end%> missing in implementation context");
7462 finish_class (objc_implementation_context);
7463 objc_ivar_chain = NULL_TREE;
7464 objc_implementation_context = NULL_TREE;
7467 klass = make_node (code);
7468 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7470 /* Check for existence of the super class, if one was specified. Note
7471 that we must have seen an @interface, not just a @class. If we
7472 are looking at a @compatibility_alias, traverse it first. */
7473 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7474 && super_name)
7476 tree super = objc_is_class_name (super_name);
7478 if (!super || !lookup_interface (super))
7480 error ("cannot find interface declaration for %qs, superclass of %qs",
7481 IDENTIFIER_POINTER (super ? super : super_name),
7482 IDENTIFIER_POINTER (class_name));
7483 super_name = NULL_TREE;
7485 else
7486 super_name = super;
7489 CLASS_NAME (klass) = class_name;
7490 CLASS_SUPER_NAME (klass) = super_name;
7491 CLASS_CLS_METHODS (klass) = NULL_TREE;
7493 if (! objc_is_class_name (class_name)
7494 && (decl = lookup_name (class_name)))
7496 error ("%qs redeclared as different kind of symbol",
7497 IDENTIFIER_POINTER (class_name));
7498 error ("previous declaration of %q+D",
7499 decl);
7502 if (code == CLASS_IMPLEMENTATION_TYPE)
7505 tree chain;
7507 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7508 if (TREE_VALUE (chain) == class_name)
7510 error ("reimplementation of class %qs",
7511 IDENTIFIER_POINTER (class_name));
7512 return error_mark_node;
7514 implemented_classes = tree_cons (NULL_TREE, class_name,
7515 implemented_classes);
7518 /* Reset for multiple classes per file. */
7519 method_slot = 0;
7521 objc_implementation_context = klass;
7523 /* Lookup the interface for this implementation. */
7525 if (!(implementation_template = lookup_interface (class_name)))
7527 warning (0, "cannot find interface declaration for %qs",
7528 IDENTIFIER_POINTER (class_name));
7529 add_class (implementation_template = objc_implementation_context,
7530 class_name);
7533 /* If a super class has been specified in the implementation,
7534 insure it conforms to the one specified in the interface. */
7536 if (super_name
7537 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7539 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7540 const char *const name =
7541 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7542 error ("conflicting super class name %qs",
7543 IDENTIFIER_POINTER (super_name));
7544 error ("previous declaration of %qs", name);
7547 else if (! super_name)
7549 CLASS_SUPER_NAME (objc_implementation_context)
7550 = CLASS_SUPER_NAME (implementation_template);
7554 else if (code == CLASS_INTERFACE_TYPE)
7556 if (lookup_interface (class_name))
7557 #ifdef OBJCPLUS
7558 error ("duplicate interface declaration for class %qs",
7559 #else
7560 warning (0, "duplicate interface declaration for class %qs",
7561 #endif
7562 IDENTIFIER_POINTER (class_name));
7563 else
7564 add_class (klass, class_name);
7566 if (protocol_list)
7567 CLASS_PROTOCOL_LIST (klass)
7568 = lookup_and_install_protocols (protocol_list);
7571 else if (code == CATEGORY_INTERFACE_TYPE)
7573 tree class_category_is_assoc_with;
7575 /* For a category, class_name is really the name of the class that
7576 the following set of methods will be associated with. We must
7577 find the interface so that can derive the objects template. */
7579 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7581 error ("cannot find interface declaration for %qs",
7582 IDENTIFIER_POINTER (class_name));
7583 exit (FATAL_EXIT_CODE);
7585 else
7586 add_category (class_category_is_assoc_with, klass);
7588 if (protocol_list)
7589 CLASS_PROTOCOL_LIST (klass)
7590 = lookup_and_install_protocols (protocol_list);
7593 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7595 /* Reset for multiple classes per file. */
7596 method_slot = 0;
7598 objc_implementation_context = klass;
7600 /* For a category, class_name is really the name of the class that
7601 the following set of methods will be associated with. We must
7602 find the interface so that can derive the objects template. */
7604 if (!(implementation_template = lookup_interface (class_name)))
7606 error ("cannot find interface declaration for %qs",
7607 IDENTIFIER_POINTER (class_name));
7608 exit (FATAL_EXIT_CODE);
7611 return klass;
7614 static tree
7615 continue_class (tree klass)
7617 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7618 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7620 struct imp_entry *imp_entry;
7622 /* Check consistency of the instance variables. */
7624 if (CLASS_RAW_IVARS (klass))
7625 check_ivars (implementation_template, klass);
7627 /* code generation */
7629 #ifdef OBJCPLUS
7630 push_lang_context (lang_name_c);
7631 #endif
7633 build_private_template (implementation_template);
7634 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7635 objc_instance_type = build_pointer_type (uprivate_record);
7637 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7639 imp_entry->next = imp_list;
7640 imp_entry->imp_context = klass;
7641 imp_entry->imp_template = implementation_template;
7643 synth_forward_declarations ();
7644 imp_entry->class_decl = UOBJC_CLASS_decl;
7645 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7646 imp_entry->has_cxx_cdtors = 0;
7648 /* Append to front and increment count. */
7649 imp_list = imp_entry;
7650 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7651 imp_count++;
7652 else
7653 cat_count++;
7655 #ifdef OBJCPLUS
7656 pop_lang_context ();
7657 #endif /* OBJCPLUS */
7659 return get_class_ivars (implementation_template, true);
7662 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7664 #ifdef OBJCPLUS
7665 push_lang_context (lang_name_c);
7666 #endif /* OBJCPLUS */
7668 build_private_template (klass);
7670 #ifdef OBJCPLUS
7671 pop_lang_context ();
7672 #endif /* OBJCPLUS */
7674 return NULL_TREE;
7677 else
7678 return error_mark_node;
7681 /* This is called once we see the "@end" in an interface/implementation. */
7683 static void
7684 finish_class (tree klass)
7686 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7688 /* All code generation is done in finish_objc. */
7690 if (implementation_template != objc_implementation_context)
7692 /* Ensure that all method listed in the interface contain bodies. */
7693 check_methods (CLASS_CLS_METHODS (implementation_template),
7694 CLASS_CLS_METHODS (objc_implementation_context), '+');
7695 check_methods (CLASS_NST_METHODS (implementation_template),
7696 CLASS_NST_METHODS (objc_implementation_context), '-');
7698 if (CLASS_PROTOCOL_LIST (implementation_template))
7699 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7700 "class",
7701 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7705 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7707 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7709 if (category)
7711 /* Ensure all method listed in the interface contain bodies. */
7712 check_methods (CLASS_CLS_METHODS (category),
7713 CLASS_CLS_METHODS (objc_implementation_context), '+');
7714 check_methods (CLASS_NST_METHODS (category),
7715 CLASS_NST_METHODS (objc_implementation_context), '-');
7717 if (CLASS_PROTOCOL_LIST (category))
7718 check_protocols (CLASS_PROTOCOL_LIST (category),
7719 "category",
7720 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7725 static tree
7726 add_protocol (tree protocol)
7728 /* Put protocol on list in reverse order. */
7729 TREE_CHAIN (protocol) = protocol_chain;
7730 protocol_chain = protocol;
7731 return protocol_chain;
7734 static tree
7735 lookup_protocol (tree ident)
7737 tree chain;
7739 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7740 if (ident == PROTOCOL_NAME (chain))
7741 return chain;
7743 return NULL_TREE;
7746 /* This function forward declares the protocols named by NAMES. If
7747 they are already declared or defined, the function has no effect. */
7749 void
7750 objc_declare_protocols (tree names)
7752 tree list;
7754 #ifdef OBJCPLUS
7755 if (current_namespace != global_namespace) {
7756 error ("Objective-C declarations may only appear in global scope");
7758 #endif /* OBJCPLUS */
7760 for (list = names; list; list = TREE_CHAIN (list))
7762 tree name = TREE_VALUE (list);
7764 if (lookup_protocol (name) == NULL_TREE)
7766 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7768 TYPE_LANG_SLOT_1 (protocol)
7769 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7770 PROTOCOL_NAME (protocol) = name;
7771 PROTOCOL_LIST (protocol) = NULL_TREE;
7772 add_protocol (protocol);
7773 PROTOCOL_DEFINED (protocol) = 0;
7774 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7779 static tree
7780 start_protocol (enum tree_code code, tree name, tree list)
7782 tree protocol;
7784 #ifdef OBJCPLUS
7785 if (current_namespace != global_namespace) {
7786 error ("Objective-C declarations may only appear in global scope");
7788 #endif /* OBJCPLUS */
7790 protocol = lookup_protocol (name);
7792 if (!protocol)
7794 protocol = make_node (code);
7795 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7797 PROTOCOL_NAME (protocol) = name;
7798 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7799 add_protocol (protocol);
7800 PROTOCOL_DEFINED (protocol) = 1;
7801 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7803 check_protocol_recursively (protocol, list);
7805 else if (! PROTOCOL_DEFINED (protocol))
7807 PROTOCOL_DEFINED (protocol) = 1;
7808 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7810 check_protocol_recursively (protocol, list);
7812 else
7814 warning (0, "duplicate declaration for protocol %qs",
7815 IDENTIFIER_POINTER (name));
7817 return protocol;
7821 /* "Encode" a data type into a string, which grows in util_obstack.
7822 ??? What is the FORMAT? Someone please document this! */
7824 static void
7825 encode_type_qualifiers (tree declspecs)
7827 tree spec;
7829 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7831 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7832 obstack_1grow (&util_obstack, 'n');
7833 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7834 obstack_1grow (&util_obstack, 'N');
7835 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7836 obstack_1grow (&util_obstack, 'o');
7837 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7838 obstack_1grow (&util_obstack, 'O');
7839 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7840 obstack_1grow (&util_obstack, 'R');
7841 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7842 obstack_1grow (&util_obstack, 'V');
7846 /* Encode a pointer type. */
7848 static void
7849 encode_pointer (tree type, int curtype, int format)
7851 tree pointer_to = TREE_TYPE (type);
7853 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7855 if (OBJC_TYPE_NAME (pointer_to)
7856 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7858 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7860 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7862 obstack_1grow (&util_obstack, '@');
7863 return;
7865 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7866 && TYPE_OBJC_INTERFACE (pointer_to))
7868 if (generating_instance_variables)
7870 obstack_1grow (&util_obstack, '@');
7871 obstack_1grow (&util_obstack, '"');
7872 obstack_grow (&util_obstack, name, strlen (name));
7873 obstack_1grow (&util_obstack, '"');
7874 return;
7876 else
7878 obstack_1grow (&util_obstack, '@');
7879 return;
7882 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7884 obstack_1grow (&util_obstack, '#');
7885 return;
7887 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7889 obstack_1grow (&util_obstack, ':');
7890 return;
7894 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7895 && TYPE_MODE (pointer_to) == QImode)
7897 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7898 ? OBJC_TYPE_NAME (pointer_to)
7899 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7901 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7903 /* It appears that "r*" means "const char *" rather than
7904 "char *const". */
7905 if (TYPE_READONLY (pointer_to))
7906 obstack_1grow (&util_obstack, 'r');
7908 obstack_1grow (&util_obstack, '*');
7909 return;
7913 /* We have a type that does not get special treatment. */
7915 /* NeXT extension */
7916 obstack_1grow (&util_obstack, '^');
7917 encode_type (pointer_to, curtype, format);
7920 static void
7921 encode_array (tree type, int curtype, int format)
7923 tree an_int_cst = TYPE_SIZE (type);
7924 tree array_of = TREE_TYPE (type);
7925 char buffer[40];
7927 /* An incomplete array is treated like a pointer. */
7928 if (an_int_cst == NULL)
7930 encode_pointer (type, curtype, format);
7931 return;
7934 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7935 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7936 else
7937 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7938 TREE_INT_CST_LOW (an_int_cst)
7939 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7941 obstack_grow (&util_obstack, buffer, strlen (buffer));
7942 encode_type (array_of, curtype, format);
7943 obstack_1grow (&util_obstack, ']');
7944 return;
7947 static void
7948 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7950 tree field = TYPE_FIELDS (type);
7952 for (; field; field = TREE_CHAIN (field))
7954 #ifdef OBJCPLUS
7955 /* C++ static members, and things that are not field at all,
7956 should not appear in the encoding. */
7957 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7958 continue;
7959 #endif
7961 /* Recursively encode fields of embedded base classes. */
7962 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7963 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7965 encode_aggregate_fields (TREE_TYPE (field),
7966 pointed_to, curtype, format);
7967 continue;
7970 if (generating_instance_variables && !pointed_to)
7972 tree fname = DECL_NAME (field);
7974 obstack_1grow (&util_obstack, '"');
7976 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7977 obstack_grow (&util_obstack,
7978 IDENTIFIER_POINTER (fname),
7979 strlen (IDENTIFIER_POINTER (fname)));
7981 obstack_1grow (&util_obstack, '"');
7984 encode_field_decl (field, curtype, format);
7988 static void
7989 encode_aggregate_within (tree type, int curtype, int format, int left,
7990 int right)
7992 tree name;
7993 /* NB: aggregates that are pointed to have slightly different encoding
7994 rules in that you never encode the names of instance variables. */
7995 int ob_size = obstack_object_size (&util_obstack);
7996 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7997 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7998 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7999 int inline_contents
8000 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8001 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8003 /* Traverse struct aliases; it is important to get the
8004 original struct and its tag name (if any). */
8005 type = TYPE_MAIN_VARIANT (type);
8006 name = OBJC_TYPE_NAME (type);
8007 /* Open parenth/bracket. */
8008 obstack_1grow (&util_obstack, left);
8010 /* Encode the struct/union tag name, or '?' if a tag was
8011 not provided. Typedef aliases do not qualify. */
8012 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8013 #ifdef OBJCPLUS
8014 /* Did this struct have a tag? */
8015 && !TYPE_WAS_ANONYMOUS (type)
8016 #endif
8018 obstack_grow (&util_obstack,
8019 IDENTIFIER_POINTER (name),
8020 strlen (IDENTIFIER_POINTER (name)));
8021 else
8022 obstack_1grow (&util_obstack, '?');
8024 /* Encode the types (and possibly names) of the inner fields,
8025 if required. */
8026 if (inline_contents)
8028 obstack_1grow (&util_obstack, '=');
8029 encode_aggregate_fields (type, pointed_to, curtype, format);
8031 /* Close parenth/bracket. */
8032 obstack_1grow (&util_obstack, right);
8035 static void
8036 encode_aggregate (tree type, int curtype, int format)
8038 enum tree_code code = TREE_CODE (type);
8040 switch (code)
8042 case RECORD_TYPE:
8044 encode_aggregate_within (type, curtype, format, '{', '}');
8045 break;
8047 case UNION_TYPE:
8049 encode_aggregate_within (type, curtype, format, '(', ')');
8050 break;
8053 case ENUMERAL_TYPE:
8054 obstack_1grow (&util_obstack, 'i');
8055 break;
8057 default:
8058 break;
8062 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8063 field type. */
8065 static void
8066 encode_next_bitfield (int width)
8068 char buffer[40];
8069 sprintf (buffer, "b%d", width);
8070 obstack_grow (&util_obstack, buffer, strlen (buffer));
8073 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8074 static void
8075 encode_type (tree type, int curtype, int format)
8077 enum tree_code code = TREE_CODE (type);
8078 char c;
8080 if (type == error_mark_node)
8081 return;
8083 if (TYPE_READONLY (type))
8084 obstack_1grow (&util_obstack, 'r');
8086 if (code == INTEGER_TYPE)
8088 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8090 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8091 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8092 case 32:
8093 if (type == long_unsigned_type_node
8094 || type == long_integer_type_node)
8095 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8096 else
8097 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8098 break;
8099 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8100 default: abort ();
8102 obstack_1grow (&util_obstack, c);
8105 else if (code == REAL_TYPE)
8107 /* Floating point types. */
8108 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8110 case 32: c = 'f'; break;
8111 case 64:
8112 case 96:
8113 case 128: c = 'd'; break;
8114 default: abort ();
8116 obstack_1grow (&util_obstack, c);
8119 else if (code == VOID_TYPE)
8120 obstack_1grow (&util_obstack, 'v');
8122 else if (code == BOOLEAN_TYPE)
8123 obstack_1grow (&util_obstack, 'B');
8125 else if (code == ARRAY_TYPE)
8126 encode_array (type, curtype, format);
8128 else if (code == POINTER_TYPE)
8129 encode_pointer (type, curtype, format);
8131 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8132 encode_aggregate (type, curtype, format);
8134 else if (code == FUNCTION_TYPE) /* '?' */
8135 obstack_1grow (&util_obstack, '?');
8137 else if (code == COMPLEX_TYPE)
8139 obstack_1grow (&util_obstack, 'j');
8140 encode_type (TREE_TYPE (type), curtype, format);
8144 static void
8145 encode_gnu_bitfield (int position, tree type, int size)
8147 enum tree_code code = TREE_CODE (type);
8148 char buffer[40];
8149 char charType = '?';
8151 if (code == INTEGER_TYPE)
8153 if (integer_zerop (TYPE_MIN_VALUE (type)))
8155 /* Unsigned integer types. */
8157 if (TYPE_MODE (type) == QImode)
8158 charType = 'C';
8159 else if (TYPE_MODE (type) == HImode)
8160 charType = 'S';
8161 else if (TYPE_MODE (type) == SImode)
8163 if (type == long_unsigned_type_node)
8164 charType = 'L';
8165 else
8166 charType = 'I';
8168 else if (TYPE_MODE (type) == DImode)
8169 charType = 'Q';
8172 else
8173 /* Signed integer types. */
8175 if (TYPE_MODE (type) == QImode)
8176 charType = 'c';
8177 else if (TYPE_MODE (type) == HImode)
8178 charType = 's';
8179 else if (TYPE_MODE (type) == SImode)
8181 if (type == long_integer_type_node)
8182 charType = 'l';
8183 else
8184 charType = 'i';
8187 else if (TYPE_MODE (type) == DImode)
8188 charType = 'q';
8191 else if (code == ENUMERAL_TYPE)
8192 charType = 'i';
8193 else
8194 abort ();
8196 sprintf (buffer, "b%d%c%d", position, charType, size);
8197 obstack_grow (&util_obstack, buffer, strlen (buffer));
8200 static void
8201 encode_field_decl (tree field_decl, int curtype, int format)
8203 tree type;
8205 #ifdef OBJCPLUS
8206 /* C++ static members, and things that are not fields at all,
8207 should not appear in the encoding. */
8208 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8209 return;
8210 #endif
8212 type = TREE_TYPE (field_decl);
8214 /* Generate the bitfield typing information, if needed. Note the difference
8215 between GNU and NeXT runtimes. */
8216 if (DECL_BIT_FIELD_TYPE (field_decl))
8218 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8220 if (flag_next_runtime)
8221 encode_next_bitfield (size);
8222 else
8223 encode_gnu_bitfield (int_bit_position (field_decl),
8224 DECL_BIT_FIELD_TYPE (field_decl), size);
8226 else
8227 encode_type (TREE_TYPE (field_decl), curtype, format);
8230 static GTY(()) tree objc_parmlist = NULL_TREE;
8232 /* Append PARM to a list of formal parameters of a method, making a necessary
8233 array-to-pointer adjustment along the way. */
8235 static void
8236 objc_push_parm (tree parm)
8238 bool relayout_needed = false;
8240 if (TREE_TYPE (parm) == error_mark_node)
8242 objc_parmlist = chainon (objc_parmlist, parm);
8243 return;
8246 /* Decay arrays and functions into pointers. */
8247 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8249 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8250 relayout_needed = true;
8252 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8254 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8255 relayout_needed = true;
8258 if (relayout_needed)
8259 relayout_decl (parm);
8262 DECL_ARG_TYPE (parm)
8263 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8265 /* Record constancy and volatility. */
8266 c_apply_type_quals_to_decl
8267 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8268 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8269 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8271 objc_parmlist = chainon (objc_parmlist, parm);
8274 /* Retrieve the formal parameter list constructed via preceding calls to
8275 objc_push_parm(). */
8277 #ifdef OBJCPLUS
8278 static tree
8279 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8280 #else
8281 static struct c_arg_info *
8282 objc_get_parm_info (int have_ellipsis)
8283 #endif
8285 #ifdef OBJCPLUS
8286 tree parm_info = objc_parmlist;
8287 objc_parmlist = NULL_TREE;
8289 return parm_info;
8290 #else
8291 tree parm_info = objc_parmlist;
8292 struct c_arg_info *arg_info;
8293 /* The C front-end requires an elaborate song and dance at
8294 this point. */
8295 push_scope ();
8296 declare_parm_level ();
8297 while (parm_info)
8299 tree next = TREE_CHAIN (parm_info);
8301 TREE_CHAIN (parm_info) = NULL_TREE;
8302 parm_info = pushdecl (parm_info);
8303 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8304 parm_info = next;
8306 arg_info = get_parm_info (have_ellipsis);
8307 pop_scope ();
8308 objc_parmlist = NULL_TREE;
8309 return arg_info;
8310 #endif
8313 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8314 method definitions. In the case of instance methods, we can be more
8315 specific as to the type of 'self'. */
8317 static void
8318 synth_self_and_ucmd_args (void)
8320 tree self_type;
8322 if (objc_method_context
8323 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8324 self_type = objc_instance_type;
8325 else
8326 /* Really a `struct objc_class *'. However, we allow people to
8327 assign to self, which changes its type midstream. */
8328 self_type = objc_object_type;
8330 /* id self; */
8331 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8333 /* SEL _cmd; */
8334 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8337 /* Transform an Objective-C method definition into a static C function
8338 definition, synthesizing the first two arguments, "self" and "_cmd",
8339 in the process. */
8341 static void
8342 start_method_def (tree method)
8344 tree parmlist;
8345 #ifdef OBJCPLUS
8346 tree parm_info;
8347 #else
8348 struct c_arg_info *parm_info;
8349 #endif
8350 int have_ellipsis = 0;
8352 /* If we are defining a "dealloc" method in a non-root class, we
8353 will need to check if a [super dealloc] is missing, and warn if
8354 it is. */
8355 if(CLASS_SUPER_NAME (objc_implementation_context)
8356 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8357 should_call_super_dealloc = 1;
8358 else
8359 should_call_super_dealloc = 0;
8361 /* Required to implement _msgSuper. */
8362 objc_method_context = method;
8363 UOBJC_SUPER_decl = NULL_TREE;
8365 /* Generate prototype declarations for arguments..."new-style". */
8366 synth_self_and_ucmd_args ();
8368 /* Generate argument declarations if a keyword_decl. */
8369 parmlist = METHOD_SEL_ARGS (method);
8370 while (parmlist)
8372 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8374 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8375 objc_push_parm (parm);
8376 parmlist = TREE_CHAIN (parmlist);
8379 if (METHOD_ADD_ARGS (method))
8381 tree akey;
8383 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8384 akey; akey = TREE_CHAIN (akey))
8386 objc_push_parm (TREE_VALUE (akey));
8389 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8390 have_ellipsis = 1;
8393 parm_info = objc_get_parm_info (have_ellipsis);
8395 really_start_method (objc_method_context, parm_info);
8398 static void
8399 warn_with_method (const char *message, int mtype, tree method)
8401 /* Add a readable method name to the warning. */
8402 warning (0, "%J%s %<%c%s%>", method,
8403 message, mtype, gen_method_decl (method));
8406 /* Return 1 if TYPE1 is equivalent to TYPE2
8407 for purposes of method overloading. */
8409 static int
8410 objc_types_are_equivalent (tree type1, tree type2)
8412 if (type1 == type2)
8413 return 1;
8415 /* Strip away indirections. */
8416 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8417 && (TREE_CODE (type1) == TREE_CODE (type2)))
8418 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8419 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8420 return 0;
8422 type1 = (TYPE_HAS_OBJC_INFO (type1)
8423 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8424 : NULL_TREE);
8425 type2 = (TYPE_HAS_OBJC_INFO (type2)
8426 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8427 : NULL_TREE);
8429 if (list_length (type1) == list_length (type2))
8431 for (; type2; type2 = TREE_CHAIN (type2))
8432 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8433 return 0;
8434 return 1;
8436 return 0;
8439 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8441 static int
8442 objc_types_share_size_and_alignment (tree type1, tree type2)
8444 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8445 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8448 /* Return 1 if PROTO1 is equivalent to PROTO2
8449 for purposes of method overloading. Ordinarily, the type signatures
8450 should match up exactly, unless STRICT is zero, in which case we
8451 shall allow differences in which the size and alignment of a type
8452 is the same. */
8454 static int
8455 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8457 tree type1, type2;
8459 /* The following test is needed in case there are hashing
8460 collisions. */
8461 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8462 return 0;
8464 /* Compare return types. */
8465 type1 = TREE_VALUE (TREE_TYPE (proto1));
8466 type2 = TREE_VALUE (TREE_TYPE (proto2));
8468 if (!objc_types_are_equivalent (type1, type2)
8469 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8470 return 0;
8472 /* Compare argument types. */
8473 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8474 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8475 type1 && type2;
8476 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8478 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8479 && (strict
8480 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8481 TREE_VALUE (type2))))
8482 return 0;
8485 return (!type1 && !type2);
8488 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8489 this occurs. ObjC method dispatches are _not_ like C++ virtual
8490 member function dispatches, and we account for the difference here. */
8491 tree
8492 #ifdef OBJCPLUS
8493 objc_fold_obj_type_ref (tree ref, tree known_type)
8494 #else
8495 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8496 tree known_type ATTRIBUTE_UNUSED)
8497 #endif
8499 #ifdef OBJCPLUS
8500 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8502 /* If the receiver does not have virtual member functions, there
8503 is nothing we can (or need to) do here. */
8504 if (!v)
8505 return NULL_TREE;
8507 /* Let C++ handle C++ virtual functions. */
8508 return cp_fold_obj_type_ref (ref, known_type);
8509 #else
8510 /* For plain ObjC, we currently do not need to do anything. */
8511 return NULL_TREE;
8512 #endif
8515 static void
8516 objc_start_function (tree name, tree type, tree attrs,
8517 #ifdef OBJCPLUS
8518 tree params
8519 #else
8520 struct c_arg_info *params
8521 #endif
8524 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8526 #ifdef OBJCPLUS
8527 DECL_ARGUMENTS (fndecl) = params;
8528 DECL_INITIAL (fndecl) = error_mark_node;
8529 DECL_EXTERNAL (fndecl) = 0;
8530 TREE_STATIC (fndecl) = 1;
8531 retrofit_lang_decl (fndecl);
8532 cplus_decl_attributes (&fndecl, attrs, 0);
8533 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8534 #else
8535 struct c_label_context_se *nstack_se;
8536 struct c_label_context_vm *nstack_vm;
8537 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8538 nstack_se->labels_def = NULL;
8539 nstack_se->labels_used = NULL;
8540 nstack_se->next = label_context_stack_se;
8541 label_context_stack_se = nstack_se;
8542 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8543 nstack_vm->labels_def = NULL;
8544 nstack_vm->labels_used = NULL;
8545 nstack_vm->scope = 0;
8546 nstack_vm->next = label_context_stack_vm;
8547 label_context_stack_vm = nstack_vm;
8548 current_function_returns_value = 0; /* Assume, until we see it does. */
8549 current_function_returns_null = 0;
8551 decl_attributes (&fndecl, attrs, 0);
8552 announce_function (fndecl);
8553 DECL_INITIAL (fndecl) = error_mark_node;
8554 DECL_EXTERNAL (fndecl) = 0;
8555 TREE_STATIC (fndecl) = 1;
8556 current_function_decl = pushdecl (fndecl);
8557 push_scope ();
8558 declare_parm_level ();
8559 DECL_RESULT (current_function_decl)
8560 = build_decl (RESULT_DECL, NULL_TREE,
8561 TREE_TYPE (TREE_TYPE (current_function_decl)));
8562 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8563 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8564 start_fname_decls ();
8565 store_parm_decls_from (params);
8566 #endif
8568 TREE_USED (current_function_decl) = 1;
8571 /* - Generate an identifier for the function. the format is "_n_cls",
8572 where 1 <= n <= nMethods, and cls is the name the implementation we
8573 are processing.
8574 - Install the return type from the method declaration.
8575 - If we have a prototype, check for type consistency. */
8577 static void
8578 really_start_method (tree method,
8579 #ifdef OBJCPLUS
8580 tree parmlist
8581 #else
8582 struct c_arg_info *parmlist
8583 #endif
8586 tree ret_type, meth_type;
8587 tree method_id;
8588 const char *sel_name, *class_name, *cat_name;
8589 char *buf;
8591 /* Synth the storage class & assemble the return type. */
8592 ret_type = TREE_VALUE (TREE_TYPE (method));
8594 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8595 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8596 cat_name = ((TREE_CODE (objc_implementation_context)
8597 == CLASS_IMPLEMENTATION_TYPE)
8598 ? NULL
8599 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8600 method_slot++;
8602 /* Make sure this is big enough for any plausible method label. */
8603 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8604 + (cat_name ? strlen (cat_name) : 0));
8606 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8607 class_name, cat_name, sel_name, method_slot);
8609 method_id = get_identifier (buf);
8611 #ifdef OBJCPLUS
8612 /* Objective-C methods cannot be overloaded, so we don't need
8613 the type encoding appended. It looks bad anyway... */
8614 push_lang_context (lang_name_c);
8615 #endif
8617 meth_type
8618 = build_function_type (ret_type,
8619 get_arg_type_list (method, METHOD_DEF, 0));
8620 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8622 /* Set self_decl from the first argument. */
8623 self_decl = DECL_ARGUMENTS (current_function_decl);
8625 /* Suppress unused warnings. */
8626 TREE_USED (self_decl) = 1;
8627 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8628 #ifdef OBJCPLUS
8629 pop_lang_context ();
8630 #endif
8632 METHOD_DEFINITION (method) = current_function_decl;
8634 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8636 if (implementation_template != objc_implementation_context)
8638 tree proto
8639 = lookup_method_static (implementation_template,
8640 METHOD_SEL_NAME (method),
8641 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8642 | OBJC_LOOKUP_NO_SUPER));
8644 if (proto)
8646 if (!comp_proto_with_proto (method, proto, 1))
8648 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8650 warn_with_method ("conflicting types for", type, method);
8651 warn_with_method ("previous declaration of", type, proto);
8654 else
8656 /* We have a method @implementation even though we did not
8657 see a corresponding @interface declaration (which is allowed
8658 by Objective-C rules). Go ahead and place the method in
8659 the @interface anyway, so that message dispatch lookups
8660 will see it. */
8661 tree interface = implementation_template;
8663 if (TREE_CODE (objc_implementation_context)
8664 == CATEGORY_IMPLEMENTATION_TYPE)
8665 interface = lookup_category
8666 (interface,
8667 CLASS_SUPER_NAME (objc_implementation_context));
8669 if (interface)
8670 objc_add_method (interface, copy_node (method),
8671 TREE_CODE (method) == CLASS_METHOD_DECL);
8676 static void *UOBJC_SUPER_scope = 0;
8678 /* _n_Method (id self, SEL sel, ...)
8680 struct objc_super _S;
8681 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8682 } */
8684 static tree
8685 get_super_receiver (void)
8687 if (objc_method_context)
8689 tree super_expr, super_expr_list;
8691 if (!UOBJC_SUPER_decl)
8693 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8694 objc_super_template);
8695 /* This prevents `unused variable' warnings when compiling with -Wall. */
8696 TREE_USED (UOBJC_SUPER_decl) = 1;
8697 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8698 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8699 UOBJC_SUPER_scope = objc_get_current_scope ();
8702 /* Set receiver to self. */
8703 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8704 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8705 super_expr_list = super_expr;
8707 /* Set class to begin searching. */
8708 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8709 get_identifier ("super_class"));
8711 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8713 /* [_cls, __cls]Super are "pre-built" in
8714 synth_forward_declarations. */
8716 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8717 ((TREE_CODE (objc_method_context)
8718 == INSTANCE_METHOD_DECL)
8719 ? ucls_super_ref
8720 : uucls_super_ref));
8723 else
8724 /* We have a category. */
8726 tree super_name = CLASS_SUPER_NAME (implementation_template);
8727 tree super_class;
8729 /* Barf if super used in a category of Object. */
8730 if (!super_name)
8732 error ("no super class declared in interface for %qs",
8733 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8734 return error_mark_node;
8737 if (flag_next_runtime && !flag_zero_link)
8739 super_class = objc_get_class_reference (super_name);
8740 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8741 /* If we are in a class method, we must retrieve the
8742 _metaclass_ for the current class, pointed at by
8743 the class's "isa" pointer. The following assumes that
8744 "isa" is the first ivar in a class (which it must be). */
8745 super_class
8746 = build_indirect_ref
8747 (build_c_cast (build_pointer_type (objc_class_type),
8748 super_class), "unary *", input_location);
8750 else
8752 add_class_reference (super_name);
8753 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8754 ? objc_get_class_decl : objc_get_meta_class_decl);
8755 assemble_external (super_class);
8756 super_class
8757 = build_function_call
8758 (super_class,
8759 build_tree_list
8760 (NULL_TREE,
8761 my_build_string_pointer
8762 (IDENTIFIER_LENGTH (super_name) + 1,
8763 IDENTIFIER_POINTER (super_name))));
8766 super_expr
8767 = build_modify_expr (super_expr, NOP_EXPR,
8768 build_c_cast (TREE_TYPE (super_expr),
8769 super_class));
8772 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8774 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8775 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8777 return super_expr_list;
8779 else
8781 error ("[super ...] must appear in a method context");
8782 return error_mark_node;
8786 /* When exiting a scope, sever links to a 'super' declaration (if any)
8787 therein contained. */
8789 void
8790 objc_clear_super_receiver (void)
8792 if (objc_method_context
8793 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8794 UOBJC_SUPER_decl = 0;
8795 UOBJC_SUPER_scope = 0;
8799 void
8800 objc_finish_method_definition (tree fndecl)
8802 /* We cannot validly inline ObjC methods, at least not without a language
8803 extension to declare that a method need not be dynamically
8804 dispatched, so suppress all thoughts of doing so. */
8805 DECL_UNINLINABLE (fndecl) = 1;
8807 #ifndef OBJCPLUS
8808 /* The C++ front-end will have called finish_function() for us. */
8809 finish_function ();
8810 #endif
8812 METHOD_ENCODING (objc_method_context)
8813 = encode_method_prototype (objc_method_context);
8815 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8816 since the optimizer may find "may be used before set" errors. */
8817 objc_method_context = NULL_TREE;
8819 if (should_call_super_dealloc)
8820 warning (0, "method possibly missing a [super dealloc] call");
8823 #if 0
8825 lang_report_error_function (tree decl)
8827 if (objc_method_context)
8829 fprintf (stderr, "In method %qs\n",
8830 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8831 return 1;
8834 else
8835 return 0;
8837 #endif
8839 /* Given a tree DECL node, produce a printable description of it in the given
8840 buffer, overwriting the buffer. */
8842 static char *
8843 gen_declaration (tree decl)
8845 errbuf[0] = '\0';
8847 if (DECL_P (decl))
8849 gen_type_name_0 (TREE_TYPE (decl));
8851 if (DECL_NAME (decl))
8853 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8854 strcat (errbuf, " ");
8856 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8859 if (DECL_INITIAL (decl)
8860 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8861 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8862 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8865 return errbuf;
8868 /* Given a tree TYPE node, produce a printable description of it in the given
8869 buffer, overwriting the buffer. */
8871 static char *
8872 gen_type_name_0 (tree type)
8874 tree orig = type, proto;
8876 if (TYPE_P (type) && TYPE_NAME (type))
8877 type = TYPE_NAME (type);
8878 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8880 tree inner = TREE_TYPE (type);
8882 while (TREE_CODE (inner) == ARRAY_TYPE)
8883 inner = TREE_TYPE (inner);
8885 gen_type_name_0 (inner);
8887 if (!POINTER_TYPE_P (inner))
8888 strcat (errbuf, " ");
8890 if (POINTER_TYPE_P (type))
8891 strcat (errbuf, "*");
8892 else
8893 while (type != inner)
8895 strcat (errbuf, "[");
8897 if (TYPE_DOMAIN (type))
8899 char sz[20];
8901 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8902 (TREE_INT_CST_LOW
8903 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8904 strcat (errbuf, sz);
8907 strcat (errbuf, "]");
8908 type = TREE_TYPE (type);
8911 goto exit_function;
8914 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8915 type = DECL_NAME (type);
8917 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8918 ? IDENTIFIER_POINTER (type)
8919 : "");
8921 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8922 if (objc_is_id (orig))
8923 orig = TREE_TYPE (orig);
8925 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8927 if (proto)
8929 strcat (errbuf, " <");
8931 while (proto) {
8932 strcat (errbuf,
8933 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8934 proto = TREE_CHAIN (proto);
8935 strcat (errbuf, proto ? ", " : ">");
8939 exit_function:
8940 return errbuf;
8943 static char *
8944 gen_type_name (tree type)
8946 errbuf[0] = '\0';
8948 return gen_type_name_0 (type);
8951 /* Given a method tree, put a printable description into the given
8952 buffer (overwriting) and return a pointer to the buffer. */
8954 static char *
8955 gen_method_decl (tree method)
8957 tree chain;
8959 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8960 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8961 strcat (errbuf, ")");
8962 chain = METHOD_SEL_ARGS (method);
8964 if (chain)
8966 /* We have a chain of keyword_decls. */
8969 if (KEYWORD_KEY_NAME (chain))
8970 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8972 strcat (errbuf, ":(");
8973 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8974 strcat (errbuf, ")");
8976 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8977 if ((chain = TREE_CHAIN (chain)))
8978 strcat (errbuf, " ");
8980 while (chain);
8982 if (METHOD_ADD_ARGS (method))
8984 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8986 /* Know we have a chain of parm_decls. */
8987 while (chain)
8989 strcat (errbuf, ", ");
8990 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8991 chain = TREE_CHAIN (chain);
8994 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8995 strcat (errbuf, ", ...");
8999 else
9000 /* We have a unary selector. */
9001 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9003 return errbuf;
9006 /* Debug info. */
9009 /* Dump an @interface declaration of the supplied class CHAIN to the
9010 supplied file FP. Used to implement the -gen-decls option (which
9011 prints out an @interface declaration of all classes compiled in
9012 this run); potentially useful for debugging the compiler too. */
9013 static void
9014 dump_interface (FILE *fp, tree chain)
9016 /* FIXME: A heap overflow here whenever a method (or ivar)
9017 declaration is so long that it doesn't fit in the buffer. The
9018 code and all the related functions should be rewritten to avoid
9019 using fixed size buffers. */
9020 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9021 tree ivar_decls = CLASS_RAW_IVARS (chain);
9022 tree nst_methods = CLASS_NST_METHODS (chain);
9023 tree cls_methods = CLASS_CLS_METHODS (chain);
9025 fprintf (fp, "\n@interface %s", my_name);
9027 /* CLASS_SUPER_NAME is used to store the superclass name for
9028 classes, and the category name for categories. */
9029 if (CLASS_SUPER_NAME (chain))
9031 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9033 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9034 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9036 fprintf (fp, " (%s)\n", name);
9038 else
9040 fprintf (fp, " : %s\n", name);
9043 else
9044 fprintf (fp, "\n");
9046 /* FIXME - the following doesn't seem to work at the moment. */
9047 if (ivar_decls)
9049 fprintf (fp, "{\n");
9052 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9053 ivar_decls = TREE_CHAIN (ivar_decls);
9055 while (ivar_decls);
9056 fprintf (fp, "}\n");
9059 while (nst_methods)
9061 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9062 nst_methods = TREE_CHAIN (nst_methods);
9065 while (cls_methods)
9067 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9068 cls_methods = TREE_CHAIN (cls_methods);
9071 fprintf (fp, "@end\n");
9074 /* Demangle function for Objective-C */
9075 static const char *
9076 objc_demangle (const char *mangled)
9078 char *demangled, *cp;
9080 if (mangled[0] == '_' &&
9081 (mangled[1] == 'i' || mangled[1] == 'c') &&
9082 mangled[2] == '_')
9084 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9085 if (mangled[1] == 'i')
9086 *cp++ = '-'; /* for instance method */
9087 else
9088 *cp++ = '+'; /* for class method */
9089 *cp++ = '['; /* opening left brace */
9090 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9091 while (*cp && *cp == '_')
9092 cp++; /* skip any initial underbars in class name */
9093 cp = strchr(cp, '_'); /* find first non-initial underbar */
9094 if (cp == NULL)
9096 free(demangled); /* not mangled name */
9097 return mangled;
9099 if (cp[1] == '_') /* easy case: no category name */
9101 *cp++ = ' '; /* replace two '_' with one ' ' */
9102 strcpy(cp, mangled + (cp - demangled) + 2);
9104 else
9106 *cp++ = '('; /* less easy case: category name */
9107 cp = strchr(cp, '_');
9108 if (cp == 0)
9110 free(demangled); /* not mangled name */
9111 return mangled;
9113 *cp++ = ')';
9114 *cp++ = ' '; /* overwriting 1st char of method name... */
9115 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9117 while (*cp && *cp == '_')
9118 cp++; /* skip any initial underbars in method name */
9119 for (; *cp; cp++)
9120 if (*cp == '_')
9121 *cp = ':'; /* replace remaining '_' with ':' */
9122 *cp++ = ']'; /* closing right brace */
9123 *cp++ = 0; /* string terminator */
9124 return demangled;
9126 else
9127 return mangled; /* not an objc mangled name */
9130 const char *
9131 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9133 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9136 static void
9137 init_objc (void)
9139 gcc_obstack_init (&util_obstack);
9140 util_firstobj = (char *) obstack_finish (&util_obstack);
9142 errbuf = XNEWVEC (char, 1024 * 10);
9143 hash_init ();
9144 synth_module_prologue ();
9147 static void
9148 finish_objc (void)
9150 struct imp_entry *impent;
9151 tree chain;
9152 /* The internally generated initializers appear to have missing braces.
9153 Don't warn about this. */
9154 int save_warn_missing_braces = warn_missing_braces;
9155 warn_missing_braces = 0;
9157 /* A missing @end may not be detected by the parser. */
9158 if (objc_implementation_context)
9160 warning (0, "%<@end%> missing in implementation context");
9161 finish_class (objc_implementation_context);
9162 objc_ivar_chain = NULL_TREE;
9163 objc_implementation_context = NULL_TREE;
9166 /* Process the static instances here because initialization of objc_symtab
9167 depends on them. */
9168 if (objc_static_instances)
9169 generate_static_references ();
9171 if (imp_list || class_names_chain
9172 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9173 generate_objc_symtab_decl ();
9175 for (impent = imp_list; impent; impent = impent->next)
9177 objc_implementation_context = impent->imp_context;
9178 implementation_template = impent->imp_template;
9180 UOBJC_CLASS_decl = impent->class_decl;
9181 UOBJC_METACLASS_decl = impent->meta_decl;
9183 /* Dump the @interface of each class as we compile it, if the
9184 -gen-decls option is in use. TODO: Dump the classes in the
9185 order they were found, rather than in reverse order as we
9186 are doing now. */
9187 if (flag_gen_declaration)
9189 dump_interface (gen_declaration_file, objc_implementation_context);
9192 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9194 /* all of the following reference the string pool... */
9195 generate_ivar_lists ();
9196 generate_dispatch_tables ();
9197 generate_shared_structures (impent->has_cxx_cdtors
9198 ? CLS_HAS_CXX_STRUCTORS
9199 : 0);
9201 else
9203 generate_dispatch_tables ();
9204 generate_category (objc_implementation_context);
9208 /* If we are using an array of selectors, we must always
9209 finish up the array decl even if no selectors were used. */
9210 if (! flag_next_runtime || sel_ref_chain)
9211 build_selector_translation_table ();
9213 if (protocol_chain)
9214 generate_protocols ();
9216 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9217 generate_objc_image_info ();
9219 /* Arrange for ObjC data structures to be initialized at run time. */
9220 if (objc_implementation_context || class_names_chain || objc_static_instances
9221 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9223 build_module_descriptor ();
9225 if (!flag_next_runtime)
9226 build_module_initializer_routine ();
9229 /* Dump the class references. This forces the appropriate classes
9230 to be linked into the executable image, preserving unix archive
9231 semantics. This can be removed when we move to a more dynamically
9232 linked environment. */
9234 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9236 handle_class_ref (chain);
9237 if (TREE_PURPOSE (chain))
9238 generate_classref_translation_entry (chain);
9241 for (impent = imp_list; impent; impent = impent->next)
9242 handle_impent (impent);
9244 if (warn_selector)
9246 int slot;
9247 hash hsh;
9249 /* Run through the selector hash tables and print a warning for any
9250 selector which has multiple methods. */
9252 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9254 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9255 check_duplicates (hsh, 0, 1);
9256 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9257 check_duplicates (hsh, 0, 1);
9261 warn_missing_braces = save_warn_missing_braces;
9264 /* Subroutines of finish_objc. */
9266 static void
9267 generate_classref_translation_entry (tree chain)
9269 tree expr, decl, type;
9271 decl = TREE_PURPOSE (chain);
9272 type = TREE_TYPE (decl);
9274 expr = add_objc_string (TREE_VALUE (chain), class_names);
9275 expr = convert (type, expr); /* cast! */
9277 /* The decl that is the one that we
9278 forward declared in build_class_reference. */
9279 finish_var_decl (decl, expr);
9280 return;
9283 static void
9284 handle_class_ref (tree chain)
9286 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9287 char *string = (char *) alloca (strlen (name) + 30);
9288 tree decl;
9289 tree exp;
9291 sprintf (string, "%sobjc_class_name_%s",
9292 (flag_next_runtime ? "." : "__"), name);
9294 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9295 if (flag_next_runtime)
9297 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9298 return;
9300 #endif
9302 /* Make a decl for this name, so we can use its address in a tree. */
9303 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9304 DECL_EXTERNAL (decl) = 1;
9305 TREE_PUBLIC (decl) = 1;
9307 pushdecl (decl);
9308 rest_of_decl_compilation (decl, 0, 0);
9310 /* Make a decl for the address. */
9311 sprintf (string, "%sobjc_class_ref_%s",
9312 (flag_next_runtime ? "." : "__"), name);
9313 exp = build1 (ADDR_EXPR, string_type_node, decl);
9314 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9315 DECL_INITIAL (decl) = exp;
9316 TREE_STATIC (decl) = 1;
9317 TREE_USED (decl) = 1;
9318 /* Force the output of the decl as this forces the reference of the class. */
9319 mark_decl_referenced (decl);
9321 pushdecl (decl);
9322 rest_of_decl_compilation (decl, 0, 0);
9325 static void
9326 handle_impent (struct imp_entry *impent)
9328 char *string;
9330 objc_implementation_context = impent->imp_context;
9331 implementation_template = impent->imp_template;
9333 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9335 const char *const class_name =
9336 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9338 string = (char *) alloca (strlen (class_name) + 30);
9340 sprintf (string, "%sobjc_class_name_%s",
9341 (flag_next_runtime ? "." : "__"), class_name);
9343 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9345 const char *const class_name =
9346 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9347 const char *const class_super_name =
9348 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9350 string = (char *) alloca (strlen (class_name)
9351 + strlen (class_super_name) + 30);
9353 /* Do the same for categories. Even though no references to
9354 these symbols are generated automatically by the compiler, it
9355 gives you a handle to pull them into an archive by hand. */
9356 sprintf (string, "*%sobjc_category_name_%s_%s",
9357 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9359 else
9360 return;
9362 #ifdef ASM_DECLARE_CLASS_REFERENCE
9363 if (flag_next_runtime)
9365 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9366 return;
9368 else
9369 #endif
9371 tree decl, init;
9373 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9374 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9375 TREE_PUBLIC (decl) = 1;
9376 TREE_READONLY (decl) = 1;
9377 TREE_USED (decl) = 1;
9378 TREE_CONSTANT (decl) = 1;
9379 DECL_CONTEXT (decl) = 0;
9380 DECL_ARTIFICIAL (decl) = 1;
9381 DECL_INITIAL (decl) = init;
9382 assemble_variable (decl, 1, 0, 0);
9386 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9387 later requires that ObjC translation units participating in F&C be
9388 specially marked. The following routine accomplishes this. */
9390 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9392 static void
9393 generate_objc_image_info (void)
9395 tree decl, initlist;
9396 int flags
9397 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9398 | (flag_objc_gc ? 2 : 0));
9400 decl = start_var_decl (build_array_type
9401 (integer_type_node,
9402 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9403 "_OBJC_IMAGE_INFO");
9405 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9406 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9407 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9409 finish_var_decl (decl, initlist);
9412 /* Look up ID as an instance variable. OTHER contains the result of
9413 the C or C++ lookup, which we may want to use instead. */
9415 tree
9416 objc_lookup_ivar (tree other, tree id)
9418 tree ivar;
9420 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9421 if (!objc_method_context)
9422 return other;
9424 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9425 /* We have a message to super. */
9426 return get_super_receiver ();
9428 /* In a class method, look up an instance variable only as a last
9429 resort. */
9430 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9431 && other && other != error_mark_node)
9432 return other;
9434 /* Look up the ivar, but do not use it if it is not accessible. */
9435 ivar = is_ivar (objc_ivar_chain, id);
9437 if (!ivar || is_private (ivar))
9438 return other;
9440 /* In an instance method, a local variable (or parameter) may hide the
9441 instance variable. */
9442 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9443 && other && other != error_mark_node
9444 #ifdef OBJCPLUS
9445 && CP_DECL_CONTEXT (other) != global_namespace)
9446 #else
9447 && !DECL_FILE_SCOPE_P (other))
9448 #endif
9450 warning (0, "local declaration of %qs hides instance variable",
9451 IDENTIFIER_POINTER (id));
9453 return other;
9456 /* At this point, we are either in an instance method with no obscuring
9457 local definitions, or in a class method with no alternate definitions
9458 at all. */
9459 return build_ivar_reference (id);
9462 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9463 needs to be done if we are calling a function through a cast. */
9465 tree
9466 objc_rewrite_function_call (tree function, tree params)
9468 if (TREE_CODE (function) == NOP_EXPR
9469 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9470 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9471 == FUNCTION_DECL)
9473 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9474 TREE_OPERAND (function, 0),
9475 TREE_VALUE (params), size_zero_node);
9478 return function;
9481 /* Look for the special case of OBJC_TYPE_REF with the address of
9482 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9483 of its cousins). */
9485 enum gimplify_status
9486 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9488 enum gimplify_status r0, r1;
9489 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9490 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9491 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9492 == FUNCTION_DECL)
9494 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9495 value of the OBJ_TYPE_REF, so force them to be emitted
9496 during subexpression evaluation rather than after the
9497 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9498 C to use direct rather than indirect calls when the
9499 object expression has a postincrement. */
9500 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9501 is_gimple_val, fb_rvalue);
9502 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9503 is_gimple_val, fb_rvalue);
9505 return MIN (r0, r1);
9508 #ifdef OBJCPLUS
9509 return cp_gimplify_expr (expr_p, pre_p, post_p);
9510 #else
9511 return c_gimplify_expr (expr_p, pre_p, post_p);
9512 #endif
9515 #include "gt-objc-objc-act.h"