2009-06-12 Andrew Pinski <andrew_pinski@playstation.sony.com>
[official-gcc.git] / gcc / objc / objc-act.c
blob41ed41ee5ba08672e095ffc677f05a4342b8d89b
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009 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 "intl.h"
73 #include "cgraph.h"
74 #include "tree-iterator.h"
75 #include "libfuncs.h"
76 #include "hashtab.h"
77 #include "langhooks-def.h"
79 #define OBJC_VOID_AT_END void_list_node
81 static unsigned int should_call_super_dealloc = 0;
83 /* When building Objective-C++, we need in_late_binary_op. */
84 #ifdef OBJCPLUS
85 bool in_late_binary_op = false;
86 #endif /* OBJCPLUS */
88 /* When building Objective-C++, we are not linking against the C front-end
89 and so need to replicate the C tree-construction functions in some way. */
90 #ifdef OBJCPLUS
91 #define OBJCP_REMAP_FUNCTIONS
92 #include "objcp-decl.h"
93 #endif /* OBJCPLUS */
95 /* This is the default way of generating a method name. */
96 /* I am not sure it is really correct.
97 Perhaps there's a danger that it will make name conflicts
98 if method names contain underscores. -- rms. */
99 #ifndef OBJC_GEN_METHOD_LABEL
100 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
101 do { \
102 char *temp; \
103 sprintf ((BUF), "_%s_%s_%s_%s", \
104 ((IS_INST) ? "i" : "c"), \
105 (CLASS_NAME), \
106 ((CAT_NAME)? (CAT_NAME) : ""), \
107 (SEL_NAME)); \
108 for (temp = (BUF); *temp; temp++) \
109 if (*temp == ':') *temp = '_'; \
110 } while (0)
111 #endif
113 /* These need specifying. */
114 #ifndef OBJC_FORWARDING_STACK_OFFSET
115 #define OBJC_FORWARDING_STACK_OFFSET 0
116 #endif
118 #ifndef OBJC_FORWARDING_MIN_OFFSET
119 #define OBJC_FORWARDING_MIN_OFFSET 0
120 #endif
122 /* Set up for use of obstacks. */
124 #include "obstack.h"
126 /* This obstack is used to accumulate the encoding of a data type. */
127 static struct obstack util_obstack;
129 /* This points to the beginning of obstack contents, so we can free
130 the whole contents. */
131 char *util_firstobj;
133 /* The version identifies which language generation and runtime
134 the module (file) was compiled for, and is recorded in the
135 module descriptor. */
137 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
138 #define PROTOCOL_VERSION 2
140 /* (Decide if these can ever be validly changed.) */
141 #define OBJC_ENCODE_INLINE_DEFS 0
142 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
144 /*** Private Interface (procedures) ***/
146 /* Used by compile_file. */
148 static void init_objc (void);
149 static void finish_objc (void);
151 /* Code generation. */
153 static tree objc_build_constructor (tree, tree);
154 static tree build_objc_method_call (int, tree, tree, tree, tree);
155 static tree get_proto_encoding (tree);
156 static tree lookup_interface (tree);
157 static tree objc_add_static_instance (tree, tree);
159 static tree start_class (enum tree_code, tree, tree, tree);
160 static tree continue_class (tree);
161 static void finish_class (tree);
162 static void start_method_def (tree);
163 #ifdef OBJCPLUS
164 static void objc_start_function (tree, tree, tree, tree);
165 #else
166 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
167 #endif
168 static tree start_protocol (enum tree_code, tree, tree);
169 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
170 static tree objc_add_method (tree, tree, int);
171 static tree add_instance_variable (tree, int, tree);
172 static tree build_ivar_reference (tree);
173 static tree is_ivar (tree, tree);
175 static void build_objc_exception_stuff (void);
176 static void build_next_objc_exception_stuff (void);
178 /* We only need the following for ObjC; ObjC++ will use C++'s definition
179 of DERIVED_FROM_P. */
180 #ifndef OBJCPLUS
181 static bool objc_derived_from_p (tree, tree);
182 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
183 #endif
184 static void objc_xref_basetypes (tree, tree);
186 static void build_class_template (void);
187 static void build_selector_template (void);
188 static void build_category_template (void);
189 static void build_super_template (void);
190 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
191 static tree get_class_ivars (tree, bool);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
195 #ifdef OBJCPLUS
196 static void objc_generate_cxx_cdtors (void);
197 #endif
199 static const char *synth_id_with_class_suffix (const char *, tree);
201 /* Hash tables to manage the global pool of method prototypes. */
203 hash *nst_method_hash_list = 0;
204 hash *cls_method_hash_list = 0;
206 static hash hash_lookup (hash *, tree);
207 static tree lookup_method (tree, tree);
208 static tree lookup_method_static (tree, tree, int);
210 enum string_section
212 class_names, /* class, category, protocol, module names */
213 meth_var_names, /* method and variable names */
214 meth_var_types /* method and variable type descriptors */
217 static tree add_objc_string (tree, enum string_section);
218 static tree build_objc_string_decl (enum string_section);
219 static void build_selector_table_decl (void);
221 /* Protocol additions. */
223 static tree lookup_protocol (tree);
224 static tree lookup_and_install_protocols (tree);
226 /* Type encoding. */
228 static void encode_type_qualifiers (tree);
229 static void encode_type (tree, int, int);
230 static void encode_field_decl (tree, int, int);
232 #ifdef OBJCPLUS
233 static void really_start_method (tree, tree);
234 #else
235 static void really_start_method (tree, struct c_arg_info *);
236 #endif
237 static int comp_proto_with_proto (tree, tree, int);
238 static void objc_push_parm (tree);
239 #ifdef OBJCPLUS
240 static tree objc_get_parm_info (int);
241 #else
242 static struct c_arg_info *objc_get_parm_info (int);
243 #endif
245 /* Utilities for debugging and error diagnostics. */
247 static char *gen_type_name (tree);
248 static char *gen_type_name_0 (tree);
249 static char *gen_method_decl (tree);
250 static char *gen_declaration (tree);
252 /* Everything else. */
254 static tree create_field_decl (tree, const char *);
255 static void add_class_reference (tree);
256 static void build_protocol_template (void);
257 static tree encode_method_prototype (tree);
258 static void generate_classref_translation_entry (tree);
259 static void handle_class_ref (tree);
260 static void generate_struct_by_value_array (void)
261 ATTRIBUTE_NORETURN;
262 static void mark_referenced_methods (void);
263 static void generate_objc_image_info (void);
265 /*** Private Interface (data) ***/
267 /* Reserved tag definitions. */
269 #define OBJECT_TYPEDEF_NAME "id"
270 #define CLASS_TYPEDEF_NAME "Class"
272 #define TAG_OBJECT "objc_object"
273 #define TAG_CLASS "objc_class"
274 #define TAG_SUPER "objc_super"
275 #define TAG_SELECTOR "objc_selector"
277 #define UTAG_CLASS "_objc_class"
278 #define UTAG_IVAR "_objc_ivar"
279 #define UTAG_IVAR_LIST "_objc_ivar_list"
280 #define UTAG_METHOD "_objc_method"
281 #define UTAG_METHOD_LIST "_objc_method_list"
282 #define UTAG_CATEGORY "_objc_category"
283 #define UTAG_MODULE "_objc_module"
284 #define UTAG_SYMTAB "_objc_symtab"
285 #define UTAG_SUPER "_objc_super"
286 #define UTAG_SELECTOR "_objc_selector"
288 #define UTAG_PROTOCOL "_objc_protocol"
289 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
290 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
292 /* Note that the string object global name is only needed for the
293 NeXT runtime. */
294 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
296 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
298 static const char *TAG_GETCLASS;
299 static const char *TAG_GETMETACLASS;
300 static const char *TAG_MSGSEND;
301 static const char *TAG_MSGSENDSUPER;
302 /* The NeXT Objective-C messenger may have two extra entry points, for use
303 when returning a structure. */
304 static const char *TAG_MSGSEND_STRET;
305 static const char *TAG_MSGSENDSUPER_STRET;
306 static const char *default_constant_string_class_name;
308 /* Runtime metadata flags. */
309 #define CLS_FACTORY 0x0001L
310 #define CLS_META 0x0002L
311 #define CLS_HAS_CXX_STRUCTORS 0x2000L
313 #define OBJC_MODIFIER_STATIC 0x00000001
314 #define OBJC_MODIFIER_FINAL 0x00000002
315 #define OBJC_MODIFIER_PUBLIC 0x00000004
316 #define OBJC_MODIFIER_PRIVATE 0x00000008
317 #define OBJC_MODIFIER_PROTECTED 0x00000010
318 #define OBJC_MODIFIER_NATIVE 0x00000020
319 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
320 #define OBJC_MODIFIER_ABSTRACT 0x00000080
321 #define OBJC_MODIFIER_VOLATILE 0x00000100
322 #define OBJC_MODIFIER_TRANSIENT 0x00000200
323 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
325 /* NeXT-specific tags. */
327 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
328 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
329 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
330 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
331 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
332 #define TAG_EXCEPTIONMATCH "objc_exception_match"
333 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
334 #define TAG_SYNCENTER "objc_sync_enter"
335 #define TAG_SYNCEXIT "objc_sync_exit"
336 #define TAG_SETJMP "_setjmp"
337 #define UTAG_EXCDATA "_objc_exception_data"
339 #define TAG_ASSIGNIVAR "objc_assign_ivar"
340 #define TAG_ASSIGNGLOBAL "objc_assign_global"
341 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
343 /* Branch entry points. All that matters here are the addresses;
344 functions with these names do not really exist in libobjc. */
346 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
347 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
349 #define TAG_CXX_CONSTRUCT ".cxx_construct"
350 #define TAG_CXX_DESTRUCT ".cxx_destruct"
352 /* GNU-specific tags. */
354 #define TAG_EXECCLASS "__objc_exec_class"
355 #define TAG_GNUINIT "__objc_gnu_init"
357 /* Flags for lookup_method_static(). */
358 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
359 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
361 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
362 tree objc_global_trees[OCTI_MAX];
364 static void handle_impent (struct imp_entry *);
366 struct imp_entry *imp_list = 0;
367 int imp_count = 0; /* `@implementation' */
368 int cat_count = 0; /* `@category' */
370 enum tree_code objc_inherit_code;
371 int objc_public_flag;
373 /* Use to generate method labels. */
374 static int method_slot = 0;
376 #define BUFSIZE 1024
378 static char *errbuf; /* Buffer for error diagnostics */
380 /* Data imported from tree.c. */
382 extern enum debug_info_type write_symbols;
384 /* Data imported from toplev.c. */
386 extern const char *dump_base_name;
388 static int flag_typed_selectors;
390 /* Store all constructed constant strings in a hash table so that
391 they get uniqued properly. */
393 struct GTY(()) string_descriptor {
394 /* The literal argument . */
395 tree literal;
397 /* The resulting constant string. */
398 tree constructor;
401 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
403 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
404 struct GTY(()) volatilized_type {
405 tree type;
408 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
410 FILE *gen_declaration_file;
412 /* Tells "encode_pointer/encode_aggregate" whether we are generating
413 type descriptors for instance variables (as opposed to methods).
414 Type descriptors for instance variables contain more information
415 than methods (for static typing and embedded structures). */
417 static int generating_instance_variables = 0;
419 /* For building an objc struct. These may not be used when this file
420 is compiled as part of obj-c++. */
422 static bool objc_building_struct;
423 static bool objc_in_struct ATTRIBUTE_UNUSED;
424 static VEC(tree,heap) *objc_struct_types ATTRIBUTE_UNUSED;
426 /* Start building a struct for objc. */
428 static tree
429 objc_start_struct (tree name)
431 gcc_assert (!objc_building_struct);
432 objc_building_struct = true;
433 return start_struct (RECORD_TYPE, name, &objc_in_struct, &objc_struct_types,
434 UNKNOWN_LOCATION);
437 /* Finish building a struct for objc. */
439 static tree
440 objc_finish_struct (tree type, tree fieldlist)
442 gcc_assert (objc_building_struct);
443 objc_building_struct = false;
444 return finish_struct (type, fieldlist, NULL_TREE, objc_in_struct,
445 objc_struct_types);
448 /* Some platforms pass small structures through registers versus
449 through an invisible pointer. Determine at what size structure is
450 the transition point between the two possibilities. */
452 static void
453 generate_struct_by_value_array (void)
455 tree type;
456 tree field_decl, field_decl_chain;
457 int i, j;
458 int aggregate_in_mem[32];
459 int found = 0;
461 /* Presumably no platform passes 32 byte structures in a register. */
462 for (i = 1; i < 32; i++)
464 char buffer[5];
466 /* Create an unnamed struct that has `i' character components */
467 type = objc_start_struct (NULL_TREE);
469 strcpy (buffer, "c1");
470 field_decl = create_field_decl (char_type_node,
471 buffer);
472 field_decl_chain = field_decl;
474 for (j = 1; j < i; j++)
476 sprintf (buffer, "c%d", j + 1);
477 field_decl = create_field_decl (char_type_node,
478 buffer);
479 chainon (field_decl_chain, field_decl);
481 objc_finish_struct (type, field_decl_chain);
483 aggregate_in_mem[i] = aggregate_value_p (type, 0);
484 if (!aggregate_in_mem[i])
485 found = 1;
488 /* We found some structures that are returned in registers instead of memory
489 so output the necessary data. */
490 if (found)
492 for (i = 31; i >= 0; i--)
493 if (!aggregate_in_mem[i])
494 break;
495 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
497 /* The first member of the structure is always 0 because we don't handle
498 structures with 0 members */
499 printf ("static int struct_forward_array[] = {\n 0");
501 for (j = 1; j <= i; j++)
502 printf (", %d", aggregate_in_mem[j]);
503 printf ("\n};\n");
506 exit (0);
509 bool
510 objc_init (void)
512 #ifdef OBJCPLUS
513 if (cxx_init () == false)
514 #else
515 if (c_objc_common_init () == false)
516 #endif
517 return false;
519 /* If gen_declaration desired, open the output file. */
520 if (flag_gen_declaration)
522 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
523 gen_declaration_file = fopen (dumpname, "w");
524 if (gen_declaration_file == 0)
525 fatal_error ("can't open %s: %m", dumpname);
526 free (dumpname);
529 if (flag_next_runtime)
531 TAG_GETCLASS = "objc_getClass";
532 TAG_GETMETACLASS = "objc_getMetaClass";
533 TAG_MSGSEND = "objc_msgSend";
534 TAG_MSGSENDSUPER = "objc_msgSendSuper";
535 TAG_MSGSEND_STRET = "objc_msgSend_stret";
536 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
537 default_constant_string_class_name = "NSConstantString";
539 else
541 TAG_GETCLASS = "objc_get_class";
542 TAG_GETMETACLASS = "objc_get_meta_class";
543 TAG_MSGSEND = "objc_msg_lookup";
544 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
545 /* GNU runtime does not provide special functions to support
546 structure-returning methods. */
547 default_constant_string_class_name = "NXConstantString";
548 flag_typed_selectors = 1;
551 init_objc ();
553 if (print_struct_values && !flag_compare_debug)
554 generate_struct_by_value_array ();
556 return true;
559 void
560 objc_finish_file (void)
562 mark_referenced_methods ();
564 #ifdef OBJCPLUS
565 /* We need to instantiate templates _before_ we emit ObjC metadata;
566 if we do not, some metadata (such as selectors) may go missing. */
567 at_eof = 1;
568 instantiate_pending_templates (0);
569 #endif
571 /* Finalize Objective-C runtime data. No need to generate tables
572 and code if only checking syntax, or if generating a PCH file. */
573 if (!flag_syntax_only && !pch_file)
574 finish_objc ();
576 if (gen_declaration_file)
577 fclose (gen_declaration_file);
580 /* Return the first occurrence of a method declaration corresponding
581 to sel_name in rproto_list. Search rproto_list recursively.
582 If is_class is 0, search for instance methods, otherwise for class
583 methods. */
584 static tree
585 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
586 int is_class)
588 tree rproto, p;
589 tree fnd = 0;
591 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
593 p = TREE_VALUE (rproto);
595 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
597 if ((fnd = lookup_method (is_class
598 ? PROTOCOL_CLS_METHODS (p)
599 : PROTOCOL_NST_METHODS (p), sel_name)))
601 else if (PROTOCOL_LIST (p))
602 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
603 sel_name, is_class);
605 else
607 ; /* An identifier...if we could not find a protocol. */
610 if (fnd)
611 return fnd;
614 return 0;
617 static tree
618 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
620 tree rproto, p;
622 /* Make sure the protocol is supported by the object on the rhs. */
623 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
625 tree fnd = 0;
626 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
628 p = TREE_VALUE (rproto);
630 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
632 if (lproto == p)
633 fnd = lproto;
635 else if (PROTOCOL_LIST (p))
636 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
639 if (fnd)
640 return fnd;
643 else
645 ; /* An identifier...if we could not find a protocol. */
648 return 0;
651 void
652 objc_start_class_interface (tree klass, tree super_class, tree protos)
654 objc_interface_context
655 = objc_ivar_context
656 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
657 objc_public_flag = 0;
660 void
661 objc_start_category_interface (tree klass, tree categ, tree protos)
663 objc_interface_context
664 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
665 objc_ivar_chain
666 = continue_class (objc_interface_context);
669 void
670 objc_start_protocol (tree name, tree protos)
672 objc_interface_context
673 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
676 void
677 objc_continue_interface (void)
679 objc_ivar_chain
680 = continue_class (objc_interface_context);
683 void
684 objc_finish_interface (void)
686 finish_class (objc_interface_context);
687 objc_interface_context = NULL_TREE;
690 void
691 objc_start_class_implementation (tree klass, tree super_class)
693 objc_implementation_context
694 = objc_ivar_context
695 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
696 objc_public_flag = 0;
699 void
700 objc_start_category_implementation (tree klass, tree categ)
702 objc_implementation_context
703 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
704 objc_ivar_chain
705 = continue_class (objc_implementation_context);
708 void
709 objc_continue_implementation (void)
711 objc_ivar_chain
712 = continue_class (objc_implementation_context);
715 void
716 objc_finish_implementation (void)
718 #ifdef OBJCPLUS
719 if (flag_objc_call_cxx_cdtors)
720 objc_generate_cxx_cdtors ();
721 #endif
723 if (objc_implementation_context)
725 finish_class (objc_implementation_context);
726 objc_ivar_chain = NULL_TREE;
727 objc_implementation_context = NULL_TREE;
729 else
730 warning (0, "%<@end%> must appear in an @implementation context");
733 void
734 objc_set_visibility (int visibility)
736 objc_public_flag = visibility;
739 void
740 objc_set_method_type (enum tree_code type)
742 objc_inherit_code = (type == PLUS_EXPR
743 ? CLASS_METHOD_DECL
744 : INSTANCE_METHOD_DECL);
747 tree
748 objc_build_method_signature (tree rettype, tree selector,
749 tree optparms, bool ellipsis)
751 return build_method_decl (objc_inherit_code, rettype, selector,
752 optparms, ellipsis);
755 void
756 objc_add_method_declaration (tree decl)
758 if (!objc_interface_context)
759 fatal_error ("method declaration not in @interface context");
761 objc_add_method (objc_interface_context,
762 decl,
763 objc_inherit_code == CLASS_METHOD_DECL);
766 void
767 objc_start_method_definition (tree decl)
769 if (!objc_implementation_context)
770 fatal_error ("method definition not in @implementation context");
772 objc_add_method (objc_implementation_context,
773 decl,
774 objc_inherit_code == CLASS_METHOD_DECL);
775 start_method_def (decl);
778 void
779 objc_add_instance_variable (tree decl)
781 (void) add_instance_variable (objc_ivar_context,
782 objc_public_flag,
783 decl);
786 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
787 an '@'. */
790 objc_is_reserved_word (tree ident)
792 unsigned char code = C_RID_CODE (ident);
794 return (OBJC_IS_AT_KEYWORD (code)
795 || code == RID_CLASS || code == RID_PUBLIC
796 || code == RID_PROTECTED || code == RID_PRIVATE
797 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
800 /* Return true if TYPE is 'id'. */
802 static bool
803 objc_is_object_id (tree type)
805 return OBJC_TYPE_NAME (type) == objc_object_id;
808 static bool
809 objc_is_class_id (tree type)
811 return OBJC_TYPE_NAME (type) == objc_class_id;
814 /* Construct a C struct with same name as KLASS, a base struct with tag
815 SUPER_NAME (if any), and FIELDS indicated. */
817 static tree
818 objc_build_struct (tree klass, tree fields, tree super_name)
820 tree name = CLASS_NAME (klass);
821 tree s = objc_start_struct (name);
822 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
823 tree t, objc_info = NULL_TREE;
825 if (super)
827 /* Prepend a packed variant of the base class into the layout. This
828 is necessary to preserve ObjC ABI compatibility. */
829 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
830 tree field = TYPE_FIELDS (super);
832 while (field && TREE_CHAIN (field)
833 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
834 field = TREE_CHAIN (field);
836 /* For ObjC ABI purposes, the "packed" size of a base class is
837 the sum of the offset and the size (in bits) of the last field
838 in the class. */
839 DECL_SIZE (base)
840 = (field && TREE_CODE (field) == FIELD_DECL
841 ? size_binop (PLUS_EXPR,
842 size_binop (PLUS_EXPR,
843 size_binop
844 (MULT_EXPR,
845 convert (bitsizetype,
846 DECL_FIELD_OFFSET (field)),
847 bitsize_int (BITS_PER_UNIT)),
848 DECL_FIELD_BIT_OFFSET (field)),
849 DECL_SIZE (field))
850 : bitsize_zero_node);
851 DECL_SIZE_UNIT (base)
852 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
853 size_int (BITS_PER_UNIT));
854 DECL_ARTIFICIAL (base) = 1;
855 DECL_ALIGN (base) = 1;
856 DECL_FIELD_CONTEXT (base) = s;
857 #ifdef OBJCPLUS
858 DECL_FIELD_IS_BASE (base) = 1;
860 if (fields)
861 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
862 #endif /* are following the ObjC ABI here. */
863 TREE_CHAIN (base) = fields;
864 fields = base;
867 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
868 in all variants of this RECORD_TYPE to be clobbered, but it is therein
869 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
870 Hence, we must squirrel away the ObjC-specific information before calling
871 finish_struct(), and then reinstate it afterwards. */
873 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
874 objc_info
875 = chainon (objc_info,
876 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
878 /* Point the struct at its related Objective-C class. */
879 INIT_TYPE_OBJC_INFO (s);
880 TYPE_OBJC_INTERFACE (s) = klass;
882 s = objc_finish_struct (s, fields);
884 for (t = TYPE_NEXT_VARIANT (s); t;
885 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
887 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
888 /* Replace the IDENTIFIER_NODE with an actual @interface. */
889 TYPE_OBJC_INTERFACE (t) = klass;
892 /* Use TYPE_BINFO structures to point at the super class, if any. */
893 objc_xref_basetypes (s, super);
895 /* Mark this struct as a class template. */
896 CLASS_STATIC_TEMPLATE (klass) = s;
898 return s;
901 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
902 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
903 process. */
904 static tree
905 objc_build_volatilized_type (tree type)
907 tree t;
909 /* Check if we have not constructed the desired variant already. */
910 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
912 /* The type qualifiers must (obviously) match up. */
913 if (!TYPE_VOLATILE (t)
914 || (TYPE_READONLY (t) != TYPE_READONLY (type))
915 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
916 continue;
918 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
919 info, if any) must match up. */
920 if (POINTER_TYPE_P (t)
921 && (TREE_TYPE (t) != TREE_TYPE (type)))
922 continue;
924 /* Everything matches up! */
925 return t;
928 /* Ok, we could not re-use any of the pre-existing variants. Create
929 a new one. */
930 t = build_variant_type_copy (type);
931 TYPE_VOLATILE (t) = 1;
933 /* Set up the canonical type information. */
934 if (TYPE_STRUCTURAL_EQUALITY_P (type))
935 SET_TYPE_STRUCTURAL_EQUALITY (t);
936 else if (TYPE_CANONICAL (type) != type)
937 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
938 else
939 TYPE_CANONICAL (t) = t;
941 return t;
944 /* Mark DECL as being 'volatile' for purposes of Darwin
945 _setjmp()/_longjmp() exception handling. Called from
946 objc_mark_locals_volatile(). */
947 void
948 objc_volatilize_decl (tree decl)
950 /* Do not mess with variables that are 'static' or (already)
951 'volatile'. */
952 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
953 && (TREE_CODE (decl) == VAR_DECL
954 || TREE_CODE (decl) == PARM_DECL))
956 tree t = TREE_TYPE (decl);
957 struct volatilized_type key;
958 void **loc;
960 t = objc_build_volatilized_type (t);
961 key.type = t;
962 loc = htab_find_slot (volatilized_htab, &key, INSERT);
964 if (!*loc)
966 *loc = ggc_alloc (sizeof (key));
967 ((struct volatilized_type *) *loc)->type = t;
970 TREE_TYPE (decl) = t;
971 TREE_THIS_VOLATILE (decl) = 1;
972 TREE_SIDE_EFFECTS (decl) = 1;
973 DECL_REGISTER (decl) = 0;
974 #ifndef OBJCPLUS
975 C_DECL_REGISTER (decl) = 0;
976 #endif
980 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
981 (including its categories and superclasses) or by object type TYP.
982 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
984 static bool
985 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
987 bool class_type = (cls != NULL_TREE);
989 while (cls)
991 tree c;
993 /* Check protocols adopted by the class and its categories. */
994 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
996 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
997 return true;
1000 /* Repeat for superclasses. */
1001 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1004 /* Check for any protocols attached directly to the object type. */
1005 if (TYPE_HAS_OBJC_INFO (typ))
1007 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1008 return true;
1011 if (warn)
1013 *errbuf = 0;
1014 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1015 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1016 "implementing" a given protocol, since they do not have an
1017 implementation. */
1018 if (class_type)
1019 warning (0, "class %qs does not implement the %qE protocol",
1020 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1021 else
1022 warning (0, "type %qs does not conform to the %qE protocol",
1023 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1026 return false;
1029 /* Check if class RCLS and instance struct type RTYP conform to at least the
1030 same protocols that LCLS and LTYP conform to. */
1032 static bool
1033 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1035 tree p;
1036 bool have_lproto = false;
1038 while (lcls)
1040 /* NB: We do _not_ look at categories defined for LCLS; these may or
1041 may not get loaded in, and therefore it is unreasonable to require
1042 that RCLS/RTYP must implement any of their protocols. */
1043 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1045 have_lproto = true;
1047 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1048 return warn;
1051 /* Repeat for superclasses. */
1052 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1055 /* Check for any protocols attached directly to the object type. */
1056 if (TYPE_HAS_OBJC_INFO (ltyp))
1058 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1060 have_lproto = true;
1062 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1063 return warn;
1067 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1068 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1069 away with simply checking for 'id' or 'Class' (!RCLS), since this
1070 routine will not get called in other cases. */
1071 return have_lproto || (rcls != NULL_TREE);
1074 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1075 an instance of RTYP to an instance of LTYP or to compare the two
1076 (if ARGNO is equal to -3), per ObjC type system rules. Before
1077 returning 'true', this routine may issue warnings related to, e.g.,
1078 protocol conformance. When returning 'false', the routine must
1079 produce absolutely no warnings; the C or C++ front-end will do so
1080 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1081 the routine must return 'false'.
1083 The ARGNO parameter is encoded as follows:
1084 >= 1 Parameter number (CALLEE contains function being called);
1085 0 Return value;
1086 -1 Assignment;
1087 -2 Initialization;
1088 -3 Comparison (LTYP and RTYP may match in either direction). */
1090 bool
1091 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1093 tree lcls, rcls, lproto, rproto;
1094 bool pointers_compatible;
1096 /* We must be dealing with pointer types */
1097 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1098 return false;
1102 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1103 rtyp = TREE_TYPE (rtyp);
1105 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1107 /* Past this point, we are only interested in ObjC class instances,
1108 or 'id' or 'Class'. */
1109 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1110 return false;
1112 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1113 && !TYPE_HAS_OBJC_INFO (ltyp))
1114 return false;
1116 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1117 && !TYPE_HAS_OBJC_INFO (rtyp))
1118 return false;
1120 /* Past this point, we are committed to returning 'true' to the caller.
1121 However, we can still warn about type and/or protocol mismatches. */
1123 if (TYPE_HAS_OBJC_INFO (ltyp))
1125 lcls = TYPE_OBJC_INTERFACE (ltyp);
1126 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1128 else
1129 lcls = lproto = NULL_TREE;
1131 if (TYPE_HAS_OBJC_INFO (rtyp))
1133 rcls = TYPE_OBJC_INTERFACE (rtyp);
1134 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1136 else
1137 rcls = rproto = NULL_TREE;
1139 /* If we could not find an @interface declaration, we must have
1140 only seen a @class declaration; for purposes of type comparison,
1141 treat it as a stand-alone (root) class. */
1143 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1144 lcls = NULL_TREE;
1146 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1147 rcls = NULL_TREE;
1149 /* If either type is an unqualified 'id', we're done. */
1150 if ((!lproto && objc_is_object_id (ltyp))
1151 || (!rproto && objc_is_object_id (rtyp)))
1152 return true;
1154 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1156 /* If the underlying types are the same, and at most one of them has
1157 a protocol list, we do not need to issue any diagnostics. */
1158 if (pointers_compatible && (!lproto || !rproto))
1159 return true;
1161 /* If exactly one of the types is 'Class', issue a diagnostic; any
1162 exceptions of this rule have already been handled. */
1163 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1164 pointers_compatible = false;
1165 /* Otherwise, check for inheritance relations. */
1166 else
1168 if (!pointers_compatible)
1169 pointers_compatible
1170 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1172 if (!pointers_compatible)
1173 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1175 if (!pointers_compatible && argno == -3)
1176 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1179 /* If the pointers match modulo protocols, check for protocol conformance
1180 mismatches. */
1181 if (pointers_compatible)
1183 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1184 argno != -3);
1186 if (!pointers_compatible && argno == -3)
1187 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1188 argno != -3);
1191 if (!pointers_compatible)
1193 /* NB: For the time being, we shall make our warnings look like their
1194 C counterparts. In the future, we may wish to make them more
1195 ObjC-specific. */
1196 switch (argno)
1198 case -3:
1199 warning (0, "comparison of distinct Objective-C types lacks a cast");
1200 break;
1202 case -2:
1203 warning (0, "initialization from distinct Objective-C type");
1204 break;
1206 case -1:
1207 warning (0, "assignment from distinct Objective-C type");
1208 break;
1210 case 0:
1211 warning (0, "distinct Objective-C type in return");
1212 break;
1214 default:
1215 warning (0, "passing argument %d of %qE from distinct "
1216 "Objective-C type", argno, callee);
1217 break;
1221 return true;
1224 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1225 lives in the volatilized hash table, ignore the 'volatile' bit when
1226 making the comparison. */
1228 bool
1229 objc_type_quals_match (tree ltyp, tree rtyp)
1231 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1232 struct volatilized_type key;
1234 key.type = ltyp;
1236 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1237 lquals &= ~TYPE_QUAL_VOLATILE;
1239 key.type = rtyp;
1241 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1242 rquals &= ~TYPE_QUAL_VOLATILE;
1244 return (lquals == rquals);
1247 #ifndef OBJCPLUS
1248 /* Determine if CHILD is derived from PARENT. The routine assumes that
1249 both parameters are RECORD_TYPEs, and is non-reflexive. */
1251 static bool
1252 objc_derived_from_p (tree parent, tree child)
1254 parent = TYPE_MAIN_VARIANT (parent);
1256 for (child = TYPE_MAIN_VARIANT (child);
1257 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1259 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1260 (TYPE_BINFO (child),
1261 0)));
1263 if (child == parent)
1264 return true;
1267 return false;
1269 #endif
1271 static tree
1272 objc_build_component_ref (tree datum, tree component)
1274 /* If COMPONENT is NULL, the caller is referring to the anonymous
1275 base class field. */
1276 if (!component)
1278 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1280 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1283 /* The 'build_component_ref' routine has been removed from the C++
1284 front-end, but 'finish_class_member_access_expr' seems to be
1285 a worthy substitute. */
1286 #ifdef OBJCPLUS
1287 return finish_class_member_access_expr (datum, component, false,
1288 tf_warning_or_error);
1289 #else
1290 return build_component_ref (datum, component);
1291 #endif
1294 /* Recursively copy inheritance information rooted at BINFO. To do this,
1295 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1297 static tree
1298 objc_copy_binfo (tree binfo)
1300 tree btype = BINFO_TYPE (binfo);
1301 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1302 tree base_binfo;
1303 int ix;
1305 BINFO_TYPE (binfo2) = btype;
1306 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1307 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1309 /* Recursively copy base binfos of BINFO. */
1310 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1312 tree base_binfo2 = objc_copy_binfo (base_binfo);
1314 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1315 BINFO_BASE_APPEND (binfo2, base_binfo2);
1318 return binfo2;
1321 /* Record superclass information provided in BASETYPE for ObjC class REF.
1322 This is loosely based on cp/decl.c:xref_basetypes(). */
1324 static void
1325 objc_xref_basetypes (tree ref, tree basetype)
1327 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1329 TYPE_BINFO (ref) = binfo;
1330 BINFO_OFFSET (binfo) = size_zero_node;
1331 BINFO_TYPE (binfo) = ref;
1333 if (basetype)
1335 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1337 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1338 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1339 BINFO_BASE_APPEND (binfo, base_binfo);
1340 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1344 static hashval_t
1345 volatilized_hash (const void *ptr)
1347 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1349 return htab_hash_pointer(typ);
1352 static int
1353 volatilized_eq (const void *ptr1, const void *ptr2)
1355 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1356 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1358 return typ1 == typ2;
1361 /* Called from finish_decl. */
1363 void
1364 objc_check_decl (tree decl)
1366 tree type = TREE_TYPE (decl);
1368 if (TREE_CODE (type) != RECORD_TYPE)
1369 return;
1370 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1371 error ("statically allocated instance of Objective-C class %qE",
1372 type);
1375 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1376 either name an Objective-C class, or refer to the special 'id' or 'Class'
1377 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1379 tree
1380 objc_get_protocol_qualified_type (tree interface, tree protocols)
1382 /* If INTERFACE is not provided, default to 'id'. */
1383 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1384 bool is_ptr = (type != NULL_TREE);
1386 if (!is_ptr)
1388 type = objc_is_class_name (interface);
1390 if (type)
1391 type = xref_tag (RECORD_TYPE, type);
1392 else
1393 return interface;
1396 if (protocols)
1398 type = build_variant_type_copy (type);
1400 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1401 to the pointee. */
1402 if (is_ptr)
1404 tree orig_pointee_type = TREE_TYPE (type);
1405 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1407 /* Set up the canonical type information. */
1408 TYPE_CANONICAL (type)
1409 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1411 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1412 type = TREE_TYPE (type);
1415 /* Look up protocols and install in lang specific list. */
1416 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1417 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1419 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1420 return the pointer to the new pointee variant. */
1421 if (is_ptr)
1422 type = TYPE_POINTER_TO (type);
1423 else
1424 TYPE_OBJC_INTERFACE (type)
1425 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1428 return type;
1431 /* Check for circular dependencies in protocols. The arguments are
1432 PROTO, the protocol to check, and LIST, a list of protocol it
1433 conforms to. */
1435 static void
1436 check_protocol_recursively (tree proto, tree list)
1438 tree p;
1440 for (p = list; p; p = TREE_CHAIN (p))
1442 tree pp = TREE_VALUE (p);
1444 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1445 pp = lookup_protocol (pp);
1447 if (pp == proto)
1448 fatal_error ("protocol %qE has circular dependency",
1449 PROTOCOL_NAME (pp));
1450 if (pp)
1451 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1455 /* Look up PROTOCOLS, and return a list of those that are found.
1456 If none are found, return NULL. */
1458 static tree
1459 lookup_and_install_protocols (tree protocols)
1461 tree proto;
1462 tree return_value = NULL_TREE;
1464 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1466 tree ident = TREE_VALUE (proto);
1467 tree p = lookup_protocol (ident);
1469 if (p)
1470 return_value = chainon (return_value,
1471 build_tree_list (NULL_TREE, p));
1472 else if (ident != error_mark_node)
1473 error ("cannot find protocol declaration for %qE",
1474 ident);
1477 return return_value;
1480 /* Create a declaration for field NAME of a given TYPE. */
1482 static tree
1483 create_field_decl (tree type, const char *name)
1485 return build_decl (FIELD_DECL, get_identifier (name), type);
1488 /* Create a global, static declaration for variable NAME of a given TYPE. The
1489 finish_var_decl() routine will need to be called on it afterwards. */
1491 static tree
1492 start_var_decl (tree type, const char *name)
1494 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1496 TREE_STATIC (var) = 1;
1497 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1498 DECL_IGNORED_P (var) = 1;
1499 DECL_ARTIFICIAL (var) = 1;
1500 DECL_CONTEXT (var) = NULL_TREE;
1501 #ifdef OBJCPLUS
1502 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1503 #endif
1505 return var;
1508 /* Finish off the variable declaration created by start_var_decl(). */
1510 static void
1511 finish_var_decl (tree var, tree initializer)
1513 finish_decl (var, initializer, NULL_TREE, NULL_TREE);
1514 /* Ensure that the variable actually gets output. */
1515 mark_decl_referenced (var);
1516 /* Mark the decl to avoid "defined but not used" warning. */
1517 TREE_USED (var) = 1;
1520 /* Find the decl for the constant string class reference. This is only
1521 used for the NeXT runtime. */
1523 static tree
1524 setup_string_decl (void)
1526 char *name;
1527 size_t length;
1529 /* %s in format will provide room for terminating null */
1530 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1531 + strlen (constant_string_class_name);
1532 name = XNEWVEC (char, length);
1533 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1534 constant_string_class_name);
1535 constant_string_global_id = get_identifier (name);
1536 string_class_decl = lookup_name (constant_string_global_id);
1538 return string_class_decl;
1541 /* Purpose: "play" parser, creating/installing representations
1542 of the declarations that are required by Objective-C.
1544 Model:
1546 type_spec--------->sc_spec
1547 (tree_list) (tree_list)
1550 identifier_node identifier_node */
1552 static void
1553 synth_module_prologue (void)
1555 tree type;
1556 enum debug_info_type save_write_symbols = write_symbols;
1557 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1559 /* Suppress outputting debug symbols, because
1560 dbxout_init hasn't been called yet. */
1561 write_symbols = NO_DEBUG;
1562 debug_hooks = &do_nothing_debug_hooks;
1564 #ifdef OBJCPLUS
1565 push_lang_context (lang_name_c); /* extern "C" */
1566 #endif
1568 /* The following are also defined in <objc/objc.h> and friends. */
1570 objc_object_id = get_identifier (TAG_OBJECT);
1571 objc_class_id = get_identifier (TAG_CLASS);
1573 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1574 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1576 objc_object_type = build_pointer_type (objc_object_reference);
1577 objc_class_type = build_pointer_type (objc_class_reference);
1579 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1580 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1582 /* Declare the 'id' and 'Class' typedefs. */
1584 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1585 objc_object_name,
1586 objc_object_type));
1587 TREE_NO_WARNING (type) = 1;
1588 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1589 objc_class_name,
1590 objc_class_type));
1591 TREE_NO_WARNING (type) = 1;
1593 /* Forward-declare '@interface Protocol'. */
1595 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1596 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1597 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1598 type));
1600 /* Declare type of selector-objects that represent an operation name. */
1602 if (flag_next_runtime)
1603 /* `struct objc_selector *' */
1604 objc_selector_type
1605 = build_pointer_type (xref_tag (RECORD_TYPE,
1606 get_identifier (TAG_SELECTOR)));
1607 else
1608 /* `const struct objc_selector *' */
1609 objc_selector_type
1610 = build_pointer_type
1611 (build_qualified_type (xref_tag (RECORD_TYPE,
1612 get_identifier (TAG_SELECTOR)),
1613 TYPE_QUAL_CONST));
1615 /* Declare receiver type used for dispatching messages to 'super'. */
1617 /* `struct objc_super *' */
1618 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1619 get_identifier (TAG_SUPER)));
1621 /* Declare pointers to method and ivar lists. */
1622 objc_method_list_ptr = build_pointer_type
1623 (xref_tag (RECORD_TYPE,
1624 get_identifier (UTAG_METHOD_LIST)));
1625 objc_method_proto_list_ptr
1626 = build_pointer_type (xref_tag (RECORD_TYPE,
1627 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1628 objc_ivar_list_ptr = build_pointer_type
1629 (xref_tag (RECORD_TYPE,
1630 get_identifier (UTAG_IVAR_LIST)));
1632 /* TREE_NOTHROW is cleared for the message-sending functions,
1633 because the function that gets called can throw in Obj-C++, or
1634 could itself call something that can throw even in Obj-C. */
1636 if (flag_next_runtime)
1638 /* NB: In order to call one of the ..._stret (struct-returning)
1639 functions, the function *MUST* first be cast to a signature that
1640 corresponds to the actual ObjC method being invoked. This is
1641 what is done by the build_objc_method_call() routine below. */
1643 /* id objc_msgSend (id, SEL, ...); */
1644 /* id objc_msgSendNonNil (id, SEL, ...); */
1645 /* id objc_msgSend_stret (id, SEL, ...); */
1646 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1647 type
1648 = build_function_type (objc_object_type,
1649 tree_cons (NULL_TREE, objc_object_type,
1650 tree_cons (NULL_TREE, objc_selector_type,
1651 NULL_TREE)));
1652 umsg_decl = add_builtin_function (TAG_MSGSEND,
1653 type, 0, NOT_BUILT_IN,
1654 NULL, NULL_TREE);
1655 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1656 type, 0, NOT_BUILT_IN,
1657 NULL, NULL_TREE);
1658 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1659 type, 0, NOT_BUILT_IN,
1660 NULL, NULL_TREE);
1661 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1662 type, 0, NOT_BUILT_IN,
1663 NULL, NULL_TREE);
1665 /* These can throw, because the function that gets called can throw
1666 in Obj-C++, or could itself call something that can throw even
1667 in Obj-C. */
1668 TREE_NOTHROW (umsg_decl) = 0;
1669 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1670 TREE_NOTHROW (umsg_stret_decl) = 0;
1671 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1673 /* id objc_msgSend_Fast (id, SEL, ...)
1674 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1675 #ifdef OFFS_MSGSEND_FAST
1676 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1677 type, 0, NOT_BUILT_IN,
1678 NULL, NULL_TREE);
1679 TREE_NOTHROW (umsg_fast_decl) = 0;
1680 DECL_ATTRIBUTES (umsg_fast_decl)
1681 = tree_cons (get_identifier ("hard_coded_address"),
1682 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1683 NULL_TREE);
1684 #else
1685 /* No direct dispatch available. */
1686 umsg_fast_decl = umsg_decl;
1687 #endif
1689 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1690 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1691 type
1692 = build_function_type (objc_object_type,
1693 tree_cons (NULL_TREE, objc_super_type,
1694 tree_cons (NULL_TREE, objc_selector_type,
1695 NULL_TREE)));
1696 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1697 type, 0, NOT_BUILT_IN,
1698 NULL, NULL_TREE);
1699 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1700 type, 0, NOT_BUILT_IN, 0,
1701 NULL_TREE);
1702 TREE_NOTHROW (umsg_super_decl) = 0;
1703 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1705 else
1707 /* GNU runtime messenger entry points. */
1709 /* typedef id (*IMP)(id, SEL, ...); */
1710 tree IMP_type
1711 = build_pointer_type
1712 (build_function_type (objc_object_type,
1713 tree_cons (NULL_TREE, objc_object_type,
1714 tree_cons (NULL_TREE, objc_selector_type,
1715 NULL_TREE))));
1717 /* IMP objc_msg_lookup (id, SEL); */
1718 type
1719 = build_function_type (IMP_type,
1720 tree_cons (NULL_TREE, objc_object_type,
1721 tree_cons (NULL_TREE, objc_selector_type,
1722 OBJC_VOID_AT_END)));
1723 umsg_decl = add_builtin_function (TAG_MSGSEND,
1724 type, 0, NOT_BUILT_IN,
1725 NULL, NULL_TREE);
1726 TREE_NOTHROW (umsg_decl) = 0;
1728 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1729 type
1730 = build_function_type (IMP_type,
1731 tree_cons (NULL_TREE, objc_super_type,
1732 tree_cons (NULL_TREE, objc_selector_type,
1733 OBJC_VOID_AT_END)));
1734 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1735 type, 0, NOT_BUILT_IN,
1736 NULL, NULL_TREE);
1737 TREE_NOTHROW (umsg_super_decl) = 0;
1739 /* The following GNU runtime entry point is called to initialize
1740 each module:
1742 __objc_exec_class (void *); */
1743 type
1744 = build_function_type (void_type_node,
1745 tree_cons (NULL_TREE, ptr_type_node,
1746 OBJC_VOID_AT_END));
1747 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1748 type, 0, NOT_BUILT_IN,
1749 NULL, NULL_TREE);
1752 /* id objc_getClass (const char *); */
1754 type = build_function_type (objc_object_type,
1755 tree_cons (NULL_TREE,
1756 const_string_type_node,
1757 OBJC_VOID_AT_END));
1759 objc_get_class_decl
1760 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1761 NULL, NULL_TREE);
1763 /* id objc_getMetaClass (const char *); */
1765 objc_get_meta_class_decl
1766 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1768 build_class_template ();
1769 build_super_template ();
1770 build_protocol_template ();
1771 build_category_template ();
1772 build_objc_exception_stuff ();
1774 if (flag_next_runtime)
1775 build_next_objc_exception_stuff ();
1777 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1779 if (! flag_next_runtime)
1780 build_selector_table_decl ();
1782 /* Forward declare constant_string_id and constant_string_type. */
1783 if (!constant_string_class_name)
1784 constant_string_class_name = default_constant_string_class_name;
1786 constant_string_id = get_identifier (constant_string_class_name);
1787 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1789 /* Pre-build the following entities - for speed/convenience. */
1790 self_id = get_identifier ("self");
1791 ucmd_id = get_identifier ("_cmd");
1793 #ifdef OBJCPLUS
1794 pop_lang_context ();
1795 #endif
1797 write_symbols = save_write_symbols;
1798 debug_hooks = save_hooks;
1801 /* Ensure that the ivar list for NSConstantString/NXConstantString
1802 (or whatever was specified via `-fconstant-string-class')
1803 contains fields at least as large as the following three, so that
1804 the runtime can stomp on them with confidence:
1806 struct STRING_OBJECT_CLASS_NAME
1808 Object isa;
1809 char *cString;
1810 unsigned int length;
1811 }; */
1813 static int
1814 check_string_class_template (void)
1816 tree field_decl = objc_get_class_ivars (constant_string_id);
1818 #define AT_LEAST_AS_LARGE_AS(F, T) \
1819 (F && TREE_CODE (F) == FIELD_DECL \
1820 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1821 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1823 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1824 return 0;
1826 field_decl = TREE_CHAIN (field_decl);
1827 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1828 return 0;
1830 field_decl = TREE_CHAIN (field_decl);
1831 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1833 #undef AT_LEAST_AS_LARGE_AS
1836 /* Avoid calling `check_string_class_template ()' more than once. */
1837 static GTY(()) int string_layout_checked;
1839 /* Construct an internal string layout to be used as a template for
1840 creating NSConstantString/NXConstantString instances. */
1842 static tree
1843 objc_build_internal_const_str_type (void)
1845 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1846 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1847 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1849 TREE_CHAIN (field) = fields; fields = field;
1850 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1851 TREE_CHAIN (field) = fields; fields = field;
1852 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1853 reverse order! */
1854 finish_builtin_struct (type, "__builtin_ObjCString",
1855 fields, NULL_TREE);
1857 return type;
1860 /* Custom build_string which sets TREE_TYPE! */
1862 static tree
1863 my_build_string (int len, const char *str)
1865 return fix_string_type (build_string (len, str));
1868 /* Build a string with contents STR and length LEN and convert it to a
1869 pointer. */
1871 static tree
1872 my_build_string_pointer (int len, const char *str)
1874 tree string = my_build_string (len, str);
1875 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1876 return build1 (ADDR_EXPR, ptrtype, string);
1879 static hashval_t
1880 string_hash (const void *ptr)
1882 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1883 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1884 int i, len = TREE_STRING_LENGTH (str);
1885 hashval_t h = len;
1887 for (i = 0; i < len; i++)
1888 h = ((h * 613) + p[i]);
1890 return h;
1893 static int
1894 string_eq (const void *ptr1, const void *ptr2)
1896 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1897 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1898 int len1 = TREE_STRING_LENGTH (str1);
1900 return (len1 == TREE_STRING_LENGTH (str2)
1901 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1902 len1));
1905 /* Given a chain of STRING_CST's, build a static instance of
1906 NXConstantString which points at the concatenation of those
1907 strings. We place the string object in the __string_objects
1908 section of the __OBJC segment. The Objective-C runtime will
1909 initialize the isa pointers of the string objects to point at the
1910 NXConstantString class object. */
1912 tree
1913 objc_build_string_object (tree string)
1915 tree initlist, constructor, constant_string_class;
1916 int length;
1917 tree fields, addr;
1918 struct string_descriptor *desc, key;
1919 void **loc;
1921 /* Prep the string argument. */
1922 string = fix_string_type (string);
1923 TREE_SET_CODE (string, STRING_CST);
1924 length = TREE_STRING_LENGTH (string) - 1;
1926 /* Check whether the string class being used actually exists and has the
1927 correct ivar layout. */
1928 if (!string_layout_checked)
1930 string_layout_checked = -1;
1931 constant_string_class = lookup_interface (constant_string_id);
1932 internal_const_str_type = objc_build_internal_const_str_type ();
1934 if (!constant_string_class
1935 || !(constant_string_type
1936 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1937 error ("cannot find interface declaration for %qE",
1938 constant_string_id);
1939 /* The NSConstantString/NXConstantString ivar layout is now known. */
1940 else if (!check_string_class_template ())
1941 error ("interface %qE does not have valid constant string layout",
1942 constant_string_id);
1943 /* For the NeXT runtime, we can generate a literal reference
1944 to the string class, don't need to run a constructor. */
1945 else if (flag_next_runtime && !setup_string_decl ())
1946 error ("cannot find reference tag for class %qE",
1947 constant_string_id);
1948 else
1950 string_layout_checked = 1; /* Success! */
1951 add_class_reference (constant_string_id);
1955 if (string_layout_checked == -1)
1956 return error_mark_node;
1958 /* Perhaps we already constructed a constant string just like this one? */
1959 key.literal = string;
1960 loc = htab_find_slot (string_htab, &key, INSERT);
1961 desc = (struct string_descriptor *) *loc;
1963 if (!desc)
1965 tree var;
1966 *loc = desc = GGC_NEW (struct string_descriptor);
1967 desc->literal = string;
1969 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1970 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1971 fields = TYPE_FIELDS (internal_const_str_type);
1972 initlist
1973 = build_tree_list (fields,
1974 flag_next_runtime
1975 ? build_unary_op (input_location,
1976 ADDR_EXPR, string_class_decl, 0)
1977 : build_int_cst (NULL_TREE, 0));
1978 fields = TREE_CHAIN (fields);
1979 initlist = tree_cons (fields, build_unary_op (input_location,
1980 ADDR_EXPR, string, 1),
1981 initlist);
1982 fields = TREE_CHAIN (fields);
1983 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1984 initlist);
1985 constructor = objc_build_constructor (internal_const_str_type,
1986 nreverse (initlist));
1988 if (!flag_next_runtime)
1989 constructor
1990 = objc_add_static_instance (constructor, constant_string_type);
1991 else
1993 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1994 DECL_INITIAL (var) = constructor;
1995 TREE_STATIC (var) = 1;
1996 pushdecl_top_level (var);
1997 constructor = var;
1999 desc->constructor = constructor;
2002 addr = convert (build_pointer_type (constant_string_type),
2003 build_unary_op (input_location,
2004 ADDR_EXPR, desc->constructor, 1));
2006 return addr;
2009 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2011 static GTY(()) int num_static_inst;
2013 static tree
2014 objc_add_static_instance (tree constructor, tree class_decl)
2016 tree *chain, decl;
2017 char buf[256];
2019 /* Find the list of static instances for the CLASS_DECL. Create one if
2020 not found. */
2021 for (chain = &objc_static_instances;
2022 *chain && TREE_VALUE (*chain) != class_decl;
2023 chain = &TREE_CHAIN (*chain));
2024 if (!*chain)
2026 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2027 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2030 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2031 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
2032 DECL_COMMON (decl) = 1;
2033 TREE_STATIC (decl) = 1;
2034 DECL_ARTIFICIAL (decl) = 1;
2035 TREE_USED (decl) = 1;
2036 DECL_INITIAL (decl) = constructor;
2038 /* We may be writing something else just now.
2039 Postpone till end of input. */
2040 DECL_DEFER_OUTPUT (decl) = 1;
2041 pushdecl_top_level (decl);
2042 rest_of_decl_compilation (decl, 1, 0);
2044 /* Add the DECL to the head of this CLASS' list. */
2045 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2047 return decl;
2050 /* Build a static constant CONSTRUCTOR
2051 with type TYPE and elements ELTS. */
2053 static tree
2054 objc_build_constructor (tree type, tree elts)
2056 tree constructor = build_constructor_from_list (type, elts);
2058 TREE_CONSTANT (constructor) = 1;
2059 TREE_STATIC (constructor) = 1;
2060 TREE_READONLY (constructor) = 1;
2062 #ifdef OBJCPLUS
2063 /* Adjust for impedance mismatch. We should figure out how to build
2064 CONSTRUCTORs that consistently please both the C and C++ gods. */
2065 if (!TREE_PURPOSE (elts))
2066 TREE_TYPE (constructor) = init_list_type_node;
2067 #endif
2069 return constructor;
2072 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2074 /* Predefine the following data type:
2076 struct _objc_symtab
2078 long sel_ref_cnt;
2079 SEL *refs;
2080 short cls_def_cnt;
2081 short cat_def_cnt;
2082 void *defs[cls_def_cnt + cat_def_cnt];
2083 }; */
2085 static void
2086 build_objc_symtab_template (void)
2088 tree field_decl, field_decl_chain;
2090 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2092 /* long sel_ref_cnt; */
2093 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2094 field_decl_chain = field_decl;
2096 /* SEL *refs; */
2097 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2098 "refs");
2099 chainon (field_decl_chain, field_decl);
2101 /* short cls_def_cnt; */
2102 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2103 chainon (field_decl_chain, field_decl);
2105 /* short cat_def_cnt; */
2106 field_decl = create_field_decl (short_integer_type_node,
2107 "cat_def_cnt");
2108 chainon (field_decl_chain, field_decl);
2110 if (imp_count || cat_count || !flag_next_runtime)
2112 /* void *defs[imp_count + cat_count (+ 1)]; */
2113 /* NB: The index is one less than the size of the array. */
2114 int index = imp_count + cat_count
2115 + (flag_next_runtime? -1: 0);
2116 field_decl = create_field_decl
2117 (build_array_type
2118 (ptr_type_node,
2119 build_index_type (build_int_cst (NULL_TREE, index))),
2120 "defs");
2121 chainon (field_decl_chain, field_decl);
2124 objc_finish_struct (objc_symtab_template, field_decl_chain);
2127 /* Create the initial value for the `defs' field of _objc_symtab.
2128 This is a CONSTRUCTOR. */
2130 static tree
2131 init_def_list (tree type)
2133 tree expr, initlist = NULL_TREE;
2134 struct imp_entry *impent;
2136 if (imp_count)
2137 for (impent = imp_list; impent; impent = impent->next)
2139 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2141 expr = build_unary_op (input_location,
2142 ADDR_EXPR, impent->class_decl, 0);
2143 initlist = tree_cons (NULL_TREE, expr, initlist);
2147 if (cat_count)
2148 for (impent = imp_list; impent; impent = impent->next)
2150 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2152 expr = build_unary_op (input_location,
2153 ADDR_EXPR, impent->class_decl, 0);
2154 initlist = tree_cons (NULL_TREE, expr, initlist);
2158 if (!flag_next_runtime)
2160 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2161 tree expr;
2163 if (static_instances_decl)
2164 expr = build_unary_op (input_location,
2165 ADDR_EXPR, static_instances_decl, 0);
2166 else
2167 expr = build_int_cst (NULL_TREE, 0);
2169 initlist = tree_cons (NULL_TREE, expr, initlist);
2172 return objc_build_constructor (type, nreverse (initlist));
2175 /* Construct the initial value for all of _objc_symtab. */
2177 static tree
2178 init_objc_symtab (tree type)
2180 tree initlist;
2182 /* sel_ref_cnt = { ..., 5, ... } */
2184 initlist = build_tree_list (NULL_TREE,
2185 build_int_cst (long_integer_type_node, 0));
2187 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2189 if (flag_next_runtime || ! sel_ref_chain)
2190 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2191 else
2192 initlist
2193 = tree_cons (NULL_TREE,
2194 convert (build_pointer_type (objc_selector_type),
2195 build_unary_op (input_location, ADDR_EXPR,
2196 UOBJC_SELECTOR_TABLE_decl, 1)),
2197 initlist);
2199 /* cls_def_cnt = { ..., 5, ... } */
2201 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2203 /* cat_def_cnt = { ..., 5, ... } */
2205 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2207 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2209 if (imp_count || cat_count || !flag_next_runtime)
2212 tree field = TYPE_FIELDS (type);
2213 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2215 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2216 initlist);
2219 return objc_build_constructor (type, nreverse (initlist));
2222 /* Generate forward declarations for metadata such as
2223 'OBJC_CLASS_...'. */
2225 static tree
2226 build_metadata_decl (const char *name, tree type)
2228 tree decl;
2230 /* struct TYPE NAME_<name>; */
2231 decl = start_var_decl (type, synth_id_with_class_suffix
2232 (name,
2233 objc_implementation_context));
2235 return decl;
2238 /* Push forward-declarations of all the categories so that
2239 init_def_list can use them in a CONSTRUCTOR. */
2241 static void
2242 forward_declare_categories (void)
2244 struct imp_entry *impent;
2245 tree sav = objc_implementation_context;
2247 for (impent = imp_list; impent; impent = impent->next)
2249 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2251 /* Set an invisible arg to synth_id_with_class_suffix. */
2252 objc_implementation_context = impent->imp_context;
2253 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2254 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2255 objc_category_template);
2258 objc_implementation_context = sav;
2261 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2262 and initialized appropriately. */
2264 static void
2265 generate_objc_symtab_decl (void)
2267 /* forward declare categories */
2268 if (cat_count)
2269 forward_declare_categories ();
2271 build_objc_symtab_template ();
2272 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2273 finish_var_decl (UOBJC_SYMBOLS_decl,
2274 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2277 static tree
2278 init_module_descriptor (tree type)
2280 tree initlist, expr;
2282 /* version = { 1, ... } */
2284 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2285 initlist = build_tree_list (NULL_TREE, expr);
2287 /* size = { ..., sizeof (struct _objc_module), ... } */
2289 expr = convert (long_integer_type_node,
2290 size_in_bytes (objc_module_template));
2291 initlist = tree_cons (NULL_TREE, expr, initlist);
2293 /* Don't provide any file name for security reasons. */
2294 /* name = { ..., "", ... } */
2296 expr = add_objc_string (get_identifier (""), class_names);
2297 initlist = tree_cons (NULL_TREE, expr, initlist);
2299 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2301 if (UOBJC_SYMBOLS_decl)
2302 expr = build_unary_op (input_location,
2303 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2304 else
2305 expr = build_int_cst (NULL_TREE, 0);
2306 initlist = tree_cons (NULL_TREE, expr, initlist);
2308 return objc_build_constructor (type, nreverse (initlist));
2311 /* Write out the data structures to describe Objective C classes defined.
2313 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2315 static void
2316 build_module_descriptor (void)
2318 tree field_decl, field_decl_chain;
2320 #ifdef OBJCPLUS
2321 push_lang_context (lang_name_c); /* extern "C" */
2322 #endif
2324 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2326 /* long version; */
2327 field_decl = create_field_decl (long_integer_type_node, "version");
2328 field_decl_chain = field_decl;
2330 /* long size; */
2331 field_decl = create_field_decl (long_integer_type_node, "size");
2332 chainon (field_decl_chain, field_decl);
2334 /* char *name; */
2335 field_decl = create_field_decl (string_type_node, "name");
2336 chainon (field_decl_chain, field_decl);
2338 /* struct _objc_symtab *symtab; */
2339 field_decl
2340 = create_field_decl (build_pointer_type
2341 (xref_tag (RECORD_TYPE,
2342 get_identifier (UTAG_SYMTAB))),
2343 "symtab");
2344 chainon (field_decl_chain, field_decl);
2346 objc_finish_struct (objc_module_template, field_decl_chain);
2348 /* Create an instance of "_objc_module". */
2349 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2350 finish_var_decl (UOBJC_MODULES_decl,
2351 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2353 #ifdef OBJCPLUS
2354 pop_lang_context ();
2355 #endif
2358 /* The GNU runtime requires us to provide a static initializer function
2359 for each module:
2361 static void __objc_gnu_init (void) {
2362 __objc_exec_class (&L_OBJC_MODULES);
2363 } */
2365 static void
2366 build_module_initializer_routine (void)
2368 tree body;
2370 #ifdef OBJCPLUS
2371 push_lang_context (lang_name_c); /* extern "C" */
2372 #endif
2374 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2375 objc_start_function (get_identifier (TAG_GNUINIT),
2376 build_function_type (void_type_node,
2377 OBJC_VOID_AT_END),
2378 NULL_TREE, objc_get_parm_info (0));
2380 body = c_begin_compound_stmt (true);
2381 add_stmt (build_function_call
2382 (execclass_decl,
2383 build_tree_list
2384 (NULL_TREE,
2385 build_unary_op (input_location, ADDR_EXPR,
2386 UOBJC_MODULES_decl, 0))));
2387 add_stmt (c_end_compound_stmt (body, true));
2389 TREE_PUBLIC (current_function_decl) = 0;
2391 #ifndef OBJCPLUS
2392 /* For Objective-C++, we will need to call __objc_gnu_init
2393 from objc_generate_static_init_call() below. */
2394 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2395 #endif
2397 GNU_INIT_decl = current_function_decl;
2398 finish_function ();
2400 #ifdef OBJCPLUS
2401 pop_lang_context ();
2402 #endif
2405 #ifdef OBJCPLUS
2406 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2407 to be called by the module initializer routine. */
2410 objc_static_init_needed_p (void)
2412 return (GNU_INIT_decl != NULL_TREE);
2415 /* Generate a call to the __objc_gnu_init initializer function. */
2417 tree
2418 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2420 add_stmt (build_stmt (EXPR_STMT,
2421 build_function_call (GNU_INIT_decl, NULL_TREE)));
2423 return ctors;
2425 #endif /* OBJCPLUS */
2427 /* Return the DECL of the string IDENT in the SECTION. */
2429 static tree
2430 get_objc_string_decl (tree ident, enum string_section section)
2432 tree chain;
2434 if (section == class_names)
2435 chain = class_names_chain;
2436 else if (section == meth_var_names)
2437 chain = meth_var_names_chain;
2438 else if (section == meth_var_types)
2439 chain = meth_var_types_chain;
2440 else
2441 abort ();
2443 for (; chain != 0; chain = TREE_CHAIN (chain))
2444 if (TREE_VALUE (chain) == ident)
2445 return (TREE_PURPOSE (chain));
2447 abort ();
2448 return NULL_TREE;
2451 /* Output references to all statically allocated objects. Return the DECL
2452 for the array built. */
2454 static void
2455 generate_static_references (void)
2457 tree decls = NULL_TREE, expr = NULL_TREE;
2458 tree class_name, klass, decl, initlist;
2459 tree cl_chain, in_chain, type
2460 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2461 int num_inst, num_class;
2462 char buf[256];
2464 if (flag_next_runtime)
2465 abort ();
2467 for (cl_chain = objc_static_instances, num_class = 0;
2468 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2470 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2471 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2473 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2474 decl = start_var_decl (type, buf);
2476 /* Output {class_name, ...}. */
2477 klass = TREE_VALUE (cl_chain);
2478 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2479 initlist = build_tree_list (NULL_TREE,
2480 build_unary_op (input_location,
2481 ADDR_EXPR, class_name, 1));
2483 /* Output {..., instance, ...}. */
2484 for (in_chain = TREE_PURPOSE (cl_chain);
2485 in_chain; in_chain = TREE_CHAIN (in_chain))
2487 expr = build_unary_op (input_location,
2488 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2489 initlist = tree_cons (NULL_TREE, expr, initlist);
2492 /* Output {..., NULL}. */
2493 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2495 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2496 finish_var_decl (decl, expr);
2497 decls
2498 = tree_cons (NULL_TREE, build_unary_op (input_location,
2499 ADDR_EXPR, decl, 1), decls);
2502 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2503 expr = objc_build_constructor (type, nreverse (decls));
2504 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2505 finish_var_decl (static_instances_decl, expr);
2508 static GTY(()) int selector_reference_idx;
2510 static tree
2511 build_selector_reference_decl (void)
2513 tree decl;
2514 char buf[256];
2516 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2517 decl = start_var_decl (objc_selector_type, buf);
2519 return decl;
2522 static void
2523 build_selector_table_decl (void)
2525 tree temp;
2527 if (flag_typed_selectors)
2529 build_selector_template ();
2530 temp = build_array_type (objc_selector_template, NULL_TREE);
2532 else
2533 temp = build_array_type (objc_selector_type, NULL_TREE);
2535 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2538 /* Just a handy wrapper for add_objc_string. */
2540 static tree
2541 build_selector (tree ident)
2543 return convert (objc_selector_type,
2544 add_objc_string (ident, meth_var_names));
2547 static void
2548 build_selector_translation_table (void)
2550 tree chain, initlist = NULL_TREE;
2551 int offset = 0;
2552 tree decl = NULL_TREE;
2554 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2556 tree expr;
2558 if (warn_selector && objc_implementation_context)
2560 tree method_chain;
2561 bool found = false;
2562 for (method_chain = meth_var_names_chain;
2563 method_chain;
2564 method_chain = TREE_CHAIN (method_chain))
2566 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2568 found = true;
2569 break;
2572 if (!found)
2574 location_t *loc;
2575 if (flag_next_runtime && TREE_PURPOSE (chain))
2576 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2577 else
2578 loc = &input_location;
2579 warning (0, "%Hcreating selector for nonexistent method %qE",
2580 loc, TREE_VALUE (chain));
2584 expr = build_selector (TREE_VALUE (chain));
2585 /* add one for the '\0' character */
2586 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2588 if (flag_next_runtime)
2590 decl = TREE_PURPOSE (chain);
2591 finish_var_decl (decl, expr);
2593 else
2595 if (flag_typed_selectors)
2597 tree eltlist = NULL_TREE;
2598 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2599 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2600 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2601 expr = objc_build_constructor (objc_selector_template,
2602 nreverse (eltlist));
2605 initlist = tree_cons (NULL_TREE, expr, initlist);
2609 if (! flag_next_runtime)
2611 /* Cause the selector table (previously forward-declared)
2612 to be actually output. */
2613 initlist = tree_cons (NULL_TREE,
2614 flag_typed_selectors
2615 ? objc_build_constructor
2616 (objc_selector_template,
2617 tree_cons (NULL_TREE,
2618 build_int_cst (NULL_TREE, 0),
2619 tree_cons (NULL_TREE,
2620 build_int_cst (NULL_TREE, 0),
2621 NULL_TREE)))
2622 : build_int_cst (NULL_TREE, 0), initlist);
2623 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2624 nreverse (initlist));
2625 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2629 static tree
2630 get_proto_encoding (tree proto)
2632 tree encoding;
2633 if (proto)
2635 if (! METHOD_ENCODING (proto))
2637 encoding = encode_method_prototype (proto);
2638 METHOD_ENCODING (proto) = encoding;
2640 else
2641 encoding = METHOD_ENCODING (proto);
2643 return add_objc_string (encoding, meth_var_types);
2645 else
2646 return build_int_cst (NULL_TREE, 0);
2649 /* sel_ref_chain is a list whose "value" fields will be instances of
2650 identifier_node that represent the selector. */
2652 static tree
2653 build_typed_selector_reference (tree ident, tree prototype)
2655 tree *chain = &sel_ref_chain;
2656 tree expr;
2657 int index = 0;
2659 while (*chain)
2661 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2662 goto return_at_index;
2664 index++;
2665 chain = &TREE_CHAIN (*chain);
2668 *chain = tree_cons (prototype, ident, NULL_TREE);
2670 return_at_index:
2671 expr = build_unary_op (input_location, ADDR_EXPR,
2672 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2673 build_int_cst (NULL_TREE, index),
2674 input_location),
2676 return convert (objc_selector_type, expr);
2679 static tree
2680 build_selector_reference (tree ident)
2682 tree *chain = &sel_ref_chain;
2683 tree expr;
2684 int index = 0;
2686 while (*chain)
2688 if (TREE_VALUE (*chain) == ident)
2689 return (flag_next_runtime
2690 ? TREE_PURPOSE (*chain)
2691 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2692 build_int_cst (NULL_TREE, index),
2693 input_location));
2695 index++;
2696 chain = &TREE_CHAIN (*chain);
2699 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2701 *chain = tree_cons (expr, ident, NULL_TREE);
2703 return (flag_next_runtime
2704 ? expr
2705 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2706 build_int_cst (NULL_TREE, index),
2707 input_location));
2710 static GTY(()) int class_reference_idx;
2712 static tree
2713 build_class_reference_decl (void)
2715 tree decl;
2716 char buf[256];
2718 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2719 decl = start_var_decl (objc_class_type, buf);
2721 return decl;
2724 /* Create a class reference, but don't create a variable to reference
2725 it. */
2727 static void
2728 add_class_reference (tree ident)
2730 tree chain;
2732 if ((chain = cls_ref_chain))
2734 tree tail;
2737 if (ident == TREE_VALUE (chain))
2738 return;
2740 tail = chain;
2741 chain = TREE_CHAIN (chain);
2743 while (chain);
2745 /* Append to the end of the list */
2746 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2748 else
2749 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2752 /* Get a class reference, creating it if necessary. Also create the
2753 reference variable. */
2755 tree
2756 objc_get_class_reference (tree ident)
2758 tree orig_ident = (DECL_P (ident)
2759 ? DECL_NAME (ident)
2760 : TYPE_P (ident)
2761 ? OBJC_TYPE_NAME (ident)
2762 : ident);
2763 bool local_scope = false;
2765 #ifdef OBJCPLUS
2766 if (processing_template_decl)
2767 /* Must wait until template instantiation time. */
2768 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2769 #endif
2771 if (TREE_CODE (ident) == TYPE_DECL)
2772 ident = (DECL_ORIGINAL_TYPE (ident)
2773 ? DECL_ORIGINAL_TYPE (ident)
2774 : TREE_TYPE (ident));
2776 #ifdef OBJCPLUS
2777 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2778 && TYPE_CONTEXT (ident) != global_namespace)
2779 local_scope = true;
2780 #endif
2782 if (local_scope || !(ident = objc_is_class_name (ident)))
2784 error ("%qE is not an Objective-C class name or alias",
2785 orig_ident);
2786 return error_mark_node;
2789 if (flag_next_runtime && !flag_zero_link)
2791 tree *chain;
2792 tree decl;
2794 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2795 if (TREE_VALUE (*chain) == ident)
2797 if (! TREE_PURPOSE (*chain))
2798 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2800 return TREE_PURPOSE (*chain);
2803 decl = build_class_reference_decl ();
2804 *chain = tree_cons (decl, ident, NULL_TREE);
2805 return decl;
2807 else
2809 tree params;
2811 add_class_reference (ident);
2813 params = build_tree_list (NULL_TREE,
2814 my_build_string_pointer
2815 (IDENTIFIER_LENGTH (ident) + 1,
2816 IDENTIFIER_POINTER (ident)));
2818 assemble_external (objc_get_class_decl);
2819 return build_function_call (objc_get_class_decl, params);
2823 /* For each string section we have a chain which maps identifier nodes
2824 to decls for the strings. */
2826 static tree
2827 add_objc_string (tree ident, enum string_section section)
2829 tree *chain, decl, type, string_expr;
2831 if (section == class_names)
2832 chain = &class_names_chain;
2833 else if (section == meth_var_names)
2834 chain = &meth_var_names_chain;
2835 else if (section == meth_var_types)
2836 chain = &meth_var_types_chain;
2837 else
2838 abort ();
2840 while (*chain)
2842 if (TREE_VALUE (*chain) == ident)
2843 return convert (string_type_node,
2844 build_unary_op (input_location,
2845 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2847 chain = &TREE_CHAIN (*chain);
2850 decl = build_objc_string_decl (section);
2852 type = build_array_type
2853 (char_type_node,
2854 build_index_type
2855 (build_int_cst (NULL_TREE,
2856 IDENTIFIER_LENGTH (ident))));
2857 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2858 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2859 IDENTIFIER_POINTER (ident));
2860 finish_var_decl (decl, string_expr);
2862 *chain = tree_cons (decl, ident, NULL_TREE);
2864 return convert (string_type_node, build_unary_op (input_location,
2865 ADDR_EXPR, decl, 1));
2868 static GTY(()) int class_names_idx;
2869 static GTY(()) int meth_var_names_idx;
2870 static GTY(()) int meth_var_types_idx;
2872 static tree
2873 build_objc_string_decl (enum string_section section)
2875 tree decl, ident;
2876 char buf[256];
2878 if (section == class_names)
2879 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2880 else if (section == meth_var_names)
2881 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2882 else if (section == meth_var_types)
2883 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2885 ident = get_identifier (buf);
2887 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2888 DECL_EXTERNAL (decl) = 1;
2889 TREE_PUBLIC (decl) = 0;
2890 TREE_USED (decl) = 1;
2891 TREE_CONSTANT (decl) = 1;
2892 DECL_CONTEXT (decl) = 0;
2893 DECL_ARTIFICIAL (decl) = 1;
2894 #ifdef OBJCPLUS
2895 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2896 #endif
2898 make_decl_rtl (decl);
2899 pushdecl_top_level (decl);
2901 return decl;
2905 void
2906 objc_declare_alias (tree alias_ident, tree class_ident)
2908 tree underlying_class;
2910 #ifdef OBJCPLUS
2911 if (current_namespace != global_namespace) {
2912 error ("Objective-C declarations may only appear in global scope");
2914 #endif /* OBJCPLUS */
2916 if (!(underlying_class = objc_is_class_name (class_ident)))
2917 warning (0, "cannot find class %qE", class_ident);
2918 else if (objc_is_class_name (alias_ident))
2919 warning (0, "class %qE already exists", alias_ident);
2920 else
2922 /* Implement @compatibility_alias as a typedef. */
2923 #ifdef OBJCPLUS
2924 push_lang_context (lang_name_c); /* extern "C" */
2925 #endif
2926 lang_hooks.decls.pushdecl (build_decl
2927 (TYPE_DECL,
2928 alias_ident,
2929 xref_tag (RECORD_TYPE, underlying_class)));
2930 #ifdef OBJCPLUS
2931 pop_lang_context ();
2932 #endif
2933 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2937 void
2938 objc_declare_class (tree ident_list)
2940 tree list;
2941 #ifdef OBJCPLUS
2942 if (current_namespace != global_namespace) {
2943 error ("Objective-C declarations may only appear in global scope");
2945 #endif /* OBJCPLUS */
2947 for (list = ident_list; list; list = TREE_CHAIN (list))
2949 tree ident = TREE_VALUE (list);
2951 if (! objc_is_class_name (ident))
2953 tree record = lookup_name (ident), type = record;
2955 if (record)
2957 if (TREE_CODE (record) == TYPE_DECL)
2958 type = DECL_ORIGINAL_TYPE (record);
2960 if (!TYPE_HAS_OBJC_INFO (type)
2961 || !TYPE_OBJC_INTERFACE (type))
2963 error ("%qE redeclared as different kind of symbol",
2964 ident);
2965 error ("previous declaration of %q+D",
2966 record);
2970 record = xref_tag (RECORD_TYPE, ident);
2971 INIT_TYPE_OBJC_INFO (record);
2972 TYPE_OBJC_INTERFACE (record) = ident;
2973 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2978 tree
2979 objc_is_class_name (tree ident)
2981 tree chain;
2983 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2984 && identifier_global_value (ident))
2985 ident = identifier_global_value (ident);
2986 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2987 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2989 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2990 ident = OBJC_TYPE_NAME (ident);
2991 #ifdef OBJCPLUS
2992 if (ident && TREE_CODE (ident) == TYPE_DECL)
2993 ident = DECL_NAME (ident);
2994 #endif
2995 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2996 return NULL_TREE;
2998 if (lookup_interface (ident))
2999 return ident;
3001 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3003 if (ident == TREE_VALUE (chain))
3004 return ident;
3007 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3009 if (ident == TREE_VALUE (chain))
3010 return TREE_PURPOSE (chain);
3013 return 0;
3016 /* Check whether TYPE is either 'id' or 'Class'. */
3018 tree
3019 objc_is_id (tree type)
3021 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3022 && identifier_global_value (type))
3023 type = identifier_global_value (type);
3025 if (type && TREE_CODE (type) == TYPE_DECL)
3026 type = TREE_TYPE (type);
3028 /* NB: This function may be called before the ObjC front-end has
3029 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3030 return (objc_object_type && type
3031 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3032 ? type
3033 : NULL_TREE);
3036 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3037 class instance. This is needed by other parts of the compiler to
3038 handle ObjC types gracefully. */
3040 tree
3041 objc_is_object_ptr (tree type)
3043 tree ret;
3045 type = TYPE_MAIN_VARIANT (type);
3046 if (!POINTER_TYPE_P (type))
3047 return 0;
3049 ret = objc_is_id (type);
3050 if (!ret)
3051 ret = objc_is_class_name (TREE_TYPE (type));
3053 return ret;
3056 static int
3057 objc_is_gcable_type (tree type, int or_strong_p)
3059 tree name;
3061 if (!TYPE_P (type))
3062 return 0;
3063 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3064 return 1;
3065 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3066 return 1;
3067 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3068 return 0;
3069 type = TREE_TYPE (type);
3070 if (TREE_CODE (type) != RECORD_TYPE)
3071 return 0;
3072 name = TYPE_NAME (type);
3073 return (objc_is_class_name (name) != NULL_TREE);
3076 static tree
3077 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3079 if (expr == oldexpr)
3080 return newexpr;
3082 switch (TREE_CODE (expr))
3084 case COMPONENT_REF:
3085 return objc_build_component_ref
3086 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3087 oldexpr,
3088 newexpr),
3089 DECL_NAME (TREE_OPERAND (expr, 1)));
3090 case ARRAY_REF:
3091 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3092 oldexpr,
3093 newexpr),
3094 TREE_OPERAND (expr, 1),
3095 input_location);
3096 case INDIRECT_REF:
3097 return build_indirect_ref (input_location,
3098 objc_substitute_decl (TREE_OPERAND (expr, 0),
3099 oldexpr,
3100 newexpr), "->");
3101 default:
3102 return expr;
3106 static tree
3107 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3109 tree func_params;
3110 /* The LHS parameter contains the expression 'outervar->memberspec';
3111 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3112 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3114 tree offs
3115 = objc_substitute_decl
3116 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3117 tree func
3118 = (flag_objc_direct_dispatch
3119 ? objc_assign_ivar_fast_decl
3120 : objc_assign_ivar_decl);
3122 offs = convert (integer_type_node, build_unary_op (input_location,
3123 ADDR_EXPR, offs, 0));
3124 offs = fold (offs);
3125 func_params = tree_cons (NULL_TREE,
3126 convert (objc_object_type, rhs),
3127 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3128 tree_cons (NULL_TREE, offs,
3129 NULL_TREE)));
3131 assemble_external (func);
3132 return build_function_call (func, func_params);
3135 static tree
3136 objc_build_global_assignment (tree lhs, tree rhs)
3138 tree func_params = tree_cons (NULL_TREE,
3139 convert (objc_object_type, rhs),
3140 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3141 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3142 NULL_TREE));
3144 assemble_external (objc_assign_global_decl);
3145 return build_function_call (objc_assign_global_decl, func_params);
3148 static tree
3149 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3151 tree func_params = tree_cons (NULL_TREE,
3152 convert (objc_object_type, rhs),
3153 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3154 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3155 NULL_TREE));
3157 assemble_external (objc_assign_strong_cast_decl);
3158 return build_function_call (objc_assign_strong_cast_decl, func_params);
3161 static int
3162 objc_is_gcable_p (tree expr)
3164 return (TREE_CODE (expr) == COMPONENT_REF
3165 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3166 : TREE_CODE (expr) == ARRAY_REF
3167 ? (objc_is_gcable_p (TREE_TYPE (expr))
3168 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3169 : TREE_CODE (expr) == ARRAY_TYPE
3170 ? objc_is_gcable_p (TREE_TYPE (expr))
3171 : TYPE_P (expr)
3172 ? objc_is_gcable_type (expr, 1)
3173 : (objc_is_gcable_p (TREE_TYPE (expr))
3174 || (DECL_P (expr)
3175 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3178 static int
3179 objc_is_ivar_reference_p (tree expr)
3181 return (TREE_CODE (expr) == ARRAY_REF
3182 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3183 : TREE_CODE (expr) == COMPONENT_REF
3184 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3185 : 0);
3188 static int
3189 objc_is_global_reference_p (tree expr)
3191 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3192 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3193 : DECL_P (expr)
3194 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3195 : 0);
3198 tree
3199 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3201 tree result = NULL_TREE, outer;
3202 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3204 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3205 will have been transformed to the form '*(type *)&expr'. */
3206 if (TREE_CODE (lhs) == INDIRECT_REF)
3208 outer = TREE_OPERAND (lhs, 0);
3210 while (!strong_cast_p
3211 && (CONVERT_EXPR_P (outer)
3212 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3214 tree lhstype = TREE_TYPE (outer);
3216 /* Descend down the cast chain, and record the first objc_gc
3217 attribute found. */
3218 if (POINTER_TYPE_P (lhstype))
3220 tree attr
3221 = lookup_attribute ("objc_gc",
3222 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3224 if (attr)
3225 strong_cast_p = 1;
3228 outer = TREE_OPERAND (outer, 0);
3232 /* If we have a __strong cast, it trumps all else. */
3233 if (strong_cast_p)
3235 if (modifycode != NOP_EXPR)
3236 goto invalid_pointer_arithmetic;
3238 if (warn_assign_intercept)
3239 warning (0, "strong-cast assignment has been intercepted");
3241 result = objc_build_strong_cast_assignment (lhs, rhs);
3243 goto exit_point;
3246 /* the lhs must be of a suitable type, regardless of its underlying
3247 structure. */
3248 if (!objc_is_gcable_p (lhs))
3249 goto exit_point;
3251 outer = lhs;
3253 while (outer
3254 && (TREE_CODE (outer) == COMPONENT_REF
3255 || TREE_CODE (outer) == ARRAY_REF))
3256 outer = TREE_OPERAND (outer, 0);
3258 if (TREE_CODE (outer) == INDIRECT_REF)
3260 outer = TREE_OPERAND (outer, 0);
3261 indirect_p = 1;
3264 outer_gc_p = objc_is_gcable_p (outer);
3266 /* Handle ivar assignments. */
3267 if (objc_is_ivar_reference_p (lhs))
3269 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3270 doesn't cut it here), the best we can do here is suggest a cast. */
3271 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3273 /* We may still be able to use the global write barrier... */
3274 if (!indirect_p && objc_is_global_reference_p (outer))
3275 goto global_reference;
3277 suggest_cast:
3278 if (modifycode == NOP_EXPR)
3280 if (warn_assign_intercept)
3281 warning (0, "strong-cast may possibly be needed");
3284 goto exit_point;
3287 if (modifycode != NOP_EXPR)
3288 goto invalid_pointer_arithmetic;
3290 if (warn_assign_intercept)
3291 warning (0, "instance variable assignment has been intercepted");
3293 result = objc_build_ivar_assignment (outer, lhs, rhs);
3295 goto exit_point;
3298 /* Likewise, intercept assignment to global/static variables if their type is
3299 GC-marked. */
3300 if (objc_is_global_reference_p (outer))
3302 if (indirect_p)
3303 goto suggest_cast;
3305 global_reference:
3306 if (modifycode != NOP_EXPR)
3308 invalid_pointer_arithmetic:
3309 if (outer_gc_p)
3310 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3312 goto exit_point;
3315 if (warn_assign_intercept)
3316 warning (0, "global/static variable assignment has been intercepted");
3318 result = objc_build_global_assignment (lhs, rhs);
3321 /* In all other cases, fall back to the normal mechanism. */
3322 exit_point:
3323 return result;
3326 struct GTY(()) interface_tuple {
3327 tree id;
3328 tree class_name;
3331 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3333 static hashval_t
3334 hash_interface (const void *p)
3336 const struct interface_tuple *d = (const struct interface_tuple *) p;
3337 return IDENTIFIER_HASH_VALUE (d->id);
3340 static int
3341 eq_interface (const void *p1, const void *p2)
3343 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3344 return d->id == p2;
3347 static tree
3348 lookup_interface (tree ident)
3350 #ifdef OBJCPLUS
3351 if (ident && TREE_CODE (ident) == TYPE_DECL)
3352 ident = DECL_NAME (ident);
3353 #endif
3355 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3356 return NULL_TREE;
3359 struct interface_tuple **slot;
3360 tree i = NULL_TREE;
3362 if (interface_htab)
3364 slot = (struct interface_tuple **)
3365 htab_find_slot_with_hash (interface_htab, ident,
3366 IDENTIFIER_HASH_VALUE (ident),
3367 NO_INSERT);
3368 if (slot && *slot)
3369 i = (*slot)->class_name;
3371 return i;
3375 /* Implement @defs (<classname>) within struct bodies. */
3377 tree
3378 objc_get_class_ivars (tree class_name)
3380 tree interface = lookup_interface (class_name);
3382 if (interface)
3383 return get_class_ivars (interface, true);
3385 error ("cannot find interface declaration for %qE",
3386 class_name);
3388 return error_mark_node;
3391 /* Used by: build_private_template, continue_class,
3392 and for @defs constructs. */
3394 static tree
3395 get_class_ivars (tree interface, bool inherited)
3397 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3399 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3400 by the current class (i.e., they do not include super-class ivars).
3401 However, the CLASS_IVARS list will be side-effected by a call to
3402 finish_struct(), which will fill in field offsets. */
3403 if (!CLASS_IVARS (interface))
3404 CLASS_IVARS (interface) = ivar_chain;
3406 if (!inherited)
3407 return ivar_chain;
3409 while (CLASS_SUPER_NAME (interface))
3411 /* Prepend super-class ivars. */
3412 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3413 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3414 ivar_chain);
3417 return ivar_chain;
3420 static tree
3421 objc_create_temporary_var (tree type)
3423 tree decl;
3425 decl = build_decl (VAR_DECL, NULL_TREE, type);
3426 TREE_USED (decl) = 1;
3427 DECL_ARTIFICIAL (decl) = 1;
3428 DECL_IGNORED_P (decl) = 1;
3429 DECL_CONTEXT (decl) = current_function_decl;
3431 return decl;
3434 /* Exception handling constructs. We begin by having the parser do most
3435 of the work and passing us blocks. What we do next depends on whether
3436 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3437 We abstract all of this in a handful of appropriately named routines. */
3439 /* Stack of open try blocks. */
3441 struct objc_try_context
3443 struct objc_try_context *outer;
3445 /* Statements (or statement lists) as processed by the parser. */
3446 tree try_body;
3447 tree finally_body;
3449 /* Some file position locations. */
3450 location_t try_locus;
3451 location_t end_try_locus;
3452 location_t end_catch_locus;
3453 location_t finally_locus;
3454 location_t end_finally_locus;
3456 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3457 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3458 tree catch_list;
3460 /* The CATCH_EXPR of an open @catch clause. */
3461 tree current_catch;
3463 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3464 tree caught_decl;
3465 tree stack_decl;
3466 tree rethrow_decl;
3469 static struct objc_try_context *cur_try_context;
3471 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3472 that represents TYPE. For Objective-C, this is just the class name. */
3473 /* ??? Isn't there a class object or some such? Is it easy to get? */
3475 #ifndef OBJCPLUS
3476 static tree
3477 objc_eh_runtime_type (tree type)
3479 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3481 #endif
3483 /* Initialize exception handling. */
3485 static void
3486 objc_init_exceptions (void)
3488 static bool done = false;
3489 if (done)
3490 return;
3491 done = true;
3493 if (flag_objc_sjlj_exceptions)
3495 /* On Darwin, ObjC exceptions require a sufficiently recent
3496 version of the runtime, so the user must ask for them explicitly. */
3497 if (!flag_objc_exceptions)
3498 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3499 "exception syntax");
3501 #ifndef OBJCPLUS
3502 else
3504 c_eh_initialized_p = true;
3505 eh_personality_libfunc
3506 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3507 ? "__gnu_objc_personality_sj0"
3508 : "__gnu_objc_personality_v0");
3509 default_init_unwind_resume_libfunc ();
3510 using_eh_for_cleanups ();
3511 lang_eh_runtime_type = objc_eh_runtime_type;
3513 #endif
3516 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3517 we'll arrange for it to be initialized (and associated with a binding)
3518 later. */
3520 static tree
3521 objc_build_exc_ptr (void)
3523 if (flag_objc_sjlj_exceptions)
3525 tree var = cur_try_context->caught_decl;
3526 if (!var)
3528 var = objc_create_temporary_var (objc_object_type);
3529 cur_try_context->caught_decl = var;
3531 return var;
3533 else
3534 return build0 (EXC_PTR_EXPR, objc_object_type);
3537 /* Build "objc_exception_try_exit(&_stack)". */
3539 static tree
3540 next_sjlj_build_try_exit (void)
3542 tree t;
3543 t = build_fold_addr_expr (cur_try_context->stack_decl);
3544 t = tree_cons (NULL, t, NULL);
3545 t = build_function_call (objc_exception_try_exit_decl, t);
3546 return t;
3549 /* Build
3550 objc_exception_try_enter (&_stack);
3551 if (_setjmp(&_stack.buf))
3553 else
3555 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3556 empty, ready for the caller to fill them in. */
3558 static tree
3559 next_sjlj_build_enter_and_setjmp (void)
3561 tree t, enter, sj, cond;
3563 t = build_fold_addr_expr (cur_try_context->stack_decl);
3564 t = tree_cons (NULL, t, NULL);
3565 enter = build_function_call (objc_exception_try_enter_decl, t);
3567 t = objc_build_component_ref (cur_try_context->stack_decl,
3568 get_identifier ("buf"));
3569 t = build_fold_addr_expr (t);
3570 #ifdef OBJCPLUS
3571 /* Convert _setjmp argument to type that is expected. */
3572 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3573 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3574 else
3575 t = convert (ptr_type_node, t);
3576 #else
3577 t = convert (ptr_type_node, t);
3578 #endif
3579 t = tree_cons (NULL, t, NULL);
3580 sj = build_function_call (objc_setjmp_decl, t);
3582 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3583 cond = c_common_truthvalue_conversion (input_location, cond);
3585 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3588 /* Build:
3590 DECL = objc_exception_extract(&_stack); */
3592 static tree
3593 next_sjlj_build_exc_extract (tree decl)
3595 tree t;
3597 t = build_fold_addr_expr (cur_try_context->stack_decl);
3598 t = tree_cons (NULL, t, NULL);
3599 t = build_function_call (objc_exception_extract_decl, t);
3600 t = convert (TREE_TYPE (decl), t);
3601 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3603 return t;
3606 /* Build
3607 if (objc_exception_match(obj_get_class(TYPE), _caught)
3608 BODY
3609 else if (...)
3611 else
3613 _rethrow = _caught;
3614 objc_exception_try_exit(&_stack);
3616 from the sequence of CATCH_EXPRs in the current try context. */
3618 static tree
3619 next_sjlj_build_catch_list (void)
3621 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3622 tree catch_seq, t;
3623 tree *last = &catch_seq;
3624 bool saw_id = false;
3626 for (; !tsi_end_p (i); tsi_next (&i))
3628 tree stmt = tsi_stmt (i);
3629 tree type = CATCH_TYPES (stmt);
3630 tree body = CATCH_BODY (stmt);
3632 if (type == NULL)
3634 *last = body;
3635 saw_id = true;
3636 break;
3638 else
3640 tree args, cond;
3642 if (type == error_mark_node)
3643 cond = error_mark_node;
3644 else
3646 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3647 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3648 args = tree_cons (NULL, t, args);
3649 t = build_function_call (objc_exception_match_decl, args);
3650 cond = c_common_truthvalue_conversion (input_location, t);
3652 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3653 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3655 *last = t;
3656 last = &COND_EXPR_ELSE (t);
3660 if (!saw_id)
3662 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3663 cur_try_context->caught_decl);
3664 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3665 append_to_statement_list (t, last);
3667 t = next_sjlj_build_try_exit ();
3668 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3669 append_to_statement_list (t, last);
3672 return catch_seq;
3675 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3676 exception handling. We aim to build:
3679 struct _objc_exception_data _stack;
3680 id _rethrow = 0;
3683 objc_exception_try_enter (&_stack);
3684 if (_setjmp(&_stack.buf))
3686 id _caught = objc_exception_extract(&_stack);
3687 objc_exception_try_enter (&_stack);
3688 if (_setjmp(&_stack.buf))
3689 _rethrow = objc_exception_extract(&_stack);
3690 else
3691 CATCH-LIST
3693 else
3694 TRY-BLOCK
3696 finally
3698 if (!_rethrow)
3699 objc_exception_try_exit(&_stack);
3700 FINALLY-BLOCK
3701 if (_rethrow)
3702 objc_exception_throw(_rethrow);
3706 If CATCH-LIST is empty, we can omit all of the block containing
3707 "_caught" except for the setting of _rethrow. Note the use of
3708 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3709 but handles goto and other exits from the block. */
3711 static tree
3712 next_sjlj_build_try_catch_finally (void)
3714 tree rethrow_decl, stack_decl, t;
3715 tree catch_seq, try_fin, bind;
3717 /* Create the declarations involved. */
3718 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3719 stack_decl = objc_create_temporary_var (t);
3720 cur_try_context->stack_decl = stack_decl;
3722 rethrow_decl = objc_create_temporary_var (objc_object_type);
3723 cur_try_context->rethrow_decl = rethrow_decl;
3724 TREE_CHAIN (rethrow_decl) = stack_decl;
3726 /* Build the outermost variable binding level. */
3727 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3728 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3729 TREE_SIDE_EFFECTS (bind) = 1;
3731 /* Initialize rethrow_decl. */
3732 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3733 convert (objc_object_type, null_pointer_node));
3734 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3735 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3737 /* Build the outermost TRY_FINALLY_EXPR. */
3738 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3739 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3740 TREE_SIDE_EFFECTS (try_fin) = 1;
3741 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3743 /* Create the complete catch sequence. */
3744 if (cur_try_context->catch_list)
3746 tree caught_decl = objc_build_exc_ptr ();
3747 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3748 TREE_SIDE_EFFECTS (catch_seq) = 1;
3750 t = next_sjlj_build_exc_extract (caught_decl);
3751 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3753 t = next_sjlj_build_enter_and_setjmp ();
3754 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3755 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3756 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3758 else
3759 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3760 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3762 /* Build the main register-and-try if statement. */
3763 t = next_sjlj_build_enter_and_setjmp ();
3764 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3765 COND_EXPR_THEN (t) = catch_seq;
3766 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3767 TREE_OPERAND (try_fin, 0) = t;
3769 /* Build the complete FINALLY statement list. */
3770 t = next_sjlj_build_try_exit ();
3771 t = build_stmt (COND_EXPR,
3772 c_common_truthvalue_conversion
3773 (input_location, rethrow_decl),
3774 NULL, t);
3775 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3776 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3778 append_to_statement_list (cur_try_context->finally_body,
3779 &TREE_OPERAND (try_fin, 1));
3781 t = tree_cons (NULL, rethrow_decl, NULL);
3782 t = build_function_call (objc_exception_throw_decl, t);
3783 t = build_stmt (COND_EXPR,
3784 c_common_truthvalue_conversion (input_location,
3785 rethrow_decl),
3786 t, NULL);
3787 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3788 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3790 return bind;
3793 /* Called just after parsing the @try and its associated BODY. We now
3794 must prepare for the tricky bits -- handling the catches and finally. */
3796 void
3797 objc_begin_try_stmt (location_t try_locus, tree body)
3799 struct objc_try_context *c = XCNEW (struct objc_try_context);
3800 c->outer = cur_try_context;
3801 c->try_body = body;
3802 c->try_locus = try_locus;
3803 c->end_try_locus = input_location;
3804 cur_try_context = c;
3806 objc_init_exceptions ();
3808 if (flag_objc_sjlj_exceptions)
3809 objc_mark_locals_volatile (NULL);
3812 /* Called just after parsing "@catch (parm)". Open a binding level,
3813 enter DECL into the binding level, and initialize it. Leave the
3814 binding level open while the body of the compound statement is parsed. */
3816 void
3817 objc_begin_catch_clause (tree decl)
3819 tree compound, type, t;
3821 /* Begin a new scope that the entire catch clause will live in. */
3822 compound = c_begin_compound_stmt (true);
3824 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3825 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3826 lang_hooks.decls.pushdecl (decl);
3828 /* Since a decl is required here by syntax, don't warn if its unused. */
3829 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3830 be what the previous objc implementation did. */
3831 TREE_USED (decl) = 1;
3833 /* Verify that the type of the catch is valid. It must be a pointer
3834 to an Objective-C class, or "id" (which is catch-all). */
3835 type = TREE_TYPE (decl);
3837 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3838 type = NULL;
3839 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3841 error ("@catch parameter is not a known Objective-C class type");
3842 type = error_mark_node;
3844 else if (cur_try_context->catch_list)
3846 /* Examine previous @catch clauses and see if we've already
3847 caught the type in question. */
3848 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3849 for (; !tsi_end_p (i); tsi_next (&i))
3851 tree stmt = tsi_stmt (i);
3852 t = CATCH_TYPES (stmt);
3853 if (t == error_mark_node)
3854 continue;
3855 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3857 warning (0, "exception of type %<%T%> will be caught",
3858 TREE_TYPE (type));
3859 warning (0, "%H by earlier handler for %<%T%>",
3860 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3861 break;
3866 /* Record the data for the catch in the try context so that we can
3867 finalize it later. */
3868 t = build_stmt (CATCH_EXPR, type, compound);
3869 cur_try_context->current_catch = t;
3871 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3872 t = objc_build_exc_ptr ();
3873 t = convert (TREE_TYPE (decl), t);
3874 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3875 add_stmt (t);
3878 /* Called just after parsing the closing brace of a @catch clause. Close
3879 the open binding level, and record a CATCH_EXPR for it. */
3881 void
3882 objc_finish_catch_clause (void)
3884 tree c = cur_try_context->current_catch;
3885 cur_try_context->current_catch = NULL;
3886 cur_try_context->end_catch_locus = input_location;
3888 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3889 append_to_statement_list (c, &cur_try_context->catch_list);
3892 /* Called after parsing a @finally clause and its associated BODY.
3893 Record the body for later placement. */
3895 void
3896 objc_build_finally_clause (location_t finally_locus, tree body)
3898 cur_try_context->finally_body = body;
3899 cur_try_context->finally_locus = finally_locus;
3900 cur_try_context->end_finally_locus = input_location;
3903 /* Called to finalize a @try construct. */
3905 tree
3906 objc_finish_try_stmt (void)
3908 struct objc_try_context *c = cur_try_context;
3909 tree stmt;
3911 if (c->catch_list == NULL && c->finally_body == NULL)
3912 error ("%<@try%> without %<@catch%> or %<@finally%>");
3914 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3915 if (flag_objc_sjlj_exceptions)
3917 bool save = in_late_binary_op;
3918 in_late_binary_op = true;
3919 if (!cur_try_context->finally_body)
3921 cur_try_context->finally_locus = input_location;
3922 cur_try_context->end_finally_locus = input_location;
3924 stmt = next_sjlj_build_try_catch_finally ();
3925 in_late_binary_op = save;
3927 else
3929 /* Otherwise, nest the CATCH inside a FINALLY. */
3930 stmt = c->try_body;
3931 if (c->catch_list)
3933 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3934 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3936 if (c->finally_body)
3938 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3939 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3942 add_stmt (stmt);
3944 cur_try_context = c->outer;
3945 free (c);
3946 return stmt;
3949 tree
3950 objc_build_throw_stmt (tree throw_expr)
3952 tree args;
3954 objc_init_exceptions ();
3956 if (throw_expr == NULL)
3958 /* If we're not inside a @catch block, there is no "current
3959 exception" to be rethrown. */
3960 if (cur_try_context == NULL
3961 || cur_try_context->current_catch == NULL)
3963 error ("%<@throw%> (rethrow) used outside of a @catch block");
3964 return NULL_TREE;
3967 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3968 value that we get from the runtime. */
3969 throw_expr = objc_build_exc_ptr ();
3972 /* A throw is just a call to the runtime throw function with the
3973 object as a parameter. */
3974 args = tree_cons (NULL, throw_expr, NULL);
3975 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3978 tree
3979 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3981 tree args, call;
3983 /* First lock the mutex. */
3984 mutex = save_expr (mutex);
3985 args = tree_cons (NULL, mutex, NULL);
3986 call = build_function_call (objc_sync_enter_decl, args);
3987 SET_EXPR_LOCATION (call, start_locus);
3988 add_stmt (call);
3990 /* Build the mutex unlock. */
3991 args = tree_cons (NULL, mutex, NULL);
3992 call = build_function_call (objc_sync_exit_decl, args);
3993 SET_EXPR_LOCATION (call, input_location);
3995 /* Put the that and the body in a TRY_FINALLY. */
3996 objc_begin_try_stmt (start_locus, body);
3997 objc_build_finally_clause (input_location, call);
3998 return objc_finish_try_stmt ();
4002 /* Predefine the following data type:
4004 struct _objc_exception_data
4006 int buf[OBJC_JBLEN];
4007 void *pointers[4];
4008 }; */
4010 /* The following yuckiness should prevent users from having to #include
4011 <setjmp.h> in their code... */
4013 /* Define to a harmless positive value so the below code doesn't die. */
4014 #ifndef OBJC_JBLEN
4015 #define OBJC_JBLEN 18
4016 #endif
4018 static void
4019 build_next_objc_exception_stuff (void)
4021 tree field_decl, field_decl_chain, index, temp_type;
4023 objc_exception_data_template
4024 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4026 /* int buf[OBJC_JBLEN]; */
4028 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
4029 field_decl = create_field_decl (build_array_type (integer_type_node, index),
4030 "buf");
4031 field_decl_chain = field_decl;
4033 /* void *pointers[4]; */
4035 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
4036 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
4037 "pointers");
4038 chainon (field_decl_chain, field_decl);
4040 objc_finish_struct (objc_exception_data_template, field_decl_chain);
4042 /* int _setjmp(...); */
4043 /* If the user includes <setjmp.h>, this shall be superseded by
4044 'int _setjmp(jmp_buf);' */
4045 temp_type = build_function_type (integer_type_node, NULL_TREE);
4046 objc_setjmp_decl
4047 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4049 /* id objc_exception_extract(struct _objc_exception_data *); */
4050 temp_type
4051 = build_function_type (objc_object_type,
4052 tree_cons (NULL_TREE,
4053 build_pointer_type (objc_exception_data_template),
4054 OBJC_VOID_AT_END));
4055 objc_exception_extract_decl
4056 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4057 NULL_TREE);
4058 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4059 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4060 temp_type
4061 = build_function_type (void_type_node,
4062 tree_cons (NULL_TREE,
4063 build_pointer_type (objc_exception_data_template),
4064 OBJC_VOID_AT_END));
4065 objc_exception_try_enter_decl
4066 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4067 NULL_TREE);
4068 objc_exception_try_exit_decl
4069 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4070 NULL_TREE);
4072 /* int objc_exception_match(id, id); */
4073 temp_type
4074 = build_function_type (integer_type_node,
4075 tree_cons (NULL_TREE, objc_object_type,
4076 tree_cons (NULL_TREE, objc_object_type,
4077 OBJC_VOID_AT_END)));
4078 objc_exception_match_decl
4079 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4080 NULL_TREE);
4082 /* id objc_assign_ivar (id, id, unsigned int); */
4083 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4084 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4085 temp_type
4086 = build_function_type (objc_object_type,
4087 tree_cons
4088 (NULL_TREE, objc_object_type,
4089 tree_cons (NULL_TREE, objc_object_type,
4090 tree_cons (NULL_TREE,
4091 unsigned_type_node,
4092 OBJC_VOID_AT_END))));
4093 objc_assign_ivar_decl
4094 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4095 NULL, NULL_TREE);
4096 #ifdef OFFS_ASSIGNIVAR_FAST
4097 objc_assign_ivar_fast_decl
4098 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4099 NOT_BUILT_IN, NULL, NULL_TREE);
4100 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4101 = tree_cons (get_identifier ("hard_coded_address"),
4102 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4103 NULL_TREE);
4104 #else
4105 /* Default to slower ivar method. */
4106 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4107 #endif
4109 /* id objc_assign_global (id, id *); */
4110 /* id objc_assign_strongCast (id, id *); */
4111 temp_type = build_function_type (objc_object_type,
4112 tree_cons (NULL_TREE, objc_object_type,
4113 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4114 OBJC_VOID_AT_END)));
4115 objc_assign_global_decl
4116 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4117 NULL_TREE);
4118 objc_assign_strong_cast_decl
4119 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4120 NULL_TREE);
4123 static void
4124 build_objc_exception_stuff (void)
4126 tree noreturn_list, nothrow_list, temp_type;
4128 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4129 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4131 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4132 /* void objc_sync_enter(id); */
4133 /* void objc_sync_exit(id); */
4134 temp_type = build_function_type (void_type_node,
4135 tree_cons (NULL_TREE, objc_object_type,
4136 OBJC_VOID_AT_END));
4137 objc_exception_throw_decl
4138 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4139 noreturn_list);
4140 objc_sync_enter_decl
4141 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4142 NULL, nothrow_list);
4143 objc_sync_exit_decl
4144 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4145 NULL, nothrow_list);
4148 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4149 name as the class:
4151 struct <classname> {
4152 struct _objc_class *isa;
4154 }; */
4156 static void
4157 build_private_template (tree klass)
4159 if (!CLASS_STATIC_TEMPLATE (klass))
4161 tree record = objc_build_struct (klass,
4162 get_class_ivars (klass, false),
4163 CLASS_SUPER_NAME (klass));
4165 /* Set the TREE_USED bit for this struct, so that stab generator
4166 can emit stabs for this struct type. */
4167 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4168 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4172 /* Begin code generation for protocols... */
4174 /* struct _objc_protocol {
4175 struct _objc_class *isa;
4176 char *protocol_name;
4177 struct _objc_protocol **protocol_list;
4178 struct _objc__method_prototype_list *instance_methods;
4179 struct _objc__method_prototype_list *class_methods;
4180 }; */
4182 static void
4183 build_protocol_template (void)
4185 tree field_decl, field_decl_chain;
4187 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4189 /* struct _objc_class *isa; */
4190 field_decl = create_field_decl (build_pointer_type
4191 (xref_tag (RECORD_TYPE,
4192 get_identifier (UTAG_CLASS))),
4193 "isa");
4194 field_decl_chain = field_decl;
4196 /* char *protocol_name; */
4197 field_decl = create_field_decl (string_type_node, "protocol_name");
4198 chainon (field_decl_chain, field_decl);
4200 /* struct _objc_protocol **protocol_list; */
4201 field_decl = create_field_decl (build_pointer_type
4202 (build_pointer_type
4203 (objc_protocol_template)),
4204 "protocol_list");
4205 chainon (field_decl_chain, field_decl);
4207 /* struct _objc__method_prototype_list *instance_methods; */
4208 field_decl = create_field_decl (objc_method_proto_list_ptr,
4209 "instance_methods");
4210 chainon (field_decl_chain, field_decl);
4212 /* struct _objc__method_prototype_list *class_methods; */
4213 field_decl = create_field_decl (objc_method_proto_list_ptr,
4214 "class_methods");
4215 chainon (field_decl_chain, field_decl);
4217 objc_finish_struct (objc_protocol_template, field_decl_chain);
4220 static tree
4221 build_descriptor_table_initializer (tree type, tree entries)
4223 tree initlist = NULL_TREE;
4227 tree eltlist = NULL_TREE;
4229 eltlist
4230 = tree_cons (NULL_TREE,
4231 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4232 eltlist
4233 = tree_cons (NULL_TREE,
4234 add_objc_string (METHOD_ENCODING (entries),
4235 meth_var_types),
4236 eltlist);
4238 initlist
4239 = tree_cons (NULL_TREE,
4240 objc_build_constructor (type, nreverse (eltlist)),
4241 initlist);
4243 entries = TREE_CHAIN (entries);
4245 while (entries);
4247 return objc_build_constructor (build_array_type (type, 0),
4248 nreverse (initlist));
4251 /* struct objc_method_prototype_list {
4252 int count;
4253 struct objc_method_prototype {
4254 SEL name;
4255 char *types;
4256 } list[1];
4257 }; */
4259 static tree
4260 build_method_prototype_list_template (tree list_type, int size)
4262 tree objc_ivar_list_record;
4263 tree field_decl, field_decl_chain;
4265 /* Generate an unnamed struct definition. */
4267 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4269 /* int method_count; */
4270 field_decl = create_field_decl (integer_type_node, "method_count");
4271 field_decl_chain = field_decl;
4273 /* struct objc_method method_list[]; */
4274 field_decl = create_field_decl (build_array_type
4275 (list_type,
4276 build_index_type
4277 (build_int_cst (NULL_TREE, size - 1))),
4278 "method_list");
4279 chainon (field_decl_chain, field_decl);
4281 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
4283 return objc_ivar_list_record;
4286 static tree
4287 build_method_prototype_template (void)
4289 tree proto_record;
4290 tree field_decl, field_decl_chain;
4292 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4294 /* SEL _cmd; */
4295 field_decl = create_field_decl (objc_selector_type, "_cmd");
4296 field_decl_chain = field_decl;
4298 /* char *method_types; */
4299 field_decl = create_field_decl (string_type_node, "method_types");
4300 chainon (field_decl_chain, field_decl);
4302 objc_finish_struct (proto_record, field_decl_chain);
4304 return proto_record;
4307 static tree
4308 objc_method_parm_type (tree type)
4310 type = TREE_VALUE (TREE_TYPE (type));
4311 if (TREE_CODE (type) == TYPE_DECL)
4312 type = TREE_TYPE (type);
4313 return type;
4316 static int
4317 objc_encoded_type_size (tree type)
4319 int sz = int_size_in_bytes (type);
4321 /* Make all integer and enum types at least as large
4322 as an int. */
4323 if (sz > 0 && INTEGRAL_TYPE_P (type))
4324 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4325 /* Treat arrays as pointers, since that's how they're
4326 passed in. */
4327 else if (TREE_CODE (type) == ARRAY_TYPE)
4328 sz = int_size_in_bytes (ptr_type_node);
4329 return sz;
4332 static tree
4333 encode_method_prototype (tree method_decl)
4335 tree parms;
4336 int parm_offset, i;
4337 char buf[40];
4338 tree result;
4340 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4341 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4343 /* Encode return type. */
4344 encode_type (objc_method_parm_type (method_decl),
4345 obstack_object_size (&util_obstack),
4346 OBJC_ENCODE_INLINE_DEFS);
4348 /* Stack size. */
4349 /* The first two arguments (self and _cmd) are pointers; account for
4350 their size. */
4351 i = int_size_in_bytes (ptr_type_node);
4352 parm_offset = 2 * i;
4353 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4354 parms = TREE_CHAIN (parms))
4356 tree type = objc_method_parm_type (parms);
4357 int sz = objc_encoded_type_size (type);
4359 /* If a type size is not known, bail out. */
4360 if (sz < 0)
4362 error ("type %q+D does not have a known size",
4363 type);
4364 /* Pretend that the encoding succeeded; the compilation will
4365 fail nevertheless. */
4366 goto finish_encoding;
4368 parm_offset += sz;
4371 sprintf (buf, "%d@0:%d", parm_offset, i);
4372 obstack_grow (&util_obstack, buf, strlen (buf));
4374 /* Argument types. */
4375 parm_offset = 2 * i;
4376 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4377 parms = TREE_CHAIN (parms))
4379 tree type = objc_method_parm_type (parms);
4381 /* Process argument qualifiers for user supplied arguments. */
4382 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4384 /* Type. */
4385 encode_type (type, obstack_object_size (&util_obstack),
4386 OBJC_ENCODE_INLINE_DEFS);
4388 /* Compute offset. */
4389 sprintf (buf, "%d", parm_offset);
4390 parm_offset += objc_encoded_type_size (type);
4392 obstack_grow (&util_obstack, buf, strlen (buf));
4395 finish_encoding:
4396 obstack_1grow (&util_obstack, '\0');
4397 result = get_identifier (XOBFINISH (&util_obstack, char *));
4398 obstack_free (&util_obstack, util_firstobj);
4399 return result;
4402 static tree
4403 generate_descriptor_table (tree type, const char *name, int size, tree list,
4404 tree proto)
4406 tree decl, initlist;
4408 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4410 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4411 initlist = tree_cons (NULL_TREE, list, initlist);
4413 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4415 return decl;
4418 static void
4419 generate_method_descriptors (tree protocol)
4421 tree initlist, chain, method_list_template;
4422 int size;
4424 if (!objc_method_prototype_template)
4425 objc_method_prototype_template = build_method_prototype_template ();
4427 chain = PROTOCOL_CLS_METHODS (protocol);
4428 if (chain)
4430 size = list_length (chain);
4432 method_list_template
4433 = build_method_prototype_list_template (objc_method_prototype_template,
4434 size);
4436 initlist
4437 = build_descriptor_table_initializer (objc_method_prototype_template,
4438 chain);
4440 UOBJC_CLASS_METHODS_decl
4441 = generate_descriptor_table (method_list_template,
4442 "_OBJC_PROTOCOL_CLASS_METHODS",
4443 size, initlist, protocol);
4445 else
4446 UOBJC_CLASS_METHODS_decl = 0;
4448 chain = PROTOCOL_NST_METHODS (protocol);
4449 if (chain)
4451 size = list_length (chain);
4453 method_list_template
4454 = build_method_prototype_list_template (objc_method_prototype_template,
4455 size);
4456 initlist
4457 = build_descriptor_table_initializer (objc_method_prototype_template,
4458 chain);
4460 UOBJC_INSTANCE_METHODS_decl
4461 = generate_descriptor_table (method_list_template,
4462 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4463 size, initlist, protocol);
4465 else
4466 UOBJC_INSTANCE_METHODS_decl = 0;
4469 static void
4470 generate_protocol_references (tree plist)
4472 tree lproto;
4474 /* Forward declare protocols referenced. */
4475 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4477 tree proto = TREE_VALUE (lproto);
4479 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4480 && PROTOCOL_NAME (proto))
4482 if (! PROTOCOL_FORWARD_DECL (proto))
4483 build_protocol_reference (proto);
4485 if (PROTOCOL_LIST (proto))
4486 generate_protocol_references (PROTOCOL_LIST (proto));
4491 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4492 current class. */
4493 #ifdef OBJCPLUS
4494 static void
4495 objc_generate_cxx_ctor_or_dtor (bool dtor)
4497 tree fn, body, compound_stmt, ivar;
4499 /* - (id) .cxx_construct { ... return self; } */
4500 /* - (void) .cxx_construct { ... } */
4502 objc_set_method_type (MINUS_EXPR);
4503 objc_start_method_definition
4504 (objc_build_method_signature (build_tree_list (NULL_TREE,
4505 dtor
4506 ? void_type_node
4507 : objc_object_type),
4508 get_identifier (dtor
4509 ? TAG_CXX_DESTRUCT
4510 : TAG_CXX_CONSTRUCT),
4511 make_node (TREE_LIST),
4512 false));
4513 body = begin_function_body ();
4514 compound_stmt = begin_compound_stmt (0);
4516 ivar = CLASS_IVARS (implementation_template);
4517 /* Destroy ivars in reverse order. */
4518 if (dtor)
4519 ivar = nreverse (copy_list (ivar));
4521 for (; ivar; ivar = TREE_CHAIN (ivar))
4523 if (TREE_CODE (ivar) == FIELD_DECL)
4525 tree type = TREE_TYPE (ivar);
4527 /* Call the ivar's default constructor or destructor. Do not
4528 call the destructor unless a corresponding constructor call
4529 has also been made (or is not needed). */
4530 if (MAYBE_CLASS_TYPE_P (type)
4531 && (dtor
4532 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4533 && (!TYPE_NEEDS_CONSTRUCTING (type)
4534 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4535 : (TYPE_NEEDS_CONSTRUCTING (type)
4536 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4537 finish_expr_stmt
4538 (build_special_member_call
4539 (build_ivar_reference (DECL_NAME (ivar)),
4540 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4541 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
4545 /* The constructor returns 'self'. */
4546 if (!dtor)
4547 finish_return_stmt (self_decl);
4549 finish_compound_stmt (compound_stmt);
4550 finish_function_body (body);
4551 fn = current_function_decl;
4552 finish_function ();
4553 objc_finish_method_definition (fn);
4556 /* The following routine will examine the current @interface for any
4557 non-POD C++ ivars requiring non-trivial construction and/or
4558 destruction, and then synthesize special '- .cxx_construct' and/or
4559 '- .cxx_destruct' methods which will run the appropriate
4560 construction or destruction code. Note that ivars inherited from
4561 super-classes are _not_ considered. */
4562 static void
4563 objc_generate_cxx_cdtors (void)
4565 bool need_ctor = false, need_dtor = false;
4566 tree ivar;
4568 /* We do not want to do this for categories, since they do not have
4569 their own ivars. */
4571 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4572 return;
4574 /* First, determine if we even need a constructor and/or destructor. */
4576 for (ivar = CLASS_IVARS (implementation_template); ivar;
4577 ivar = TREE_CHAIN (ivar))
4579 if (TREE_CODE (ivar) == FIELD_DECL)
4581 tree type = TREE_TYPE (ivar);
4583 if (MAYBE_CLASS_TYPE_P (type))
4585 if (TYPE_NEEDS_CONSTRUCTING (type)
4586 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4587 /* NB: If a default constructor is not available, we will not
4588 be able to initialize this ivar; the add_instance_variable()
4589 routine will already have warned about this. */
4590 need_ctor = true;
4592 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4593 && (!TYPE_NEEDS_CONSTRUCTING (type)
4594 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4595 /* NB: If a default constructor is not available, we will not
4596 call the destructor either, for symmetry. */
4597 need_dtor = true;
4602 /* Generate '- .cxx_construct' if needed. */
4604 if (need_ctor)
4605 objc_generate_cxx_ctor_or_dtor (false);
4607 /* Generate '- .cxx_destruct' if needed. */
4609 if (need_dtor)
4610 objc_generate_cxx_ctor_or_dtor (true);
4612 /* The 'imp_list' variable points at an imp_entry record for the current
4613 @implementation. Record the existence of '- .cxx_construct' and/or
4614 '- .cxx_destruct' methods therein; it will be included in the
4615 metadata for the class. */
4616 if (flag_next_runtime)
4617 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4619 #endif
4621 /* For each protocol which was referenced either from a @protocol()
4622 expression, or because a class/category implements it (then a
4623 pointer to the protocol is stored in the struct describing the
4624 class/category), we create a statically allocated instance of the
4625 Protocol class. The code is written in such a way as to generate
4626 as few Protocol objects as possible; we generate a unique Protocol
4627 instance for each protocol, and we don't generate a Protocol
4628 instance if the protocol is never referenced (either from a
4629 @protocol() or from a class/category implementation). These
4630 statically allocated objects can be referred to via the static
4631 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4633 The statically allocated Protocol objects that we generate here
4634 need to be fixed up at runtime in order to be used: the 'isa'
4635 pointer of the objects need to be set up to point to the 'Protocol'
4636 class, as known at runtime.
4638 The NeXT runtime fixes up all protocols at program startup time,
4639 before main() is entered. It uses a low-level trick to look up all
4640 those symbols, then loops on them and fixes them up.
4642 The GNU runtime as well fixes up all protocols before user code
4643 from the module is executed; it requires pointers to those symbols
4644 to be put in the objc_symtab (which is then passed as argument to
4645 the function __objc_exec_class() which the compiler sets up to be
4646 executed automatically when the module is loaded); setup of those
4647 Protocol objects happen in two ways in the GNU runtime: all
4648 Protocol objects referred to by a class or category implementation
4649 are fixed up when the class/category is loaded; all Protocol
4650 objects referred to by a @protocol() expression are added by the
4651 compiler to the list of statically allocated instances to fixup
4652 (the same list holding the statically allocated constant string
4653 objects). Because, as explained above, the compiler generates as
4654 few Protocol objects as possible, some Protocol object might end up
4655 being referenced multiple times when compiled with the GNU runtime,
4656 and end up being fixed up multiple times at runtime initialization.
4657 But that doesn't hurt, it's just a little inefficient. */
4659 static void
4660 generate_protocols (void)
4662 tree p, encoding;
4663 tree decl;
4664 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4666 /* If a protocol was directly referenced, pull in indirect references. */
4667 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4668 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4669 generate_protocol_references (PROTOCOL_LIST (p));
4671 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4673 tree nst_methods = PROTOCOL_NST_METHODS (p);
4674 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4676 /* If protocol wasn't referenced, don't generate any code. */
4677 decl = PROTOCOL_FORWARD_DECL (p);
4679 if (!decl)
4680 continue;
4682 /* Make sure we link in the Protocol class. */
4683 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4685 while (nst_methods)
4687 if (! METHOD_ENCODING (nst_methods))
4689 encoding = encode_method_prototype (nst_methods);
4690 METHOD_ENCODING (nst_methods) = encoding;
4692 nst_methods = TREE_CHAIN (nst_methods);
4695 while (cls_methods)
4697 if (! METHOD_ENCODING (cls_methods))
4699 encoding = encode_method_prototype (cls_methods);
4700 METHOD_ENCODING (cls_methods) = encoding;
4703 cls_methods = TREE_CHAIN (cls_methods);
4705 generate_method_descriptors (p);
4707 if (PROTOCOL_LIST (p))
4708 refs_decl = generate_protocol_list (p);
4709 else
4710 refs_decl = 0;
4712 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4713 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4715 if (refs_decl)
4716 refs_expr = convert (build_pointer_type (build_pointer_type
4717 (objc_protocol_template)),
4718 build_unary_op (input_location,
4719 ADDR_EXPR, refs_decl, 0));
4720 else
4721 refs_expr = build_int_cst (NULL_TREE, 0);
4723 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4724 by generate_method_descriptors, which is called above. */
4725 initlist = build_protocol_initializer (TREE_TYPE (decl),
4726 protocol_name_expr, refs_expr,
4727 UOBJC_INSTANCE_METHODS_decl,
4728 UOBJC_CLASS_METHODS_decl);
4729 finish_var_decl (decl, initlist);
4733 static tree
4734 build_protocol_initializer (tree type, tree protocol_name,
4735 tree protocol_list, tree instance_methods,
4736 tree class_methods)
4738 tree initlist = NULL_TREE, expr;
4739 tree cast_type = build_pointer_type
4740 (xref_tag (RECORD_TYPE,
4741 get_identifier (UTAG_CLASS)));
4743 /* Filling the "isa" in with one allows the runtime system to
4744 detect that the version change...should remove before final release. */
4746 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4747 initlist = tree_cons (NULL_TREE, expr, initlist);
4748 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4749 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4751 if (!instance_methods)
4752 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4753 else
4755 expr = convert (objc_method_proto_list_ptr,
4756 build_unary_op (input_location,
4757 ADDR_EXPR, instance_methods, 0));
4758 initlist = tree_cons (NULL_TREE, expr, initlist);
4761 if (!class_methods)
4762 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4763 else
4765 expr = convert (objc_method_proto_list_ptr,
4766 build_unary_op (input_location,
4767 ADDR_EXPR, class_methods, 0));
4768 initlist = tree_cons (NULL_TREE, expr, initlist);
4771 return objc_build_constructor (type, nreverse (initlist));
4774 /* struct _objc_category {
4775 char *category_name;
4776 char *class_name;
4777 struct _objc_method_list *instance_methods;
4778 struct _objc_method_list *class_methods;
4779 struct _objc_protocol_list *protocols;
4780 }; */
4782 static void
4783 build_category_template (void)
4785 tree field_decl, field_decl_chain;
4787 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
4789 /* char *category_name; */
4790 field_decl = create_field_decl (string_type_node, "category_name");
4791 field_decl_chain = field_decl;
4793 /* char *class_name; */
4794 field_decl = create_field_decl (string_type_node, "class_name");
4795 chainon (field_decl_chain, field_decl);
4797 /* struct _objc_method_list *instance_methods; */
4798 field_decl = create_field_decl (objc_method_list_ptr,
4799 "instance_methods");
4800 chainon (field_decl_chain, field_decl);
4802 /* struct _objc_method_list *class_methods; */
4803 field_decl = create_field_decl (objc_method_list_ptr,
4804 "class_methods");
4805 chainon (field_decl_chain, field_decl);
4807 /* struct _objc_protocol **protocol_list; */
4808 field_decl = create_field_decl (build_pointer_type
4809 (build_pointer_type
4810 (objc_protocol_template)),
4811 "protocol_list");
4812 chainon (field_decl_chain, field_decl);
4814 objc_finish_struct (objc_category_template, field_decl_chain);
4817 /* struct _objc_selector {
4818 SEL sel_id;
4819 char *sel_type;
4820 }; */
4822 static void
4823 build_selector_template (void)
4825 tree field_decl, field_decl_chain;
4827 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
4829 /* SEL sel_id; */
4830 field_decl = create_field_decl (objc_selector_type, "sel_id");
4831 field_decl_chain = field_decl;
4833 /* char *sel_type; */
4834 field_decl = create_field_decl (string_type_node, "sel_type");
4835 chainon (field_decl_chain, field_decl);
4837 objc_finish_struct (objc_selector_template, field_decl_chain);
4840 /* struct _objc_class {
4841 struct _objc_class *isa;
4842 struct _objc_class *super_class;
4843 char *name;
4844 long version;
4845 long info;
4846 long instance_size;
4847 struct _objc_ivar_list *ivars;
4848 struct _objc_method_list *methods;
4849 #ifdef __NEXT_RUNTIME__
4850 struct objc_cache *cache;
4851 #else
4852 struct sarray *dtable;
4853 struct _objc_class *subclass_list;
4854 struct _objc_class *sibling_class;
4855 #endif
4856 struct _objc_protocol_list *protocols;
4857 #ifdef __NEXT_RUNTIME__
4858 void *sel_id;
4859 #endif
4860 void *gc_object_type;
4861 }; */
4863 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4864 the NeXT/Apple runtime; still, the compiler must generate them to
4865 maintain backward binary compatibility (and to allow for future
4866 expansion). */
4868 static void
4869 build_class_template (void)
4871 tree field_decl, field_decl_chain;
4873 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
4875 /* struct _objc_class *isa; */
4876 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4877 "isa");
4878 field_decl_chain = field_decl;
4880 /* struct _objc_class *super_class; */
4881 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4882 "super_class");
4883 chainon (field_decl_chain, field_decl);
4885 /* char *name; */
4886 field_decl = create_field_decl (string_type_node, "name");
4887 chainon (field_decl_chain, field_decl);
4889 /* long version; */
4890 field_decl = create_field_decl (long_integer_type_node, "version");
4891 chainon (field_decl_chain, field_decl);
4893 /* long info; */
4894 field_decl = create_field_decl (long_integer_type_node, "info");
4895 chainon (field_decl_chain, field_decl);
4897 /* long instance_size; */
4898 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4899 chainon (field_decl_chain, field_decl);
4901 /* struct _objc_ivar_list *ivars; */
4902 field_decl = create_field_decl (objc_ivar_list_ptr,
4903 "ivars");
4904 chainon (field_decl_chain, field_decl);
4906 /* struct _objc_method_list *methods; */
4907 field_decl = create_field_decl (objc_method_list_ptr,
4908 "methods");
4909 chainon (field_decl_chain, field_decl);
4911 if (flag_next_runtime)
4913 /* struct objc_cache *cache; */
4914 field_decl = create_field_decl (build_pointer_type
4915 (xref_tag (RECORD_TYPE,
4916 get_identifier
4917 ("objc_cache"))),
4918 "cache");
4919 chainon (field_decl_chain, field_decl);
4921 else
4923 /* struct sarray *dtable; */
4924 field_decl = create_field_decl (build_pointer_type
4925 (xref_tag (RECORD_TYPE,
4926 get_identifier
4927 ("sarray"))),
4928 "dtable");
4929 chainon (field_decl_chain, field_decl);
4931 /* struct objc_class *subclass_list; */
4932 field_decl = create_field_decl (build_pointer_type
4933 (objc_class_template),
4934 "subclass_list");
4935 chainon (field_decl_chain, field_decl);
4937 /* struct objc_class *sibling_class; */
4938 field_decl = create_field_decl (build_pointer_type
4939 (objc_class_template),
4940 "sibling_class");
4941 chainon (field_decl_chain, field_decl);
4944 /* struct _objc_protocol **protocol_list; */
4945 field_decl = create_field_decl (build_pointer_type
4946 (build_pointer_type
4947 (xref_tag (RECORD_TYPE,
4948 get_identifier
4949 (UTAG_PROTOCOL)))),
4950 "protocol_list");
4951 chainon (field_decl_chain, field_decl);
4953 if (flag_next_runtime)
4955 /* void *sel_id; */
4956 field_decl = create_field_decl (build_pointer_type (void_type_node),
4957 "sel_id");
4958 chainon (field_decl_chain, field_decl);
4961 /* void *gc_object_type; */
4962 field_decl = create_field_decl (build_pointer_type (void_type_node),
4963 "gc_object_type");
4964 chainon (field_decl_chain, field_decl);
4966 objc_finish_struct (objc_class_template, field_decl_chain);
4969 /* Generate appropriate forward declarations for an implementation. */
4971 static void
4972 synth_forward_declarations (void)
4974 tree an_id;
4976 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4977 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4978 objc_class_template);
4980 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4981 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4982 objc_class_template);
4984 /* Pre-build the following entities - for speed/convenience. */
4986 an_id = get_identifier ("super_class");
4987 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4988 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4991 static void
4992 error_with_ivar (const char *message, tree decl)
4994 error ("%J%s %qs", decl,
4995 message, identifier_to_locale (gen_declaration (decl)));
4999 static void
5000 check_ivars (tree inter, tree imp)
5002 tree intdecls = CLASS_RAW_IVARS (inter);
5003 tree impdecls = CLASS_RAW_IVARS (imp);
5005 while (1)
5007 tree t1, t2;
5009 #ifdef OBJCPLUS
5010 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5011 intdecls = TREE_CHAIN (intdecls);
5012 #endif
5013 if (intdecls == 0 && impdecls == 0)
5014 break;
5015 if (intdecls == 0 || impdecls == 0)
5017 error ("inconsistent instance variable specification");
5018 break;
5021 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5023 if (!comptypes (t1, t2)
5024 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5025 DECL_INITIAL (impdecls)))
5027 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5029 error_with_ivar ("conflicting instance variable type",
5030 impdecls);
5031 error_with_ivar ("previous declaration of",
5032 intdecls);
5034 else /* both the type and the name don't match */
5036 error ("inconsistent instance variable specification");
5037 break;
5041 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5043 error_with_ivar ("conflicting instance variable name",
5044 impdecls);
5045 error_with_ivar ("previous declaration of",
5046 intdecls);
5049 intdecls = TREE_CHAIN (intdecls);
5050 impdecls = TREE_CHAIN (impdecls);
5054 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5055 This needs to be done just once per compilation. */
5057 /* struct _objc_super {
5058 struct _objc_object *self;
5059 struct _objc_class *super_class;
5060 }; */
5062 static void
5063 build_super_template (void)
5065 tree field_decl, field_decl_chain;
5067 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5069 /* struct _objc_object *self; */
5070 field_decl = create_field_decl (objc_object_type, "self");
5071 field_decl_chain = field_decl;
5073 /* struct _objc_class *super_class; */
5074 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5075 "super_class");
5076 chainon (field_decl_chain, field_decl);
5078 objc_finish_struct (objc_super_template, field_decl_chain);
5081 /* struct _objc_ivar {
5082 char *ivar_name;
5083 char *ivar_type;
5084 int ivar_offset;
5085 }; */
5087 static tree
5088 build_ivar_template (void)
5090 tree objc_ivar_id, objc_ivar_record;
5091 tree field_decl, field_decl_chain;
5093 objc_ivar_id = get_identifier (UTAG_IVAR);
5094 objc_ivar_record = objc_start_struct (objc_ivar_id);
5096 /* char *ivar_name; */
5097 field_decl = create_field_decl (string_type_node, "ivar_name");
5098 field_decl_chain = field_decl;
5100 /* char *ivar_type; */
5101 field_decl = create_field_decl (string_type_node, "ivar_type");
5102 chainon (field_decl_chain, field_decl);
5104 /* int ivar_offset; */
5105 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5106 chainon (field_decl_chain, field_decl);
5108 objc_finish_struct (objc_ivar_record, field_decl_chain);
5110 return objc_ivar_record;
5113 /* struct {
5114 int ivar_count;
5115 struct objc_ivar ivar_list[ivar_count];
5116 }; */
5118 static tree
5119 build_ivar_list_template (tree list_type, int size)
5121 tree objc_ivar_list_record;
5122 tree field_decl, field_decl_chain;
5124 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5126 /* int ivar_count; */
5127 field_decl = create_field_decl (integer_type_node, "ivar_count");
5128 field_decl_chain = field_decl;
5130 /* struct objc_ivar ivar_list[]; */
5131 field_decl = create_field_decl (build_array_type
5132 (list_type,
5133 build_index_type
5134 (build_int_cst (NULL_TREE, size - 1))),
5135 "ivar_list");
5136 chainon (field_decl_chain, field_decl);
5138 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5140 return objc_ivar_list_record;
5143 /* struct {
5144 struct _objc__method_prototype_list *method_next;
5145 int method_count;
5146 struct objc_method method_list[method_count];
5147 }; */
5149 static tree
5150 build_method_list_template (tree list_type, int size)
5152 tree objc_ivar_list_record;
5153 tree field_decl, field_decl_chain;
5155 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5157 /* struct _objc__method_prototype_list *method_next; */
5158 field_decl = create_field_decl (objc_method_proto_list_ptr,
5159 "method_next");
5160 field_decl_chain = field_decl;
5162 /* int method_count; */
5163 field_decl = create_field_decl (integer_type_node, "method_count");
5164 chainon (field_decl_chain, field_decl);
5166 /* struct objc_method method_list[]; */
5167 field_decl = create_field_decl (build_array_type
5168 (list_type,
5169 build_index_type
5170 (build_int_cst (NULL_TREE, size - 1))),
5171 "method_list");
5172 chainon (field_decl_chain, field_decl);
5174 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5176 return objc_ivar_list_record;
5179 static tree
5180 build_ivar_list_initializer (tree type, tree field_decl)
5182 tree initlist = NULL_TREE;
5186 tree ivar = NULL_TREE;
5188 /* Set name. */
5189 if (DECL_NAME (field_decl))
5190 ivar = tree_cons (NULL_TREE,
5191 add_objc_string (DECL_NAME (field_decl),
5192 meth_var_names),
5193 ivar);
5194 else
5195 /* Unnamed bit-field ivar (yuck). */
5196 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5198 /* Set type. */
5199 encode_field_decl (field_decl,
5200 obstack_object_size (&util_obstack),
5201 OBJC_ENCODE_DONT_INLINE_DEFS);
5203 /* Null terminate string. */
5204 obstack_1grow (&util_obstack, 0);
5205 ivar
5206 = tree_cons
5207 (NULL_TREE,
5208 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5209 meth_var_types),
5210 ivar);
5211 obstack_free (&util_obstack, util_firstobj);
5213 /* Set offset. */
5214 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5215 initlist = tree_cons (NULL_TREE,
5216 objc_build_constructor (type, nreverse (ivar)),
5217 initlist);
5219 field_decl = TREE_CHAIN (field_decl);
5220 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5222 while (field_decl);
5224 return objc_build_constructor (build_array_type (type, 0),
5225 nreverse (initlist));
5228 static tree
5229 generate_ivars_list (tree type, const char *name, int size, tree list)
5231 tree decl, initlist;
5233 decl = start_var_decl (type, synth_id_with_class_suffix
5234 (name, objc_implementation_context));
5236 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5237 initlist = tree_cons (NULL_TREE, list, initlist);
5239 finish_var_decl (decl,
5240 objc_build_constructor (TREE_TYPE (decl),
5241 nreverse (initlist)));
5243 return decl;
5246 /* Count only the fields occurring in T. */
5248 static int
5249 ivar_list_length (tree t)
5251 int count = 0;
5253 for (; t; t = TREE_CHAIN (t))
5254 if (TREE_CODE (t) == FIELD_DECL)
5255 ++count;
5257 return count;
5260 static void
5261 generate_ivar_lists (void)
5263 tree initlist, ivar_list_template, chain;
5264 int size;
5266 generating_instance_variables = 1;
5268 if (!objc_ivar_template)
5269 objc_ivar_template = build_ivar_template ();
5271 /* Only generate class variables for the root of the inheritance
5272 hierarchy since these will be the same for every class. */
5274 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5275 && (chain = TYPE_FIELDS (objc_class_template)))
5277 size = ivar_list_length (chain);
5279 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5280 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5282 UOBJC_CLASS_VARIABLES_decl
5283 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5284 size, initlist);
5286 else
5287 UOBJC_CLASS_VARIABLES_decl = 0;
5289 chain = CLASS_IVARS (implementation_template);
5290 if (chain)
5292 size = ivar_list_length (chain);
5293 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5294 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5296 UOBJC_INSTANCE_VARIABLES_decl
5297 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5298 size, initlist);
5300 else
5301 UOBJC_INSTANCE_VARIABLES_decl = 0;
5303 generating_instance_variables = 0;
5306 static tree
5307 build_dispatch_table_initializer (tree type, tree entries)
5309 tree initlist = NULL_TREE;
5313 tree elemlist = NULL_TREE;
5315 elemlist = tree_cons (NULL_TREE,
5316 build_selector (METHOD_SEL_NAME (entries)),
5317 NULL_TREE);
5319 /* Generate the method encoding if we don't have one already. */
5320 if (! METHOD_ENCODING (entries))
5321 METHOD_ENCODING (entries) =
5322 encode_method_prototype (entries);
5324 elemlist = tree_cons (NULL_TREE,
5325 add_objc_string (METHOD_ENCODING (entries),
5326 meth_var_types),
5327 elemlist);
5329 elemlist
5330 = tree_cons (NULL_TREE,
5331 convert (ptr_type_node,
5332 build_unary_op (input_location, ADDR_EXPR,
5333 METHOD_DEFINITION (entries), 1)),
5334 elemlist);
5336 initlist = tree_cons (NULL_TREE,
5337 objc_build_constructor (type, nreverse (elemlist)),
5338 initlist);
5340 entries = TREE_CHAIN (entries);
5342 while (entries);
5344 return objc_build_constructor (build_array_type (type, 0),
5345 nreverse (initlist));
5348 /* To accomplish method prototyping without generating all kinds of
5349 inane warnings, the definition of the dispatch table entries were
5350 changed from:
5352 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5354 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5356 static tree
5357 build_method_template (void)
5359 tree _SLT_record;
5360 tree field_decl, field_decl_chain;
5362 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5364 /* SEL _cmd; */
5365 field_decl = create_field_decl (objc_selector_type, "_cmd");
5366 field_decl_chain = field_decl;
5368 /* char *method_types; */
5369 field_decl = create_field_decl (string_type_node, "method_types");
5370 chainon (field_decl_chain, field_decl);
5372 /* void *_imp; */
5373 field_decl = create_field_decl (build_pointer_type (void_type_node),
5374 "_imp");
5375 chainon (field_decl_chain, field_decl);
5377 objc_finish_struct (_SLT_record, field_decl_chain);
5379 return _SLT_record;
5383 static tree
5384 generate_dispatch_table (tree type, const char *name, int size, tree list)
5386 tree decl, initlist;
5388 decl = start_var_decl (type, synth_id_with_class_suffix
5389 (name, objc_implementation_context));
5391 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5392 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5393 initlist = tree_cons (NULL_TREE, list, initlist);
5395 finish_var_decl (decl,
5396 objc_build_constructor (TREE_TYPE (decl),
5397 nreverse (initlist)));
5399 return decl;
5402 static void
5403 mark_referenced_methods (void)
5405 struct imp_entry *impent;
5406 tree chain;
5408 for (impent = imp_list; impent; impent = impent->next)
5410 chain = CLASS_CLS_METHODS (impent->imp_context);
5411 while (chain)
5413 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5414 chain = TREE_CHAIN (chain);
5417 chain = CLASS_NST_METHODS (impent->imp_context);
5418 while (chain)
5420 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5421 chain = TREE_CHAIN (chain);
5426 static void
5427 generate_dispatch_tables (void)
5429 tree initlist, chain, method_list_template;
5430 int size;
5432 if (!objc_method_template)
5433 objc_method_template = build_method_template ();
5435 chain = CLASS_CLS_METHODS (objc_implementation_context);
5436 if (chain)
5438 size = list_length (chain);
5440 method_list_template
5441 = build_method_list_template (objc_method_template, size);
5442 initlist
5443 = build_dispatch_table_initializer (objc_method_template, chain);
5445 UOBJC_CLASS_METHODS_decl
5446 = generate_dispatch_table (method_list_template,
5447 ((TREE_CODE (objc_implementation_context)
5448 == CLASS_IMPLEMENTATION_TYPE)
5449 ? "_OBJC_CLASS_METHODS"
5450 : "_OBJC_CATEGORY_CLASS_METHODS"),
5451 size, initlist);
5453 else
5454 UOBJC_CLASS_METHODS_decl = 0;
5456 chain = CLASS_NST_METHODS (objc_implementation_context);
5457 if (chain)
5459 size = list_length (chain);
5461 method_list_template
5462 = build_method_list_template (objc_method_template, size);
5463 initlist
5464 = build_dispatch_table_initializer (objc_method_template, chain);
5466 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5467 UOBJC_INSTANCE_METHODS_decl
5468 = generate_dispatch_table (method_list_template,
5469 "_OBJC_INSTANCE_METHODS",
5470 size, initlist);
5471 else
5472 /* We have a category. */
5473 UOBJC_INSTANCE_METHODS_decl
5474 = generate_dispatch_table (method_list_template,
5475 "_OBJC_CATEGORY_INSTANCE_METHODS",
5476 size, initlist);
5478 else
5479 UOBJC_INSTANCE_METHODS_decl = 0;
5482 static tree
5483 generate_protocol_list (tree i_or_p)
5485 tree initlist;
5486 tree refs_decl, lproto, e, plist;
5487 int size = 0;
5488 const char *ref_name;
5490 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5491 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5492 plist = CLASS_PROTOCOL_LIST (i_or_p);
5493 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5494 plist = PROTOCOL_LIST (i_or_p);
5495 else
5496 abort ();
5498 /* Compute size. */
5499 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5500 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5501 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5502 size++;
5504 /* Build initializer. */
5505 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5506 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5507 initlist = tree_cons (NULL_TREE, e, initlist);
5509 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5511 tree pval = TREE_VALUE (lproto);
5513 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5514 && PROTOCOL_FORWARD_DECL (pval))
5516 e = build_unary_op (input_location, ADDR_EXPR,
5517 PROTOCOL_FORWARD_DECL (pval), 0);
5518 initlist = tree_cons (NULL_TREE, e, initlist);
5522 /* static struct objc_protocol *refs[n]; */
5524 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5525 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5526 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5527 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5528 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5529 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5530 else
5531 abort ();
5533 refs_decl = start_var_decl
5534 (build_array_type
5535 (build_pointer_type (objc_protocol_template),
5536 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5537 ref_name);
5539 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5540 nreverse (initlist)));
5542 return refs_decl;
5545 static tree
5546 build_category_initializer (tree type, tree cat_name, tree class_name,
5547 tree instance_methods, tree class_methods,
5548 tree protocol_list)
5550 tree initlist = NULL_TREE, expr;
5552 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5553 initlist = tree_cons (NULL_TREE, class_name, initlist);
5555 if (!instance_methods)
5556 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5557 else
5559 expr = convert (objc_method_list_ptr,
5560 build_unary_op (input_location, ADDR_EXPR,
5561 instance_methods, 0));
5562 initlist = tree_cons (NULL_TREE, expr, initlist);
5564 if (!class_methods)
5565 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5566 else
5568 expr = convert (objc_method_list_ptr,
5569 build_unary_op (input_location, ADDR_EXPR,
5570 class_methods, 0));
5571 initlist = tree_cons (NULL_TREE, expr, initlist);
5574 /* protocol_list = */
5575 if (!protocol_list)
5576 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5577 else
5579 expr = convert (build_pointer_type
5580 (build_pointer_type
5581 (objc_protocol_template)),
5582 build_unary_op (input_location, ADDR_EXPR,
5583 protocol_list, 0));
5584 initlist = tree_cons (NULL_TREE, expr, initlist);
5587 return objc_build_constructor (type, nreverse (initlist));
5590 /* struct _objc_class {
5591 struct objc_class *isa;
5592 struct objc_class *super_class;
5593 char *name;
5594 long version;
5595 long info;
5596 long instance_size;
5597 struct objc_ivar_list *ivars;
5598 struct objc_method_list *methods;
5599 if (flag_next_runtime)
5600 struct objc_cache *cache;
5601 else {
5602 struct sarray *dtable;
5603 struct objc_class *subclass_list;
5604 struct objc_class *sibling_class;
5606 struct objc_protocol_list *protocols;
5607 if (flag_next_runtime)
5608 void *sel_id;
5609 void *gc_object_type;
5610 }; */
5612 static tree
5613 build_shared_structure_initializer (tree type, tree isa, tree super,
5614 tree name, tree size, int status,
5615 tree dispatch_table, tree ivar_list,
5616 tree protocol_list)
5618 tree initlist = NULL_TREE, expr;
5620 /* isa = */
5621 initlist = tree_cons (NULL_TREE, isa, initlist);
5623 /* super_class = */
5624 initlist = tree_cons (NULL_TREE, super, initlist);
5626 /* name = */
5627 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5629 /* version = */
5630 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5631 initlist);
5633 /* info = */
5634 initlist = tree_cons (NULL_TREE,
5635 build_int_cst (long_integer_type_node, status),
5636 initlist);
5638 /* instance_size = */
5639 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5640 initlist);
5642 /* objc_ivar_list = */
5643 if (!ivar_list)
5644 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5645 else
5647 expr = convert (objc_ivar_list_ptr,
5648 build_unary_op (input_location, ADDR_EXPR,
5649 ivar_list, 0));
5650 initlist = tree_cons (NULL_TREE, expr, initlist);
5653 /* objc_method_list = */
5654 if (!dispatch_table)
5655 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5656 else
5658 expr = convert (objc_method_list_ptr,
5659 build_unary_op (input_location, ADDR_EXPR,
5660 dispatch_table, 0));
5661 initlist = tree_cons (NULL_TREE, expr, initlist);
5664 if (flag_next_runtime)
5665 /* method_cache = */
5666 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5667 else
5669 /* dtable = */
5670 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5672 /* subclass_list = */
5673 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5675 /* sibling_class = */
5676 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5679 /* protocol_list = */
5680 if (! protocol_list)
5681 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5682 else
5684 expr = convert (build_pointer_type
5685 (build_pointer_type
5686 (objc_protocol_template)),
5687 build_unary_op (input_location, ADDR_EXPR,
5688 protocol_list, 0));
5689 initlist = tree_cons (NULL_TREE, expr, initlist);
5692 if (flag_next_runtime)
5693 /* sel_id = NULL */
5694 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5696 /* gc_object_type = NULL */
5697 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5699 return objc_build_constructor (type, nreverse (initlist));
5702 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5704 static inline tree
5705 lookup_category (tree klass, tree cat_name)
5707 tree category = CLASS_CATEGORY_LIST (klass);
5709 while (category && CLASS_SUPER_NAME (category) != cat_name)
5710 category = CLASS_CATEGORY_LIST (category);
5711 return category;
5714 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5716 static void
5717 generate_category (tree cat)
5719 tree decl;
5720 tree initlist, cat_name_expr, class_name_expr;
5721 tree protocol_decl, category;
5723 add_class_reference (CLASS_NAME (cat));
5724 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5726 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5728 category = lookup_category (implementation_template,
5729 CLASS_SUPER_NAME (cat));
5731 if (category && CLASS_PROTOCOL_LIST (category))
5733 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5734 protocol_decl = generate_protocol_list (category);
5736 else
5737 protocol_decl = 0;
5739 decl = start_var_decl (objc_category_template,
5740 synth_id_with_class_suffix
5741 ("_OBJC_CATEGORY", objc_implementation_context));
5743 initlist = build_category_initializer (TREE_TYPE (decl),
5744 cat_name_expr, class_name_expr,
5745 UOBJC_INSTANCE_METHODS_decl,
5746 UOBJC_CLASS_METHODS_decl,
5747 protocol_decl);
5749 finish_var_decl (decl, initlist);
5752 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5753 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5755 static void
5756 generate_shared_structures (int cls_flags)
5758 tree sc_spec, decl_specs, decl;
5759 tree name_expr, super_expr, root_expr;
5760 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5761 tree cast_type, initlist, protocol_decl;
5763 my_super_id = CLASS_SUPER_NAME (implementation_template);
5764 if (my_super_id)
5766 add_class_reference (my_super_id);
5768 /* Compute "my_root_id" - this is required for code generation.
5769 the "isa" for all meta class structures points to the root of
5770 the inheritance hierarchy (e.g. "__Object")... */
5771 my_root_id = my_super_id;
5774 tree my_root_int = lookup_interface (my_root_id);
5776 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5777 my_root_id = CLASS_SUPER_NAME (my_root_int);
5778 else
5779 break;
5781 while (1);
5783 else
5784 /* No super class. */
5785 my_root_id = CLASS_NAME (implementation_template);
5787 cast_type = build_pointer_type (objc_class_template);
5788 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5789 class_names);
5791 /* Install class `isa' and `super' pointers at runtime. */
5792 if (my_super_id)
5794 super_expr = add_objc_string (my_super_id, class_names);
5795 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5797 else
5798 super_expr = build_int_cst (NULL_TREE, 0);
5800 root_expr = add_objc_string (my_root_id, class_names);
5801 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5803 if (CLASS_PROTOCOL_LIST (implementation_template))
5805 generate_protocol_references
5806 (CLASS_PROTOCOL_LIST (implementation_template));
5807 protocol_decl = generate_protocol_list (implementation_template);
5809 else
5810 protocol_decl = 0;
5812 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5814 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5815 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5817 decl = start_var_decl (objc_class_template,
5818 IDENTIFIER_POINTER
5819 (DECL_NAME (UOBJC_METACLASS_decl)));
5821 initlist
5822 = build_shared_structure_initializer
5823 (TREE_TYPE (decl),
5824 root_expr, super_expr, name_expr,
5825 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5826 2 /*CLS_META*/,
5827 UOBJC_CLASS_METHODS_decl,
5828 UOBJC_CLASS_VARIABLES_decl,
5829 protocol_decl);
5831 finish_var_decl (decl, initlist);
5833 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5835 decl = start_var_decl (objc_class_template,
5836 IDENTIFIER_POINTER
5837 (DECL_NAME (UOBJC_CLASS_decl)));
5839 initlist
5840 = build_shared_structure_initializer
5841 (TREE_TYPE (decl),
5842 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5843 super_expr, name_expr,
5844 convert (integer_type_node,
5845 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5846 (implementation_template))),
5847 1 /*CLS_FACTORY*/ | cls_flags,
5848 UOBJC_INSTANCE_METHODS_decl,
5849 UOBJC_INSTANCE_VARIABLES_decl,
5850 protocol_decl);
5852 finish_var_decl (decl, initlist);
5856 static const char *
5857 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5859 static char string[BUFSIZE];
5861 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5862 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5864 sprintf (string, "%s_%s", preamble,
5865 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5867 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5868 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5870 /* We have a category. */
5871 const char *const class_name
5872 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5873 const char *const class_super_name
5874 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5875 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5877 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5879 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5880 sprintf (string, "%s_%s", preamble, protocol_name);
5882 else
5883 abort ();
5885 return string;
5888 /* If type is empty or only type qualifiers are present, add default
5889 type of id (otherwise grokdeclarator will default to int). */
5891 static tree
5892 adjust_type_for_id_default (tree type)
5894 if (!type)
5895 type = make_node (TREE_LIST);
5897 if (!TREE_VALUE (type))
5898 TREE_VALUE (type) = objc_object_type;
5899 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5900 && TYPED_OBJECT (TREE_VALUE (type)))
5901 error ("can not use an object as parameter to a method");
5903 return type;
5906 /* Usage:
5907 keyworddecl:
5908 selector ':' '(' typename ')' identifier
5910 Purpose:
5911 Transform an Objective-C keyword argument into
5912 the C equivalent parameter declarator.
5914 In: key_name, an "identifier_node" (optional).
5915 arg_type, a "tree_list" (optional).
5916 arg_name, an "identifier_node".
5918 Note: It would be really nice to strongly type the preceding
5919 arguments in the function prototype; however, then I
5920 could not use the "accessor" macros defined in "tree.h".
5922 Out: an instance of "keyword_decl". */
5924 tree
5925 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5927 tree keyword_decl;
5929 /* If no type is specified, default to "id". */
5930 arg_type = adjust_type_for_id_default (arg_type);
5932 keyword_decl = make_node (KEYWORD_DECL);
5934 TREE_TYPE (keyword_decl) = arg_type;
5935 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5936 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5938 return keyword_decl;
5941 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5943 static tree
5944 build_keyword_selector (tree selector)
5946 int len = 0;
5947 tree key_chain, key_name;
5948 char *buf;
5950 /* Scan the selector to see how much space we'll need. */
5951 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5953 if (TREE_CODE (selector) == KEYWORD_DECL)
5954 key_name = KEYWORD_KEY_NAME (key_chain);
5955 else if (TREE_CODE (selector) == TREE_LIST)
5956 key_name = TREE_PURPOSE (key_chain);
5957 else
5958 abort ();
5960 if (key_name)
5961 len += IDENTIFIER_LENGTH (key_name) + 1;
5962 else
5963 /* Just a ':' arg. */
5964 len++;
5967 buf = (char *) alloca (len + 1);
5968 /* Start the buffer out as an empty string. */
5969 buf[0] = '\0';
5971 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5973 if (TREE_CODE (selector) == KEYWORD_DECL)
5974 key_name = KEYWORD_KEY_NAME (key_chain);
5975 else if (TREE_CODE (selector) == TREE_LIST)
5977 key_name = TREE_PURPOSE (key_chain);
5978 /* The keyword decl chain will later be used as a function argument
5979 chain. Unhook the selector itself so as to not confuse other
5980 parts of the compiler. */
5981 TREE_PURPOSE (key_chain) = NULL_TREE;
5983 else
5984 abort ();
5986 if (key_name)
5987 strcat (buf, IDENTIFIER_POINTER (key_name));
5988 strcat (buf, ":");
5991 return get_identifier (buf);
5994 /* Used for declarations and definitions. */
5996 static tree
5997 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5998 tree add_args, bool ellipsis)
6000 tree method_decl;
6002 /* If no type is specified, default to "id". */
6003 ret_type = adjust_type_for_id_default (ret_type);
6005 method_decl = make_node (code);
6006 TREE_TYPE (method_decl) = ret_type;
6008 /* If we have a keyword selector, create an identifier_node that
6009 represents the full selector name (`:' included)... */
6010 if (TREE_CODE (selector) == KEYWORD_DECL)
6012 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6013 METHOD_SEL_ARGS (method_decl) = selector;
6014 METHOD_ADD_ARGS (method_decl) = add_args;
6015 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6017 else
6019 METHOD_SEL_NAME (method_decl) = selector;
6020 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6021 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6024 return method_decl;
6027 #define METHOD_DEF 0
6028 #define METHOD_REF 1
6030 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6031 an argument list for method METH. CONTEXT is either METHOD_DEF or
6032 METHOD_REF, saying whether we are trying to define a method or call
6033 one. SUPERFLAG says this is for a send to super; this makes a
6034 difference for the NeXT calling sequence in which the lookup and
6035 the method call are done together. If METH is null, user-defined
6036 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6038 static tree
6039 get_arg_type_list (tree meth, int context, int superflag)
6041 tree arglist, akey;
6043 /* Receiver type. */
6044 if (flag_next_runtime && superflag)
6045 arglist = build_tree_list (NULL_TREE, objc_super_type);
6046 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6047 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6048 else
6049 arglist = build_tree_list (NULL_TREE, objc_object_type);
6051 /* Selector type - will eventually change to `int'. */
6052 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6054 /* No actual method prototype given -- assume that remaining arguments
6055 are `...'. */
6056 if (!meth)
6057 return arglist;
6059 /* Build a list of argument types. */
6060 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6062 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6064 /* Decay arrays and functions into pointers. */
6065 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6066 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6067 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6068 arg_type = build_pointer_type (arg_type);
6070 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6073 if (METHOD_ADD_ARGS (meth))
6075 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6076 akey; akey = TREE_CHAIN (akey))
6078 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6080 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6083 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6084 goto lack_of_ellipsis;
6086 else
6088 lack_of_ellipsis:
6089 chainon (arglist, OBJC_VOID_AT_END);
6092 return arglist;
6095 static tree
6096 check_duplicates (hash hsh, int methods, int is_class)
6098 tree meth = NULL_TREE;
6100 if (hsh)
6102 meth = hsh->key;
6104 if (hsh->list)
6106 /* We have two or more methods with the same name but
6107 different types. */
6108 attr loop;
6110 /* But just how different are those types? If
6111 -Wno-strict-selector-match is specified, we shall not
6112 complain if the differences are solely among types with
6113 identical size and alignment. */
6114 if (!warn_strict_selector_match)
6116 for (loop = hsh->list; loop; loop = loop->next)
6117 if (!comp_proto_with_proto (meth, loop->value, 0))
6118 goto issue_warning;
6120 return meth;
6123 issue_warning:
6124 if (methods)
6126 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6128 warning (0, "multiple methods named %<%c%E%> found",
6129 (is_class ? '+' : '-'),
6130 METHOD_SEL_NAME (meth));
6131 inform (0, "%Jusing %<%c%s%>", meth,
6132 (type ? '-' : '+'),
6133 identifier_to_locale (gen_method_decl (meth)));
6135 else
6137 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6139 warning (0, "multiple selectors named %<%c%E%> found",
6140 (is_class ? '+' : '-'),
6141 METHOD_SEL_NAME (meth));
6142 inform (0, "%Jfound %<%c%s%>", meth,
6143 (type ? '-' : '+'),
6144 identifier_to_locale (gen_method_decl (meth)));
6147 for (loop = hsh->list; loop; loop = loop->next)
6149 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6151 inform (0, "%Jalso found %<%c%s%>", loop->value,
6152 (type ? '-' : '+'),
6153 identifier_to_locale (gen_method_decl (loop->value)));
6157 return meth;
6160 /* If RECEIVER is a class reference, return the identifier node for
6161 the referenced class. RECEIVER is created by objc_get_class_reference,
6162 so we check the exact form created depending on which runtimes are
6163 used. */
6165 static tree
6166 receiver_is_class_object (tree receiver, int self, int super)
6168 tree chain, exp, arg;
6170 /* The receiver is 'self' or 'super' in the context of a class method. */
6171 if (objc_method_context
6172 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6173 && (self || super))
6174 return (super
6175 ? CLASS_SUPER_NAME (implementation_template)
6176 : CLASS_NAME (implementation_template));
6178 if (flag_next_runtime)
6180 /* The receiver is a variable created by
6181 build_class_reference_decl. */
6182 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6183 /* Look up the identifier. */
6184 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6185 if (TREE_PURPOSE (chain) == receiver)
6186 return TREE_VALUE (chain);
6189 /* The receiver is a function call that returns an id. Check if
6190 it is a call to objc_getClass, if so, pick up the class name. */
6191 if (TREE_CODE (receiver) == CALL_EXPR
6192 && (exp = CALL_EXPR_FN (receiver))
6193 && TREE_CODE (exp) == ADDR_EXPR
6194 && (exp = TREE_OPERAND (exp, 0))
6195 && TREE_CODE (exp) == FUNCTION_DECL
6196 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6197 prototypes for objc_get_class(). Thankfully, they seem to share the
6198 same function type. */
6199 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6200 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6201 /* We have a call to objc_get_class/objc_getClass! */
6202 && (arg = CALL_EXPR_ARG (receiver, 0)))
6204 STRIP_NOPS (arg);
6205 if (TREE_CODE (arg) == ADDR_EXPR
6206 && (arg = TREE_OPERAND (arg, 0))
6207 && TREE_CODE (arg) == STRING_CST)
6208 /* Finally, we have the class name. */
6209 return get_identifier (TREE_STRING_POINTER (arg));
6211 return 0;
6214 /* If we are currently building a message expr, this holds
6215 the identifier of the selector of the message. This is
6216 used when printing warnings about argument mismatches. */
6218 static tree current_objc_message_selector = 0;
6220 tree
6221 objc_message_selector (void)
6223 return current_objc_message_selector;
6226 /* Construct an expression for sending a message.
6227 MESS has the object to send to in TREE_PURPOSE
6228 and the argument list (including selector) in TREE_VALUE.
6230 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6231 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6233 tree
6234 objc_build_message_expr (tree mess)
6236 tree receiver = TREE_PURPOSE (mess);
6237 tree sel_name;
6238 #ifdef OBJCPLUS
6239 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6240 #else
6241 tree args = TREE_VALUE (mess);
6242 #endif
6243 tree method_params = NULL_TREE;
6245 if (TREE_CODE (receiver) == ERROR_MARK)
6246 return error_mark_node;
6248 /* Obtain the full selector name. */
6249 if (TREE_CODE (args) == IDENTIFIER_NODE)
6250 /* A unary selector. */
6251 sel_name = args;
6252 else if (TREE_CODE (args) == TREE_LIST)
6253 sel_name = build_keyword_selector (args);
6254 else
6255 abort ();
6257 /* Build the parameter list to give to the method. */
6258 if (TREE_CODE (args) == TREE_LIST)
6259 #ifdef OBJCPLUS
6260 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6261 #else
6263 tree chain = args, prev = NULL_TREE;
6265 /* We have a keyword selector--check for comma expressions. */
6266 while (chain)
6268 tree element = TREE_VALUE (chain);
6270 /* We have a comma expression, must collapse... */
6271 if (TREE_CODE (element) == TREE_LIST)
6273 if (prev)
6274 TREE_CHAIN (prev) = element;
6275 else
6276 args = element;
6278 prev = chain;
6279 chain = TREE_CHAIN (chain);
6281 method_params = args;
6283 #endif
6285 #ifdef OBJCPLUS
6286 if (processing_template_decl)
6287 /* Must wait until template instantiation time. */
6288 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6289 method_params);
6290 #endif
6292 return objc_finish_message_expr (receiver, sel_name, method_params);
6295 /* Look up method SEL_NAME that would be suitable for receiver
6296 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6297 nonzero), and report on any duplicates. */
6299 static tree
6300 lookup_method_in_hash_lists (tree sel_name, int is_class)
6302 hash method_prototype = NULL;
6304 if (!is_class)
6305 method_prototype = hash_lookup (nst_method_hash_list,
6306 sel_name);
6308 if (!method_prototype)
6310 method_prototype = hash_lookup (cls_method_hash_list,
6311 sel_name);
6312 is_class = 1;
6315 return check_duplicates (method_prototype, 1, is_class);
6318 /* The 'objc_finish_message_expr' routine is called from within
6319 'objc_build_message_expr' for non-template functions. In the case of
6320 C++ template functions, it is called from 'build_expr_from_tree'
6321 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6323 tree
6324 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6326 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6327 tree selector, retval, class_tree;
6328 int self, super, have_cast;
6330 /* Extract the receiver of the message, as well as its type
6331 (where the latter may take the form of a cast or be inferred
6332 from the implementation context). */
6333 rtype = receiver;
6334 while (TREE_CODE (rtype) == COMPOUND_EXPR
6335 || TREE_CODE (rtype) == MODIFY_EXPR
6336 || CONVERT_EXPR_P (rtype)
6337 || TREE_CODE (rtype) == COMPONENT_REF)
6338 rtype = TREE_OPERAND (rtype, 0);
6339 self = (rtype == self_decl);
6340 super = (rtype == UOBJC_SUPER_decl);
6341 rtype = TREE_TYPE (receiver);
6342 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6343 || (TREE_CODE (receiver) == COMPOUND_EXPR
6344 && !IS_SUPER (rtype)));
6346 /* If we are calling [super dealloc], reset our warning flag. */
6347 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6348 should_call_super_dealloc = 0;
6350 /* If the receiver is a class object, retrieve the corresponding
6351 @interface, if one exists. */
6352 class_tree = receiver_is_class_object (receiver, self, super);
6354 /* Now determine the receiver type (if an explicit cast has not been
6355 provided). */
6356 if (!have_cast)
6358 if (class_tree)
6359 rtype = lookup_interface (class_tree);
6360 /* Handle `self' and `super'. */
6361 else if (super)
6363 if (!CLASS_SUPER_NAME (implementation_template))
6365 error ("no super class declared in @interface for %qE",
6366 CLASS_NAME (implementation_template));
6367 return error_mark_node;
6369 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6371 else if (self)
6372 rtype = lookup_interface (CLASS_NAME (implementation_template));
6375 /* If receiver is of type `id' or `Class' (or if the @interface for a
6376 class is not visible), we shall be satisfied with the existence of
6377 any instance or class method. */
6378 if (objc_is_id (rtype))
6380 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6381 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6382 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6383 : NULL_TREE);
6384 rtype = NULL_TREE;
6386 if (rprotos)
6388 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6389 in protocols themselves for the method prototype. */
6390 method_prototype
6391 = lookup_method_in_protocol_list (rprotos, sel_name,
6392 class_tree != NULL_TREE);
6394 /* If messaging 'Class <Proto>' but did not find a class method
6395 prototype, search for an instance method instead, and warn
6396 about having done so. */
6397 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6399 method_prototype
6400 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6402 if (method_prototype)
6403 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
6404 sel_name, sel_name);
6408 else if (rtype)
6410 tree orig_rtype = rtype, saved_rtype;
6412 if (TREE_CODE (rtype) == POINTER_TYPE)
6413 rtype = TREE_TYPE (rtype);
6414 /* Traverse typedef aliases */
6415 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6416 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6417 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6418 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6419 saved_rtype = rtype;
6420 if (TYPED_OBJECT (rtype))
6422 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6423 rtype = TYPE_OBJC_INTERFACE (rtype);
6425 /* If we could not find an @interface declaration, we must have
6426 only seen a @class declaration; so, we cannot say anything
6427 more intelligent about which methods the receiver will
6428 understand. */
6429 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6430 rtype = NULL_TREE;
6431 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6432 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6434 /* We have a valid ObjC class name. Look up the method name
6435 in the published @interface for the class (and its
6436 superclasses). */
6437 method_prototype
6438 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6440 /* If the method was not found in the @interface, it may still
6441 exist locally as part of the @implementation. */
6442 if (!method_prototype && objc_implementation_context
6443 && CLASS_NAME (objc_implementation_context)
6444 == OBJC_TYPE_NAME (rtype))
6445 method_prototype
6446 = lookup_method
6447 ((class_tree
6448 ? CLASS_CLS_METHODS (objc_implementation_context)
6449 : CLASS_NST_METHODS (objc_implementation_context)),
6450 sel_name);
6452 /* If we haven't found a candidate method by now, try looking for
6453 it in the protocol list. */
6454 if (!method_prototype && rprotos)
6455 method_prototype
6456 = lookup_method_in_protocol_list (rprotos, sel_name,
6457 class_tree != NULL_TREE);
6459 else
6461 warning (0, "invalid receiver type %qs",
6462 identifier_to_locale (gen_type_name (orig_rtype)));
6463 /* After issuing the "invalid receiver" warning, perform method
6464 lookup as if we were messaging 'id'. */
6465 rtype = rprotos = NULL_TREE;
6470 /* For 'id' or 'Class' receivers, search in the global hash table
6471 as a last resort. For all receivers, warn if protocol searches
6472 have failed. */
6473 if (!method_prototype)
6475 if (rprotos)
6476 warning (0, "%<%c%E%> not found in protocol(s)",
6477 (class_tree ? '+' : '-'),
6478 sel_name);
6480 if (!rtype)
6481 method_prototype
6482 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6485 if (!method_prototype)
6487 static bool warn_missing_methods = false;
6489 if (rtype)
6490 warning (0, "%qE may not respond to %<%c%E%>",
6491 OBJC_TYPE_NAME (rtype),
6492 (class_tree ? '+' : '-'),
6493 sel_name);
6494 /* If we are messaging an 'id' or 'Class' object and made it here,
6495 then we have failed to find _any_ instance or class method,
6496 respectively. */
6497 else
6498 warning (0, "no %<%c%E%> method found",
6499 (class_tree ? '+' : '-'),
6500 sel_name);
6502 if (!warn_missing_methods)
6504 warning (0, "(Messages without a matching method signature");
6505 warning (0, "will be assumed to return %<id%> and accept");
6506 warning (0, "%<...%> as arguments.)");
6507 warn_missing_methods = true;
6511 /* Save the selector name for printing error messages. */
6512 current_objc_message_selector = sel_name;
6514 /* Build the parameters list for looking up the method.
6515 These are the object itself and the selector. */
6517 if (flag_typed_selectors)
6518 selector = build_typed_selector_reference (sel_name, method_prototype);
6519 else
6520 selector = build_selector_reference (sel_name);
6522 retval = build_objc_method_call (super, method_prototype,
6523 receiver,
6524 selector, method_params);
6526 current_objc_message_selector = 0;
6528 return retval;
6531 /* Build a tree expression to send OBJECT the operation SELECTOR,
6532 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6533 assuming the method has prototype METHOD_PROTOTYPE.
6534 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6535 Use METHOD_PARAMS as list of args to pass to the method.
6536 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6538 static tree
6539 build_objc_method_call (int super_flag, tree method_prototype,
6540 tree lookup_object, tree selector,
6541 tree method_params)
6543 tree sender = (super_flag ? umsg_super_decl :
6544 (!flag_next_runtime || flag_nil_receivers
6545 ? (flag_objc_direct_dispatch
6546 ? umsg_fast_decl
6547 : umsg_decl)
6548 : umsg_nonnil_decl));
6549 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6551 /* If a prototype for the method to be called exists, then cast
6552 the sender's return type and arguments to match that of the method.
6553 Otherwise, leave sender as is. */
6554 tree ret_type
6555 = (method_prototype
6556 ? TREE_VALUE (TREE_TYPE (method_prototype))
6557 : objc_object_type);
6558 tree sender_cast
6559 = build_pointer_type
6560 (build_function_type
6561 (ret_type,
6562 get_arg_type_list
6563 (method_prototype, METHOD_REF, super_flag)));
6564 tree method, t;
6566 lookup_object = build_c_cast (rcv_p, lookup_object);
6568 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6569 lookup_object = save_expr (lookup_object);
6571 if (flag_next_runtime)
6573 /* If we are returning a struct in memory, and the address
6574 of that memory location is passed as a hidden first
6575 argument, then change which messenger entry point this
6576 expr will call. NB: Note that sender_cast remains
6577 unchanged (it already has a struct return type). */
6578 if (!targetm.calls.struct_value_rtx (0, 0)
6579 && (TREE_CODE (ret_type) == RECORD_TYPE
6580 || TREE_CODE (ret_type) == UNION_TYPE)
6581 && targetm.calls.return_in_memory (ret_type, 0))
6582 sender = (super_flag ? umsg_super_stret_decl :
6583 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6585 method_params = tree_cons (NULL_TREE, lookup_object,
6586 tree_cons (NULL_TREE, selector,
6587 method_params));
6588 method = build_fold_addr_expr (sender);
6590 else
6592 /* This is the portable (GNU) way. */
6593 tree object;
6595 /* First, call the lookup function to get a pointer to the method,
6596 then cast the pointer, then call it with the method arguments. */
6598 object = (super_flag ? self_decl : lookup_object);
6600 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6601 t = tree_cons (NULL_TREE, lookup_object, t);
6602 method = build_function_call (sender, t);
6604 /* Pass the object to the method. */
6605 method_params = tree_cons (NULL_TREE, object,
6606 tree_cons (NULL_TREE, selector,
6607 method_params));
6610 /* ??? Selector is not at this point something we can use inside
6611 the compiler itself. Set it to garbage for the nonce. */
6612 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6613 return build_function_call (t, method_params);
6616 static void
6617 build_protocol_reference (tree p)
6619 tree decl;
6620 const char *proto_name;
6622 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6624 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6625 decl = start_var_decl (objc_protocol_template, proto_name);
6627 PROTOCOL_FORWARD_DECL (p) = decl;
6630 /* This function is called by the parser when (and only when) a
6631 @protocol() expression is found, in order to compile it. */
6632 tree
6633 objc_build_protocol_expr (tree protoname)
6635 tree expr;
6636 tree p = lookup_protocol (protoname);
6638 if (!p)
6640 error ("cannot find protocol declaration for %qE",
6641 protoname);
6642 return error_mark_node;
6645 if (!PROTOCOL_FORWARD_DECL (p))
6646 build_protocol_reference (p);
6648 expr = build_unary_op (input_location,
6649 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6651 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6652 if we have it, rather than converting it here. */
6653 expr = convert (objc_protocol_type, expr);
6655 /* The @protocol() expression is being compiled into a pointer to a
6656 statically allocated instance of the Protocol class. To become
6657 usable at runtime, the 'isa' pointer of the instance need to be
6658 fixed up at runtime by the runtime library, to point to the
6659 actual 'Protocol' class. */
6661 /* For the GNU runtime, put the static Protocol instance in the list
6662 of statically allocated instances, so that we make sure that its
6663 'isa' pointer is fixed up at runtime by the GNU runtime library
6664 to point to the Protocol class (at runtime, when loading the
6665 module, the GNU runtime library loops on the statically allocated
6666 instances (as found in the defs field in objc_symtab) and fixups
6667 all the 'isa' pointers of those objects). */
6668 if (! flag_next_runtime)
6670 /* This type is a struct containing the fields of a Protocol
6671 object. (Cfr. objc_protocol_type instead is the type of a pointer
6672 to such a struct). */
6673 tree protocol_struct_type = xref_tag
6674 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6675 tree *chain;
6677 /* Look for the list of Protocol statically allocated instances
6678 to fixup at runtime. Create a new list to hold Protocol
6679 statically allocated instances, if the list is not found. At
6680 present there is only another list, holding NSConstantString
6681 static instances to be fixed up at runtime. */
6682 for (chain = &objc_static_instances;
6683 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6684 chain = &TREE_CHAIN (*chain));
6685 if (!*chain)
6687 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6688 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6689 class_names);
6692 /* Add this statically allocated instance to the Protocol list. */
6693 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6694 PROTOCOL_FORWARD_DECL (p),
6695 TREE_PURPOSE (*chain));
6699 return expr;
6702 /* This function is called by the parser when a @selector() expression
6703 is found, in order to compile it. It is only called by the parser
6704 and only to compile a @selector(). */
6705 tree
6706 objc_build_selector_expr (tree selnamelist)
6708 tree selname;
6710 /* Obtain the full selector name. */
6711 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6712 /* A unary selector. */
6713 selname = selnamelist;
6714 else if (TREE_CODE (selnamelist) == TREE_LIST)
6715 selname = build_keyword_selector (selnamelist);
6716 else
6717 abort ();
6719 /* If we are required to check @selector() expressions as they
6720 are found, check that the selector has been declared. */
6721 if (warn_undeclared_selector)
6723 /* Look the selector up in the list of all known class and
6724 instance methods (up to this line) to check that the selector
6725 exists. */
6726 hash hsh;
6728 /* First try with instance methods. */
6729 hsh = hash_lookup (nst_method_hash_list, selname);
6731 /* If not found, try with class methods. */
6732 if (!hsh)
6734 hsh = hash_lookup (cls_method_hash_list, selname);
6737 /* If still not found, print out a warning. */
6738 if (!hsh)
6740 warning (0, "undeclared selector %qE", selname);
6745 if (flag_typed_selectors)
6746 return build_typed_selector_reference (selname, 0);
6747 else
6748 return build_selector_reference (selname);
6751 tree
6752 objc_build_encode_expr (tree type)
6754 tree result;
6755 const char *string;
6757 encode_type (type, obstack_object_size (&util_obstack),
6758 OBJC_ENCODE_INLINE_DEFS);
6759 obstack_1grow (&util_obstack, 0); /* null terminate string */
6760 string = XOBFINISH (&util_obstack, const char *);
6762 /* Synthesize a string that represents the encoded struct/union. */
6763 result = my_build_string (strlen (string) + 1, string);
6764 obstack_free (&util_obstack, util_firstobj);
6765 return result;
6768 static tree
6769 build_ivar_reference (tree id)
6771 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6773 /* Historically, a class method that produced objects (factory
6774 method) would assign `self' to the instance that it
6775 allocated. This would effectively turn the class method into
6776 an instance method. Following this assignment, the instance
6777 variables could be accessed. That practice, while safe,
6778 violates the simple rule that a class method should not refer
6779 to an instance variable. It's better to catch the cases
6780 where this is done unknowingly than to support the above
6781 paradigm. */
6782 warning (0, "instance variable %qE accessed in class method",
6783 id);
6784 self_decl = convert (objc_instance_type, self_decl); /* cast */
6787 return objc_build_component_ref (build_indirect_ref (input_location,
6788 self_decl, "->"), id);
6791 /* Compute a hash value for a given method SEL_NAME. */
6793 static size_t
6794 hash_func (tree sel_name)
6796 const unsigned char *s
6797 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6798 size_t h = 0;
6800 while (*s)
6801 h = h * 67 + *s++ - 113;
6802 return h;
6805 static void
6806 hash_init (void)
6808 nst_method_hash_list
6809 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6810 cls_method_hash_list
6811 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6813 /* Initialize the hash table used to hold the constant string objects. */
6814 string_htab = htab_create_ggc (31, string_hash,
6815 string_eq, NULL);
6817 /* Initialize the hash table used to hold EH-volatilized types. */
6818 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6819 volatilized_eq, NULL);
6822 /* WARNING!!!! hash_enter is called with a method, and will peek
6823 inside to find its selector! But hash_lookup is given a selector
6824 directly, and looks for the selector that's inside the found
6825 entry's key (method) for comparison. */
6827 static void
6828 hash_enter (hash *hashlist, tree method)
6830 hash obj;
6831 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6833 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6834 obj->list = 0;
6835 obj->next = hashlist[slot];
6836 obj->key = method;
6838 hashlist[slot] = obj; /* append to front */
6841 static hash
6842 hash_lookup (hash *hashlist, tree sel_name)
6844 hash target;
6846 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6848 while (target)
6850 if (sel_name == METHOD_SEL_NAME (target->key))
6851 return target;
6853 target = target->next;
6855 return 0;
6858 static void
6859 hash_add_attr (hash entry, tree value)
6861 attr obj;
6863 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6864 obj->next = entry->list;
6865 obj->value = value;
6867 entry->list = obj; /* append to front */
6870 static tree
6871 lookup_method (tree mchain, tree method)
6873 tree key;
6875 if (TREE_CODE (method) == IDENTIFIER_NODE)
6876 key = method;
6877 else
6878 key = METHOD_SEL_NAME (method);
6880 while (mchain)
6882 if (METHOD_SEL_NAME (mchain) == key)
6883 return mchain;
6885 mchain = TREE_CHAIN (mchain);
6887 return NULL_TREE;
6890 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6891 in INTERFACE, along with any categories and protocols attached thereto.
6892 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6893 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6894 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6895 be found in INTERFACE or any of its superclasses, look for an _instance_
6896 method of the same name in the root class as a last resort.
6898 If a suitable method cannot be found, return NULL_TREE. */
6900 static tree
6901 lookup_method_static (tree interface, tree ident, int flags)
6903 tree meth = NULL_TREE, root_inter = NULL_TREE;
6904 tree inter = interface;
6905 int is_class = (flags & OBJC_LOOKUP_CLASS);
6906 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6908 while (inter)
6910 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6911 tree category = inter;
6913 /* First, look up the method in the class itself. */
6914 if ((meth = lookup_method (chain, ident)))
6915 return meth;
6917 /* Failing that, look for the method in each category of the class. */
6918 while ((category = CLASS_CATEGORY_LIST (category)))
6920 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6922 /* Check directly in each category. */
6923 if ((meth = lookup_method (chain, ident)))
6924 return meth;
6926 /* Failing that, check in each category's protocols. */
6927 if (CLASS_PROTOCOL_LIST (category))
6929 if ((meth = (lookup_method_in_protocol_list
6930 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6931 return meth;
6935 /* If not found in categories, check in protocols of the main class. */
6936 if (CLASS_PROTOCOL_LIST (inter))
6938 if ((meth = (lookup_method_in_protocol_list
6939 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6940 return meth;
6943 /* If we were instructed not to look in superclasses, don't. */
6944 if (no_superclasses)
6945 return NULL_TREE;
6947 /* Failing that, climb up the inheritance hierarchy. */
6948 root_inter = inter;
6949 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6951 while (inter);
6953 /* If no class (factory) method was found, check if an _instance_
6954 method of the same name exists in the root class. This is what
6955 the Objective-C runtime will do. If an instance method was not
6956 found, return 0. */
6957 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6960 /* Add the method to the hash list if it doesn't contain an identical
6961 method already. */
6963 static void
6964 add_method_to_hash_list (hash *hash_list, tree method)
6966 hash hsh;
6968 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6970 /* Install on a global chain. */
6971 hash_enter (hash_list, method);
6973 else
6975 /* Check types against those; if different, add to a list. */
6976 attr loop;
6977 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6978 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6979 already_there |= comp_proto_with_proto (method, loop->value, 1);
6980 if (!already_there)
6981 hash_add_attr (hsh, method);
6985 static tree
6986 objc_add_method (tree klass, tree method, int is_class)
6988 tree mth;
6990 if (!(mth = lookup_method (is_class
6991 ? CLASS_CLS_METHODS (klass)
6992 : CLASS_NST_METHODS (klass), method)))
6994 /* put method on list in reverse order */
6995 if (is_class)
6997 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
6998 CLASS_CLS_METHODS (klass) = method;
7000 else
7002 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
7003 CLASS_NST_METHODS (klass) = method;
7006 else
7008 /* When processing an @interface for a class or category, give hard
7009 errors on methods with identical selectors but differing argument
7010 and/or return types. We do not do this for @implementations, because
7011 C/C++ will do it for us (i.e., there will be duplicate function
7012 definition errors). */
7013 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7014 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7015 && !comp_proto_with_proto (method, mth, 1))
7016 error ("duplicate declaration of method %<%c%E%>",
7017 is_class ? '+' : '-',
7018 METHOD_SEL_NAME (mth));
7021 if (is_class)
7022 add_method_to_hash_list (cls_method_hash_list, method);
7023 else
7025 add_method_to_hash_list (nst_method_hash_list, method);
7027 /* Instance methods in root classes (and categories thereof)
7028 may act as class methods as a last resort. We also add
7029 instance methods listed in @protocol declarations to
7030 the class hash table, on the assumption that @protocols
7031 may be adopted by root classes or categories. */
7032 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7033 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7034 klass = lookup_interface (CLASS_NAME (klass));
7036 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7037 || !CLASS_SUPER_NAME (klass))
7038 add_method_to_hash_list (cls_method_hash_list, method);
7041 return method;
7044 static tree
7045 add_class (tree class_name, tree name)
7047 struct interface_tuple **slot;
7049 /* Put interfaces on list in reverse order. */
7050 TREE_CHAIN (class_name) = interface_chain;
7051 interface_chain = class_name;
7053 if (interface_htab == NULL)
7054 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7055 slot = (struct interface_tuple **)
7056 htab_find_slot_with_hash (interface_htab, name,
7057 IDENTIFIER_HASH_VALUE (name),
7058 INSERT);
7059 if (!*slot)
7061 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7062 (*slot)->id = name;
7064 (*slot)->class_name = class_name;
7066 return interface_chain;
7069 static void
7070 add_category (tree klass, tree category)
7072 /* Put categories on list in reverse order. */
7073 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7075 if (cat)
7077 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7078 CLASS_NAME (klass),
7079 CLASS_SUPER_NAME (category));
7081 else
7083 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7084 CLASS_CATEGORY_LIST (klass) = category;
7088 /* Called after parsing each instance variable declaration. Necessary to
7089 preserve typedefs and implement public/private...
7091 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7093 static tree
7094 add_instance_variable (tree klass, int visibility, tree field_decl)
7096 tree field_type = TREE_TYPE (field_decl);
7097 const char *ivar_name = DECL_NAME (field_decl)
7098 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7099 : _("<unnamed>");
7101 #ifdef OBJCPLUS
7102 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7104 error ("illegal reference type specified for instance variable %qs",
7105 ivar_name);
7106 /* Return class as is without adding this ivar. */
7107 return klass;
7109 #endif
7111 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7112 || TYPE_SIZE (field_type) == error_mark_node)
7113 /* 'type[0]' is allowed, but 'type[]' is not! */
7115 error ("instance variable %qs has unknown size", ivar_name);
7116 /* Return class as is without adding this ivar. */
7117 return klass;
7120 #ifdef OBJCPLUS
7121 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7122 need to either (1) warn the user about it or (2) generate suitable
7123 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7124 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7125 if (MAYBE_CLASS_TYPE_P (field_type)
7126 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7127 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7128 || TYPE_POLYMORPHIC_P (field_type)))
7130 tree type_name = OBJC_TYPE_NAME (field_type);
7132 if (flag_objc_call_cxx_cdtors)
7134 /* Since the ObjC runtime will be calling the constructors and
7135 destructors for us, the only thing we can't handle is the lack
7136 of a default constructor. */
7137 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7138 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7140 warning (0, "type %qE has no default constructor to call",
7141 type_name);
7143 /* If we cannot call a constructor, we should also avoid
7144 calling the destructor, for symmetry. */
7145 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7146 warning (0, "destructor for %qE shall not be run either",
7147 type_name);
7150 else
7152 static bool warn_cxx_ivars = false;
7154 if (TYPE_POLYMORPHIC_P (field_type))
7156 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7157 initialize them. */
7158 error ("type %qE has virtual member functions", type_name);
7159 error ("illegal aggregate type %qE specified "
7160 "for instance variable %qs",
7161 type_name, ivar_name);
7162 /* Return class as is without adding this ivar. */
7163 return klass;
7166 /* User-defined constructors and destructors are not known to Obj-C
7167 and hence will not be called. This may or may not be a problem. */
7168 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7169 warning (0, "type %qE has a user-defined constructor", type_name);
7170 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7171 warning (0, "type %qE has a user-defined destructor", type_name);
7173 if (!warn_cxx_ivars)
7175 warning (0, "C++ constructors and destructors will not "
7176 "be invoked for Objective-C fields");
7177 warn_cxx_ivars = true;
7181 #endif
7183 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7184 switch (visibility)
7186 case 0:
7187 TREE_PUBLIC (field_decl) = 0;
7188 TREE_PRIVATE (field_decl) = 0;
7189 TREE_PROTECTED (field_decl) = 1;
7190 break;
7192 case 1:
7193 TREE_PUBLIC (field_decl) = 1;
7194 TREE_PRIVATE (field_decl) = 0;
7195 TREE_PROTECTED (field_decl) = 0;
7196 break;
7198 case 2:
7199 TREE_PUBLIC (field_decl) = 0;
7200 TREE_PRIVATE (field_decl) = 1;
7201 TREE_PROTECTED (field_decl) = 0;
7202 break;
7206 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7208 return klass;
7211 static tree
7212 is_ivar (tree decl_chain, tree ident)
7214 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7215 if (DECL_NAME (decl_chain) == ident)
7216 return decl_chain;
7217 return NULL_TREE;
7220 /* True if the ivar is private and we are not in its implementation. */
7222 static int
7223 is_private (tree decl)
7225 return (TREE_PRIVATE (decl)
7226 && ! is_ivar (CLASS_IVARS (implementation_template),
7227 DECL_NAME (decl)));
7230 /* We have an instance variable reference;, check to see if it is public. */
7233 objc_is_public (tree expr, tree identifier)
7235 tree basetype, decl;
7237 #ifdef OBJCPLUS
7238 if (processing_template_decl)
7239 return 1;
7240 #endif
7242 if (TREE_TYPE (expr) == error_mark_node)
7243 return 1;
7245 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7247 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7249 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7251 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7253 if (!klass)
7255 error ("cannot find interface declaration for %qE",
7256 OBJC_TYPE_NAME (basetype));
7257 return 0;
7260 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7262 if (TREE_PUBLIC (decl))
7263 return 1;
7265 /* Important difference between the Stepstone translator:
7266 all instance variables should be public within the context
7267 of the implementation. */
7268 if (objc_implementation_context
7269 && ((TREE_CODE (objc_implementation_context)
7270 == CLASS_IMPLEMENTATION_TYPE)
7271 || (TREE_CODE (objc_implementation_context)
7272 == CATEGORY_IMPLEMENTATION_TYPE)))
7274 tree curtype = TYPE_MAIN_VARIANT
7275 (CLASS_STATIC_TEMPLATE
7276 (implementation_template));
7278 if (basetype == curtype
7279 || DERIVED_FROM_P (basetype, curtype))
7281 int priv = is_private (decl);
7283 if (priv)
7284 error ("instance variable %qE is declared private",
7285 DECL_NAME (decl));
7287 return !priv;
7291 /* The 2.95.2 compiler sometimes allowed C functions to access
7292 non-@public ivars. We will let this slide for now... */
7293 if (!objc_method_context)
7295 warning (0, "instance variable %qE is %s; "
7296 "this will be a hard error in the future",
7297 identifier,
7298 TREE_PRIVATE (decl) ? "@private" : "@protected");
7299 return 1;
7302 error ("instance variable %qE is declared %s",
7303 identifier,
7304 TREE_PRIVATE (decl) ? "private" : "protected");
7305 return 0;
7310 return 1;
7313 /* Make sure all entries in CHAIN are also in LIST. */
7315 static int
7316 check_methods (tree chain, tree list, int mtype)
7318 int first = 1;
7320 while (chain)
7322 if (!lookup_method (list, chain))
7324 if (first)
7326 if (TREE_CODE (objc_implementation_context)
7327 == CLASS_IMPLEMENTATION_TYPE)
7328 warning (0, "incomplete implementation of class %qE",
7329 CLASS_NAME (objc_implementation_context));
7330 else if (TREE_CODE (objc_implementation_context)
7331 == CATEGORY_IMPLEMENTATION_TYPE)
7332 warning (0, "incomplete implementation of category %qE",
7333 CLASS_SUPER_NAME (objc_implementation_context));
7334 first = 0;
7337 warning (0, "method definition for %<%c%E%> not found",
7338 mtype, METHOD_SEL_NAME (chain));
7341 chain = TREE_CHAIN (chain);
7344 return first;
7347 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7349 static int
7350 conforms_to_protocol (tree klass, tree protocol)
7352 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7354 tree p = CLASS_PROTOCOL_LIST (klass);
7355 while (p && TREE_VALUE (p) != protocol)
7356 p = TREE_CHAIN (p);
7358 if (!p)
7360 tree super = (CLASS_SUPER_NAME (klass)
7361 ? lookup_interface (CLASS_SUPER_NAME (klass))
7362 : NULL_TREE);
7363 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7364 if (!tmp)
7365 return 0;
7369 return 1;
7372 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7373 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7375 static int
7376 check_methods_accessible (tree chain, tree context, int mtype)
7378 int first = 1;
7379 tree list;
7380 tree base_context = context;
7382 while (chain)
7384 context = base_context;
7385 while (context)
7387 if (mtype == '+')
7388 list = CLASS_CLS_METHODS (context);
7389 else
7390 list = CLASS_NST_METHODS (context);
7392 if (lookup_method (list, chain))
7393 break;
7395 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7396 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7397 context = (CLASS_SUPER_NAME (context)
7398 ? lookup_interface (CLASS_SUPER_NAME (context))
7399 : NULL_TREE);
7401 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7402 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7403 context = (CLASS_NAME (context)
7404 ? lookup_interface (CLASS_NAME (context))
7405 : NULL_TREE);
7406 else
7407 abort ();
7410 if (context == NULL_TREE)
7412 if (first)
7414 if (TREE_CODE (objc_implementation_context)
7415 == CLASS_IMPLEMENTATION_TYPE)
7416 warning (0, "incomplete implementation of class %qE",
7417 CLASS_NAME (objc_implementation_context));
7418 else if (TREE_CODE (objc_implementation_context)
7419 == CATEGORY_IMPLEMENTATION_TYPE)
7420 warning (0, "incomplete implementation of category %qE",
7421 CLASS_SUPER_NAME (objc_implementation_context));
7422 first = 0;
7424 warning (0, "method definition for %<%c%E%> not found",
7425 mtype, METHOD_SEL_NAME (chain));
7428 chain = TREE_CHAIN (chain); /* next method... */
7430 return first;
7433 /* Check whether the current interface (accessible via
7434 'objc_implementation_context') actually implements protocol P, along
7435 with any protocols that P inherits. */
7437 static void
7438 check_protocol (tree p, const char *type, tree name)
7440 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7442 int f1, f2;
7444 /* Ensure that all protocols have bodies! */
7445 if (warn_protocol)
7447 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7448 CLASS_CLS_METHODS (objc_implementation_context),
7449 '+');
7450 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7451 CLASS_NST_METHODS (objc_implementation_context),
7452 '-');
7454 else
7456 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7457 objc_implementation_context,
7458 '+');
7459 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7460 objc_implementation_context,
7461 '-');
7464 if (!f1 || !f2)
7465 warning (0, "%s %qE does not fully implement the %qE protocol",
7466 type, name, PROTOCOL_NAME (p));
7469 /* Check protocols recursively. */
7470 if (PROTOCOL_LIST (p))
7472 tree subs = PROTOCOL_LIST (p);
7473 tree super_class =
7474 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7476 while (subs)
7478 tree sub = TREE_VALUE (subs);
7480 /* If the superclass does not conform to the protocols
7481 inherited by P, then we must! */
7482 if (!super_class || !conforms_to_protocol (super_class, sub))
7483 check_protocol (sub, type, name);
7484 subs = TREE_CHAIN (subs);
7489 /* Check whether the current interface (accessible via
7490 'objc_implementation_context') actually implements the protocols listed
7491 in PROTO_LIST. */
7493 static void
7494 check_protocols (tree proto_list, const char *type, tree name)
7496 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7498 tree p = TREE_VALUE (proto_list);
7500 check_protocol (p, type, name);
7504 /* Make sure that the class CLASS_NAME is defined
7505 CODE says which kind of thing CLASS_NAME ought to be.
7506 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7507 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7509 static tree
7510 start_class (enum tree_code code, tree class_name, tree super_name,
7511 tree protocol_list)
7513 tree klass, decl;
7515 #ifdef OBJCPLUS
7516 if (current_namespace != global_namespace) {
7517 error ("Objective-C declarations may only appear in global scope");
7519 #endif /* OBJCPLUS */
7521 if (objc_implementation_context)
7523 warning (0, "%<@end%> missing in implementation context");
7524 finish_class (objc_implementation_context);
7525 objc_ivar_chain = NULL_TREE;
7526 objc_implementation_context = NULL_TREE;
7529 klass = make_node (code);
7530 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7532 /* Check for existence of the super class, if one was specified. Note
7533 that we must have seen an @interface, not just a @class. If we
7534 are looking at a @compatibility_alias, traverse it first. */
7535 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7536 && super_name)
7538 tree super = objc_is_class_name (super_name);
7540 if (!super || !lookup_interface (super))
7542 error ("cannot find interface declaration for %qE, superclass of %qE",
7543 super ? super : super_name,
7544 class_name);
7545 super_name = NULL_TREE;
7547 else
7548 super_name = super;
7551 CLASS_NAME (klass) = class_name;
7552 CLASS_SUPER_NAME (klass) = super_name;
7553 CLASS_CLS_METHODS (klass) = NULL_TREE;
7555 if (! objc_is_class_name (class_name)
7556 && (decl = lookup_name (class_name)))
7558 error ("%qE redeclared as different kind of symbol",
7559 class_name);
7560 error ("previous declaration of %q+D",
7561 decl);
7564 if (code == CLASS_IMPLEMENTATION_TYPE)
7567 tree chain;
7569 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7570 if (TREE_VALUE (chain) == class_name)
7572 error ("reimplementation of class %qE",
7573 class_name);
7574 return error_mark_node;
7576 implemented_classes = tree_cons (NULL_TREE, class_name,
7577 implemented_classes);
7580 /* Reset for multiple classes per file. */
7581 method_slot = 0;
7583 objc_implementation_context = klass;
7585 /* Lookup the interface for this implementation. */
7587 if (!(implementation_template = lookup_interface (class_name)))
7589 warning (0, "cannot find interface declaration for %qE",
7590 class_name);
7591 add_class (implementation_template = objc_implementation_context,
7592 class_name);
7595 /* If a super class has been specified in the implementation,
7596 insure it conforms to the one specified in the interface. */
7598 if (super_name
7599 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7601 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7602 error ("conflicting super class name %qE",
7603 super_name);
7604 if (previous_name)
7605 error ("previous declaration of %qE", previous_name);
7606 else
7607 error ("previous declaration");
7610 else if (! super_name)
7612 CLASS_SUPER_NAME (objc_implementation_context)
7613 = CLASS_SUPER_NAME (implementation_template);
7617 else if (code == CLASS_INTERFACE_TYPE)
7619 if (lookup_interface (class_name))
7620 #ifdef OBJCPLUS
7621 error ("duplicate interface declaration for class %qE",
7622 #else
7623 warning (0, "duplicate interface declaration for class %qE",
7624 #endif
7625 class_name);
7626 else
7627 add_class (klass, class_name);
7629 if (protocol_list)
7630 CLASS_PROTOCOL_LIST (klass)
7631 = lookup_and_install_protocols (protocol_list);
7634 else if (code == CATEGORY_INTERFACE_TYPE)
7636 tree class_category_is_assoc_with;
7638 /* For a category, class_name is really the name of the class that
7639 the following set of methods will be associated with. We must
7640 find the interface so that can derive the objects template. */
7642 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7644 error ("cannot find interface declaration for %qE",
7645 class_name);
7646 exit (FATAL_EXIT_CODE);
7648 else
7649 add_category (class_category_is_assoc_with, klass);
7651 if (protocol_list)
7652 CLASS_PROTOCOL_LIST (klass)
7653 = lookup_and_install_protocols (protocol_list);
7656 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7658 /* Reset for multiple classes per file. */
7659 method_slot = 0;
7661 objc_implementation_context = klass;
7663 /* For a category, class_name is really the name of the class that
7664 the following set of methods will be associated with. We must
7665 find the interface so that can derive the objects template. */
7667 if (!(implementation_template = lookup_interface (class_name)))
7669 error ("cannot find interface declaration for %qE",
7670 class_name);
7671 exit (FATAL_EXIT_CODE);
7674 return klass;
7677 static tree
7678 continue_class (tree klass)
7680 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7681 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7683 struct imp_entry *imp_entry;
7685 /* Check consistency of the instance variables. */
7687 if (CLASS_RAW_IVARS (klass))
7688 check_ivars (implementation_template, klass);
7690 /* code generation */
7692 #ifdef OBJCPLUS
7693 push_lang_context (lang_name_c);
7694 #endif
7696 build_private_template (implementation_template);
7697 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7698 objc_instance_type = build_pointer_type (uprivate_record);
7700 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7702 imp_entry->next = imp_list;
7703 imp_entry->imp_context = klass;
7704 imp_entry->imp_template = implementation_template;
7706 synth_forward_declarations ();
7707 imp_entry->class_decl = UOBJC_CLASS_decl;
7708 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7709 imp_entry->has_cxx_cdtors = 0;
7711 /* Append to front and increment count. */
7712 imp_list = imp_entry;
7713 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7714 imp_count++;
7715 else
7716 cat_count++;
7718 #ifdef OBJCPLUS
7719 pop_lang_context ();
7720 #endif /* OBJCPLUS */
7722 return get_class_ivars (implementation_template, true);
7725 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7727 #ifdef OBJCPLUS
7728 push_lang_context (lang_name_c);
7729 #endif /* OBJCPLUS */
7731 build_private_template (klass);
7733 #ifdef OBJCPLUS
7734 pop_lang_context ();
7735 #endif /* OBJCPLUS */
7737 return NULL_TREE;
7740 else
7741 return error_mark_node;
7744 /* This is called once we see the "@end" in an interface/implementation. */
7746 static void
7747 finish_class (tree klass)
7749 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7751 /* All code generation is done in finish_objc. */
7753 if (implementation_template != objc_implementation_context)
7755 /* Ensure that all method listed in the interface contain bodies. */
7756 check_methods (CLASS_CLS_METHODS (implementation_template),
7757 CLASS_CLS_METHODS (objc_implementation_context), '+');
7758 check_methods (CLASS_NST_METHODS (implementation_template),
7759 CLASS_NST_METHODS (objc_implementation_context), '-');
7761 if (CLASS_PROTOCOL_LIST (implementation_template))
7762 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7763 "class",
7764 CLASS_NAME (objc_implementation_context));
7768 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7770 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7772 if (category)
7774 /* Ensure all method listed in the interface contain bodies. */
7775 check_methods (CLASS_CLS_METHODS (category),
7776 CLASS_CLS_METHODS (objc_implementation_context), '+');
7777 check_methods (CLASS_NST_METHODS (category),
7778 CLASS_NST_METHODS (objc_implementation_context), '-');
7780 if (CLASS_PROTOCOL_LIST (category))
7781 check_protocols (CLASS_PROTOCOL_LIST (category),
7782 "category",
7783 CLASS_SUPER_NAME (objc_implementation_context));
7788 static tree
7789 add_protocol (tree protocol)
7791 /* Put protocol on list in reverse order. */
7792 TREE_CHAIN (protocol) = protocol_chain;
7793 protocol_chain = protocol;
7794 return protocol_chain;
7797 static tree
7798 lookup_protocol (tree ident)
7800 tree chain;
7802 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7803 if (ident == PROTOCOL_NAME (chain))
7804 return chain;
7806 return NULL_TREE;
7809 /* This function forward declares the protocols named by NAMES. If
7810 they are already declared or defined, the function has no effect. */
7812 void
7813 objc_declare_protocols (tree names)
7815 tree list;
7817 #ifdef OBJCPLUS
7818 if (current_namespace != global_namespace) {
7819 error ("Objective-C declarations may only appear in global scope");
7821 #endif /* OBJCPLUS */
7823 for (list = names; list; list = TREE_CHAIN (list))
7825 tree name = TREE_VALUE (list);
7827 if (lookup_protocol (name) == NULL_TREE)
7829 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7831 TYPE_LANG_SLOT_1 (protocol)
7832 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7833 PROTOCOL_NAME (protocol) = name;
7834 PROTOCOL_LIST (protocol) = NULL_TREE;
7835 add_protocol (protocol);
7836 PROTOCOL_DEFINED (protocol) = 0;
7837 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7842 static tree
7843 start_protocol (enum tree_code code, tree name, tree list)
7845 tree protocol;
7847 #ifdef OBJCPLUS
7848 if (current_namespace != global_namespace) {
7849 error ("Objective-C declarations may only appear in global scope");
7851 #endif /* OBJCPLUS */
7853 protocol = lookup_protocol (name);
7855 if (!protocol)
7857 protocol = make_node (code);
7858 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7860 PROTOCOL_NAME (protocol) = name;
7861 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7862 add_protocol (protocol);
7863 PROTOCOL_DEFINED (protocol) = 1;
7864 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7866 check_protocol_recursively (protocol, list);
7868 else if (! PROTOCOL_DEFINED (protocol))
7870 PROTOCOL_DEFINED (protocol) = 1;
7871 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7873 check_protocol_recursively (protocol, list);
7875 else
7877 warning (0, "duplicate declaration for protocol %qE",
7878 name);
7880 return protocol;
7884 /* "Encode" a data type into a string, which grows in util_obstack.
7885 ??? What is the FORMAT? Someone please document this! */
7887 static void
7888 encode_type_qualifiers (tree declspecs)
7890 tree spec;
7892 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7894 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7895 obstack_1grow (&util_obstack, 'n');
7896 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7897 obstack_1grow (&util_obstack, 'N');
7898 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7899 obstack_1grow (&util_obstack, 'o');
7900 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7901 obstack_1grow (&util_obstack, 'O');
7902 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7903 obstack_1grow (&util_obstack, 'R');
7904 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7905 obstack_1grow (&util_obstack, 'V');
7909 /* Encode a pointer type. */
7911 static void
7912 encode_pointer (tree type, int curtype, int format)
7914 tree pointer_to = TREE_TYPE (type);
7916 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7918 if (OBJC_TYPE_NAME (pointer_to)
7919 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7921 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7923 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7925 obstack_1grow (&util_obstack, '@');
7926 return;
7928 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7929 && TYPE_OBJC_INTERFACE (pointer_to))
7931 if (generating_instance_variables)
7933 obstack_1grow (&util_obstack, '@');
7934 obstack_1grow (&util_obstack, '"');
7935 obstack_grow (&util_obstack, name, strlen (name));
7936 obstack_1grow (&util_obstack, '"');
7937 return;
7939 else
7941 obstack_1grow (&util_obstack, '@');
7942 return;
7945 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7947 obstack_1grow (&util_obstack, '#');
7948 return;
7950 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7952 obstack_1grow (&util_obstack, ':');
7953 return;
7957 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7958 && TYPE_MODE (pointer_to) == QImode)
7960 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7961 ? OBJC_TYPE_NAME (pointer_to)
7962 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7964 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7966 /* It appears that "r*" means "const char *" rather than
7967 "char *const". */
7968 if (TYPE_READONLY (pointer_to))
7969 obstack_1grow (&util_obstack, 'r');
7971 obstack_1grow (&util_obstack, '*');
7972 return;
7976 /* We have a type that does not get special treatment. */
7978 /* NeXT extension */
7979 obstack_1grow (&util_obstack, '^');
7980 encode_type (pointer_to, curtype, format);
7983 static void
7984 encode_array (tree type, int curtype, int format)
7986 tree an_int_cst = TYPE_SIZE (type);
7987 tree array_of = TREE_TYPE (type);
7988 char buffer[40];
7990 /* An incomplete array is treated like a pointer. */
7991 if (an_int_cst == NULL)
7993 encode_pointer (type, curtype, format);
7994 return;
7997 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7998 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7999 else
8000 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
8001 TREE_INT_CST_LOW (an_int_cst)
8002 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
8004 obstack_grow (&util_obstack, buffer, strlen (buffer));
8005 encode_type (array_of, curtype, format);
8006 obstack_1grow (&util_obstack, ']');
8007 return;
8010 static void
8011 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
8013 tree field = TYPE_FIELDS (type);
8015 for (; field; field = TREE_CHAIN (field))
8017 #ifdef OBJCPLUS
8018 /* C++ static members, and things that are not field at all,
8019 should not appear in the encoding. */
8020 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
8021 continue;
8022 #endif
8024 /* Recursively encode fields of embedded base classes. */
8025 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
8026 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
8028 encode_aggregate_fields (TREE_TYPE (field),
8029 pointed_to, curtype, format);
8030 continue;
8033 if (generating_instance_variables && !pointed_to)
8035 tree fname = DECL_NAME (field);
8037 obstack_1grow (&util_obstack, '"');
8039 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
8040 obstack_grow (&util_obstack,
8041 IDENTIFIER_POINTER (fname),
8042 strlen (IDENTIFIER_POINTER (fname)));
8044 obstack_1grow (&util_obstack, '"');
8047 encode_field_decl (field, curtype, format);
8051 static void
8052 encode_aggregate_within (tree type, int curtype, int format, int left,
8053 int right)
8055 tree name;
8056 /* NB: aggregates that are pointed to have slightly different encoding
8057 rules in that you never encode the names of instance variables. */
8058 int ob_size = obstack_object_size (&util_obstack);
8059 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8060 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8061 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8062 int inline_contents
8063 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8064 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8066 /* Traverse struct aliases; it is important to get the
8067 original struct and its tag name (if any). */
8068 type = TYPE_MAIN_VARIANT (type);
8069 name = OBJC_TYPE_NAME (type);
8070 /* Open parenth/bracket. */
8071 obstack_1grow (&util_obstack, left);
8073 /* Encode the struct/union tag name, or '?' if a tag was
8074 not provided. Typedef aliases do not qualify. */
8075 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8076 #ifdef OBJCPLUS
8077 /* Did this struct have a tag? */
8078 && !TYPE_WAS_ANONYMOUS (type)
8079 #endif
8081 obstack_grow (&util_obstack,
8082 IDENTIFIER_POINTER (name),
8083 strlen (IDENTIFIER_POINTER (name)));
8084 else
8085 obstack_1grow (&util_obstack, '?');
8087 /* Encode the types (and possibly names) of the inner fields,
8088 if required. */
8089 if (inline_contents)
8091 obstack_1grow (&util_obstack, '=');
8092 encode_aggregate_fields (type, pointed_to, curtype, format);
8094 /* Close parenth/bracket. */
8095 obstack_1grow (&util_obstack, right);
8098 static void
8099 encode_aggregate (tree type, int curtype, int format)
8101 enum tree_code code = TREE_CODE (type);
8103 switch (code)
8105 case RECORD_TYPE:
8107 encode_aggregate_within (type, curtype, format, '{', '}');
8108 break;
8110 case UNION_TYPE:
8112 encode_aggregate_within (type, curtype, format, '(', ')');
8113 break;
8116 case ENUMERAL_TYPE:
8117 obstack_1grow (&util_obstack, 'i');
8118 break;
8120 default:
8121 break;
8125 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8126 field type. */
8128 static void
8129 encode_next_bitfield (int width)
8131 char buffer[40];
8132 sprintf (buffer, "b%d", width);
8133 obstack_grow (&util_obstack, buffer, strlen (buffer));
8136 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8137 static void
8138 encode_type (tree type, int curtype, int format)
8140 enum tree_code code = TREE_CODE (type);
8141 char c;
8143 if (type == error_mark_node)
8144 return;
8146 if (TYPE_READONLY (type))
8147 obstack_1grow (&util_obstack, 'r');
8149 if (code == INTEGER_TYPE)
8151 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8153 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8154 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8155 case 32:
8156 if (type == long_unsigned_type_node
8157 || type == long_integer_type_node)
8158 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8159 else
8160 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8161 break;
8162 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8163 default: abort ();
8165 obstack_1grow (&util_obstack, c);
8168 else if (code == REAL_TYPE)
8170 /* Floating point types. */
8171 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8173 case 32: c = 'f'; break;
8174 case 64:
8175 case 96:
8176 case 128: c = 'd'; break;
8177 default: abort ();
8179 obstack_1grow (&util_obstack, c);
8182 else if (code == VOID_TYPE)
8183 obstack_1grow (&util_obstack, 'v');
8185 else if (code == BOOLEAN_TYPE)
8186 obstack_1grow (&util_obstack, 'B');
8188 else if (code == ARRAY_TYPE)
8189 encode_array (type, curtype, format);
8191 else if (code == POINTER_TYPE)
8192 encode_pointer (type, curtype, format);
8194 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8195 encode_aggregate (type, curtype, format);
8197 else if (code == FUNCTION_TYPE) /* '?' */
8198 obstack_1grow (&util_obstack, '?');
8200 else if (code == COMPLEX_TYPE)
8202 obstack_1grow (&util_obstack, 'j');
8203 encode_type (TREE_TYPE (type), curtype, format);
8207 static void
8208 encode_gnu_bitfield (int position, tree type, int size)
8210 enum tree_code code = TREE_CODE (type);
8211 char buffer[40];
8212 char charType = '?';
8214 if (code == INTEGER_TYPE)
8216 if (integer_zerop (TYPE_MIN_VALUE (type)))
8218 /* Unsigned integer types. */
8220 if (TYPE_MODE (type) == QImode)
8221 charType = 'C';
8222 else if (TYPE_MODE (type) == HImode)
8223 charType = 'S';
8224 else if (TYPE_MODE (type) == SImode)
8226 if (type == long_unsigned_type_node)
8227 charType = 'L';
8228 else
8229 charType = 'I';
8231 else if (TYPE_MODE (type) == DImode)
8232 charType = 'Q';
8235 else
8236 /* Signed integer types. */
8238 if (TYPE_MODE (type) == QImode)
8239 charType = 'c';
8240 else if (TYPE_MODE (type) == HImode)
8241 charType = 's';
8242 else if (TYPE_MODE (type) == SImode)
8244 if (type == long_integer_type_node)
8245 charType = 'l';
8246 else
8247 charType = 'i';
8250 else if (TYPE_MODE (type) == DImode)
8251 charType = 'q';
8254 else if (code == ENUMERAL_TYPE)
8255 charType = 'i';
8256 else
8257 abort ();
8259 sprintf (buffer, "b%d%c%d", position, charType, size);
8260 obstack_grow (&util_obstack, buffer, strlen (buffer));
8263 static void
8264 encode_field_decl (tree field_decl, int curtype, int format)
8266 tree type;
8268 #ifdef OBJCPLUS
8269 /* C++ static members, and things that are not fields at all,
8270 should not appear in the encoding. */
8271 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8272 return;
8273 #endif
8275 type = TREE_TYPE (field_decl);
8277 /* Generate the bitfield typing information, if needed. Note the difference
8278 between GNU and NeXT runtimes. */
8279 if (DECL_BIT_FIELD_TYPE (field_decl))
8281 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8283 if (flag_next_runtime)
8284 encode_next_bitfield (size);
8285 else
8286 encode_gnu_bitfield (int_bit_position (field_decl),
8287 DECL_BIT_FIELD_TYPE (field_decl), size);
8289 else
8290 encode_type (TREE_TYPE (field_decl), curtype, format);
8293 static GTY(()) tree objc_parmlist = NULL_TREE;
8295 /* Append PARM to a list of formal parameters of a method, making a necessary
8296 array-to-pointer adjustment along the way. */
8298 static void
8299 objc_push_parm (tree parm)
8301 bool relayout_needed = false;
8303 if (TREE_TYPE (parm) == error_mark_node)
8305 objc_parmlist = chainon (objc_parmlist, parm);
8306 return;
8309 /* Decay arrays and functions into pointers. */
8310 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8312 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8313 relayout_needed = true;
8315 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8317 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8318 relayout_needed = true;
8321 if (relayout_needed)
8322 relayout_decl (parm);
8325 DECL_ARG_TYPE (parm)
8326 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8328 /* Record constancy and volatility. */
8329 c_apply_type_quals_to_decl
8330 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8331 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8332 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8334 objc_parmlist = chainon (objc_parmlist, parm);
8337 /* Retrieve the formal parameter list constructed via preceding calls to
8338 objc_push_parm(). */
8340 #ifdef OBJCPLUS
8341 static tree
8342 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8343 #else
8344 static struct c_arg_info *
8345 objc_get_parm_info (int have_ellipsis)
8346 #endif
8348 #ifdef OBJCPLUS
8349 tree parm_info = objc_parmlist;
8350 objc_parmlist = NULL_TREE;
8352 return parm_info;
8353 #else
8354 tree parm_info = objc_parmlist;
8355 struct c_arg_info *arg_info;
8356 /* The C front-end requires an elaborate song and dance at
8357 this point. */
8358 push_scope ();
8359 declare_parm_level ();
8360 while (parm_info)
8362 tree next = TREE_CHAIN (parm_info);
8364 TREE_CHAIN (parm_info) = NULL_TREE;
8365 parm_info = pushdecl (parm_info);
8366 finish_decl (parm_info, NULL_TREE, NULL_TREE, NULL_TREE);
8367 parm_info = next;
8369 arg_info = get_parm_info (have_ellipsis);
8370 pop_scope ();
8371 objc_parmlist = NULL_TREE;
8372 return arg_info;
8373 #endif
8376 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8377 method definitions. In the case of instance methods, we can be more
8378 specific as to the type of 'self'. */
8380 static void
8381 synth_self_and_ucmd_args (void)
8383 tree self_type;
8385 if (objc_method_context
8386 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8387 self_type = objc_instance_type;
8388 else
8389 /* Really a `struct objc_class *'. However, we allow people to
8390 assign to self, which changes its type midstream. */
8391 self_type = objc_object_type;
8393 /* id self; */
8394 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8396 /* SEL _cmd; */
8397 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8400 /* Transform an Objective-C method definition into a static C function
8401 definition, synthesizing the first two arguments, "self" and "_cmd",
8402 in the process. */
8404 static void
8405 start_method_def (tree method)
8407 tree parmlist;
8408 #ifdef OBJCPLUS
8409 tree parm_info;
8410 #else
8411 struct c_arg_info *parm_info;
8412 #endif
8413 int have_ellipsis = 0;
8415 /* If we are defining a "dealloc" method in a non-root class, we
8416 will need to check if a [super dealloc] is missing, and warn if
8417 it is. */
8418 if(CLASS_SUPER_NAME (objc_implementation_context)
8419 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8420 should_call_super_dealloc = 1;
8421 else
8422 should_call_super_dealloc = 0;
8424 /* Required to implement _msgSuper. */
8425 objc_method_context = method;
8426 UOBJC_SUPER_decl = NULL_TREE;
8428 /* Generate prototype declarations for arguments..."new-style". */
8429 synth_self_and_ucmd_args ();
8431 /* Generate argument declarations if a keyword_decl. */
8432 parmlist = METHOD_SEL_ARGS (method);
8433 while (parmlist)
8435 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8437 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8438 objc_push_parm (parm);
8439 parmlist = TREE_CHAIN (parmlist);
8442 if (METHOD_ADD_ARGS (method))
8444 tree akey;
8446 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8447 akey; akey = TREE_CHAIN (akey))
8449 objc_push_parm (TREE_VALUE (akey));
8452 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8453 have_ellipsis = 1;
8456 parm_info = objc_get_parm_info (have_ellipsis);
8458 really_start_method (objc_method_context, parm_info);
8461 /* Return 1 if TYPE1 is equivalent to TYPE2
8462 for purposes of method overloading. */
8464 static int
8465 objc_types_are_equivalent (tree type1, tree type2)
8467 if (type1 == type2)
8468 return 1;
8470 /* Strip away indirections. */
8471 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8472 && (TREE_CODE (type1) == TREE_CODE (type2)))
8473 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8474 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8475 return 0;
8477 type1 = (TYPE_HAS_OBJC_INFO (type1)
8478 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8479 : NULL_TREE);
8480 type2 = (TYPE_HAS_OBJC_INFO (type2)
8481 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8482 : NULL_TREE);
8484 if (list_length (type1) == list_length (type2))
8486 for (; type2; type2 = TREE_CHAIN (type2))
8487 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8488 return 0;
8489 return 1;
8491 return 0;
8494 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8496 static int
8497 objc_types_share_size_and_alignment (tree type1, tree type2)
8499 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8500 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8503 /* Return 1 if PROTO1 is equivalent to PROTO2
8504 for purposes of method overloading. Ordinarily, the type signatures
8505 should match up exactly, unless STRICT is zero, in which case we
8506 shall allow differences in which the size and alignment of a type
8507 is the same. */
8509 static int
8510 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8512 tree type1, type2;
8514 /* The following test is needed in case there are hashing
8515 collisions. */
8516 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8517 return 0;
8519 /* Compare return types. */
8520 type1 = TREE_VALUE (TREE_TYPE (proto1));
8521 type2 = TREE_VALUE (TREE_TYPE (proto2));
8523 if (!objc_types_are_equivalent (type1, type2)
8524 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8525 return 0;
8527 /* Compare argument types. */
8528 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8529 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8530 type1 && type2;
8531 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8533 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8534 && (strict
8535 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8536 TREE_VALUE (type2))))
8537 return 0;
8540 return (!type1 && !type2);
8543 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8544 this occurs. ObjC method dispatches are _not_ like C++ virtual
8545 member function dispatches, and we account for the difference here. */
8546 tree
8547 #ifdef OBJCPLUS
8548 objc_fold_obj_type_ref (tree ref, tree known_type)
8549 #else
8550 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8551 tree known_type ATTRIBUTE_UNUSED)
8552 #endif
8554 #ifdef OBJCPLUS
8555 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8557 /* If the receiver does not have virtual member functions, there
8558 is nothing we can (or need to) do here. */
8559 if (!v)
8560 return NULL_TREE;
8562 /* Let C++ handle C++ virtual functions. */
8563 return cp_fold_obj_type_ref (ref, known_type);
8564 #else
8565 /* For plain ObjC, we currently do not need to do anything. */
8566 return NULL_TREE;
8567 #endif
8570 static void
8571 objc_start_function (tree name, tree type, tree attrs,
8572 #ifdef OBJCPLUS
8573 tree params
8574 #else
8575 struct c_arg_info *params
8576 #endif
8579 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8581 #ifdef OBJCPLUS
8582 DECL_ARGUMENTS (fndecl) = params;
8583 DECL_INITIAL (fndecl) = error_mark_node;
8584 DECL_EXTERNAL (fndecl) = 0;
8585 TREE_STATIC (fndecl) = 1;
8586 retrofit_lang_decl (fndecl);
8587 cplus_decl_attributes (&fndecl, attrs, 0);
8588 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8589 #else
8590 struct c_label_context_se *nstack_se;
8591 struct c_label_context_vm *nstack_vm;
8592 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8593 nstack_se->labels_def = NULL;
8594 nstack_se->labels_used = NULL;
8595 nstack_se->next = label_context_stack_se;
8596 label_context_stack_se = nstack_se;
8597 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8598 nstack_vm->labels_def = NULL;
8599 nstack_vm->labels_used = NULL;
8600 nstack_vm->scope = 0;
8601 nstack_vm->next = label_context_stack_vm;
8602 label_context_stack_vm = nstack_vm;
8603 current_function_returns_value = 0; /* Assume, until we see it does. */
8604 current_function_returns_null = 0;
8606 decl_attributes (&fndecl, attrs, 0);
8607 announce_function (fndecl);
8608 DECL_INITIAL (fndecl) = error_mark_node;
8609 DECL_EXTERNAL (fndecl) = 0;
8610 TREE_STATIC (fndecl) = 1;
8611 current_function_decl = pushdecl (fndecl);
8612 push_scope ();
8613 declare_parm_level ();
8614 DECL_RESULT (current_function_decl)
8615 = build_decl (RESULT_DECL, NULL_TREE,
8616 TREE_TYPE (TREE_TYPE (current_function_decl)));
8617 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8618 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8619 start_fname_decls ();
8620 store_parm_decls_from (params);
8621 #endif
8623 TREE_USED (current_function_decl) = 1;
8626 /* - Generate an identifier for the function. the format is "_n_cls",
8627 where 1 <= n <= nMethods, and cls is the name the implementation we
8628 are processing.
8629 - Install the return type from the method declaration.
8630 - If we have a prototype, check for type consistency. */
8632 static void
8633 really_start_method (tree method,
8634 #ifdef OBJCPLUS
8635 tree parmlist
8636 #else
8637 struct c_arg_info *parmlist
8638 #endif
8641 tree ret_type, meth_type;
8642 tree method_id;
8643 const char *sel_name, *class_name, *cat_name;
8644 char *buf;
8646 /* Synth the storage class & assemble the return type. */
8647 ret_type = TREE_VALUE (TREE_TYPE (method));
8649 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8650 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8651 cat_name = ((TREE_CODE (objc_implementation_context)
8652 == CLASS_IMPLEMENTATION_TYPE)
8653 ? NULL
8654 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8655 method_slot++;
8657 /* Make sure this is big enough for any plausible method label. */
8658 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8659 + (cat_name ? strlen (cat_name) : 0));
8661 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8662 class_name, cat_name, sel_name, method_slot);
8664 method_id = get_identifier (buf);
8666 #ifdef OBJCPLUS
8667 /* Objective-C methods cannot be overloaded, so we don't need
8668 the type encoding appended. It looks bad anyway... */
8669 push_lang_context (lang_name_c);
8670 #endif
8672 meth_type
8673 = build_function_type (ret_type,
8674 get_arg_type_list (method, METHOD_DEF, 0));
8675 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8677 /* Set self_decl from the first argument. */
8678 self_decl = DECL_ARGUMENTS (current_function_decl);
8680 /* Suppress unused warnings. */
8681 TREE_USED (self_decl) = 1;
8682 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8683 #ifdef OBJCPLUS
8684 pop_lang_context ();
8685 #endif
8687 METHOD_DEFINITION (method) = current_function_decl;
8689 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8691 if (implementation_template != objc_implementation_context)
8693 tree proto
8694 = lookup_method_static (implementation_template,
8695 METHOD_SEL_NAME (method),
8696 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8697 | OBJC_LOOKUP_NO_SUPER));
8699 if (proto)
8701 if (!comp_proto_with_proto (method, proto, 1))
8703 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8705 warning (0, "%Jconflicting types for %<%c%s%>", method,
8706 (type ? '-' : '+'),
8707 identifier_to_locale (gen_method_decl (method)));
8708 inform (0, "%Jprevious declaration of %<%c%s%>", proto,
8709 (type ? '-' : '+'),
8710 identifier_to_locale (gen_method_decl (proto)));
8713 else
8715 /* We have a method @implementation even though we did not
8716 see a corresponding @interface declaration (which is allowed
8717 by Objective-C rules). Go ahead and place the method in
8718 the @interface anyway, so that message dispatch lookups
8719 will see it. */
8720 tree interface = implementation_template;
8722 if (TREE_CODE (objc_implementation_context)
8723 == CATEGORY_IMPLEMENTATION_TYPE)
8724 interface = lookup_category
8725 (interface,
8726 CLASS_SUPER_NAME (objc_implementation_context));
8728 if (interface)
8729 objc_add_method (interface, copy_node (method),
8730 TREE_CODE (method) == CLASS_METHOD_DECL);
8735 static void *UOBJC_SUPER_scope = 0;
8737 /* _n_Method (id self, SEL sel, ...)
8739 struct objc_super _S;
8740 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8741 } */
8743 static tree
8744 get_super_receiver (void)
8746 if (objc_method_context)
8748 tree super_expr, super_expr_list;
8750 if (!UOBJC_SUPER_decl)
8752 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8753 objc_super_template);
8754 /* This prevents `unused variable' warnings when compiling with -Wall. */
8755 TREE_USED (UOBJC_SUPER_decl) = 1;
8756 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8757 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE, NULL_TREE);
8758 UOBJC_SUPER_scope = objc_get_current_scope ();
8761 /* Set receiver to self. */
8762 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8763 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8764 NOP_EXPR, self_decl, NULL_TREE);
8765 super_expr_list = super_expr;
8767 /* Set class to begin searching. */
8768 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8769 get_identifier ("super_class"));
8771 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8773 /* [_cls, __cls]Super are "pre-built" in
8774 synth_forward_declarations. */
8776 super_expr = build_modify_expr (input_location, super_expr,
8777 NULL_TREE, NOP_EXPR,
8778 ((TREE_CODE (objc_method_context)
8779 == INSTANCE_METHOD_DECL)
8780 ? ucls_super_ref
8781 : uucls_super_ref),
8782 NULL_TREE);
8785 else
8786 /* We have a category. */
8788 tree super_name = CLASS_SUPER_NAME (implementation_template);
8789 tree super_class;
8791 /* Barf if super used in a category of Object. */
8792 if (!super_name)
8794 error ("no super class declared in interface for %qE",
8795 CLASS_NAME (implementation_template));
8796 return error_mark_node;
8799 if (flag_next_runtime && !flag_zero_link)
8801 super_class = objc_get_class_reference (super_name);
8802 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8803 /* If we are in a class method, we must retrieve the
8804 _metaclass_ for the current class, pointed at by
8805 the class's "isa" pointer. The following assumes that
8806 "isa" is the first ivar in a class (which it must be). */
8807 super_class
8808 = build_indirect_ref
8809 (input_location,
8810 build_c_cast (build_pointer_type (objc_class_type),
8811 super_class), "unary *");
8813 else
8815 add_class_reference (super_name);
8816 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8817 ? objc_get_class_decl : objc_get_meta_class_decl);
8818 assemble_external (super_class);
8819 super_class
8820 = build_function_call
8821 (super_class,
8822 build_tree_list
8823 (NULL_TREE,
8824 my_build_string_pointer
8825 (IDENTIFIER_LENGTH (super_name) + 1,
8826 IDENTIFIER_POINTER (super_name))));
8829 super_expr
8830 = build_modify_expr (input_location, super_expr, NULL_TREE,
8831 NOP_EXPR,
8832 build_c_cast (TREE_TYPE (super_expr),
8833 super_class),
8834 NULL_TREE);
8837 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8839 super_expr = build_unary_op (input_location,
8840 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8841 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8843 return super_expr_list;
8845 else
8847 error ("[super ...] must appear in a method context");
8848 return error_mark_node;
8852 /* When exiting a scope, sever links to a 'super' declaration (if any)
8853 therein contained. */
8855 void
8856 objc_clear_super_receiver (void)
8858 if (objc_method_context
8859 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8860 UOBJC_SUPER_decl = 0;
8861 UOBJC_SUPER_scope = 0;
8865 void
8866 objc_finish_method_definition (tree fndecl)
8868 /* We cannot validly inline ObjC methods, at least not without a language
8869 extension to declare that a method need not be dynamically
8870 dispatched, so suppress all thoughts of doing so. */
8871 DECL_UNINLINABLE (fndecl) = 1;
8873 #ifndef OBJCPLUS
8874 /* The C++ front-end will have called finish_function() for us. */
8875 finish_function ();
8876 #endif
8878 METHOD_ENCODING (objc_method_context)
8879 = encode_method_prototype (objc_method_context);
8881 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8882 since the optimizer may find "may be used before set" errors. */
8883 objc_method_context = NULL_TREE;
8885 if (should_call_super_dealloc)
8886 warning (0, "method possibly missing a [super dealloc] call");
8889 /* Given a tree DECL node, produce a printable description of it in the given
8890 buffer, overwriting the buffer. */
8892 static char *
8893 gen_declaration (tree decl)
8895 errbuf[0] = '\0';
8897 if (DECL_P (decl))
8899 gen_type_name_0 (TREE_TYPE (decl));
8901 if (DECL_NAME (decl))
8903 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8904 strcat (errbuf, " ");
8906 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8909 if (DECL_INITIAL (decl)
8910 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8911 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8912 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8915 return errbuf;
8918 /* Given a tree TYPE node, produce a printable description of it in the given
8919 buffer, overwriting the buffer. */
8921 static char *
8922 gen_type_name_0 (tree type)
8924 tree orig = type, proto;
8926 if (TYPE_P (type) && TYPE_NAME (type))
8927 type = TYPE_NAME (type);
8928 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8930 tree inner = TREE_TYPE (type);
8932 while (TREE_CODE (inner) == ARRAY_TYPE)
8933 inner = TREE_TYPE (inner);
8935 gen_type_name_0 (inner);
8937 if (!POINTER_TYPE_P (inner))
8938 strcat (errbuf, " ");
8940 if (POINTER_TYPE_P (type))
8941 strcat (errbuf, "*");
8942 else
8943 while (type != inner)
8945 strcat (errbuf, "[");
8947 if (TYPE_DOMAIN (type))
8949 char sz[20];
8951 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8952 (TREE_INT_CST_LOW
8953 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8954 strcat (errbuf, sz);
8957 strcat (errbuf, "]");
8958 type = TREE_TYPE (type);
8961 goto exit_function;
8964 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8965 type = DECL_NAME (type);
8967 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8968 ? IDENTIFIER_POINTER (type)
8969 : "");
8971 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8972 if (objc_is_id (orig))
8973 orig = TREE_TYPE (orig);
8975 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8977 if (proto)
8979 strcat (errbuf, " <");
8981 while (proto) {
8982 strcat (errbuf,
8983 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8984 proto = TREE_CHAIN (proto);
8985 strcat (errbuf, proto ? ", " : ">");
8989 exit_function:
8990 return errbuf;
8993 static char *
8994 gen_type_name (tree type)
8996 errbuf[0] = '\0';
8998 return gen_type_name_0 (type);
9001 /* Given a method tree, put a printable description into the given
9002 buffer (overwriting) and return a pointer to the buffer. */
9004 static char *
9005 gen_method_decl (tree method)
9007 tree chain;
9009 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
9010 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
9011 strcat (errbuf, ")");
9012 chain = METHOD_SEL_ARGS (method);
9014 if (chain)
9016 /* We have a chain of keyword_decls. */
9019 if (KEYWORD_KEY_NAME (chain))
9020 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
9022 strcat (errbuf, ":(");
9023 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9024 strcat (errbuf, ")");
9026 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9027 if ((chain = TREE_CHAIN (chain)))
9028 strcat (errbuf, " ");
9030 while (chain);
9032 if (METHOD_ADD_ARGS (method))
9034 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9036 /* Know we have a chain of parm_decls. */
9037 while (chain)
9039 strcat (errbuf, ", ");
9040 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9041 chain = TREE_CHAIN (chain);
9044 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9045 strcat (errbuf, ", ...");
9049 else
9050 /* We have a unary selector. */
9051 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9053 return errbuf;
9056 /* Debug info. */
9059 /* Dump an @interface declaration of the supplied class CHAIN to the
9060 supplied file FP. Used to implement the -gen-decls option (which
9061 prints out an @interface declaration of all classes compiled in
9062 this run); potentially useful for debugging the compiler too. */
9063 static void
9064 dump_interface (FILE *fp, tree chain)
9066 /* FIXME: A heap overflow here whenever a method (or ivar)
9067 declaration is so long that it doesn't fit in the buffer. The
9068 code and all the related functions should be rewritten to avoid
9069 using fixed size buffers. */
9070 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9071 tree ivar_decls = CLASS_RAW_IVARS (chain);
9072 tree nst_methods = CLASS_NST_METHODS (chain);
9073 tree cls_methods = CLASS_CLS_METHODS (chain);
9075 fprintf (fp, "\n@interface %s", my_name);
9077 /* CLASS_SUPER_NAME is used to store the superclass name for
9078 classes, and the category name for categories. */
9079 if (CLASS_SUPER_NAME (chain))
9081 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9083 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9084 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9086 fprintf (fp, " (%s)\n", name);
9088 else
9090 fprintf (fp, " : %s\n", name);
9093 else
9094 fprintf (fp, "\n");
9096 /* FIXME - the following doesn't seem to work at the moment. */
9097 if (ivar_decls)
9099 fprintf (fp, "{\n");
9102 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9103 ivar_decls = TREE_CHAIN (ivar_decls);
9105 while (ivar_decls);
9106 fprintf (fp, "}\n");
9109 while (nst_methods)
9111 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9112 nst_methods = TREE_CHAIN (nst_methods);
9115 while (cls_methods)
9117 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9118 cls_methods = TREE_CHAIN (cls_methods);
9121 fprintf (fp, "@end\n");
9124 /* Demangle function for Objective-C */
9125 static const char *
9126 objc_demangle (const char *mangled)
9128 char *demangled, *cp;
9130 if (mangled[0] == '_' &&
9131 (mangled[1] == 'i' || mangled[1] == 'c') &&
9132 mangled[2] == '_')
9134 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9135 if (mangled[1] == 'i')
9136 *cp++ = '-'; /* for instance method */
9137 else
9138 *cp++ = '+'; /* for class method */
9139 *cp++ = '['; /* opening left brace */
9140 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9141 while (*cp && *cp == '_')
9142 cp++; /* skip any initial underbars in class name */
9143 cp = strchr(cp, '_'); /* find first non-initial underbar */
9144 if (cp == NULL)
9146 free(demangled); /* not mangled name */
9147 return mangled;
9149 if (cp[1] == '_') /* easy case: no category name */
9151 *cp++ = ' '; /* replace two '_' with one ' ' */
9152 strcpy(cp, mangled + (cp - demangled) + 2);
9154 else
9156 *cp++ = '('; /* less easy case: category name */
9157 cp = strchr(cp, '_');
9158 if (cp == 0)
9160 free(demangled); /* not mangled name */
9161 return mangled;
9163 *cp++ = ')';
9164 *cp++ = ' '; /* overwriting 1st char of method name... */
9165 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9167 while (*cp && *cp == '_')
9168 cp++; /* skip any initial underbars in method name */
9169 for (; *cp; cp++)
9170 if (*cp == '_')
9171 *cp = ':'; /* replace remaining '_' with ':' */
9172 *cp++ = ']'; /* closing right brace */
9173 *cp++ = 0; /* string terminator */
9174 return demangled;
9176 else
9177 return mangled; /* not an objc mangled name */
9180 const char *
9181 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9183 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9186 static void
9187 init_objc (void)
9189 gcc_obstack_init (&util_obstack);
9190 util_firstobj = (char *) obstack_finish (&util_obstack);
9192 errbuf = XNEWVEC (char, 1024 * 10);
9193 hash_init ();
9194 synth_module_prologue ();
9197 static void
9198 finish_objc (void)
9200 struct imp_entry *impent;
9201 tree chain;
9202 /* The internally generated initializers appear to have missing braces.
9203 Don't warn about this. */
9204 int save_warn_missing_braces = warn_missing_braces;
9205 warn_missing_braces = 0;
9207 /* A missing @end may not be detected by the parser. */
9208 if (objc_implementation_context)
9210 warning (0, "%<@end%> missing in implementation context");
9211 finish_class (objc_implementation_context);
9212 objc_ivar_chain = NULL_TREE;
9213 objc_implementation_context = NULL_TREE;
9216 /* Process the static instances here because initialization of objc_symtab
9217 depends on them. */
9218 if (objc_static_instances)
9219 generate_static_references ();
9221 if (imp_list || class_names_chain
9222 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9223 generate_objc_symtab_decl ();
9225 for (impent = imp_list; impent; impent = impent->next)
9227 objc_implementation_context = impent->imp_context;
9228 implementation_template = impent->imp_template;
9230 UOBJC_CLASS_decl = impent->class_decl;
9231 UOBJC_METACLASS_decl = impent->meta_decl;
9233 /* Dump the @interface of each class as we compile it, if the
9234 -gen-decls option is in use. TODO: Dump the classes in the
9235 order they were found, rather than in reverse order as we
9236 are doing now. */
9237 if (flag_gen_declaration)
9239 dump_interface (gen_declaration_file, objc_implementation_context);
9242 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9244 /* all of the following reference the string pool... */
9245 generate_ivar_lists ();
9246 generate_dispatch_tables ();
9247 generate_shared_structures (impent->has_cxx_cdtors
9248 ? CLS_HAS_CXX_STRUCTORS
9249 : 0);
9251 else
9253 generate_dispatch_tables ();
9254 generate_category (objc_implementation_context);
9258 /* If we are using an array of selectors, we must always
9259 finish up the array decl even if no selectors were used. */
9260 if (! flag_next_runtime || sel_ref_chain)
9261 build_selector_translation_table ();
9263 if (protocol_chain)
9264 generate_protocols ();
9266 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9267 generate_objc_image_info ();
9269 /* Arrange for ObjC data structures to be initialized at run time. */
9270 if (objc_implementation_context || class_names_chain || objc_static_instances
9271 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9273 build_module_descriptor ();
9275 if (!flag_next_runtime)
9276 build_module_initializer_routine ();
9279 /* Dump the class references. This forces the appropriate classes
9280 to be linked into the executable image, preserving unix archive
9281 semantics. This can be removed when we move to a more dynamically
9282 linked environment. */
9284 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9286 handle_class_ref (chain);
9287 if (TREE_PURPOSE (chain))
9288 generate_classref_translation_entry (chain);
9291 for (impent = imp_list; impent; impent = impent->next)
9292 handle_impent (impent);
9294 if (warn_selector)
9296 int slot;
9297 hash hsh;
9299 /* Run through the selector hash tables and print a warning for any
9300 selector which has multiple methods. */
9302 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9304 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9305 check_duplicates (hsh, 0, 1);
9306 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9307 check_duplicates (hsh, 0, 1);
9311 warn_missing_braces = save_warn_missing_braces;
9314 /* Subroutines of finish_objc. */
9316 static void
9317 generate_classref_translation_entry (tree chain)
9319 tree expr, decl, type;
9321 decl = TREE_PURPOSE (chain);
9322 type = TREE_TYPE (decl);
9324 expr = add_objc_string (TREE_VALUE (chain), class_names);
9325 expr = convert (type, expr); /* cast! */
9327 /* The decl that is the one that we
9328 forward declared in build_class_reference. */
9329 finish_var_decl (decl, expr);
9330 return;
9333 static void
9334 handle_class_ref (tree chain)
9336 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9337 char *string = (char *) alloca (strlen (name) + 30);
9338 tree decl;
9339 tree exp;
9341 sprintf (string, "%sobjc_class_name_%s",
9342 (flag_next_runtime ? "." : "__"), name);
9344 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9345 if (flag_next_runtime)
9347 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9348 return;
9350 #endif
9352 /* Make a decl for this name, so we can use its address in a tree. */
9353 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9354 DECL_EXTERNAL (decl) = 1;
9355 TREE_PUBLIC (decl) = 1;
9357 pushdecl (decl);
9358 rest_of_decl_compilation (decl, 0, 0);
9360 /* Make a decl for the address. */
9361 sprintf (string, "%sobjc_class_ref_%s",
9362 (flag_next_runtime ? "." : "__"), name);
9363 exp = build1 (ADDR_EXPR, string_type_node, decl);
9364 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9365 DECL_INITIAL (decl) = exp;
9366 TREE_STATIC (decl) = 1;
9367 TREE_USED (decl) = 1;
9368 /* Force the output of the decl as this forces the reference of the class. */
9369 mark_decl_referenced (decl);
9371 pushdecl (decl);
9372 rest_of_decl_compilation (decl, 0, 0);
9375 static void
9376 handle_impent (struct imp_entry *impent)
9378 char *string;
9380 objc_implementation_context = impent->imp_context;
9381 implementation_template = impent->imp_template;
9383 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9385 const char *const class_name =
9386 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9388 string = (char *) alloca (strlen (class_name) + 30);
9390 sprintf (string, "%sobjc_class_name_%s",
9391 (flag_next_runtime ? "." : "__"), class_name);
9393 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9395 const char *const class_name =
9396 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9397 const char *const class_super_name =
9398 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9400 string = (char *) alloca (strlen (class_name)
9401 + strlen (class_super_name) + 30);
9403 /* Do the same for categories. Even though no references to
9404 these symbols are generated automatically by the compiler, it
9405 gives you a handle to pull them into an archive by hand. */
9406 sprintf (string, "*%sobjc_category_name_%s_%s",
9407 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9409 else
9410 return;
9412 #ifdef ASM_DECLARE_CLASS_REFERENCE
9413 if (flag_next_runtime)
9415 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9416 return;
9418 else
9419 #endif
9421 tree decl, init;
9423 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9424 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9425 TREE_PUBLIC (decl) = 1;
9426 TREE_READONLY (decl) = 1;
9427 TREE_USED (decl) = 1;
9428 TREE_CONSTANT (decl) = 1;
9429 DECL_CONTEXT (decl) = 0;
9430 DECL_ARTIFICIAL (decl) = 1;
9431 DECL_INITIAL (decl) = init;
9432 assemble_variable (decl, 1, 0, 0);
9436 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9437 later requires that ObjC translation units participating in F&C be
9438 specially marked. The following routine accomplishes this. */
9440 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9442 static void
9443 generate_objc_image_info (void)
9445 tree decl, initlist;
9446 int flags
9447 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9448 | (flag_objc_gc ? 2 : 0));
9450 decl = start_var_decl (build_array_type
9451 (integer_type_node,
9452 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9453 "_OBJC_IMAGE_INFO");
9455 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9456 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9457 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9459 finish_var_decl (decl, initlist);
9462 /* Look up ID as an instance variable. OTHER contains the result of
9463 the C or C++ lookup, which we may want to use instead. */
9465 tree
9466 objc_lookup_ivar (tree other, tree id)
9468 tree ivar;
9470 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9471 if (!objc_method_context)
9472 return other;
9474 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9475 /* We have a message to super. */
9476 return get_super_receiver ();
9478 /* In a class method, look up an instance variable only as a last
9479 resort. */
9480 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9481 && other && other != error_mark_node)
9482 return other;
9484 /* Look up the ivar, but do not use it if it is not accessible. */
9485 ivar = is_ivar (objc_ivar_chain, id);
9487 if (!ivar || is_private (ivar))
9488 return other;
9490 /* In an instance method, a local variable (or parameter) may hide the
9491 instance variable. */
9492 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9493 && other && other != error_mark_node
9494 #ifdef OBJCPLUS
9495 && CP_DECL_CONTEXT (other) != global_namespace)
9496 #else
9497 && !DECL_FILE_SCOPE_P (other))
9498 #endif
9500 warning (0, "local declaration of %qE hides instance variable",
9501 id);
9503 return other;
9506 /* At this point, we are either in an instance method with no obscuring
9507 local definitions, or in a class method with no alternate definitions
9508 at all. */
9509 return build_ivar_reference (id);
9512 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9513 needs to be done if we are calling a function through a cast. */
9515 tree
9516 objc_rewrite_function_call (tree function, tree first_param)
9518 if (TREE_CODE (function) == NOP_EXPR
9519 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9520 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9521 == FUNCTION_DECL)
9523 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9524 TREE_OPERAND (function, 0),
9525 first_param, size_zero_node);
9528 return function;
9531 /* Look for the special case of OBJC_TYPE_REF with the address of
9532 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9533 of its cousins). */
9536 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9538 enum gimplify_status r0, r1;
9539 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9540 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9541 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9542 == FUNCTION_DECL)
9544 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9545 value of the OBJ_TYPE_REF, so force them to be emitted
9546 during subexpression evaluation rather than after the
9547 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9548 C to use direct rather than indirect calls when the
9549 object expression has a postincrement. */
9550 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9551 is_gimple_val, fb_rvalue);
9552 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9553 is_gimple_val, fb_rvalue);
9555 return MIN (r0, r1);
9558 #ifdef OBJCPLUS
9559 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9560 #else
9561 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9562 #endif
9565 #include "gt-objc-objc-act.h"