Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / objc / objc-act.c
blob526dec6144b706dc8e9dff979905e3879d95b2f8
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
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 COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
34 the translator.
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
57 #include "c-common.h"
58 #include "c-pragma.h"
59 #include "flags.h"
60 #include "langhooks.h"
61 #include "objc-act.h"
62 #include "input.h"
63 #include "except.h"
64 #include "function.h"
65 #include "output.h"
66 #include "toplev.h"
67 #include "ggc.h"
68 #include "varray.h"
69 #include "debug.h"
70 #include "target.h"
71 #include "diagnostic.h"
72 #include "cgraph.h"
73 #include "tree-iterator.h"
74 #include "libfuncs.h"
75 #include "hashtab.h"
76 #include "langhooks-def.h"
78 #define OBJC_VOID_AT_END void_list_node
80 static unsigned int should_call_super_dealloc = 0;
82 /* When building Objective-C++, we are not linking against the C front-end
83 and so need to replicate the C tree-construction functions in some way. */
84 #ifdef OBJCPLUS
85 #define OBJCP_REMAP_FUNCTIONS
86 #include "objcp-decl.h"
87 #endif /* OBJCPLUS */
89 /* This is the default way of generating a method name. */
90 /* I am not sure it is really correct.
91 Perhaps there's a danger that it will make name conflicts
92 if method names contain underscores. -- rms. */
93 #ifndef OBJC_GEN_METHOD_LABEL
94 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
95 do { \
96 char *temp; \
97 sprintf ((BUF), "_%s_%s_%s_%s", \
98 ((IS_INST) ? "i" : "c"), \
99 (CLASS_NAME), \
100 ((CAT_NAME)? (CAT_NAME) : ""), \
101 (SEL_NAME)); \
102 for (temp = (BUF); *temp; temp++) \
103 if (*temp == ':') *temp = '_'; \
104 } while (0)
105 #endif
107 /* These need specifying. */
108 #ifndef OBJC_FORWARDING_STACK_OFFSET
109 #define OBJC_FORWARDING_STACK_OFFSET 0
110 #endif
112 #ifndef OBJC_FORWARDING_MIN_OFFSET
113 #define OBJC_FORWARDING_MIN_OFFSET 0
114 #endif
116 /* Set up for use of obstacks. */
118 #include "obstack.h"
120 /* This obstack is used to accumulate the encoding of a data type. */
121 static struct obstack util_obstack;
123 /* This points to the beginning of obstack contents, so we can free
124 the whole contents. */
125 char *util_firstobj;
127 /* The version identifies which language generation and runtime
128 the module (file) was compiled for, and is recorded in the
129 module descriptor. */
131 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
132 #define PROTOCOL_VERSION 2
134 /* (Decide if these can ever be validly changed.) */
135 #define OBJC_ENCODE_INLINE_DEFS 0
136 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
138 /*** Private Interface (procedures) ***/
140 /* Used by compile_file. */
142 static void init_objc (void);
143 static void finish_objc (void);
145 /* Code generation. */
147 static tree objc_build_constructor (tree, tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static tree get_proto_encoding (tree);
150 static tree lookup_interface (tree);
151 static tree objc_add_static_instance (tree, tree);
153 static tree start_class (enum tree_code, tree, tree, tree);
154 static tree continue_class (tree);
155 static void finish_class (tree);
156 static void start_method_def (tree);
157 #ifdef OBJCPLUS
158 static void objc_start_function (tree, tree, tree, tree);
159 #else
160 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
161 #endif
162 static tree start_protocol (enum tree_code, tree, tree);
163 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
164 static tree objc_add_method (tree, tree, int);
165 static tree add_instance_variable (tree, int, tree);
166 static tree build_ivar_reference (tree);
167 static tree is_ivar (tree, tree);
169 static void build_objc_exception_stuff (void);
170 static void build_next_objc_exception_stuff (void);
172 /* We only need the following for ObjC; ObjC++ will use C++'s definition
173 of DERIVED_FROM_P. */
174 #ifndef OBJCPLUS
175 static bool objc_derived_from_p (tree, tree);
176 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
177 #endif
178 static void objc_xref_basetypes (tree, tree);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static void build_super_template (void);
184 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
185 static tree get_class_ivars (tree, bool);
186 static tree generate_protocol_list (tree);
187 static void build_protocol_reference (tree);
188 static tree objc_build_volatilized_type (tree);
190 #ifdef OBJCPLUS
191 static void objc_generate_cxx_cdtors (void);
192 #endif
194 static const char *synth_id_with_class_suffix (const char *, tree);
196 /* Hash tables to manage the global pool of method prototypes. */
198 hash *nst_method_hash_list = 0;
199 hash *cls_method_hash_list = 0;
201 static hash hash_lookup (hash *, tree);
202 static tree lookup_method (tree, tree);
203 static tree lookup_method_static (tree, tree, int);
205 enum string_section
207 class_names, /* class, category, protocol, module names */
208 meth_var_names, /* method and variable names */
209 meth_var_types /* method and variable type descriptors */
212 static tree add_objc_string (tree, enum string_section);
213 static tree build_objc_string_decl (enum string_section);
214 static void build_selector_table_decl (void);
216 /* Protocol additions. */
218 static tree lookup_protocol (tree);
219 static tree lookup_and_install_protocols (tree);
221 /* Type encoding. */
223 static void encode_type_qualifiers (tree);
224 static void encode_type (tree, int, int);
225 static void encode_field_decl (tree, int, int);
227 #ifdef OBJCPLUS
228 static void really_start_method (tree, tree);
229 #else
230 static void really_start_method (tree, struct c_arg_info *);
231 #endif
232 static int comp_proto_with_proto (tree, tree, int);
233 static void objc_push_parm (tree);
234 #ifdef OBJCPLUS
235 static tree objc_get_parm_info (int);
236 #else
237 static struct c_arg_info *objc_get_parm_info (int);
238 #endif
240 /* Utilities for debugging and error diagnostics. */
242 static void warn_with_method (const char *, int, tree);
243 static char *gen_type_name (tree);
244 static char *gen_type_name_0 (tree);
245 static char *gen_method_decl (tree);
246 static char *gen_declaration (tree);
248 /* Everything else. */
250 static tree create_field_decl (tree, const char *);
251 static void add_class_reference (tree);
252 static void build_protocol_template (void);
253 static tree encode_method_prototype (tree);
254 static void generate_classref_translation_entry (tree);
255 static void handle_class_ref (tree);
256 static void generate_struct_by_value_array (void)
257 ATTRIBUTE_NORETURN;
258 static void mark_referenced_methods (void);
259 static void generate_objc_image_info (void);
261 /*** Private Interface (data) ***/
263 /* Reserved tag definitions. */
265 #define OBJECT_TYPEDEF_NAME "id"
266 #define CLASS_TYPEDEF_NAME "Class"
268 #define TAG_OBJECT "objc_object"
269 #define TAG_CLASS "objc_class"
270 #define TAG_SUPER "objc_super"
271 #define TAG_SELECTOR "objc_selector"
273 #define UTAG_CLASS "_objc_class"
274 #define UTAG_IVAR "_objc_ivar"
275 #define UTAG_IVAR_LIST "_objc_ivar_list"
276 #define UTAG_METHOD "_objc_method"
277 #define UTAG_METHOD_LIST "_objc_method_list"
278 #define UTAG_CATEGORY "_objc_category"
279 #define UTAG_MODULE "_objc_module"
280 #define UTAG_SYMTAB "_objc_symtab"
281 #define UTAG_SUPER "_objc_super"
282 #define UTAG_SELECTOR "_objc_selector"
284 #define UTAG_PROTOCOL "_objc_protocol"
285 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
286 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
288 /* Note that the string object global name is only needed for the
289 NeXT runtime. */
290 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
292 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
294 static const char *TAG_GETCLASS;
295 static const char *TAG_GETMETACLASS;
296 static const char *TAG_MSGSEND;
297 static const char *TAG_MSGSENDSUPER;
298 /* The NeXT Objective-C messenger may have two extra entry points, for use
299 when returning a structure. */
300 static const char *TAG_MSGSEND_STRET;
301 static const char *TAG_MSGSENDSUPER_STRET;
302 static const char *default_constant_string_class_name;
304 /* Runtime metadata flags. */
305 #define CLS_FACTORY 0x0001L
306 #define CLS_META 0x0002L
307 #define CLS_HAS_CXX_STRUCTORS 0x2000L
309 #define OBJC_MODIFIER_STATIC 0x00000001
310 #define OBJC_MODIFIER_FINAL 0x00000002
311 #define OBJC_MODIFIER_PUBLIC 0x00000004
312 #define OBJC_MODIFIER_PRIVATE 0x00000008
313 #define OBJC_MODIFIER_PROTECTED 0x00000010
314 #define OBJC_MODIFIER_NATIVE 0x00000020
315 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
316 #define OBJC_MODIFIER_ABSTRACT 0x00000080
317 #define OBJC_MODIFIER_VOLATILE 0x00000100
318 #define OBJC_MODIFIER_TRANSIENT 0x00000200
319 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
321 /* NeXT-specific tags. */
323 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
324 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
325 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
326 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
327 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
328 #define TAG_EXCEPTIONMATCH "objc_exception_match"
329 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
330 #define TAG_SYNCENTER "objc_sync_enter"
331 #define TAG_SYNCEXIT "objc_sync_exit"
332 #define TAG_SETJMP "_setjmp"
333 #define UTAG_EXCDATA "_objc_exception_data"
335 #define TAG_ASSIGNIVAR "objc_assign_ivar"
336 #define TAG_ASSIGNGLOBAL "objc_assign_global"
337 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
339 /* Branch entry points. All that matters here are the addresses;
340 functions with these names do not really exist in libobjc. */
342 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
343 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
345 #define TAG_CXX_CONSTRUCT ".cxx_construct"
346 #define TAG_CXX_DESTRUCT ".cxx_destruct"
348 /* GNU-specific tags. */
350 #define TAG_EXECCLASS "__objc_exec_class"
351 #define TAG_GNUINIT "__objc_gnu_init"
353 /* Flags for lookup_method_static(). */
354 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
355 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
357 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
358 tree objc_global_trees[OCTI_MAX];
360 static void handle_impent (struct imp_entry *);
362 struct imp_entry *imp_list = 0;
363 int imp_count = 0; /* `@implementation' */
364 int cat_count = 0; /* `@category' */
366 enum tree_code objc_inherit_code;
367 int objc_public_flag;
369 /* Use to generate method labels. */
370 static int method_slot = 0;
372 #define BUFSIZE 1024
374 static char *errbuf; /* Buffer for error diagnostics */
376 /* Data imported from tree.c. */
378 extern enum debug_info_type write_symbols;
380 /* Data imported from toplev.c. */
382 extern const char *dump_base_name;
384 static int flag_typed_selectors;
386 /* Store all constructed constant strings in a hash table so that
387 they get uniqued properly. */
389 struct string_descriptor GTY(())
391 /* The literal argument . */
392 tree literal;
394 /* The resulting constant string. */
395 tree constructor;
398 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
400 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
401 struct volatilized_type GTY(())
403 tree type;
406 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
408 FILE *gen_declaration_file;
410 /* Tells "encode_pointer/encode_aggregate" whether we are generating
411 type descriptors for instance variables (as opposed to methods).
412 Type descriptors for instance variables contain more information
413 than methods (for static typing and embedded structures). */
415 static int generating_instance_variables = 0;
417 /* Some platforms pass small structures through registers versus
418 through an invisible pointer. Determine at what size structure is
419 the transition point between the two possibilities. */
421 static void
422 generate_struct_by_value_array (void)
424 tree type;
425 tree field_decl, field_decl_chain;
426 int i, j;
427 int aggregate_in_mem[32];
428 int found = 0;
430 /* Presumably no platform passes 32 byte structures in a register. */
431 for (i = 1; i < 32; i++)
433 char buffer[5];
435 /* Create an unnamed struct that has `i' character components */
436 type = start_struct (RECORD_TYPE, NULL_TREE);
438 strcpy (buffer, "c1");
439 field_decl = create_field_decl (char_type_node,
440 buffer);
441 field_decl_chain = field_decl;
443 for (j = 1; j < i; j++)
445 sprintf (buffer, "c%d", j + 1);
446 field_decl = create_field_decl (char_type_node,
447 buffer);
448 chainon (field_decl_chain, field_decl);
450 finish_struct (type, field_decl_chain, NULL_TREE);
452 aggregate_in_mem[i] = aggregate_value_p (type, 0);
453 if (!aggregate_in_mem[i])
454 found = 1;
457 /* We found some structures that are returned in registers instead of memory
458 so output the necessary data. */
459 if (found)
461 for (i = 31; i >= 0; i--)
462 if (!aggregate_in_mem[i])
463 break;
464 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
466 /* The first member of the structure is always 0 because we don't handle
467 structures with 0 members */
468 printf ("static int struct_forward_array[] = {\n 0");
470 for (j = 1; j <= i; j++)
471 printf (", %d", aggregate_in_mem[j]);
472 printf ("\n};\n");
475 exit (0);
478 bool
479 objc_init (void)
481 #ifdef OBJCPLUS
482 if (cxx_init () == false)
483 #else
484 if (c_objc_common_init () == false)
485 #endif
486 return false;
488 #ifndef USE_MAPPED_LOCATION
489 /* Force the line number back to 0; check_newline will have
490 raised it to 1, which will make the builtin functions appear
491 not to be built in. */
492 input_line = 0;
493 #endif
495 /* If gen_declaration desired, open the output file. */
496 if (flag_gen_declaration)
498 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
499 gen_declaration_file = fopen (dumpname, "w");
500 if (gen_declaration_file == 0)
501 fatal_error ("can't open %s: %m", dumpname);
502 free (dumpname);
505 if (flag_next_runtime)
507 TAG_GETCLASS = "objc_getClass";
508 TAG_GETMETACLASS = "objc_getMetaClass";
509 TAG_MSGSEND = "objc_msgSend";
510 TAG_MSGSENDSUPER = "objc_msgSendSuper";
511 TAG_MSGSEND_STRET = "objc_msgSend_stret";
512 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
513 default_constant_string_class_name = "NSConstantString";
515 else
517 TAG_GETCLASS = "objc_get_class";
518 TAG_GETMETACLASS = "objc_get_meta_class";
519 TAG_MSGSEND = "objc_msg_lookup";
520 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
521 /* GNU runtime does not provide special functions to support
522 structure-returning methods. */
523 default_constant_string_class_name = "NXConstantString";
524 flag_typed_selectors = 1;
527 init_objc ();
529 if (print_struct_values)
530 generate_struct_by_value_array ();
532 return true;
535 void
536 objc_finish_file (void)
538 mark_referenced_methods ();
540 #ifdef OBJCPLUS
541 /* We need to instantiate templates _before_ we emit ObjC metadata;
542 if we do not, some metadata (such as selectors) may go missing. */
543 at_eof = 1;
544 instantiate_pending_templates (0);
545 #endif
547 /* Finalize Objective-C runtime data. No need to generate tables
548 and code if only checking syntax, or if generating a PCH file. */
549 if (!flag_syntax_only && !pch_file)
550 finish_objc ();
552 if (gen_declaration_file)
553 fclose (gen_declaration_file);
555 #ifdef OBJCPLUS
556 cp_finish_file ();
557 #endif
560 /* Return the first occurrence of a method declaration corresponding
561 to sel_name in rproto_list. Search rproto_list recursively.
562 If is_class is 0, search for instance methods, otherwise for class
563 methods. */
564 static tree
565 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
566 int is_class)
568 tree rproto, p;
569 tree fnd = 0;
571 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
573 p = TREE_VALUE (rproto);
575 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
577 if ((fnd = lookup_method (is_class
578 ? PROTOCOL_CLS_METHODS (p)
579 : PROTOCOL_NST_METHODS (p), sel_name)))
581 else if (PROTOCOL_LIST (p))
582 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
583 sel_name, is_class);
585 else
587 ; /* An identifier...if we could not find a protocol. */
590 if (fnd)
591 return fnd;
594 return 0;
597 static tree
598 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
600 tree rproto, p;
602 /* Make sure the protocol is supported by the object on the rhs. */
603 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
605 tree fnd = 0;
606 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
608 p = TREE_VALUE (rproto);
610 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
612 if (lproto == p)
613 fnd = lproto;
615 else if (PROTOCOL_LIST (p))
616 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
619 if (fnd)
620 return fnd;
623 else
625 ; /* An identifier...if we could not find a protocol. */
628 return 0;
631 void
632 objc_start_class_interface (tree class, tree super_class, tree protos)
634 objc_interface_context
635 = objc_ivar_context
636 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
637 objc_public_flag = 0;
640 void
641 objc_start_category_interface (tree class, tree categ, tree protos)
643 objc_interface_context
644 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
645 objc_ivar_chain
646 = continue_class (objc_interface_context);
649 void
650 objc_start_protocol (tree name, tree protos)
652 objc_interface_context
653 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
656 void
657 objc_continue_interface (void)
659 objc_ivar_chain
660 = continue_class (objc_interface_context);
663 void
664 objc_finish_interface (void)
666 finish_class (objc_interface_context);
667 objc_interface_context = NULL_TREE;
670 void
671 objc_start_class_implementation (tree class, tree super_class)
673 objc_implementation_context
674 = objc_ivar_context
675 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
676 objc_public_flag = 0;
679 void
680 objc_start_category_implementation (tree class, tree categ)
682 objc_implementation_context
683 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
684 objc_ivar_chain
685 = continue_class (objc_implementation_context);
688 void
689 objc_continue_implementation (void)
691 objc_ivar_chain
692 = continue_class (objc_implementation_context);
695 void
696 objc_finish_implementation (void)
698 #ifdef OBJCPLUS
699 if (flag_objc_call_cxx_cdtors)
700 objc_generate_cxx_cdtors ();
701 #endif
703 if (objc_implementation_context)
705 finish_class (objc_implementation_context);
706 objc_ivar_chain = NULL_TREE;
707 objc_implementation_context = NULL_TREE;
709 else
710 warning (0, "%<@end%> must appear in an @implementation context");
713 void
714 objc_set_visibility (int visibility)
716 objc_public_flag = visibility;
719 void
720 objc_set_method_type (enum tree_code type)
722 objc_inherit_code = (type == PLUS_EXPR
723 ? CLASS_METHOD_DECL
724 : INSTANCE_METHOD_DECL);
727 tree
728 objc_build_method_signature (tree rettype, tree selector,
729 tree optparms, bool ellipsis)
731 return build_method_decl (objc_inherit_code, rettype, selector,
732 optparms, ellipsis);
735 void
736 objc_add_method_declaration (tree decl)
738 if (!objc_interface_context)
739 fatal_error ("method declaration not in @interface context");
741 objc_add_method (objc_interface_context,
742 decl,
743 objc_inherit_code == CLASS_METHOD_DECL);
746 void
747 objc_start_method_definition (tree decl)
749 if (!objc_implementation_context)
750 fatal_error ("method definition not in @implementation context");
752 objc_add_method (objc_implementation_context,
753 decl,
754 objc_inherit_code == CLASS_METHOD_DECL);
755 start_method_def (decl);
758 void
759 objc_add_instance_variable (tree decl)
761 (void) add_instance_variable (objc_ivar_context,
762 objc_public_flag,
763 decl);
766 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
767 an '@'. */
770 objc_is_reserved_word (tree ident)
772 unsigned char code = C_RID_CODE (ident);
774 return (OBJC_IS_AT_KEYWORD (code)
775 #ifdef OBJCPLUS
776 || code == RID_CLASS || code == RID_PUBLIC
777 || code == RID_PROTECTED || code == RID_PRIVATE
778 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
779 #endif
783 /* Return true if TYPE is 'id'. */
785 static bool
786 objc_is_object_id (tree type)
788 return OBJC_TYPE_NAME (type) == objc_object_id;
791 static bool
792 objc_is_class_id (tree type)
794 return OBJC_TYPE_NAME (type) == objc_class_id;
797 /* Construct a C struct with same name as CLASS, a base struct with tag
798 SUPER_NAME (if any), and FIELDS indicated. */
800 static tree
801 objc_build_struct (tree class, tree fields, tree super_name)
803 tree name = CLASS_NAME (class);
804 tree s = start_struct (RECORD_TYPE, name);
805 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
806 tree t, objc_info = NULL_TREE;
808 if (super)
810 /* Prepend a packed variant of the base class into the layout. This
811 is necessary to preserve ObjC ABI compatibility. */
812 tree base = build_decl (FIELD_DECL, NULL_TREE, super);
813 tree field = TYPE_FIELDS (super);
815 while (field && TREE_CHAIN (field)
816 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
817 field = TREE_CHAIN (field);
819 /* For ObjC ABI purposes, the "packed" size of a base class is the
820 the sum of the offset and the size (in bits) of the last field
821 in the class. */
822 DECL_SIZE (base)
823 = (field && TREE_CODE (field) == FIELD_DECL
824 ? size_binop (PLUS_EXPR,
825 size_binop (PLUS_EXPR,
826 size_binop
827 (MULT_EXPR,
828 convert (bitsizetype,
829 DECL_FIELD_OFFSET (field)),
830 bitsize_int (BITS_PER_UNIT)),
831 DECL_FIELD_BIT_OFFSET (field)),
832 DECL_SIZE (field))
833 : bitsize_zero_node);
834 DECL_SIZE_UNIT (base)
835 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
836 size_int (BITS_PER_UNIT));
837 DECL_ARTIFICIAL (base) = 1;
838 DECL_ALIGN (base) = 1;
839 DECL_FIELD_CONTEXT (base) = s;
840 #ifdef OBJCPLUS
841 DECL_FIELD_IS_BASE (base) = 1;
843 if (fields)
844 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
845 #endif /* are following the ObjC ABI here. */
846 TREE_CHAIN (base) = fields;
847 fields = base;
850 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
851 in all variants of this RECORD_TYPE to be clobbered, but it is therein
852 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
853 Hence, we must squirrel away the ObjC-specific information before calling
854 finish_struct(), and then reinstate it afterwards. */
856 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
857 objc_info
858 = chainon (objc_info,
859 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
861 /* Point the struct at its related Objective-C class. */
862 INIT_TYPE_OBJC_INFO (s);
863 TYPE_OBJC_INTERFACE (s) = class;
865 s = finish_struct (s, fields, NULL_TREE);
867 for (t = TYPE_NEXT_VARIANT (s); t;
868 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
870 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
871 /* Replace the IDENTIFIER_NODE with an actual @interface. */
872 TYPE_OBJC_INTERFACE (t) = class;
875 /* Use TYPE_BINFO structures to point at the super class, if any. */
876 objc_xref_basetypes (s, super);
878 /* Mark this struct as a class template. */
879 CLASS_STATIC_TEMPLATE (class) = s;
881 return s;
884 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
885 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
886 process. */
887 static tree
888 objc_build_volatilized_type (tree type)
890 tree t;
892 /* Check if we have not constructed the desired variant already. */
893 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
895 /* The type qualifiers must (obviously) match up. */
896 if (!TYPE_VOLATILE (t)
897 || (TYPE_READONLY (t) != TYPE_READONLY (type))
898 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
899 continue;
901 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
902 info, if any) must match up. */
903 if (POINTER_TYPE_P (t)
904 && (TREE_TYPE (t) != TREE_TYPE (type)))
905 continue;
907 /* Everything matches up! */
908 return t;
911 /* Ok, we could not re-use any of the pre-existing variants. Create
912 a new one. */
913 t = build_variant_type_copy (type);
914 TYPE_VOLATILE (t) = 1;
916 return t;
919 /* Mark DECL as being 'volatile' for purposes of Darwin
920 _setjmp()/_longjmp() exception handling. Called from
921 objc_mark_locals_volatile(). */
922 void
923 objc_volatilize_decl (tree decl)
925 /* Do not mess with variables that are 'static' or (already)
926 'volatile'. */
927 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
928 && (TREE_CODE (decl) == VAR_DECL
929 || TREE_CODE (decl) == PARM_DECL))
931 tree t = TREE_TYPE (decl);
932 struct volatilized_type key;
933 void **loc;
935 t = objc_build_volatilized_type (t);
936 key.type = t;
937 loc = htab_find_slot (volatilized_htab, &key, INSERT);
939 if (!*loc)
941 *loc = ggc_alloc (sizeof (key));
942 ((struct volatilized_type *) *loc)->type = t;
945 TREE_TYPE (decl) = t;
946 TREE_THIS_VOLATILE (decl) = 1;
947 TREE_SIDE_EFFECTS (decl) = 1;
948 DECL_REGISTER (decl) = 0;
949 #ifndef OBJCPLUS
950 C_DECL_REGISTER (decl) = 0;
951 #endif
955 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
956 (including its categoreis and superclasses) or by object type TYP.
957 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
959 static bool
960 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
962 bool class_type = (cls != NULL_TREE);
964 while (cls)
966 tree c;
968 /* Check protocols adopted by the class and its categories. */
969 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
971 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
972 return true;
975 /* Repeat for superclasses. */
976 cls = lookup_interface (CLASS_SUPER_NAME (cls));
979 /* Check for any protocols attached directly to the object type. */
980 if (TYPE_HAS_OBJC_INFO (typ))
982 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
983 return true;
986 if (warn)
988 strcpy (errbuf, class_type ? "class \'" : "type \'");
989 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
990 strcat (errbuf, "\' does not ");
991 /* NB: Types 'id' and 'Class' cannot reasonably be described as
992 "implementing" a given protocol, since they do not have an
993 implementation. */
994 strcat (errbuf, class_type ? "implement" : "conform to");
995 strcat (errbuf, " the \'");
996 strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
997 strcat (errbuf, "\' protocol");
998 warning (0, errbuf);
1001 return false;
1004 /* Check if class RCLS and instance struct type RTYP conform to at least the
1005 same protocols that LCLS and LTYP conform to. */
1007 static bool
1008 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1010 tree p;
1011 bool have_lproto = false;
1013 while (lcls)
1015 /* NB: We do _not_ look at categories defined for LCLS; these may or
1016 may not get loaded in, and therefore it is unreasonable to require
1017 that RCLS/RTYP must implement any of their protocols. */
1018 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1020 have_lproto = true;
1022 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1023 return warn;
1026 /* Repeat for superclasses. */
1027 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1030 /* Check for any protocols attached directly to the object type. */
1031 if (TYPE_HAS_OBJC_INFO (ltyp))
1033 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1035 have_lproto = true;
1037 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1038 return warn;
1042 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1043 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1044 away with simply checking for 'id' or 'Class' (!RCLS), since this
1045 routine will not get called in other cases. */
1046 return have_lproto || (rcls != NULL_TREE);
1049 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1050 an instance of RTYP to an instance of LTYP or to compare the two
1051 (if ARGNO is equal to -3), per ObjC type system rules. Before
1052 returning 'true', this routine may issue warnings related to, e.g.,
1053 protocol conformance. When returning 'false', the routine must
1054 produce absolutely no warnings; the C or C++ front-end will do so
1055 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1056 the routine must return 'false'.
1058 The ARGNO parameter is encoded as follows:
1059 >= 1 Parameter number (CALLEE contains function being called);
1060 0 Return value;
1061 -1 Assignment;
1062 -2 Initialization;
1063 -3 Comparison (LTYP and RTYP may match in either direction). */
1065 bool
1066 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1068 tree lcls, rcls, lproto, rproto;
1069 bool pointers_compatible;
1071 /* We must be dealing with pointer types */
1072 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1073 return false;
1077 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1078 rtyp = TREE_TYPE (rtyp);
1080 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1082 /* Past this point, we are only interested in ObjC class instances,
1083 or 'id' or 'Class'. */
1084 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1085 return false;
1087 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1088 && !TYPE_HAS_OBJC_INFO (ltyp))
1089 return false;
1091 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1092 && !TYPE_HAS_OBJC_INFO (rtyp))
1093 return false;
1095 /* Past this point, we are committed to returning 'true' to the caller.
1096 However, we can still warn about type and/or protocol mismatches. */
1098 if (TYPE_HAS_OBJC_INFO (ltyp))
1100 lcls = TYPE_OBJC_INTERFACE (ltyp);
1101 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1103 else
1104 lcls = lproto = NULL_TREE;
1106 if (TYPE_HAS_OBJC_INFO (rtyp))
1108 rcls = TYPE_OBJC_INTERFACE (rtyp);
1109 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1111 else
1112 rcls = rproto = NULL_TREE;
1114 /* If we could not find an @interface declaration, we must have
1115 only seen a @class declaration; for purposes of type comparison,
1116 treat it as a stand-alone (root) class. */
1118 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1119 lcls = NULL_TREE;
1121 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1122 rcls = NULL_TREE;
1124 /* If either type is an unqualified 'id', we're done. */
1125 if ((!lproto && objc_is_object_id (ltyp))
1126 || (!rproto && objc_is_object_id (rtyp)))
1127 return true;
1129 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1131 /* If the underlying types are the same, and at most one of them has
1132 a protocol list, we do not need to issue any diagnostics. */
1133 if (pointers_compatible && (!lproto || !rproto))
1134 return true;
1136 /* If exactly one of the types is 'Class', issue a diagnostic; any
1137 exceptions of this rule have already been handled. */
1138 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1139 pointers_compatible = false;
1140 /* Otherwise, check for inheritance relations. */
1141 else
1143 if (!pointers_compatible)
1144 pointers_compatible
1145 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1147 if (!pointers_compatible)
1148 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1150 if (!pointers_compatible && argno == -3)
1151 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1154 /* If the pointers match modulo protocols, check for protocol conformance
1155 mismatches. */
1156 if (pointers_compatible)
1158 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1159 argno != -3);
1161 if (!pointers_compatible && argno == -3)
1162 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1163 argno != -3);
1166 if (!pointers_compatible)
1168 /* NB: For the time being, we shall make our warnings look like their
1169 C counterparts. In the future, we may wish to make them more
1170 ObjC-specific. */
1171 switch (argno)
1173 case -3:
1174 warning (0, "comparison of distinct Objective-C types lacks a cast");
1175 break;
1177 case -2:
1178 warning (0, "initialization from distinct Objective-C type");
1179 break;
1181 case -1:
1182 warning (0, "assignment from distinct Objective-C type");
1183 break;
1185 case 0:
1186 warning (0, "distinct Objective-C type in return");
1187 break;
1189 default:
1190 warning (0, "passing argument %d of %qE from distinct "
1191 "Objective-C type", argno, callee);
1192 break;
1196 return true;
1199 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1200 lives in the volatilized hash table, ignore the 'volatile' bit when
1201 making the comparison. */
1203 bool
1204 objc_type_quals_match (tree ltyp, tree rtyp)
1206 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1207 struct volatilized_type key;
1209 key.type = ltyp;
1211 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1212 lquals &= ~TYPE_QUAL_VOLATILE;
1214 key.type = rtyp;
1216 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1217 rquals &= ~TYPE_QUAL_VOLATILE;
1219 return (lquals == rquals);
1222 #ifndef OBJCPLUS
1223 /* Determine if CHILD is derived from PARENT. The routine assumes that
1224 both parameters are RECORD_TYPEs, and is non-reflexive. */
1226 static bool
1227 objc_derived_from_p (tree parent, tree child)
1229 parent = TYPE_MAIN_VARIANT (parent);
1231 for (child = TYPE_MAIN_VARIANT (child);
1232 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1234 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1235 (TYPE_BINFO (child),
1236 0)));
1238 if (child == parent)
1239 return true;
1242 return false;
1244 #endif
1246 static tree
1247 objc_build_component_ref (tree datum, tree component)
1249 /* If COMPONENT is NULL, the caller is referring to the anonymous
1250 base class field. */
1251 if (!component)
1253 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1255 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1258 /* The 'build_component_ref' routine has been removed from the C++
1259 front-end, but 'finish_class_member_access_expr' seems to be
1260 a worthy substitute. */
1261 #ifdef OBJCPLUS
1262 return finish_class_member_access_expr (datum, component, false);
1263 #else
1264 return build_component_ref (datum, component);
1265 #endif
1268 /* Recursively copy inheritance information rooted at BINFO. To do this,
1269 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1271 static tree
1272 objc_copy_binfo (tree binfo)
1274 tree btype = BINFO_TYPE (binfo);
1275 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1276 tree base_binfo;
1277 int ix;
1279 BINFO_TYPE (binfo2) = btype;
1280 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1281 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1283 /* Recursively copy base binfos of BINFO. */
1284 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1286 tree base_binfo2 = objc_copy_binfo (base_binfo);
1288 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1289 BINFO_BASE_APPEND (binfo2, base_binfo2);
1292 return binfo2;
1295 /* Record superclass information provided in BASETYPE for ObjC class REF.
1296 This is loosely based on cp/decl.c:xref_basetypes(). */
1298 static void
1299 objc_xref_basetypes (tree ref, tree basetype)
1301 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1303 TYPE_BINFO (ref) = binfo;
1304 BINFO_OFFSET (binfo) = size_zero_node;
1305 BINFO_TYPE (binfo) = ref;
1307 if (basetype)
1309 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1311 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1312 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1313 BINFO_BASE_APPEND (binfo, base_binfo);
1314 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1318 static hashval_t
1319 volatilized_hash (const void *ptr)
1321 tree typ = ((struct volatilized_type *)ptr)->type;
1323 return htab_hash_pointer(typ);
1326 static int
1327 volatilized_eq (const void *ptr1, const void *ptr2)
1329 tree typ1 = ((struct volatilized_type *)ptr1)->type;
1330 tree typ2 = ((struct volatilized_type *)ptr2)->type;
1332 return typ1 == typ2;
1335 /* Called from finish_decl. */
1337 void
1338 objc_check_decl (tree decl)
1340 tree type = TREE_TYPE (decl);
1342 if (TREE_CODE (type) != RECORD_TYPE)
1343 return;
1344 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1345 error ("statically allocated instance of Objective-C class %qs",
1346 IDENTIFIER_POINTER (type));
1349 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1350 either name an Objective-C class, or refer to the special 'id' or 'Class'
1351 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1353 tree
1354 objc_get_protocol_qualified_type (tree interface, tree protocols)
1356 /* If INTERFACE is not provided, default to 'id'. */
1357 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1358 bool is_ptr = (type != NULL_TREE);
1360 if (!is_ptr)
1362 type = objc_is_class_name (interface);
1364 if (type)
1365 type = xref_tag (RECORD_TYPE, type);
1366 else
1367 return interface;
1370 if (protocols)
1372 type = build_variant_type_copy (type);
1374 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1375 to the pointee. */
1376 if (is_ptr)
1378 TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
1379 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1380 type = TREE_TYPE (type);
1383 /* Look up protocols and install in lang specific list. */
1384 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1385 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1387 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1388 return the pointer to the new pointee variant. */
1389 if (is_ptr)
1390 type = TYPE_POINTER_TO (type);
1391 else
1392 TYPE_OBJC_INTERFACE (type)
1393 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1396 return type;
1399 /* Check for circular dependencies in protocols. The arguments are
1400 PROTO, the protocol to check, and LIST, a list of protocol it
1401 conforms to. */
1403 static void
1404 check_protocol_recursively (tree proto, tree list)
1406 tree p;
1408 for (p = list; p; p = TREE_CHAIN (p))
1410 tree pp = TREE_VALUE (p);
1412 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1413 pp = lookup_protocol (pp);
1415 if (pp == proto)
1416 fatal_error ("protocol %qs has circular dependency",
1417 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1418 if (pp)
1419 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1423 /* Look up PROTOCOLS, and return a list of those that are found.
1424 If none are found, return NULL. */
1426 static tree
1427 lookup_and_install_protocols (tree protocols)
1429 tree proto;
1430 tree return_value = NULL_TREE;
1432 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1434 tree ident = TREE_VALUE (proto);
1435 tree p = lookup_protocol (ident);
1437 if (!p)
1438 error ("cannot find protocol declaration for %qs",
1439 IDENTIFIER_POINTER (ident));
1440 else
1441 return_value = chainon (return_value,
1442 build_tree_list (NULL_TREE, p));
1445 return return_value;
1448 /* Create a declaration for field NAME of a given TYPE. */
1450 static tree
1451 create_field_decl (tree type, const char *name)
1453 return build_decl (FIELD_DECL, get_identifier (name), type);
1456 /* Create a global, static declaration for variable NAME of a given TYPE. The
1457 finish_var_decl() routine will need to be called on it afterwards. */
1459 static tree
1460 start_var_decl (tree type, const char *name)
1462 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1464 TREE_STATIC (var) = 1;
1465 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1466 DECL_IGNORED_P (var) = 1;
1467 DECL_ARTIFICIAL (var) = 1;
1468 DECL_CONTEXT (var) = NULL_TREE;
1469 #ifdef OBJCPLUS
1470 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1471 #endif
1473 return var;
1476 /* Finish off the variable declaration created by start_var_decl(). */
1478 static void
1479 finish_var_decl (tree var, tree initializer)
1481 finish_decl (var, initializer, NULL_TREE);
1482 /* Ensure that the variable actually gets output. */
1483 mark_decl_referenced (var);
1484 /* Mark the decl to avoid "defined but not used" warning. */
1485 TREE_USED (var) = 1;
1488 /* Find the decl for the constant string class reference. This is only
1489 used for the NeXT runtime. */
1491 static tree
1492 setup_string_decl (void)
1494 char *name;
1495 size_t length;
1497 /* %s in format will provide room for terminating null */
1498 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1499 + strlen (constant_string_class_name);
1500 name = xmalloc (length);
1501 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1502 constant_string_class_name);
1503 constant_string_global_id = get_identifier (name);
1504 string_class_decl = lookup_name (constant_string_global_id);
1506 return string_class_decl;
1509 /* Purpose: "play" parser, creating/installing representations
1510 of the declarations that are required by Objective-C.
1512 Model:
1514 type_spec--------->sc_spec
1515 (tree_list) (tree_list)
1518 identifier_node identifier_node */
1520 static void
1521 synth_module_prologue (void)
1523 tree type;
1524 enum debug_info_type save_write_symbols = write_symbols;
1525 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1527 /* Suppress outputting debug symbols, because
1528 dbxout_init hasn'r been called yet. */
1529 write_symbols = NO_DEBUG;
1530 debug_hooks = &do_nothing_debug_hooks;
1532 #ifdef OBJCPLUS
1533 push_lang_context (lang_name_c); /* extern "C" */
1534 #endif
1536 /* The following are also defined in <objc/objc.h> and friends. */
1538 objc_object_id = get_identifier (TAG_OBJECT);
1539 objc_class_id = get_identifier (TAG_CLASS);
1541 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1542 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1544 objc_object_type = build_pointer_type (objc_object_reference);
1545 objc_class_type = build_pointer_type (objc_class_reference);
1547 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1548 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1550 /* Declare the 'id' and 'Class' typedefs. */
1552 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1553 objc_object_name,
1554 objc_object_type));
1555 DECL_IN_SYSTEM_HEADER (type) = 1;
1556 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1557 objc_class_name,
1558 objc_class_type));
1559 DECL_IN_SYSTEM_HEADER (type) = 1;
1561 /* Forward-declare '@interface Protocol'. */
1563 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1564 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1565 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1566 type));
1568 /* Declare type of selector-objects that represent an operation name. */
1570 if (flag_next_runtime)
1571 /* `struct objc_selector *' */
1572 objc_selector_type
1573 = build_pointer_type (xref_tag (RECORD_TYPE,
1574 get_identifier (TAG_SELECTOR)));
1575 else
1576 /* `const struct objc_selector *' */
1577 objc_selector_type
1578 = build_pointer_type
1579 (build_qualified_type (xref_tag (RECORD_TYPE,
1580 get_identifier (TAG_SELECTOR)),
1581 TYPE_QUAL_CONST));
1583 /* Declare receiver type used for dispatching messages to 'super'. */
1585 /* `struct objc_super *' */
1586 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1587 get_identifier (TAG_SUPER)));
1589 /* Declare pointers to method and ivar lists. */
1590 objc_method_list_ptr = build_pointer_type
1591 (xref_tag (RECORD_TYPE,
1592 get_identifier (UTAG_METHOD_LIST)));
1593 objc_method_proto_list_ptr
1594 = build_pointer_type (xref_tag (RECORD_TYPE,
1595 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1596 objc_ivar_list_ptr = build_pointer_type
1597 (xref_tag (RECORD_TYPE,
1598 get_identifier (UTAG_IVAR_LIST)));
1600 /* TREE_NOTHROW is cleared for the message-sending functions,
1601 because the function that gets called can throw in Obj-C++, or
1602 could itself call something that can throw even in Obj-C. */
1604 if (flag_next_runtime)
1606 /* NB: In order to call one of the ..._stret (struct-returning)
1607 functions, the function *MUST* first be cast to a signature that
1608 corresponds to the actual ObjC method being invoked. This is
1609 what is done by the build_objc_method_call() routine below. */
1611 /* id objc_msgSend (id, SEL, ...); */
1612 /* id objc_msgSendNonNil (id, SEL, ...); */
1613 /* id objc_msgSend_stret (id, SEL, ...); */
1614 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1615 type
1616 = build_function_type (objc_object_type,
1617 tree_cons (NULL_TREE, objc_object_type,
1618 tree_cons (NULL_TREE, objc_selector_type,
1619 NULL_TREE)));
1620 umsg_decl = builtin_function (TAG_MSGSEND,
1621 type, 0, NOT_BUILT_IN,
1622 NULL, NULL_TREE);
1623 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1624 type, 0, NOT_BUILT_IN,
1625 NULL, NULL_TREE);
1626 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1627 type, 0, NOT_BUILT_IN,
1628 NULL, NULL_TREE);
1629 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1630 type, 0, NOT_BUILT_IN,
1631 NULL, NULL_TREE);
1633 /* These can throw, because the function that gets called can throw
1634 in Obj-C++, or could itself call something that can throw even
1635 in Obj-C. */
1636 TREE_NOTHROW (umsg_decl) = 0;
1637 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1638 TREE_NOTHROW (umsg_stret_decl) = 0;
1639 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1641 /* id objc_msgSend_Fast (id, SEL, ...)
1642 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1643 #ifdef OFFS_MSGSEND_FAST
1644 umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
1645 type, 0, NOT_BUILT_IN,
1646 NULL, NULL_TREE);
1647 TREE_NOTHROW (umsg_fast_decl) = 0;
1648 DECL_ATTRIBUTES (umsg_fast_decl)
1649 = tree_cons (get_identifier ("hard_coded_address"),
1650 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1651 NULL_TREE);
1652 #else
1653 /* No direct dispatch availible. */
1654 umsg_fast_decl = umsg_decl;
1655 #endif
1657 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1658 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1659 type
1660 = build_function_type (objc_object_type,
1661 tree_cons (NULL_TREE, objc_super_type,
1662 tree_cons (NULL_TREE, objc_selector_type,
1663 NULL_TREE)));
1664 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1665 type, 0, NOT_BUILT_IN,
1666 NULL, NULL_TREE);
1667 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1668 type, 0, NOT_BUILT_IN, 0,
1669 NULL_TREE);
1670 TREE_NOTHROW (umsg_super_decl) = 0;
1671 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1673 else
1675 /* GNU runtime messenger entry points. */
1677 /* typedef id (*IMP)(id, SEL, ...); */
1678 tree IMP_type
1679 = build_pointer_type
1680 (build_function_type (objc_object_type,
1681 tree_cons (NULL_TREE, objc_object_type,
1682 tree_cons (NULL_TREE, objc_selector_type,
1683 NULL_TREE))));
1685 /* IMP objc_msg_lookup (id, SEL); */
1686 type
1687 = build_function_type (IMP_type,
1688 tree_cons (NULL_TREE, objc_object_type,
1689 tree_cons (NULL_TREE, objc_selector_type,
1690 OBJC_VOID_AT_END)));
1691 umsg_decl = builtin_function (TAG_MSGSEND,
1692 type, 0, NOT_BUILT_IN,
1693 NULL, NULL_TREE);
1694 TREE_NOTHROW (umsg_decl) = 0;
1696 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1697 type
1698 = build_function_type (IMP_type,
1699 tree_cons (NULL_TREE, objc_super_type,
1700 tree_cons (NULL_TREE, objc_selector_type,
1701 OBJC_VOID_AT_END)));
1702 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1703 type, 0, NOT_BUILT_IN,
1704 NULL, NULL_TREE);
1705 TREE_NOTHROW (umsg_super_decl) = 0;
1707 /* The following GNU runtime entry point is called to initialize
1708 each module:
1710 __objc_exec_class (void *); */
1711 type
1712 = build_function_type (void_type_node,
1713 tree_cons (NULL_TREE, ptr_type_node,
1714 OBJC_VOID_AT_END));
1715 execclass_decl = builtin_function (TAG_EXECCLASS,
1716 type, 0, NOT_BUILT_IN,
1717 NULL, NULL_TREE);
1720 /* id objc_getClass (const char *); */
1722 type = build_function_type (objc_object_type,
1723 tree_cons (NULL_TREE,
1724 const_string_type_node,
1725 OBJC_VOID_AT_END));
1727 objc_get_class_decl
1728 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1729 NULL, NULL_TREE);
1731 /* id objc_getMetaClass (const char *); */
1733 objc_get_meta_class_decl
1734 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1736 build_class_template ();
1737 build_super_template ();
1738 build_protocol_template ();
1739 build_category_template ();
1740 build_objc_exception_stuff ();
1742 if (flag_next_runtime)
1743 build_next_objc_exception_stuff ();
1745 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1747 if (! flag_next_runtime)
1748 build_selector_table_decl ();
1750 /* Forward declare constant_string_id and constant_string_type. */
1751 if (!constant_string_class_name)
1752 constant_string_class_name = default_constant_string_class_name;
1754 constant_string_id = get_identifier (constant_string_class_name);
1755 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1757 /* Pre-build the following entities - for speed/convenience. */
1758 self_id = get_identifier ("self");
1759 ucmd_id = get_identifier ("_cmd");
1761 #ifdef OBJCPLUS
1762 pop_lang_context ();
1763 #endif
1765 write_symbols = save_write_symbols;
1766 debug_hooks = save_hooks;
1769 /* Ensure that the ivar list for NSConstantString/NXConstantString
1770 (or whatever was specified via `-fconstant-string-class')
1771 contains fields at least as large as the following three, so that
1772 the runtime can stomp on them with confidence:
1774 struct STRING_OBJECT_CLASS_NAME
1776 Object isa;
1777 char *cString;
1778 unsigned int length;
1779 }; */
1781 static int
1782 check_string_class_template (void)
1784 tree field_decl = objc_get_class_ivars (constant_string_id);
1786 #define AT_LEAST_AS_LARGE_AS(F, T) \
1787 (F && TREE_CODE (F) == FIELD_DECL \
1788 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1789 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1791 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1792 return 0;
1794 field_decl = TREE_CHAIN (field_decl);
1795 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1796 return 0;
1798 field_decl = TREE_CHAIN (field_decl);
1799 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1801 #undef AT_LEAST_AS_LARGE_AS
1804 /* Avoid calling `check_string_class_template ()' more than once. */
1805 static GTY(()) int string_layout_checked;
1807 /* Construct an internal string layout to be used as a template for
1808 creating NSConstantString/NXConstantString instances. */
1810 static tree
1811 objc_build_internal_const_str_type (void)
1813 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1814 tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1815 tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
1817 TREE_CHAIN (field) = fields; fields = field;
1818 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
1819 TREE_CHAIN (field) = fields; fields = field;
1820 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1821 reverse order! */
1822 finish_builtin_struct (type, "__builtin_ObjCString",
1823 fields, NULL_TREE);
1825 return type;
1828 /* Custom build_string which sets TREE_TYPE! */
1830 static tree
1831 my_build_string (int len, const char *str)
1833 return fix_string_type (build_string (len, str));
1836 /* Build a string with contents STR and length LEN and convert it to a
1837 pointer. */
1839 static tree
1840 my_build_string_pointer (int len, const char *str)
1842 tree string = my_build_string (len, str);
1843 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1844 return build1 (ADDR_EXPR, ptrtype, string);
1847 static hashval_t
1848 string_hash (const void *ptr)
1850 tree str = ((struct string_descriptor *)ptr)->literal;
1851 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1852 int i, len = TREE_STRING_LENGTH (str);
1853 hashval_t h = len;
1855 for (i = 0; i < len; i++)
1856 h = ((h * 613) + p[i]);
1858 return h;
1861 static int
1862 string_eq (const void *ptr1, const void *ptr2)
1864 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1865 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1866 int len1 = TREE_STRING_LENGTH (str1);
1868 return (len1 == TREE_STRING_LENGTH (str2)
1869 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1870 len1));
1873 /* Given a chain of STRING_CST's, build a static instance of
1874 NXConstantString which points at the concatenation of those
1875 strings. We place the string object in the __string_objects
1876 section of the __OBJC segment. The Objective-C runtime will
1877 initialize the isa pointers of the string objects to point at the
1878 NXConstantString class object. */
1880 tree
1881 objc_build_string_object (tree string)
1883 tree initlist, constructor, constant_string_class;
1884 int length;
1885 tree fields, addr;
1886 struct string_descriptor *desc, key;
1887 void **loc;
1889 /* Prep the string argument. */
1890 string = fix_string_type (string);
1891 TREE_SET_CODE (string, STRING_CST);
1892 length = TREE_STRING_LENGTH (string) - 1;
1894 /* Check whether the string class being used actually exists and has the
1895 correct ivar layout. */
1896 if (!string_layout_checked)
1898 string_layout_checked = -1;
1899 constant_string_class = lookup_interface (constant_string_id);
1900 internal_const_str_type = objc_build_internal_const_str_type ();
1902 if (!constant_string_class
1903 || !(constant_string_type
1904 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1905 error ("cannot find interface declaration for %qs",
1906 IDENTIFIER_POINTER (constant_string_id));
1907 /* The NSConstantString/NXConstantString ivar layout is now known. */
1908 else if (!check_string_class_template ())
1909 error ("interface %qs does not have valid constant string layout",
1910 IDENTIFIER_POINTER (constant_string_id));
1911 /* For the NeXT runtime, we can generate a literal reference
1912 to the string class, don't need to run a constructor. */
1913 else if (flag_next_runtime && !setup_string_decl ())
1914 error ("cannot find reference tag for class %qs",
1915 IDENTIFIER_POINTER (constant_string_id));
1916 else
1918 string_layout_checked = 1; /* Success! */
1919 add_class_reference (constant_string_id);
1923 if (string_layout_checked == -1)
1924 return error_mark_node;
1926 /* Perhaps we already constructed a constant string just like this one? */
1927 key.literal = string;
1928 loc = htab_find_slot (string_htab, &key, INSERT);
1929 desc = *loc;
1931 if (!desc)
1933 tree var;
1934 *loc = desc = ggc_alloc (sizeof (*desc));
1935 desc->literal = string;
1937 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1938 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1939 fields = TYPE_FIELDS (internal_const_str_type);
1940 initlist
1941 = build_tree_list (fields,
1942 flag_next_runtime
1943 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1944 : build_int_cst (NULL_TREE, 0));
1945 fields = TREE_CHAIN (fields);
1946 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1947 initlist);
1948 fields = TREE_CHAIN (fields);
1949 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1950 initlist);
1951 constructor = objc_build_constructor (internal_const_str_type,
1952 nreverse (initlist));
1953 TREE_INVARIANT (constructor) = true;
1955 if (!flag_next_runtime)
1956 constructor
1957 = objc_add_static_instance (constructor, constant_string_type);
1958 else
1960 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1961 DECL_INITIAL (var) = constructor;
1962 TREE_STATIC (var) = 1;
1963 pushdecl_top_level (var);
1964 constructor = var;
1966 desc->constructor = constructor;
1969 addr = convert (build_pointer_type (constant_string_type),
1970 build_unary_op (ADDR_EXPR, desc->constructor, 1));
1972 return addr;
1975 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1977 static GTY(()) int num_static_inst;
1979 static tree
1980 objc_add_static_instance (tree constructor, tree class_decl)
1982 tree *chain, decl;
1983 char buf[256];
1985 /* Find the list of static instances for the CLASS_DECL. Create one if
1986 not found. */
1987 for (chain = &objc_static_instances;
1988 *chain && TREE_VALUE (*chain) != class_decl;
1989 chain = &TREE_CHAIN (*chain));
1990 if (!*chain)
1992 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1993 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1996 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1997 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1998 DECL_COMMON (decl) = 1;
1999 TREE_STATIC (decl) = 1;
2000 DECL_ARTIFICIAL (decl) = 1;
2001 DECL_INITIAL (decl) = constructor;
2003 /* We may be writing something else just now.
2004 Postpone till end of input. */
2005 DECL_DEFER_OUTPUT (decl) = 1;
2006 pushdecl_top_level (decl);
2007 rest_of_decl_compilation (decl, 1, 0);
2009 /* Add the DECL to the head of this CLASS' list. */
2010 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2012 return decl;
2015 /* Build a static constant CONSTRUCTOR
2016 with type TYPE and elements ELTS. */
2018 static tree
2019 objc_build_constructor (tree type, tree elts)
2021 tree constructor = build_constructor_from_list (type, elts);
2023 TREE_CONSTANT (constructor) = 1;
2024 TREE_STATIC (constructor) = 1;
2025 TREE_READONLY (constructor) = 1;
2027 #ifdef OBJCPLUS
2028 /* Adjust for impedance mismatch. We should figure out how to build
2029 CONSTRUCTORs that consistently please both the C and C++ gods. */
2030 if (!TREE_PURPOSE (elts))
2031 TREE_TYPE (constructor) = NULL_TREE;
2032 TREE_HAS_CONSTRUCTOR (constructor) = 1;
2033 #endif
2035 return constructor;
2038 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2040 /* Predefine the following data type:
2042 struct _objc_symtab
2044 long sel_ref_cnt;
2045 SEL *refs;
2046 short cls_def_cnt;
2047 short cat_def_cnt;
2048 void *defs[cls_def_cnt + cat_def_cnt];
2049 }; */
2051 static void
2052 build_objc_symtab_template (void)
2054 tree field_decl, field_decl_chain;
2056 objc_symtab_template
2057 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
2059 /* long sel_ref_cnt; */
2060 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2061 field_decl_chain = field_decl;
2063 /* SEL *refs; */
2064 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2065 "refs");
2066 chainon (field_decl_chain, field_decl);
2068 /* short cls_def_cnt; */
2069 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2070 chainon (field_decl_chain, field_decl);
2072 /* short cat_def_cnt; */
2073 field_decl = create_field_decl (short_integer_type_node,
2074 "cat_def_cnt");
2075 chainon (field_decl_chain, field_decl);
2077 if (imp_count || cat_count || !flag_next_runtime)
2079 /* void *defs[imp_count + cat_count (+ 1)]; */
2080 /* NB: The index is one less than the size of the array. */
2081 int index = imp_count + cat_count
2082 + (flag_next_runtime? -1: 0);
2083 field_decl = create_field_decl
2084 (build_array_type
2085 (ptr_type_node,
2086 build_index_type (build_int_cst (NULL_TREE, index))),
2087 "defs");
2088 chainon (field_decl_chain, field_decl);
2091 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
2094 /* Create the initial value for the `defs' field of _objc_symtab.
2095 This is a CONSTRUCTOR. */
2097 static tree
2098 init_def_list (tree type)
2100 tree expr, initlist = NULL_TREE;
2101 struct imp_entry *impent;
2103 if (imp_count)
2104 for (impent = imp_list; impent; impent = impent->next)
2106 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2108 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2109 initlist = tree_cons (NULL_TREE, expr, initlist);
2113 if (cat_count)
2114 for (impent = imp_list; impent; impent = impent->next)
2116 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2118 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
2119 initlist = tree_cons (NULL_TREE, expr, initlist);
2123 if (!flag_next_runtime)
2125 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2126 tree expr;
2128 if (static_instances_decl)
2129 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
2130 else
2131 expr = build_int_cst (NULL_TREE, 0);
2133 initlist = tree_cons (NULL_TREE, expr, initlist);
2136 return objc_build_constructor (type, nreverse (initlist));
2139 /* Construct the initial value for all of _objc_symtab. */
2141 static tree
2142 init_objc_symtab (tree type)
2144 tree initlist;
2146 /* sel_ref_cnt = { ..., 5, ... } */
2148 initlist = build_tree_list (NULL_TREE,
2149 build_int_cst (long_integer_type_node, 0));
2151 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2153 if (flag_next_runtime || ! sel_ref_chain)
2154 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2155 else
2156 initlist
2157 = tree_cons (NULL_TREE,
2158 convert (build_pointer_type (objc_selector_type),
2159 build_unary_op (ADDR_EXPR,
2160 UOBJC_SELECTOR_TABLE_decl, 1)),
2161 initlist);
2163 /* cls_def_cnt = { ..., 5, ... } */
2165 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2167 /* cat_def_cnt = { ..., 5, ... } */
2169 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2171 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2173 if (imp_count || cat_count || !flag_next_runtime)
2176 tree field = TYPE_FIELDS (type);
2177 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2179 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2180 initlist);
2183 return objc_build_constructor (type, nreverse (initlist));
2186 /* Generate forward declarations for metadata such as
2187 'OBJC_CLASS_...'. */
2189 static tree
2190 build_metadata_decl (const char *name, tree type)
2192 tree decl;
2194 /* struct TYPE NAME_<name>; */
2195 decl = start_var_decl (type, synth_id_with_class_suffix
2196 (name,
2197 objc_implementation_context));
2199 return decl;
2202 /* Push forward-declarations of all the categories so that
2203 init_def_list can use them in a CONSTRUCTOR. */
2205 static void
2206 forward_declare_categories (void)
2208 struct imp_entry *impent;
2209 tree sav = objc_implementation_context;
2211 for (impent = imp_list; impent; impent = impent->next)
2213 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2215 /* Set an invisible arg to synth_id_with_class_suffix. */
2216 objc_implementation_context = impent->imp_context;
2217 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2218 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2219 objc_category_template);
2222 objc_implementation_context = sav;
2225 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2226 and initialized appropriately. */
2228 static void
2229 generate_objc_symtab_decl (void)
2231 /* forward declare categories */
2232 if (cat_count)
2233 forward_declare_categories ();
2235 build_objc_symtab_template ();
2236 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2237 finish_var_decl (UOBJC_SYMBOLS_decl,
2238 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2241 static tree
2242 init_module_descriptor (tree type)
2244 tree initlist, expr;
2246 /* version = { 1, ... } */
2248 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2249 initlist = build_tree_list (NULL_TREE, expr);
2251 /* size = { ..., sizeof (struct _objc_module), ... } */
2253 expr = convert (long_integer_type_node,
2254 size_in_bytes (objc_module_template));
2255 initlist = tree_cons (NULL_TREE, expr, initlist);
2257 /* name = { ..., "foo.m", ... } */
2259 expr = add_objc_string (get_identifier (input_filename), class_names);
2260 initlist = tree_cons (NULL_TREE, expr, initlist);
2262 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2264 if (UOBJC_SYMBOLS_decl)
2265 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2266 else
2267 expr = build_int_cst (NULL_TREE, 0);
2268 initlist = tree_cons (NULL_TREE, expr, initlist);
2270 return objc_build_constructor (type, nreverse (initlist));
2273 /* Write out the data structures to describe Objective C classes defined.
2275 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2277 static void
2278 build_module_descriptor (void)
2280 tree field_decl, field_decl_chain;
2282 #ifdef OBJCPLUS
2283 push_lang_context (lang_name_c); /* extern "C" */
2284 #endif
2286 objc_module_template
2287 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2289 /* long version; */
2290 field_decl = create_field_decl (long_integer_type_node, "version");
2291 field_decl_chain = field_decl;
2293 /* long size; */
2294 field_decl = create_field_decl (long_integer_type_node, "size");
2295 chainon (field_decl_chain, field_decl);
2297 /* char *name; */
2298 field_decl = create_field_decl (string_type_node, "name");
2299 chainon (field_decl_chain, field_decl);
2301 /* struct _objc_symtab *symtab; */
2302 field_decl
2303 = create_field_decl (build_pointer_type
2304 (xref_tag (RECORD_TYPE,
2305 get_identifier (UTAG_SYMTAB))),
2306 "symtab");
2307 chainon (field_decl_chain, field_decl);
2309 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2311 /* Create an instance of "_objc_module". */
2312 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2313 finish_var_decl (UOBJC_MODULES_decl,
2314 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2316 #ifdef OBJCPLUS
2317 pop_lang_context ();
2318 #endif
2321 /* The GNU runtime requires us to provide a static initializer function
2322 for each module:
2324 static void __objc_gnu_init (void) {
2325 __objc_exec_class (&L_OBJC_MODULES);
2326 } */
2328 static void
2329 build_module_initializer_routine (void)
2331 tree body;
2333 #ifdef OBJCPLUS
2334 push_lang_context (lang_name_c); /* extern "C" */
2335 #endif
2337 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2338 objc_start_function (get_identifier (TAG_GNUINIT),
2339 build_function_type (void_type_node,
2340 OBJC_VOID_AT_END),
2341 NULL_TREE, objc_get_parm_info (0));
2343 body = c_begin_compound_stmt (true);
2344 add_stmt (build_function_call
2345 (execclass_decl,
2346 build_tree_list
2347 (NULL_TREE,
2348 build_unary_op (ADDR_EXPR,
2349 UOBJC_MODULES_decl, 0))));
2350 add_stmt (c_end_compound_stmt (body, true));
2352 TREE_PUBLIC (current_function_decl) = 0;
2354 #ifndef OBJCPLUS
2355 /* For Objective-C++, we will need to call __objc_gnu_init
2356 from objc_generate_static_init_call() below. */
2357 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2358 #endif
2360 GNU_INIT_decl = current_function_decl;
2361 finish_function ();
2363 #ifdef OBJCPLUS
2364 pop_lang_context ();
2365 #endif
2368 #ifdef OBJCPLUS
2369 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2370 to be called by the module initializer routine. */
2373 objc_static_init_needed_p (void)
2375 return (GNU_INIT_decl != NULL_TREE);
2378 /* Generate a call to the __objc_gnu_init initializer function. */
2380 tree
2381 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2383 add_stmt (build_stmt (EXPR_STMT,
2384 build_function_call (GNU_INIT_decl, NULL_TREE)));
2386 return ctors;
2388 #endif /* OBJCPLUS */
2390 /* Return the DECL of the string IDENT in the SECTION. */
2392 static tree
2393 get_objc_string_decl (tree ident, enum string_section section)
2395 tree chain;
2397 if (section == class_names)
2398 chain = class_names_chain;
2399 else if (section == meth_var_names)
2400 chain = meth_var_names_chain;
2401 else if (section == meth_var_types)
2402 chain = meth_var_types_chain;
2403 else
2404 abort ();
2406 for (; chain != 0; chain = TREE_CHAIN (chain))
2407 if (TREE_VALUE (chain) == ident)
2408 return (TREE_PURPOSE (chain));
2410 abort ();
2411 return NULL_TREE;
2414 /* Output references to all statically allocated objects. Return the DECL
2415 for the array built. */
2417 static void
2418 generate_static_references (void)
2420 tree decls = NULL_TREE, expr = NULL_TREE;
2421 tree class_name, class, decl, initlist;
2422 tree cl_chain, in_chain, type
2423 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2424 int num_inst, num_class;
2425 char buf[256];
2427 if (flag_next_runtime)
2428 abort ();
2430 for (cl_chain = objc_static_instances, num_class = 0;
2431 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2433 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2434 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2436 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2437 decl = start_var_decl (type, buf);
2439 /* Output {class_name, ...}. */
2440 class = TREE_VALUE (cl_chain);
2441 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2442 initlist = build_tree_list (NULL_TREE,
2443 build_unary_op (ADDR_EXPR, class_name, 1));
2445 /* Output {..., instance, ...}. */
2446 for (in_chain = TREE_PURPOSE (cl_chain);
2447 in_chain; in_chain = TREE_CHAIN (in_chain))
2449 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2450 initlist = tree_cons (NULL_TREE, expr, initlist);
2453 /* Output {..., NULL}. */
2454 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2456 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2457 finish_var_decl (decl, expr);
2458 decls
2459 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2462 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2463 expr = objc_build_constructor (type, nreverse (decls));
2464 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2465 finish_var_decl (static_instances_decl, expr);
2468 static GTY(()) int selector_reference_idx;
2470 static tree
2471 build_selector_reference_decl (void)
2473 tree decl;
2474 char buf[256];
2476 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2477 decl = start_var_decl (objc_selector_type, buf);
2479 return decl;
2482 static void
2483 build_selector_table_decl (void)
2485 tree temp;
2487 if (flag_typed_selectors)
2489 build_selector_template ();
2490 temp = build_array_type (objc_selector_template, NULL_TREE);
2492 else
2493 temp = build_array_type (objc_selector_type, NULL_TREE);
2495 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2498 /* Just a handy wrapper for add_objc_string. */
2500 static tree
2501 build_selector (tree ident)
2503 return convert (objc_selector_type,
2504 add_objc_string (ident, meth_var_names));
2507 static void
2508 build_selector_translation_table (void)
2510 tree chain, initlist = NULL_TREE;
2511 int offset = 0;
2512 tree decl = NULL_TREE;
2514 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2516 tree expr;
2518 if (warn_selector && objc_implementation_context)
2520 tree method_chain;
2521 bool found = false;
2522 for (method_chain = meth_var_names_chain;
2523 method_chain;
2524 method_chain = TREE_CHAIN (method_chain))
2526 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2528 found = true;
2529 break;
2532 if (!found)
2534 location_t *loc;
2535 if (flag_next_runtime && TREE_PURPOSE (chain))
2536 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2537 else
2538 loc = &input_location;
2539 warning (0, "%Hcreating selector for nonexistent method %qE",
2540 loc, TREE_VALUE (chain));
2544 expr = build_selector (TREE_VALUE (chain));
2545 /* add one for the '\0' character */
2546 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2548 if (flag_next_runtime)
2550 decl = TREE_PURPOSE (chain);
2551 finish_var_decl (decl, expr);
2553 else
2555 if (flag_typed_selectors)
2557 tree eltlist = NULL_TREE;
2558 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2559 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2560 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2561 expr = objc_build_constructor (objc_selector_template,
2562 nreverse (eltlist));
2565 initlist = tree_cons (NULL_TREE, expr, initlist);
2569 if (! flag_next_runtime)
2571 /* Cause the selector table (previously forward-declared)
2572 to be actually output. */
2573 initlist = tree_cons (NULL_TREE,
2574 flag_typed_selectors
2575 ? objc_build_constructor
2576 (objc_selector_template,
2577 tree_cons (NULL_TREE,
2578 build_int_cst (NULL_TREE, 0),
2579 tree_cons (NULL_TREE,
2580 build_int_cst (NULL_TREE, 0),
2581 NULL_TREE)))
2582 : build_int_cst (NULL_TREE, 0), initlist);
2583 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2584 nreverse (initlist));
2585 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2589 static tree
2590 get_proto_encoding (tree proto)
2592 tree encoding;
2593 if (proto)
2595 if (! METHOD_ENCODING (proto))
2597 encoding = encode_method_prototype (proto);
2598 METHOD_ENCODING (proto) = encoding;
2600 else
2601 encoding = METHOD_ENCODING (proto);
2603 return add_objc_string (encoding, meth_var_types);
2605 else
2606 return build_int_cst (NULL_TREE, 0);
2609 /* sel_ref_chain is a list whose "value" fields will be instances of
2610 identifier_node that represent the selector. */
2612 static tree
2613 build_typed_selector_reference (tree ident, tree prototype)
2615 tree *chain = &sel_ref_chain;
2616 tree expr;
2617 int index = 0;
2619 while (*chain)
2621 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2622 goto return_at_index;
2624 index++;
2625 chain = &TREE_CHAIN (*chain);
2628 *chain = tree_cons (prototype, ident, NULL_TREE);
2630 return_at_index:
2631 expr = build_unary_op (ADDR_EXPR,
2632 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2633 build_int_cst (NULL_TREE, index)),
2635 return convert (objc_selector_type, expr);
2638 static tree
2639 build_selector_reference (tree ident)
2641 tree *chain = &sel_ref_chain;
2642 tree expr;
2643 int index = 0;
2645 while (*chain)
2647 if (TREE_VALUE (*chain) == ident)
2648 return (flag_next_runtime
2649 ? TREE_PURPOSE (*chain)
2650 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2651 build_int_cst (NULL_TREE, index)));
2653 index++;
2654 chain = &TREE_CHAIN (*chain);
2657 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2659 *chain = tree_cons (expr, ident, NULL_TREE);
2661 return (flag_next_runtime
2662 ? expr
2663 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2664 build_int_cst (NULL_TREE, index)));
2667 static GTY(()) int class_reference_idx;
2669 static tree
2670 build_class_reference_decl (void)
2672 tree decl;
2673 char buf[256];
2675 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2676 decl = start_var_decl (objc_class_type, buf);
2678 return decl;
2681 /* Create a class reference, but don't create a variable to reference
2682 it. */
2684 static void
2685 add_class_reference (tree ident)
2687 tree chain;
2689 if ((chain = cls_ref_chain))
2691 tree tail;
2694 if (ident == TREE_VALUE (chain))
2695 return;
2697 tail = chain;
2698 chain = TREE_CHAIN (chain);
2700 while (chain);
2702 /* Append to the end of the list */
2703 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2705 else
2706 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2709 /* Get a class reference, creating it if necessary. Also create the
2710 reference variable. */
2712 tree
2713 objc_get_class_reference (tree ident)
2715 tree orig_ident = (DECL_P (ident)
2716 ? DECL_NAME (ident)
2717 : TYPE_P (ident)
2718 ? OBJC_TYPE_NAME (ident)
2719 : ident);
2720 bool local_scope = false;
2722 #ifdef OBJCPLUS
2723 if (processing_template_decl)
2724 /* Must wait until template instantiation time. */
2725 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2726 #endif
2728 if (TREE_CODE (ident) == TYPE_DECL)
2729 ident = (DECL_ORIGINAL_TYPE (ident)
2730 ? DECL_ORIGINAL_TYPE (ident)
2731 : TREE_TYPE (ident));
2733 #ifdef OBJCPLUS
2734 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2735 && TYPE_CONTEXT (ident) != global_namespace)
2736 local_scope = true;
2737 #endif
2739 if (local_scope || !(ident = objc_is_class_name (ident)))
2741 error ("%qs is not an Objective-C class name or alias",
2742 IDENTIFIER_POINTER (orig_ident));
2743 return error_mark_node;
2746 if (flag_next_runtime && !flag_zero_link)
2748 tree *chain;
2749 tree decl;
2751 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2752 if (TREE_VALUE (*chain) == ident)
2754 if (! TREE_PURPOSE (*chain))
2755 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2757 return TREE_PURPOSE (*chain);
2760 decl = build_class_reference_decl ();
2761 *chain = tree_cons (decl, ident, NULL_TREE);
2762 return decl;
2764 else
2766 tree params;
2768 add_class_reference (ident);
2770 params = build_tree_list (NULL_TREE,
2771 my_build_string_pointer
2772 (IDENTIFIER_LENGTH (ident) + 1,
2773 IDENTIFIER_POINTER (ident)));
2775 assemble_external (objc_get_class_decl);
2776 return build_function_call (objc_get_class_decl, params);
2780 /* For each string section we have a chain which maps identifier nodes
2781 to decls for the strings. */
2783 static tree
2784 add_objc_string (tree ident, enum string_section section)
2786 tree *chain, decl, type, string_expr;
2788 if (section == class_names)
2789 chain = &class_names_chain;
2790 else if (section == meth_var_names)
2791 chain = &meth_var_names_chain;
2792 else if (section == meth_var_types)
2793 chain = &meth_var_types_chain;
2794 else
2795 abort ();
2797 while (*chain)
2799 if (TREE_VALUE (*chain) == ident)
2800 return convert (string_type_node,
2801 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2803 chain = &TREE_CHAIN (*chain);
2806 decl = build_objc_string_decl (section);
2808 type = build_array_type
2809 (char_type_node,
2810 build_index_type
2811 (build_int_cst (NULL_TREE,
2812 IDENTIFIER_LENGTH (ident))));
2813 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2814 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2815 IDENTIFIER_POINTER (ident));
2816 finish_var_decl (decl, string_expr);
2818 *chain = tree_cons (decl, ident, NULL_TREE);
2820 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2823 static GTY(()) int class_names_idx;
2824 static GTY(()) int meth_var_names_idx;
2825 static GTY(()) int meth_var_types_idx;
2827 static tree
2828 build_objc_string_decl (enum string_section section)
2830 tree decl, ident;
2831 char buf[256];
2833 if (section == class_names)
2834 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2835 else if (section == meth_var_names)
2836 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2837 else if (section == meth_var_types)
2838 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2840 ident = get_identifier (buf);
2842 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2843 DECL_EXTERNAL (decl) = 1;
2844 TREE_PUBLIC (decl) = 0;
2845 TREE_USED (decl) = 1;
2846 TREE_CONSTANT (decl) = 1;
2847 DECL_CONTEXT (decl) = 0;
2848 DECL_ARTIFICIAL (decl) = 1;
2849 #ifdef OBJCPLUS
2850 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2851 #endif
2853 make_decl_rtl (decl);
2854 pushdecl_top_level (decl);
2856 return decl;
2860 void
2861 objc_declare_alias (tree alias_ident, tree class_ident)
2863 tree underlying_class;
2865 #ifdef OBJCPLUS
2866 if (current_namespace != global_namespace) {
2867 error ("Objective-C declarations may only appear in global scope");
2869 #endif /* OBJCPLUS */
2871 if (!(underlying_class = objc_is_class_name (class_ident)))
2872 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2873 else if (objc_is_class_name (alias_ident))
2874 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2875 else
2877 /* Implement @compatibility_alias as a typedef. */
2878 #ifdef OBJCPLUS
2879 push_lang_context (lang_name_c); /* extern "C" */
2880 #endif
2881 lang_hooks.decls.pushdecl (build_decl
2882 (TYPE_DECL,
2883 alias_ident,
2884 xref_tag (RECORD_TYPE, underlying_class)));
2885 #ifdef OBJCPLUS
2886 pop_lang_context ();
2887 #endif
2888 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2892 void
2893 objc_declare_class (tree ident_list)
2895 tree list;
2896 #ifdef OBJCPLUS
2897 if (current_namespace != global_namespace) {
2898 error ("Objective-C declarations may only appear in global scope");
2900 #endif /* OBJCPLUS */
2902 for (list = ident_list; list; list = TREE_CHAIN (list))
2904 tree ident = TREE_VALUE (list);
2906 if (! objc_is_class_name (ident))
2908 tree record = lookup_name (ident), type = record;
2910 if (record)
2912 if (TREE_CODE (record) == TYPE_DECL)
2913 type = DECL_ORIGINAL_TYPE (record);
2915 if (!TYPE_HAS_OBJC_INFO (type)
2916 || !TYPE_OBJC_INTERFACE (type))
2918 error ("%qs redeclared as different kind of symbol",
2919 IDENTIFIER_POINTER (ident));
2920 error ("previous declaration of %q+D",
2921 record);
2925 record = xref_tag (RECORD_TYPE, ident);
2926 INIT_TYPE_OBJC_INFO (record);
2927 TYPE_OBJC_INTERFACE (record) = ident;
2928 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2933 tree
2934 objc_is_class_name (tree ident)
2936 tree chain;
2938 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2939 && identifier_global_value (ident))
2940 ident = identifier_global_value (ident);
2941 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2942 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2944 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2945 ident = OBJC_TYPE_NAME (ident);
2946 #ifdef OBJCPLUS
2947 if (ident && TREE_CODE (ident) == TYPE_DECL)
2948 ident = DECL_NAME (ident);
2949 #endif
2950 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2951 return NULL_TREE;
2953 if (lookup_interface (ident))
2954 return ident;
2956 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2958 if (ident == TREE_VALUE (chain))
2959 return ident;
2962 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2964 if (ident == TREE_VALUE (chain))
2965 return TREE_PURPOSE (chain);
2968 return 0;
2971 /* Check whether TYPE is either 'id' or 'Class'. */
2973 tree
2974 objc_is_id (tree type)
2976 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2977 && identifier_global_value (type))
2978 type = identifier_global_value (type);
2980 if (type && TREE_CODE (type) == TYPE_DECL)
2981 type = TREE_TYPE (type);
2983 /* NB: This function may be called before the ObjC front-end has
2984 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2985 return (objc_object_type && type
2986 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2987 ? type
2988 : NULL_TREE);
2991 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2992 class instance. This is needed by other parts of the compiler to
2993 handle ObjC types gracefully. */
2995 tree
2996 objc_is_object_ptr (tree type)
2998 tree ret;
3000 type = TYPE_MAIN_VARIANT (type);
3001 if (!POINTER_TYPE_P (type))
3002 return 0;
3004 ret = objc_is_id (type);
3005 if (!ret)
3006 ret = objc_is_class_name (TREE_TYPE (type));
3008 return ret;
3011 static int
3012 objc_is_gcable_type (tree type, int or_strong_p)
3014 tree name;
3016 if (!TYPE_P (type))
3017 return 0;
3018 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3019 return 1;
3020 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3021 return 1;
3022 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3023 return 0;
3024 type = TREE_TYPE (type);
3025 if (TREE_CODE (type) != RECORD_TYPE)
3026 return 0;
3027 name = TYPE_NAME (type);
3028 return (objc_is_class_name (name) != NULL_TREE);
3031 static tree
3032 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3034 if (expr == oldexpr)
3035 return newexpr;
3037 switch (TREE_CODE (expr))
3039 case COMPONENT_REF:
3040 return objc_build_component_ref
3041 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3042 oldexpr,
3043 newexpr),
3044 DECL_NAME (TREE_OPERAND (expr, 1)));
3045 case ARRAY_REF:
3046 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3047 oldexpr,
3048 newexpr),
3049 TREE_OPERAND (expr, 1));
3050 case INDIRECT_REF:
3051 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3052 oldexpr,
3053 newexpr), "->");
3054 default:
3055 return expr;
3059 static tree
3060 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3062 tree func_params;
3063 /* The LHS parameter contains the expression 'outervar->memberspec';
3064 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3065 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3067 tree offs
3068 = objc_substitute_decl
3069 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3070 tree func
3071 = (flag_objc_direct_dispatch
3072 ? objc_assign_ivar_fast_decl
3073 : objc_assign_ivar_decl);
3075 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3076 offs = fold (offs);
3077 func_params = tree_cons (NULL_TREE,
3078 convert (objc_object_type, rhs),
3079 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3080 tree_cons (NULL_TREE, offs,
3081 NULL_TREE)));
3083 assemble_external (func);
3084 return build_function_call (func, func_params);
3087 static tree
3088 objc_build_global_assignment (tree lhs, tree rhs)
3090 tree func_params = tree_cons (NULL_TREE,
3091 convert (objc_object_type, rhs),
3092 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3093 build_unary_op (ADDR_EXPR, lhs, 0)),
3094 NULL_TREE));
3096 assemble_external (objc_assign_global_decl);
3097 return build_function_call (objc_assign_global_decl, func_params);
3100 static tree
3101 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3103 tree func_params = tree_cons (NULL_TREE,
3104 convert (objc_object_type, rhs),
3105 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3106 build_unary_op (ADDR_EXPR, lhs, 0)),
3107 NULL_TREE));
3109 assemble_external (objc_assign_strong_cast_decl);
3110 return build_function_call (objc_assign_strong_cast_decl, func_params);
3113 static int
3114 objc_is_gcable_p (tree expr)
3116 return (TREE_CODE (expr) == COMPONENT_REF
3117 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3118 : TREE_CODE (expr) == ARRAY_REF
3119 ? (objc_is_gcable_p (TREE_TYPE (expr))
3120 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3121 : TREE_CODE (expr) == ARRAY_TYPE
3122 ? objc_is_gcable_p (TREE_TYPE (expr))
3123 : TYPE_P (expr)
3124 ? objc_is_gcable_type (expr, 1)
3125 : (objc_is_gcable_p (TREE_TYPE (expr))
3126 || (DECL_P (expr)
3127 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3130 static int
3131 objc_is_ivar_reference_p (tree expr)
3133 return (TREE_CODE (expr) == ARRAY_REF
3134 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3135 : TREE_CODE (expr) == COMPONENT_REF
3136 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3137 : 0);
3140 static int
3141 objc_is_global_reference_p (tree expr)
3143 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3144 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3145 : DECL_P (expr)
3146 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3147 : 0);
3150 tree
3151 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3153 tree result = NULL_TREE, outer;
3154 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3156 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3157 will have been transformed to the form '*(type *)&expr'. */
3158 if (TREE_CODE (lhs) == INDIRECT_REF)
3160 outer = TREE_OPERAND (lhs, 0);
3162 while (!strong_cast_p
3163 && (TREE_CODE (outer) == CONVERT_EXPR
3164 || TREE_CODE (outer) == NOP_EXPR
3165 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3167 tree lhstype = TREE_TYPE (outer);
3169 /* Descend down the cast chain, and record the first objc_gc
3170 attribute found. */
3171 if (POINTER_TYPE_P (lhstype))
3173 tree attr
3174 = lookup_attribute ("objc_gc",
3175 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3177 if (attr)
3178 strong_cast_p = 1;
3181 outer = TREE_OPERAND (outer, 0);
3185 /* If we have a __strong cast, it trumps all else. */
3186 if (strong_cast_p)
3188 if (modifycode != NOP_EXPR)
3189 goto invalid_pointer_arithmetic;
3191 if (warn_assign_intercept)
3192 warning (0, "strong-cast assignment has been intercepted");
3194 result = objc_build_strong_cast_assignment (lhs, rhs);
3196 goto exit_point;
3199 /* the lhs must be of a suitable type, regardless of its underlying
3200 structure. */
3201 if (!objc_is_gcable_p (lhs))
3202 goto exit_point;
3204 outer = lhs;
3206 while (outer
3207 && (TREE_CODE (outer) == COMPONENT_REF
3208 || TREE_CODE (outer) == ARRAY_REF))
3209 outer = TREE_OPERAND (outer, 0);
3211 if (TREE_CODE (outer) == INDIRECT_REF)
3213 outer = TREE_OPERAND (outer, 0);
3214 indirect_p = 1;
3217 outer_gc_p = objc_is_gcable_p (outer);
3219 /* Handle ivar assignments. */
3220 if (objc_is_ivar_reference_p (lhs))
3222 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3223 doesn't cut it here), the best we can do here is suggest a cast. */
3224 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3226 /* We may still be able to use the global write barrier... */
3227 if (!indirect_p && objc_is_global_reference_p (outer))
3228 goto global_reference;
3230 suggest_cast:
3231 if (modifycode == NOP_EXPR)
3233 if (warn_assign_intercept)
3234 warning (0, "strong-cast may possibly be needed");
3237 goto exit_point;
3240 if (modifycode != NOP_EXPR)
3241 goto invalid_pointer_arithmetic;
3243 if (warn_assign_intercept)
3244 warning (0, "instance variable assignment has been intercepted");
3246 result = objc_build_ivar_assignment (outer, lhs, rhs);
3248 goto exit_point;
3251 /* Likewise, intercept assignment to global/static variables if their type is
3252 GC-marked. */
3253 if (objc_is_global_reference_p (outer))
3255 if (indirect_p)
3256 goto suggest_cast;
3258 global_reference:
3259 if (modifycode != NOP_EXPR)
3261 invalid_pointer_arithmetic:
3262 if (outer_gc_p)
3263 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3265 goto exit_point;
3268 if (warn_assign_intercept)
3269 warning (0, "global/static variable assignment has been intercepted");
3271 result = objc_build_global_assignment (lhs, rhs);
3274 /* In all other cases, fall back to the normal mechanism. */
3275 exit_point:
3276 return result;
3279 struct interface_tuple GTY(())
3281 tree id;
3282 tree class_name;
3285 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3287 static hashval_t
3288 hash_interface (const void *p)
3290 const struct interface_tuple *d = p;
3291 return htab_hash_pointer (d->id);
3294 static int
3295 eq_interface (const void *p1, const void *p2)
3297 const struct interface_tuple *d = p1;
3298 return d->id == p2;
3301 static tree
3302 lookup_interface (tree ident)
3304 #ifdef OBJCPLUS
3305 if (ident && TREE_CODE (ident) == TYPE_DECL)
3306 ident = DECL_NAME (ident);
3307 #endif
3309 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3310 return NULL_TREE;
3313 struct interface_tuple **slot;
3314 tree i = NULL_TREE;
3316 if (interface_htab)
3318 slot = (struct interface_tuple **)
3319 htab_find_slot_with_hash (interface_htab, ident,
3320 htab_hash_pointer (ident),
3321 NO_INSERT);
3322 if (slot && *slot)
3323 i = (*slot)->class_name;
3325 return i;
3329 /* Implement @defs (<classname>) within struct bodies. */
3331 tree
3332 objc_get_class_ivars (tree class_name)
3334 tree interface = lookup_interface (class_name);
3336 if (interface)
3337 return get_class_ivars (interface, true);
3339 error ("cannot find interface declaration for %qs",
3340 IDENTIFIER_POINTER (class_name));
3342 return error_mark_node;
3345 /* Used by: build_private_template, continue_class,
3346 and for @defs constructs. */
3348 static tree
3349 get_class_ivars (tree interface, bool inherited)
3351 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3353 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3354 by the current class (i.e., they do not include super-class ivars).
3355 However, the CLASS_IVARS list will be side-effected by a call to
3356 finish_struct(), which will fill in field offsets. */
3357 if (!CLASS_IVARS (interface))
3358 CLASS_IVARS (interface) = ivar_chain;
3360 if (!inherited)
3361 return ivar_chain;
3363 while (CLASS_SUPER_NAME (interface))
3365 /* Prepend super-class ivars. */
3366 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3367 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3368 ivar_chain);
3371 return ivar_chain;
3374 static tree
3375 objc_create_temporary_var (tree type)
3377 tree decl;
3379 decl = build_decl (VAR_DECL, NULL_TREE, type);
3380 TREE_USED (decl) = 1;
3381 DECL_ARTIFICIAL (decl) = 1;
3382 DECL_IGNORED_P (decl) = 1;
3383 DECL_CONTEXT (decl) = current_function_decl;
3385 return decl;
3388 /* Exception handling constructs. We begin by having the parser do most
3389 of the work and passing us blocks. What we do next depends on whether
3390 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3391 We abstract all of this in a handful of appropriately named routines. */
3393 /* Stack of open try blocks. */
3395 struct objc_try_context
3397 struct objc_try_context *outer;
3399 /* Statements (or statement lists) as processed by the parser. */
3400 tree try_body;
3401 tree finally_body;
3403 /* Some file position locations. */
3404 location_t try_locus;
3405 location_t end_try_locus;
3406 location_t end_catch_locus;
3407 location_t finally_locus;
3408 location_t end_finally_locus;
3410 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3411 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3412 tree catch_list;
3414 /* The CATCH_EXPR of an open @catch clause. */
3415 tree current_catch;
3417 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3418 tree caught_decl;
3419 tree stack_decl;
3420 tree rethrow_decl;
3423 static struct objc_try_context *cur_try_context;
3425 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3426 that represents TYPE. For Objective-C, this is just the class name. */
3427 /* ??? Isn't there a class object or some such? Is it easy to get? */
3429 #ifndef OBJCPLUS
3430 static tree
3431 objc_eh_runtime_type (tree type)
3433 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3435 #endif
3437 /* Initialize exception handling. */
3439 static void
3440 objc_init_exceptions (void)
3442 static bool done = false;
3443 if (done)
3444 return;
3445 done = true;
3447 if (flag_objc_sjlj_exceptions)
3449 /* On Darwin, ObjC exceptions require a sufficiently recent
3450 version of the runtime, so the user must ask for them explicitly. */
3451 if (!flag_objc_exceptions)
3452 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3453 "exception syntax");
3455 #ifndef OBJCPLUS
3456 else
3458 c_eh_initialized_p = true;
3459 eh_personality_libfunc
3460 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3461 ? "__gnu_objc_personality_sj0"
3462 : "__gnu_objc_personality_v0");
3463 default_init_unwind_resume_libfunc ();
3464 using_eh_for_cleanups ();
3465 lang_eh_runtime_type = objc_eh_runtime_type;
3467 #endif
3470 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3471 we'll arrange for it to be initialized (and associated with a binding)
3472 later. */
3474 static tree
3475 objc_build_exc_ptr (void)
3477 if (flag_objc_sjlj_exceptions)
3479 tree var = cur_try_context->caught_decl;
3480 if (!var)
3482 var = objc_create_temporary_var (objc_object_type);
3483 cur_try_context->caught_decl = var;
3485 return var;
3487 else
3488 return build0 (EXC_PTR_EXPR, objc_object_type);
3491 /* Build "objc_exception_try_exit(&_stack)". */
3493 static tree
3494 next_sjlj_build_try_exit (void)
3496 tree t;
3497 t = build_fold_addr_expr (cur_try_context->stack_decl);
3498 t = tree_cons (NULL, t, NULL);
3499 t = build_function_call (objc_exception_try_exit_decl, t);
3500 return t;
3503 /* Build
3504 objc_exception_try_enter (&_stack);
3505 if (_setjmp(&_stack.buf))
3507 else
3509 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3510 empty, ready for the caller to fill them in. */
3512 static tree
3513 next_sjlj_build_enter_and_setjmp (void)
3515 tree t, enter, sj, cond;
3517 t = build_fold_addr_expr (cur_try_context->stack_decl);
3518 t = tree_cons (NULL, t, NULL);
3519 enter = build_function_call (objc_exception_try_enter_decl, t);
3521 t = objc_build_component_ref (cur_try_context->stack_decl,
3522 get_identifier ("buf"));
3523 t = build_fold_addr_expr (t);
3524 #ifdef OBJCPLUS
3525 /* Convert _setjmp argument to type that is expected. */
3526 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3527 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3528 else
3529 t = convert (ptr_type_node, t);
3530 #else
3531 t = convert (ptr_type_node, t);
3532 #endif
3533 t = tree_cons (NULL, t, NULL);
3534 sj = build_function_call (objc_setjmp_decl, t);
3536 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3537 cond = c_common_truthvalue_conversion (cond);
3539 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3542 /* Build
3543 DECL = objc_exception_extract(&_stack);
3546 static tree
3547 next_sjlj_build_exc_extract (tree decl)
3549 tree t;
3551 t = build_fold_addr_expr (cur_try_context->stack_decl);
3552 t = tree_cons (NULL, t, NULL);
3553 t = build_function_call (objc_exception_extract_decl, t);
3554 t = convert (TREE_TYPE (decl), t);
3555 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3557 return t;
3560 /* Build
3561 if (objc_exception_match(obj_get_class(TYPE), _caught)
3562 BODY
3563 else if (...)
3565 else
3567 _rethrow = _caught;
3568 objc_exception_try_exit(&_stack);
3570 from the sequence of CATCH_EXPRs in the current try context. */
3572 static tree
3573 next_sjlj_build_catch_list (void)
3575 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3576 tree catch_seq, t;
3577 tree *last = &catch_seq;
3578 bool saw_id = false;
3580 for (; !tsi_end_p (i); tsi_next (&i))
3582 tree stmt = tsi_stmt (i);
3583 tree type = CATCH_TYPES (stmt);
3584 tree body = CATCH_BODY (stmt);
3586 if (type == NULL)
3588 *last = body;
3589 saw_id = true;
3590 break;
3592 else
3594 tree args, cond;
3596 if (type == error_mark_node)
3597 cond = error_mark_node;
3598 else
3600 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3601 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3602 args = tree_cons (NULL, t, args);
3603 t = build_function_call (objc_exception_match_decl, args);
3604 cond = c_common_truthvalue_conversion (t);
3606 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3607 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3609 *last = t;
3610 last = &COND_EXPR_ELSE (t);
3614 if (!saw_id)
3616 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3617 cur_try_context->caught_decl);
3618 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3619 append_to_statement_list (t, last);
3621 t = next_sjlj_build_try_exit ();
3622 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3623 append_to_statement_list (t, last);
3626 return catch_seq;
3629 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3630 exception handling. We aim to build:
3633 struct _objc_exception_data _stack;
3634 id volatile _rethrow = 0;
3637 objc_exception_try_enter (&_stack);
3638 if (_setjmp(&_stack.buf))
3640 id _caught = objc_exception_extract(&_stack);
3641 objc_exception_try_enter (&_stack);
3642 if (_setjmp(&_stack.buf))
3643 _rethrow = objc_exception_extract(&_stack);
3644 else
3645 CATCH-LIST
3647 else
3648 TRY-BLOCK
3650 finally
3652 if (!_rethrow)
3653 objc_exception_try_exit(&_stack);
3654 FINALLY-BLOCK
3655 if (_rethrow)
3656 objc_exception_throw(_rethrow);
3660 If CATCH-LIST is empty, we can omit all of the block containing
3661 "_caught" except for the setting of _rethrow. Note the use of
3662 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3663 but handles goto and other exits from the block. */
3665 static tree
3666 next_sjlj_build_try_catch_finally (void)
3668 tree rethrow_decl, stack_decl, t;
3669 tree catch_seq, try_fin, bind;
3671 /* Create the declarations involved. */
3672 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3673 stack_decl = objc_create_temporary_var (t);
3674 cur_try_context->stack_decl = stack_decl;
3676 rethrow_decl = objc_create_temporary_var (objc_object_type);
3677 cur_try_context->rethrow_decl = rethrow_decl;
3678 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3679 TREE_CHAIN (rethrow_decl) = stack_decl;
3681 /* Build the outermost variable binding level. */
3682 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3683 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3684 TREE_SIDE_EFFECTS (bind) = 1;
3686 /* Initialize rethrow_decl. */
3687 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3688 convert (objc_object_type, null_pointer_node));
3689 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3690 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3692 /* Build the outermost TRY_FINALLY_EXPR. */
3693 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3694 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3695 TREE_SIDE_EFFECTS (try_fin) = 1;
3696 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3698 /* Create the complete catch sequence. */
3699 if (cur_try_context->catch_list)
3701 tree caught_decl = objc_build_exc_ptr ();
3702 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3703 TREE_SIDE_EFFECTS (catch_seq) = 1;
3705 t = next_sjlj_build_exc_extract (caught_decl);
3706 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3708 t = next_sjlj_build_enter_and_setjmp ();
3709 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3710 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3711 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3713 else
3714 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3715 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3717 /* Build the main register-and-try if statement. */
3718 t = next_sjlj_build_enter_and_setjmp ();
3719 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3720 COND_EXPR_THEN (t) = catch_seq;
3721 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3722 TREE_OPERAND (try_fin, 0) = t;
3724 /* Build the complete FINALLY statement list. */
3725 t = next_sjlj_build_try_exit ();
3726 t = build_stmt (COND_EXPR,
3727 c_common_truthvalue_conversion (rethrow_decl),
3728 NULL, t);
3729 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3730 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3732 append_to_statement_list (cur_try_context->finally_body,
3733 &TREE_OPERAND (try_fin, 1));
3735 t = tree_cons (NULL, rethrow_decl, NULL);
3736 t = build_function_call (objc_exception_throw_decl, t);
3737 t = build_stmt (COND_EXPR,
3738 c_common_truthvalue_conversion (rethrow_decl),
3739 t, NULL);
3740 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3741 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3743 return bind;
3746 /* Called just after parsing the @try and its associated BODY. We now
3747 must prepare for the tricky bits -- handling the catches and finally. */
3749 void
3750 objc_begin_try_stmt (location_t try_locus, tree body)
3752 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3753 c->outer = cur_try_context;
3754 c->try_body = body;
3755 c->try_locus = try_locus;
3756 c->end_try_locus = input_location;
3757 cur_try_context = c;
3759 objc_init_exceptions ();
3761 if (flag_objc_sjlj_exceptions)
3762 objc_mark_locals_volatile (NULL);
3765 /* Called just after parsing "@catch (parm)". Open a binding level,
3766 enter DECL into the binding level, and initialize it. Leave the
3767 binding level open while the body of the compound statement is parsed. */
3769 void
3770 objc_begin_catch_clause (tree decl)
3772 tree compound, type, t;
3774 /* Begin a new scope that the entire catch clause will live in. */
3775 compound = c_begin_compound_stmt (true);
3777 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3778 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3779 lang_hooks.decls.pushdecl (decl);
3781 /* Since a decl is required here by syntax, don't warn if its unused. */
3782 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3783 be what the previous objc implementation did. */
3784 TREE_USED (decl) = 1;
3786 /* Verify that the type of the catch is valid. It must be a pointer
3787 to an Objective-C class, or "id" (which is catch-all). */
3788 type = TREE_TYPE (decl);
3790 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3791 type = NULL;
3792 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3794 error ("@catch parameter is not a known Objective-C class type");
3795 type = error_mark_node;
3797 else if (cur_try_context->catch_list)
3799 /* Examine previous @catch clauses and see if we've already
3800 caught the type in question. */
3801 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3802 for (; !tsi_end_p (i); tsi_next (&i))
3804 tree stmt = tsi_stmt (i);
3805 t = CATCH_TYPES (stmt);
3806 if (t == error_mark_node)
3807 continue;
3808 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3810 warning (0, "exception of type %<%T%> will be caught",
3811 TREE_TYPE (type));
3812 warning (0, "%H by earlier handler for %<%T%>",
3813 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3814 break;
3819 /* Record the data for the catch in the try context so that we can
3820 finalize it later. */
3821 t = build_stmt (CATCH_EXPR, type, compound);
3822 cur_try_context->current_catch = t;
3824 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3825 t = objc_build_exc_ptr ();
3826 t = convert (TREE_TYPE (decl), t);
3827 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3828 add_stmt (t);
3831 /* Called just after parsing the closing brace of a @catch clause. Close
3832 the open binding level, and record a CATCH_EXPR for it. */
3834 void
3835 objc_finish_catch_clause (void)
3837 tree c = cur_try_context->current_catch;
3838 cur_try_context->current_catch = NULL;
3839 cur_try_context->end_catch_locus = input_location;
3841 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3842 append_to_statement_list (c, &cur_try_context->catch_list);
3845 /* Called after parsing a @finally clause and its associated BODY.
3846 Record the body for later placement. */
3848 void
3849 objc_build_finally_clause (location_t finally_locus, tree body)
3851 cur_try_context->finally_body = body;
3852 cur_try_context->finally_locus = finally_locus;
3853 cur_try_context->end_finally_locus = input_location;
3856 /* Called to finalize a @try construct. */
3858 tree
3859 objc_finish_try_stmt (void)
3861 struct objc_try_context *c = cur_try_context;
3862 tree stmt;
3864 if (c->catch_list == NULL && c->finally_body == NULL)
3865 error ("%<@try%> without %<@catch%> or %<@finally%>");
3867 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3868 if (flag_objc_sjlj_exceptions)
3870 if (!cur_try_context->finally_body)
3872 cur_try_context->finally_locus = input_location;
3873 cur_try_context->end_finally_locus = input_location;
3875 stmt = next_sjlj_build_try_catch_finally ();
3877 else
3879 /* Otherwise, nest the CATCH inside a FINALLY. */
3880 stmt = c->try_body;
3881 if (c->catch_list)
3883 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3884 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3886 if (c->finally_body)
3888 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3889 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3892 add_stmt (stmt);
3894 cur_try_context = c->outer;
3895 free (c);
3896 return stmt;
3899 tree
3900 objc_build_throw_stmt (tree throw_expr)
3902 tree args;
3904 objc_init_exceptions ();
3906 if (throw_expr == NULL)
3908 /* If we're not inside a @catch block, there is no "current
3909 exception" to be rethrown. */
3910 if (cur_try_context == NULL
3911 || cur_try_context->current_catch == NULL)
3913 error ("%<@throw%> (rethrow) used outside of a @catch block");
3914 return NULL_TREE;
3917 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3918 value that we get from the runtime. */
3919 throw_expr = objc_build_exc_ptr ();
3922 /* A throw is just a call to the runtime throw function with the
3923 object as a parameter. */
3924 args = tree_cons (NULL, throw_expr, NULL);
3925 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3928 tree
3929 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3931 tree args, call;
3933 /* First lock the mutex. */
3934 mutex = save_expr (mutex);
3935 args = tree_cons (NULL, mutex, NULL);
3936 call = build_function_call (objc_sync_enter_decl, args);
3937 SET_EXPR_LOCATION (call, start_locus);
3938 add_stmt (call);
3940 /* Build the mutex unlock. */
3941 args = tree_cons (NULL, mutex, NULL);
3942 call = build_function_call (objc_sync_exit_decl, args);
3943 SET_EXPR_LOCATION (call, input_location);
3945 /* Put the that and the body in a TRY_FINALLY. */
3946 objc_begin_try_stmt (start_locus, body);
3947 objc_build_finally_clause (input_location, call);
3948 return objc_finish_try_stmt ();
3952 /* Predefine the following data type:
3954 struct _objc_exception_data
3956 int buf[_JBLEN];
3957 void *pointers[4];
3958 }; */
3960 /* The following yuckiness should prevent users from having to #include
3961 <setjmp.h> in their code... */
3963 #ifdef TARGET_POWERPC
3964 /* snarfed from /usr/include/ppc/setjmp.h */
3965 #define _JBLEN (26 + 36 + 129 + 1)
3966 #else
3967 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3968 #define _JBLEN 18
3969 #endif
3971 static void
3972 build_next_objc_exception_stuff (void)
3974 tree field_decl, field_decl_chain, index, temp_type;
3976 objc_exception_data_template
3977 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3979 /* int buf[_JBLEN]; */
3981 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3982 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3983 "buf");
3984 field_decl_chain = field_decl;
3986 /* void *pointers[4]; */
3988 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3989 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3990 "pointers");
3991 chainon (field_decl_chain, field_decl);
3993 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3995 /* int _setjmp(...); */
3996 /* If the user includes <setjmp.h>, this shall be superseded by
3997 'int _setjmp(jmp_buf);' */
3998 temp_type = build_function_type (integer_type_node, NULL_TREE);
3999 objc_setjmp_decl
4000 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4002 /* id objc_exception_extract(struct _objc_exception_data *); */
4003 temp_type
4004 = build_function_type (objc_object_type,
4005 tree_cons (NULL_TREE,
4006 build_pointer_type (objc_exception_data_template),
4007 OBJC_VOID_AT_END));
4008 objc_exception_extract_decl
4009 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4010 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4011 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4012 temp_type
4013 = build_function_type (void_type_node,
4014 tree_cons (NULL_TREE,
4015 build_pointer_type (objc_exception_data_template),
4016 OBJC_VOID_AT_END));
4017 objc_exception_try_enter_decl
4018 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4019 objc_exception_try_exit_decl
4020 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4022 /* int objc_exception_match(id, id); */
4023 temp_type
4024 = build_function_type (integer_type_node,
4025 tree_cons (NULL_TREE, objc_object_type,
4026 tree_cons (NULL_TREE, objc_object_type,
4027 OBJC_VOID_AT_END)));
4028 objc_exception_match_decl
4029 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4031 /* id objc_assign_ivar (id, id, unsigned int); */
4032 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4033 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4034 temp_type
4035 = build_function_type (objc_object_type,
4036 tree_cons
4037 (NULL_TREE, objc_object_type,
4038 tree_cons (NULL_TREE, objc_object_type,
4039 tree_cons (NULL_TREE,
4040 unsigned_type_node,
4041 OBJC_VOID_AT_END))));
4042 objc_assign_ivar_decl
4043 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4044 NULL, NULL_TREE);
4045 #ifdef OFFS_ASSIGNIVAR_FAST
4046 objc_assign_ivar_fast_decl
4047 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4048 NOT_BUILT_IN, NULL, NULL_TREE);
4049 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4050 = tree_cons (get_identifier ("hard_coded_address"),
4051 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4052 NULL_TREE);
4053 #else
4054 /* Default to slower ivar method. */
4055 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4056 #endif
4058 /* id objc_assign_global (id, id *); */
4059 /* id objc_assign_strongCast (id, id *); */
4060 temp_type = build_function_type (objc_object_type,
4061 tree_cons (NULL_TREE, objc_object_type,
4062 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4063 OBJC_VOID_AT_END)));
4064 objc_assign_global_decl
4065 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4066 objc_assign_strong_cast_decl
4067 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4070 static void
4071 build_objc_exception_stuff (void)
4073 tree noreturn_list, nothrow_list, temp_type;
4075 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4076 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4078 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4079 /* void objc_sync_enter(id); */
4080 /* void objc_sync_exit(id); */
4081 temp_type = build_function_type (void_type_node,
4082 tree_cons (NULL_TREE, objc_object_type,
4083 OBJC_VOID_AT_END));
4084 objc_exception_throw_decl
4085 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4086 noreturn_list);
4087 objc_sync_enter_decl
4088 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4089 NULL, nothrow_list);
4090 objc_sync_exit_decl
4091 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4092 NULL, nothrow_list);
4095 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4096 name as the class:
4098 struct <classname> {
4099 struct _objc_class *isa;
4101 }; */
4103 static void
4104 build_private_template (tree class)
4106 if (!CLASS_STATIC_TEMPLATE (class))
4108 tree record = objc_build_struct (class,
4109 get_class_ivars (class, false),
4110 CLASS_SUPER_NAME (class));
4112 /* Set the TREE_USED bit for this struct, so that stab generator
4113 can emit stabs for this struct type. */
4114 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4115 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4119 /* Begin code generation for protocols... */
4121 /* struct _objc_protocol {
4122 struct _objc_class *isa;
4123 char *protocol_name;
4124 struct _objc_protocol **protocol_list;
4125 struct _objc__method_prototype_list *instance_methods;
4126 struct _objc__method_prototype_list *class_methods;
4127 }; */
4129 static void
4130 build_protocol_template (void)
4132 tree field_decl, field_decl_chain;
4134 objc_protocol_template = start_struct (RECORD_TYPE,
4135 get_identifier (UTAG_PROTOCOL));
4137 /* struct _objc_class *isa; */
4138 field_decl = create_field_decl (build_pointer_type
4139 (xref_tag (RECORD_TYPE,
4140 get_identifier (UTAG_CLASS))),
4141 "isa");
4142 field_decl_chain = field_decl;
4144 /* char *protocol_name; */
4145 field_decl = create_field_decl (string_type_node, "protocol_name");
4146 chainon (field_decl_chain, field_decl);
4148 /* struct _objc_protocol **protocol_list; */
4149 field_decl = create_field_decl (build_pointer_type
4150 (build_pointer_type
4151 (objc_protocol_template)),
4152 "protocol_list");
4153 chainon (field_decl_chain, field_decl);
4155 /* struct _objc__method_prototype_list *instance_methods; */
4156 field_decl = create_field_decl (objc_method_proto_list_ptr,
4157 "instance_methods");
4158 chainon (field_decl_chain, field_decl);
4160 /* struct _objc__method_prototype_list *class_methods; */
4161 field_decl = create_field_decl (objc_method_proto_list_ptr,
4162 "class_methods");
4163 chainon (field_decl_chain, field_decl);
4165 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4168 static tree
4169 build_descriptor_table_initializer (tree type, tree entries)
4171 tree initlist = NULL_TREE;
4175 tree eltlist = NULL_TREE;
4177 eltlist
4178 = tree_cons (NULL_TREE,
4179 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4180 eltlist
4181 = tree_cons (NULL_TREE,
4182 add_objc_string (METHOD_ENCODING (entries),
4183 meth_var_types),
4184 eltlist);
4186 initlist
4187 = tree_cons (NULL_TREE,
4188 objc_build_constructor (type, nreverse (eltlist)),
4189 initlist);
4191 entries = TREE_CHAIN (entries);
4193 while (entries);
4195 return objc_build_constructor (build_array_type (type, 0),
4196 nreverse (initlist));
4199 /* struct objc_method_prototype_list {
4200 int count;
4201 struct objc_method_prototype {
4202 SEL name;
4203 char *types;
4204 } list[1];
4205 }; */
4207 static tree
4208 build_method_prototype_list_template (tree list_type, int size)
4210 tree objc_ivar_list_record;
4211 tree field_decl, field_decl_chain;
4213 /* Generate an unnamed struct definition. */
4215 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4217 /* int method_count; */
4218 field_decl = create_field_decl (integer_type_node, "method_count");
4219 field_decl_chain = field_decl;
4221 /* struct objc_method method_list[]; */
4222 field_decl = create_field_decl (build_array_type
4223 (list_type,
4224 build_index_type
4225 (build_int_cst (NULL_TREE, size - 1))),
4226 "method_list");
4227 chainon (field_decl_chain, field_decl);
4229 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4231 return objc_ivar_list_record;
4234 static tree
4235 build_method_prototype_template (void)
4237 tree proto_record;
4238 tree field_decl, field_decl_chain;
4240 proto_record
4241 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4243 /* SEL _cmd; */
4244 field_decl = create_field_decl (objc_selector_type, "_cmd");
4245 field_decl_chain = field_decl;
4247 /* char *method_types; */
4248 field_decl = create_field_decl (string_type_node, "method_types");
4249 chainon (field_decl_chain, field_decl);
4251 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4253 return proto_record;
4256 static tree
4257 objc_method_parm_type (tree type)
4259 type = TREE_VALUE (TREE_TYPE (type));
4260 if (TREE_CODE (type) == TYPE_DECL)
4261 type = TREE_TYPE (type);
4262 return type;
4265 static int
4266 objc_encoded_type_size (tree type)
4268 int sz = int_size_in_bytes (type);
4270 /* Make all integer and enum types at least as large
4271 as an int. */
4272 if (sz > 0 && INTEGRAL_TYPE_P (type))
4273 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4274 /* Treat arrays as pointers, since that's how they're
4275 passed in. */
4276 else if (TREE_CODE (type) == ARRAY_TYPE)
4277 sz = int_size_in_bytes (ptr_type_node);
4278 return sz;
4281 static tree
4282 encode_method_prototype (tree method_decl)
4284 tree parms;
4285 int parm_offset, i;
4286 char buf[40];
4287 tree result;
4289 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4290 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4292 /* Encode return type. */
4293 encode_type (objc_method_parm_type (method_decl),
4294 obstack_object_size (&util_obstack),
4295 OBJC_ENCODE_INLINE_DEFS);
4297 /* Stack size. */
4298 /* The first two arguments (self and _cmd) are pointers; account for
4299 their size. */
4300 i = int_size_in_bytes (ptr_type_node);
4301 parm_offset = 2 * i;
4302 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4303 parms = TREE_CHAIN (parms))
4305 tree type = objc_method_parm_type (parms);
4306 int sz = objc_encoded_type_size (type);
4308 /* If a type size is not known, bail out. */
4309 if (sz < 0)
4311 error ("type %q+D does not have a known size",
4312 type);
4313 /* Pretend that the encoding succeeded; the compilation will
4314 fail nevertheless. */
4315 goto finish_encoding;
4317 parm_offset += sz;
4320 sprintf (buf, "%d@0:%d", parm_offset, i);
4321 obstack_grow (&util_obstack, buf, strlen (buf));
4323 /* Argument types. */
4324 parm_offset = 2 * i;
4325 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4326 parms = TREE_CHAIN (parms))
4328 tree type = objc_method_parm_type (parms);
4330 /* Process argument qualifiers for user supplied arguments. */
4331 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4333 /* Type. */
4334 encode_type (type, obstack_object_size (&util_obstack),
4335 OBJC_ENCODE_INLINE_DEFS);
4337 /* Compute offset. */
4338 sprintf (buf, "%d", parm_offset);
4339 parm_offset += objc_encoded_type_size (type);
4341 obstack_grow (&util_obstack, buf, strlen (buf));
4344 finish_encoding:
4345 obstack_1grow (&util_obstack, '\0');
4346 result = get_identifier (obstack_finish (&util_obstack));
4347 obstack_free (&util_obstack, util_firstobj);
4348 return result;
4351 static tree
4352 generate_descriptor_table (tree type, const char *name, int size, tree list,
4353 tree proto)
4355 tree decl, initlist;
4357 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4359 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4360 initlist = tree_cons (NULL_TREE, list, initlist);
4362 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4364 return decl;
4367 static void
4368 generate_method_descriptors (tree protocol)
4370 tree initlist, chain, method_list_template;
4371 int size;
4373 if (!objc_method_prototype_template)
4374 objc_method_prototype_template = build_method_prototype_template ();
4376 chain = PROTOCOL_CLS_METHODS (protocol);
4377 if (chain)
4379 size = list_length (chain);
4381 method_list_template
4382 = build_method_prototype_list_template (objc_method_prototype_template,
4383 size);
4385 initlist
4386 = build_descriptor_table_initializer (objc_method_prototype_template,
4387 chain);
4389 UOBJC_CLASS_METHODS_decl
4390 = generate_descriptor_table (method_list_template,
4391 "_OBJC_PROTOCOL_CLASS_METHODS",
4392 size, initlist, protocol);
4394 else
4395 UOBJC_CLASS_METHODS_decl = 0;
4397 chain = PROTOCOL_NST_METHODS (protocol);
4398 if (chain)
4400 size = list_length (chain);
4402 method_list_template
4403 = build_method_prototype_list_template (objc_method_prototype_template,
4404 size);
4405 initlist
4406 = build_descriptor_table_initializer (objc_method_prototype_template,
4407 chain);
4409 UOBJC_INSTANCE_METHODS_decl
4410 = generate_descriptor_table (method_list_template,
4411 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4412 size, initlist, protocol);
4414 else
4415 UOBJC_INSTANCE_METHODS_decl = 0;
4418 static void
4419 generate_protocol_references (tree plist)
4421 tree lproto;
4423 /* Forward declare protocols referenced. */
4424 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4426 tree proto = TREE_VALUE (lproto);
4428 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4429 && PROTOCOL_NAME (proto))
4431 if (! PROTOCOL_FORWARD_DECL (proto))
4432 build_protocol_reference (proto);
4434 if (PROTOCOL_LIST (proto))
4435 generate_protocol_references (PROTOCOL_LIST (proto));
4440 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4441 current class. */
4442 #ifdef OBJCPLUS
4443 static void
4444 objc_generate_cxx_ctor_or_dtor (bool dtor)
4446 tree fn, body, compound_stmt, ivar;
4448 /* - (id) .cxx_construct { ... return self; } */
4449 /* - (void) .cxx_construct { ... } */
4451 objc_set_method_type (MINUS_EXPR);
4452 objc_start_method_definition
4453 (objc_build_method_signature (build_tree_list (NULL_TREE,
4454 dtor
4455 ? void_type_node
4456 : objc_object_type),
4457 get_identifier (dtor
4458 ? TAG_CXX_DESTRUCT
4459 : TAG_CXX_CONSTRUCT),
4460 make_node (TREE_LIST),
4461 false));
4462 body = begin_function_body ();
4463 compound_stmt = begin_compound_stmt (0);
4465 ivar = CLASS_IVARS (implementation_template);
4466 /* Destroy ivars in reverse order. */
4467 if (dtor)
4468 ivar = nreverse (copy_list (ivar));
4470 for (; ivar; ivar = TREE_CHAIN (ivar))
4472 if (TREE_CODE (ivar) == FIELD_DECL)
4474 tree type = TREE_TYPE (ivar);
4476 /* Call the ivar's default constructor or destructor. Do not
4477 call the destructor unless a corresponding constructor call
4478 has also been made (or is not needed). */
4479 if (IS_AGGR_TYPE (type)
4480 && (dtor
4481 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4482 && (!TYPE_NEEDS_CONSTRUCTING (type)
4483 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4484 : (TYPE_NEEDS_CONSTRUCTING (type)
4485 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4486 finish_expr_stmt
4487 (build_special_member_call
4488 (build_ivar_reference (DECL_NAME (ivar)),
4489 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4490 NULL_TREE, type, LOOKUP_NORMAL));
4494 /* The constructor returns 'self'. */
4495 if (!dtor)
4496 finish_return_stmt (self_decl);
4498 finish_compound_stmt (compound_stmt);
4499 finish_function_body (body);
4500 fn = current_function_decl;
4501 finish_function ();
4502 objc_finish_method_definition (fn);
4505 /* The following routine will examine the current @interface for any
4506 non-POD C++ ivars requiring non-trivial construction and/or
4507 destruction, and then synthesize special '- .cxx_construct' and/or
4508 '- .cxx_destruct' methods which will run the appropriate
4509 construction or destruction code. Note that ivars inherited from
4510 super-classes are _not_ considered. */
4511 static void
4512 objc_generate_cxx_cdtors (void)
4514 bool need_ctor = false, need_dtor = false;
4515 tree ivar;
4517 /* We do not want to do this for categories, since they do not have
4518 their own ivars. */
4520 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4521 return;
4523 /* First, determine if we even need a constructor and/or destructor. */
4525 for (ivar = CLASS_IVARS (implementation_template); ivar;
4526 ivar = TREE_CHAIN (ivar))
4528 if (TREE_CODE (ivar) == FIELD_DECL)
4530 tree type = TREE_TYPE (ivar);
4532 if (IS_AGGR_TYPE (type))
4534 if (TYPE_NEEDS_CONSTRUCTING (type)
4535 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4536 /* NB: If a default constructor is not available, we will not
4537 be able to initialize this ivar; the add_instance_variable()
4538 routine will already have warned about this. */
4539 need_ctor = true;
4541 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4542 && (!TYPE_NEEDS_CONSTRUCTING (type)
4543 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4544 /* NB: If a default constructor is not available, we will not
4545 call the destructor either, for symmetry. */
4546 need_dtor = true;
4551 /* Generate '- .cxx_construct' if needed. */
4553 if (need_ctor)
4554 objc_generate_cxx_ctor_or_dtor (false);
4556 /* Generate '- .cxx_destruct' if needed. */
4558 if (need_dtor)
4559 objc_generate_cxx_ctor_or_dtor (true);
4561 /* The 'imp_list' variable points at an imp_entry record for the current
4562 @implementation. Record the existence of '- .cxx_construct' and/or
4563 '- .cxx_destruct' methods therein; it will be included in the
4564 metadata for the class. */
4565 if (flag_next_runtime)
4566 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4568 #endif
4570 /* For each protocol which was referenced either from a @protocol()
4571 expression, or because a class/category implements it (then a
4572 pointer to the protocol is stored in the struct describing the
4573 class/category), we create a statically allocated instance of the
4574 Protocol class. The code is written in such a way as to generate
4575 as few Protocol objects as possible; we generate a unique Protocol
4576 instance for each protocol, and we don't generate a Protocol
4577 instance if the protocol is never referenced (either from a
4578 @protocol() or from a class/category implementation). These
4579 statically allocated objects can be referred to via the static
4580 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4582 The statically allocated Protocol objects that we generate here
4583 need to be fixed up at runtime in order to be used: the 'isa'
4584 pointer of the objects need to be set up to point to the 'Protocol'
4585 class, as known at runtime.
4587 The NeXT runtime fixes up all protocols at program startup time,
4588 before main() is entered. It uses a low-level trick to look up all
4589 those symbols, then loops on them and fixes them up.
4591 The GNU runtime as well fixes up all protocols before user code
4592 from the module is executed; it requires pointers to those symbols
4593 to be put in the objc_symtab (which is then passed as argument to
4594 the function __objc_exec_class() which the compiler sets up to be
4595 executed automatically when the module is loaded); setup of those
4596 Protocol objects happen in two ways in the GNU runtime: all
4597 Protocol objects referred to by a class or category implementation
4598 are fixed up when the class/category is loaded; all Protocol
4599 objects referred to by a @protocol() expression are added by the
4600 compiler to the list of statically allocated instances to fixup
4601 (the same list holding the statically allocated constant string
4602 objects). Because, as explained above, the compiler generates as
4603 few Protocol objects as possible, some Protocol object might end up
4604 being referenced multiple times when compiled with the GNU runtime,
4605 and end up being fixed up multiple times at runtime initialization.
4606 But that doesn't hurt, it's just a little inefficient. */
4608 static void
4609 generate_protocols (void)
4611 tree p, encoding;
4612 tree decl;
4613 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4615 /* If a protocol was directly referenced, pull in indirect references. */
4616 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4617 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4618 generate_protocol_references (PROTOCOL_LIST (p));
4620 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4622 tree nst_methods = PROTOCOL_NST_METHODS (p);
4623 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4625 /* If protocol wasn't referenced, don't generate any code. */
4626 decl = PROTOCOL_FORWARD_DECL (p);
4628 if (!decl)
4629 continue;
4631 /* Make sure we link in the Protocol class. */
4632 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4634 while (nst_methods)
4636 if (! METHOD_ENCODING (nst_methods))
4638 encoding = encode_method_prototype (nst_methods);
4639 METHOD_ENCODING (nst_methods) = encoding;
4641 nst_methods = TREE_CHAIN (nst_methods);
4644 while (cls_methods)
4646 if (! METHOD_ENCODING (cls_methods))
4648 encoding = encode_method_prototype (cls_methods);
4649 METHOD_ENCODING (cls_methods) = encoding;
4652 cls_methods = TREE_CHAIN (cls_methods);
4654 generate_method_descriptors (p);
4656 if (PROTOCOL_LIST (p))
4657 refs_decl = generate_protocol_list (p);
4658 else
4659 refs_decl = 0;
4661 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4662 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4664 if (refs_decl)
4665 refs_expr = convert (build_pointer_type (build_pointer_type
4666 (objc_protocol_template)),
4667 build_unary_op (ADDR_EXPR, refs_decl, 0));
4668 else
4669 refs_expr = build_int_cst (NULL_TREE, 0);
4671 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4672 by generate_method_descriptors, which is called above. */
4673 initlist = build_protocol_initializer (TREE_TYPE (decl),
4674 protocol_name_expr, refs_expr,
4675 UOBJC_INSTANCE_METHODS_decl,
4676 UOBJC_CLASS_METHODS_decl);
4677 finish_var_decl (decl, initlist);
4681 static tree
4682 build_protocol_initializer (tree type, tree protocol_name,
4683 tree protocol_list, tree instance_methods,
4684 tree class_methods)
4686 tree initlist = NULL_TREE, expr;
4687 tree cast_type = build_pointer_type
4688 (xref_tag (RECORD_TYPE,
4689 get_identifier (UTAG_CLASS)));
4691 /* Filling the "isa" in with one allows the runtime system to
4692 detect that the version change...should remove before final release. */
4694 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4695 initlist = tree_cons (NULL_TREE, expr, initlist);
4696 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4697 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4699 if (!instance_methods)
4700 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4701 else
4703 expr = convert (objc_method_proto_list_ptr,
4704 build_unary_op (ADDR_EXPR, instance_methods, 0));
4705 initlist = tree_cons (NULL_TREE, expr, initlist);
4708 if (!class_methods)
4709 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4710 else
4712 expr = convert (objc_method_proto_list_ptr,
4713 build_unary_op (ADDR_EXPR, class_methods, 0));
4714 initlist = tree_cons (NULL_TREE, expr, initlist);
4717 return objc_build_constructor (type, nreverse (initlist));
4720 /* struct _objc_category {
4721 char *category_name;
4722 char *class_name;
4723 struct _objc_method_list *instance_methods;
4724 struct _objc_method_list *class_methods;
4725 struct _objc_protocol_list *protocols;
4726 }; */
4728 static void
4729 build_category_template (void)
4731 tree field_decl, field_decl_chain;
4733 objc_category_template = start_struct (RECORD_TYPE,
4734 get_identifier (UTAG_CATEGORY));
4736 /* char *category_name; */
4737 field_decl = create_field_decl (string_type_node, "category_name");
4738 field_decl_chain = field_decl;
4740 /* char *class_name; */
4741 field_decl = create_field_decl (string_type_node, "class_name");
4742 chainon (field_decl_chain, field_decl);
4744 /* struct _objc_method_list *instance_methods; */
4745 field_decl = create_field_decl (objc_method_list_ptr,
4746 "instance_methods");
4747 chainon (field_decl_chain, field_decl);
4749 /* struct _objc_method_list *class_methods; */
4750 field_decl = create_field_decl (objc_method_list_ptr,
4751 "class_methods");
4752 chainon (field_decl_chain, field_decl);
4754 /* struct _objc_protocol **protocol_list; */
4755 field_decl = create_field_decl (build_pointer_type
4756 (build_pointer_type
4757 (objc_protocol_template)),
4758 "protocol_list");
4759 chainon (field_decl_chain, field_decl);
4761 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4764 /* struct _objc_selector {
4765 SEL sel_id;
4766 char *sel_type;
4767 }; */
4769 static void
4770 build_selector_template (void)
4773 tree field_decl, field_decl_chain;
4775 objc_selector_template
4776 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4778 /* SEL sel_id; */
4779 field_decl = create_field_decl (objc_selector_type, "sel_id");
4780 field_decl_chain = field_decl;
4782 /* char *sel_type; */
4783 field_decl = create_field_decl (string_type_node, "sel_type");
4784 chainon (field_decl_chain, field_decl);
4786 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4789 /* struct _objc_class {
4790 struct _objc_class *isa;
4791 struct _objc_class *super_class;
4792 char *name;
4793 long version;
4794 long info;
4795 long instance_size;
4796 struct _objc_ivar_list *ivars;
4797 struct _objc_method_list *methods;
4798 #ifdef __NEXT_RUNTIME__
4799 struct objc_cache *cache;
4800 #else
4801 struct sarray *dtable;
4802 struct _objc_class *subclass_list;
4803 struct _objc_class *sibling_class;
4804 #endif
4805 struct _objc_protocol_list *protocols;
4806 #ifdef __NEXT_RUNTIME__
4807 void *sel_id;
4808 #endif
4809 void *gc_object_type;
4810 }; */
4812 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4813 the NeXT/Apple runtime; still, the compiler must generate them to
4814 maintain backward binary compatibility (and to allow for future
4815 expansion). */
4817 static void
4818 build_class_template (void)
4820 tree field_decl, field_decl_chain;
4822 objc_class_template
4823 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4825 /* struct _objc_class *isa; */
4826 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4827 "isa");
4828 field_decl_chain = field_decl;
4830 /* struct _objc_class *super_class; */
4831 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4832 "super_class");
4833 chainon (field_decl_chain, field_decl);
4835 /* char *name; */
4836 field_decl = create_field_decl (string_type_node, "name");
4837 chainon (field_decl_chain, field_decl);
4839 /* long version; */
4840 field_decl = create_field_decl (long_integer_type_node, "version");
4841 chainon (field_decl_chain, field_decl);
4843 /* long info; */
4844 field_decl = create_field_decl (long_integer_type_node, "info");
4845 chainon (field_decl_chain, field_decl);
4847 /* long instance_size; */
4848 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4849 chainon (field_decl_chain, field_decl);
4851 /* struct _objc_ivar_list *ivars; */
4852 field_decl = create_field_decl (objc_ivar_list_ptr,
4853 "ivars");
4854 chainon (field_decl_chain, field_decl);
4856 /* struct _objc_method_list *methods; */
4857 field_decl = create_field_decl (objc_method_list_ptr,
4858 "methods");
4859 chainon (field_decl_chain, field_decl);
4861 if (flag_next_runtime)
4863 /* struct objc_cache *cache; */
4864 field_decl = create_field_decl (build_pointer_type
4865 (xref_tag (RECORD_TYPE,
4866 get_identifier
4867 ("objc_cache"))),
4868 "cache");
4869 chainon (field_decl_chain, field_decl);
4871 else
4873 /* struct sarray *dtable; */
4874 field_decl = create_field_decl (build_pointer_type
4875 (xref_tag (RECORD_TYPE,
4876 get_identifier
4877 ("sarray"))),
4878 "dtable");
4879 chainon (field_decl_chain, field_decl);
4881 /* struct objc_class *subclass_list; */
4882 field_decl = create_field_decl (build_pointer_type
4883 (objc_class_template),
4884 "subclass_list");
4885 chainon (field_decl_chain, field_decl);
4887 /* struct objc_class *sibling_class; */
4888 field_decl = create_field_decl (build_pointer_type
4889 (objc_class_template),
4890 "sibling_class");
4891 chainon (field_decl_chain, field_decl);
4894 /* struct _objc_protocol **protocol_list; */
4895 field_decl = create_field_decl (build_pointer_type
4896 (build_pointer_type
4897 (xref_tag (RECORD_TYPE,
4898 get_identifier
4899 (UTAG_PROTOCOL)))),
4900 "protocol_list");
4901 chainon (field_decl_chain, field_decl);
4903 if (flag_next_runtime)
4905 /* void *sel_id; */
4906 field_decl = create_field_decl (build_pointer_type (void_type_node),
4907 "sel_id");
4908 chainon (field_decl_chain, field_decl);
4911 /* void *gc_object_type; */
4912 field_decl = create_field_decl (build_pointer_type (void_type_node),
4913 "gc_object_type");
4914 chainon (field_decl_chain, field_decl);
4916 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4919 /* Generate appropriate forward declarations for an implementation. */
4921 static void
4922 synth_forward_declarations (void)
4924 tree an_id;
4926 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4927 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4928 objc_class_template);
4930 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4931 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4932 objc_class_template);
4934 /* Pre-build the following entities - for speed/convenience. */
4936 an_id = get_identifier ("super_class");
4937 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4938 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4941 static void
4942 error_with_ivar (const char *message, tree decl)
4944 error ("%J%s %qs", decl,
4945 message, gen_declaration (decl));
4949 static void
4950 check_ivars (tree inter, tree imp)
4952 tree intdecls = CLASS_RAW_IVARS (inter);
4953 tree impdecls = CLASS_RAW_IVARS (imp);
4955 while (1)
4957 tree t1, t2;
4959 #ifdef OBJCPLUS
4960 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4961 intdecls = TREE_CHAIN (intdecls);
4962 #endif
4963 if (intdecls == 0 && impdecls == 0)
4964 break;
4965 if (intdecls == 0 || impdecls == 0)
4967 error ("inconsistent instance variable specification");
4968 break;
4971 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4973 if (!comptypes (t1, t2)
4974 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4975 DECL_INITIAL (impdecls)))
4977 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4979 error_with_ivar ("conflicting instance variable type",
4980 impdecls);
4981 error_with_ivar ("previous declaration of",
4982 intdecls);
4984 else /* both the type and the name don't match */
4986 error ("inconsistent instance variable specification");
4987 break;
4991 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4993 error_with_ivar ("conflicting instance variable name",
4994 impdecls);
4995 error_with_ivar ("previous declaration of",
4996 intdecls);
4999 intdecls = TREE_CHAIN (intdecls);
5000 impdecls = TREE_CHAIN (impdecls);
5004 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5005 This needs to be done just once per compilation. */
5007 /* struct _objc_super {
5008 struct _objc_object *self;
5009 struct _objc_class *super_class;
5010 }; */
5012 static void
5013 build_super_template (void)
5015 tree field_decl, field_decl_chain;
5017 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5019 /* struct _objc_object *self; */
5020 field_decl = create_field_decl (objc_object_type, "self");
5021 field_decl_chain = field_decl;
5023 /* struct _objc_class *super_class; */
5024 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5025 "super_class");
5026 chainon (field_decl_chain, field_decl);
5028 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5031 /* struct _objc_ivar {
5032 char *ivar_name;
5033 char *ivar_type;
5034 int ivar_offset;
5035 }; */
5037 static tree
5038 build_ivar_template (void)
5040 tree objc_ivar_id, objc_ivar_record;
5041 tree field_decl, field_decl_chain;
5043 objc_ivar_id = get_identifier (UTAG_IVAR);
5044 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5046 /* char *ivar_name; */
5047 field_decl = create_field_decl (string_type_node, "ivar_name");
5048 field_decl_chain = field_decl;
5050 /* char *ivar_type; */
5051 field_decl = create_field_decl (string_type_node, "ivar_type");
5052 chainon (field_decl_chain, field_decl);
5054 /* int ivar_offset; */
5055 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5056 chainon (field_decl_chain, field_decl);
5058 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5060 return objc_ivar_record;
5063 /* struct {
5064 int ivar_count;
5065 struct objc_ivar ivar_list[ivar_count];
5066 }; */
5068 static tree
5069 build_ivar_list_template (tree list_type, int size)
5071 tree objc_ivar_list_record;
5072 tree field_decl, field_decl_chain;
5074 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5076 /* int ivar_count; */
5077 field_decl = create_field_decl (integer_type_node, "ivar_count");
5078 field_decl_chain = field_decl;
5080 /* struct objc_ivar ivar_list[]; */
5081 field_decl = create_field_decl (build_array_type
5082 (list_type,
5083 build_index_type
5084 (build_int_cst (NULL_TREE, size - 1))),
5085 "ivar_list");
5086 chainon (field_decl_chain, field_decl);
5088 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5090 return objc_ivar_list_record;
5093 /* struct {
5094 struct _objc__method_prototype_list *method_next;
5095 int method_count;
5096 struct objc_method method_list[method_count];
5097 }; */
5099 static tree
5100 build_method_list_template (tree list_type, int size)
5102 tree objc_ivar_list_record;
5103 tree field_decl, field_decl_chain;
5105 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5107 /* struct _objc__method_prototype_list *method_next; */
5108 field_decl = create_field_decl (objc_method_proto_list_ptr,
5109 "method_next");
5110 field_decl_chain = field_decl;
5112 /* int method_count; */
5113 field_decl = create_field_decl (integer_type_node, "method_count");
5114 chainon (field_decl_chain, field_decl);
5116 /* struct objc_method method_list[]; */
5117 field_decl = create_field_decl (build_array_type
5118 (list_type,
5119 build_index_type
5120 (build_int_cst (NULL_TREE, size - 1))),
5121 "method_list");
5122 chainon (field_decl_chain, field_decl);
5124 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5126 return objc_ivar_list_record;
5129 static tree
5130 build_ivar_list_initializer (tree type, tree field_decl)
5132 tree initlist = NULL_TREE;
5136 tree ivar = NULL_TREE;
5138 /* Set name. */
5139 if (DECL_NAME (field_decl))
5140 ivar = tree_cons (NULL_TREE,
5141 add_objc_string (DECL_NAME (field_decl),
5142 meth_var_names),
5143 ivar);
5144 else
5145 /* Unnamed bit-field ivar (yuck). */
5146 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5148 /* Set type. */
5149 encode_field_decl (field_decl,
5150 obstack_object_size (&util_obstack),
5151 OBJC_ENCODE_DONT_INLINE_DEFS);
5153 /* Null terminate string. */
5154 obstack_1grow (&util_obstack, 0);
5155 ivar
5156 = tree_cons
5157 (NULL_TREE,
5158 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5159 meth_var_types),
5160 ivar);
5161 obstack_free (&util_obstack, util_firstobj);
5163 /* Set offset. */
5164 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5165 initlist = tree_cons (NULL_TREE,
5166 objc_build_constructor (type, nreverse (ivar)),
5167 initlist);
5169 field_decl = TREE_CHAIN (field_decl);
5170 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5172 while (field_decl);
5174 return objc_build_constructor (build_array_type (type, 0),
5175 nreverse (initlist));
5178 static tree
5179 generate_ivars_list (tree type, const char *name, int size, tree list)
5181 tree decl, initlist;
5183 decl = start_var_decl (type, synth_id_with_class_suffix
5184 (name, objc_implementation_context));
5186 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5187 initlist = tree_cons (NULL_TREE, list, initlist);
5189 finish_var_decl (decl,
5190 objc_build_constructor (TREE_TYPE (decl),
5191 nreverse (initlist)));
5193 return decl;
5196 /* Count only the fields occurring in T. */
5197 static int
5198 ivar_list_length (tree t)
5200 int count = 0;
5202 for (; t; t = TREE_CHAIN (t))
5203 if (TREE_CODE (t) == FIELD_DECL)
5204 ++count;
5206 return count;
5209 static void
5210 generate_ivar_lists (void)
5212 tree initlist, ivar_list_template, chain;
5213 int size;
5215 generating_instance_variables = 1;
5217 if (!objc_ivar_template)
5218 objc_ivar_template = build_ivar_template ();
5220 /* Only generate class variables for the root of the inheritance
5221 hierarchy since these will be the same for every class. */
5223 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5224 && (chain = TYPE_FIELDS (objc_class_template)))
5226 size = ivar_list_length (chain);
5228 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5229 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5231 UOBJC_CLASS_VARIABLES_decl
5232 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5233 size, initlist);
5235 else
5236 UOBJC_CLASS_VARIABLES_decl = 0;
5238 chain = CLASS_IVARS (implementation_template);
5239 if (chain)
5241 size = ivar_list_length (chain);
5242 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5243 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5245 UOBJC_INSTANCE_VARIABLES_decl
5246 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5247 size, initlist);
5249 else
5250 UOBJC_INSTANCE_VARIABLES_decl = 0;
5252 generating_instance_variables = 0;
5255 static tree
5256 build_dispatch_table_initializer (tree type, tree entries)
5258 tree initlist = NULL_TREE;
5262 tree elemlist = NULL_TREE;
5264 elemlist = tree_cons (NULL_TREE,
5265 build_selector (METHOD_SEL_NAME (entries)),
5266 NULL_TREE);
5268 /* Generate the method encoding if we don't have one already. */
5269 if (! METHOD_ENCODING (entries))
5270 METHOD_ENCODING (entries) =
5271 encode_method_prototype (entries);
5273 elemlist = tree_cons (NULL_TREE,
5274 add_objc_string (METHOD_ENCODING (entries),
5275 meth_var_types),
5276 elemlist);
5278 elemlist
5279 = tree_cons (NULL_TREE,
5280 convert (ptr_type_node,
5281 build_unary_op (ADDR_EXPR,
5282 METHOD_DEFINITION (entries), 1)),
5283 elemlist);
5285 initlist = tree_cons (NULL_TREE,
5286 objc_build_constructor (type, nreverse (elemlist)),
5287 initlist);
5289 entries = TREE_CHAIN (entries);
5291 while (entries);
5293 return objc_build_constructor (build_array_type (type, 0),
5294 nreverse (initlist));
5297 /* To accomplish method prototyping without generating all kinds of
5298 inane warnings, the definition of the dispatch table entries were
5299 changed from:
5301 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5303 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5305 static tree
5306 build_method_template (void)
5308 tree _SLT_record;
5309 tree field_decl, field_decl_chain;
5311 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5313 /* SEL _cmd; */
5314 field_decl = create_field_decl (objc_selector_type, "_cmd");
5315 field_decl_chain = field_decl;
5317 /* char *method_types; */
5318 field_decl = create_field_decl (string_type_node, "method_types");
5319 chainon (field_decl_chain, field_decl);
5321 /* void *_imp; */
5322 field_decl = create_field_decl (build_pointer_type (void_type_node),
5323 "_imp");
5324 chainon (field_decl_chain, field_decl);
5326 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5328 return _SLT_record;
5332 static tree
5333 generate_dispatch_table (tree type, const char *name, int size, tree list)
5335 tree decl, initlist;
5337 decl = start_var_decl (type, synth_id_with_class_suffix
5338 (name, objc_implementation_context));
5340 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5341 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5342 initlist = tree_cons (NULL_TREE, list, initlist);
5344 finish_var_decl (decl,
5345 objc_build_constructor (TREE_TYPE (decl),
5346 nreverse (initlist)));
5348 return decl;
5351 static void
5352 mark_referenced_methods (void)
5354 struct imp_entry *impent;
5355 tree chain;
5357 for (impent = imp_list; impent; impent = impent->next)
5359 chain = CLASS_CLS_METHODS (impent->imp_context);
5360 while (chain)
5362 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5363 chain = TREE_CHAIN (chain);
5366 chain = CLASS_NST_METHODS (impent->imp_context);
5367 while (chain)
5369 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5370 chain = TREE_CHAIN (chain);
5375 static void
5376 generate_dispatch_tables (void)
5378 tree initlist, chain, method_list_template;
5379 int size;
5381 if (!objc_method_template)
5382 objc_method_template = build_method_template ();
5384 chain = CLASS_CLS_METHODS (objc_implementation_context);
5385 if (chain)
5387 size = list_length (chain);
5389 method_list_template
5390 = build_method_list_template (objc_method_template, size);
5391 initlist
5392 = build_dispatch_table_initializer (objc_method_template, chain);
5394 UOBJC_CLASS_METHODS_decl
5395 = generate_dispatch_table (method_list_template,
5396 ((TREE_CODE (objc_implementation_context)
5397 == CLASS_IMPLEMENTATION_TYPE)
5398 ? "_OBJC_CLASS_METHODS"
5399 : "_OBJC_CATEGORY_CLASS_METHODS"),
5400 size, initlist);
5402 else
5403 UOBJC_CLASS_METHODS_decl = 0;
5405 chain = CLASS_NST_METHODS (objc_implementation_context);
5406 if (chain)
5408 size = list_length (chain);
5410 method_list_template
5411 = build_method_list_template (objc_method_template, size);
5412 initlist
5413 = build_dispatch_table_initializer (objc_method_template, chain);
5415 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5416 UOBJC_INSTANCE_METHODS_decl
5417 = generate_dispatch_table (method_list_template,
5418 "_OBJC_INSTANCE_METHODS",
5419 size, initlist);
5420 else
5421 /* We have a category. */
5422 UOBJC_INSTANCE_METHODS_decl
5423 = generate_dispatch_table (method_list_template,
5424 "_OBJC_CATEGORY_INSTANCE_METHODS",
5425 size, initlist);
5427 else
5428 UOBJC_INSTANCE_METHODS_decl = 0;
5431 static tree
5432 generate_protocol_list (tree i_or_p)
5434 tree initlist;
5435 tree refs_decl, lproto, e, plist;
5436 int size = 0;
5437 const char *ref_name;
5439 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5440 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5441 plist = CLASS_PROTOCOL_LIST (i_or_p);
5442 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5443 plist = PROTOCOL_LIST (i_or_p);
5444 else
5445 abort ();
5447 /* Compute size. */
5448 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5449 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5450 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5451 size++;
5453 /* Build initializer. */
5454 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5455 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5456 initlist = tree_cons (NULL_TREE, e, initlist);
5458 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5460 tree pval = TREE_VALUE (lproto);
5462 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5463 && PROTOCOL_FORWARD_DECL (pval))
5465 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5466 initlist = tree_cons (NULL_TREE, e, initlist);
5470 /* static struct objc_protocol *refs[n]; */
5472 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5473 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5474 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5475 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5476 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5477 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5478 else
5479 abort ();
5481 refs_decl = start_var_decl
5482 (build_array_type
5483 (build_pointer_type (objc_protocol_template),
5484 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5485 ref_name);
5487 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5488 nreverse (initlist)));
5490 return refs_decl;
5493 static tree
5494 build_category_initializer (tree type, tree cat_name, tree class_name,
5495 tree instance_methods, tree class_methods,
5496 tree protocol_list)
5498 tree initlist = NULL_TREE, expr;
5500 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5501 initlist = tree_cons (NULL_TREE, class_name, initlist);
5503 if (!instance_methods)
5504 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5505 else
5507 expr = convert (objc_method_list_ptr,
5508 build_unary_op (ADDR_EXPR, instance_methods, 0));
5509 initlist = tree_cons (NULL_TREE, expr, initlist);
5511 if (!class_methods)
5512 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5513 else
5515 expr = convert (objc_method_list_ptr,
5516 build_unary_op (ADDR_EXPR, class_methods, 0));
5517 initlist = tree_cons (NULL_TREE, expr, initlist);
5520 /* protocol_list = */
5521 if (!protocol_list)
5522 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5523 else
5525 expr = convert (build_pointer_type
5526 (build_pointer_type
5527 (objc_protocol_template)),
5528 build_unary_op (ADDR_EXPR, protocol_list, 0));
5529 initlist = tree_cons (NULL_TREE, expr, initlist);
5532 return objc_build_constructor (type, nreverse (initlist));
5535 /* struct _objc_class {
5536 struct objc_class *isa;
5537 struct objc_class *super_class;
5538 char *name;
5539 long version;
5540 long info;
5541 long instance_size;
5542 struct objc_ivar_list *ivars;
5543 struct objc_method_list *methods;
5544 if (flag_next_runtime)
5545 struct objc_cache *cache;
5546 else {
5547 struct sarray *dtable;
5548 struct objc_class *subclass_list;
5549 struct objc_class *sibling_class;
5551 struct objc_protocol_list *protocols;
5552 if (flag_next_runtime)
5553 void *sel_id;
5554 void *gc_object_type;
5555 }; */
5557 static tree
5558 build_shared_structure_initializer (tree type, tree isa, tree super,
5559 tree name, tree size, int status,
5560 tree dispatch_table, tree ivar_list,
5561 tree protocol_list)
5563 tree initlist = NULL_TREE, expr;
5565 /* isa = */
5566 initlist = tree_cons (NULL_TREE, isa, initlist);
5568 /* super_class = */
5569 initlist = tree_cons (NULL_TREE, super, initlist);
5571 /* name = */
5572 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5574 /* version = */
5575 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5576 initlist);
5578 /* info = */
5579 initlist = tree_cons (NULL_TREE,
5580 build_int_cst (long_integer_type_node, status),
5581 initlist);
5583 /* instance_size = */
5584 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5585 initlist);
5587 /* objc_ivar_list = */
5588 if (!ivar_list)
5589 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5590 else
5592 expr = convert (objc_ivar_list_ptr,
5593 build_unary_op (ADDR_EXPR, ivar_list, 0));
5594 initlist = tree_cons (NULL_TREE, expr, initlist);
5597 /* objc_method_list = */
5598 if (!dispatch_table)
5599 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5600 else
5602 expr = convert (objc_method_list_ptr,
5603 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5604 initlist = tree_cons (NULL_TREE, expr, initlist);
5607 if (flag_next_runtime)
5608 /* method_cache = */
5609 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5610 else
5612 /* dtable = */
5613 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5615 /* subclass_list = */
5616 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5618 /* sibling_class = */
5619 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5622 /* protocol_list = */
5623 if (! protocol_list)
5624 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5625 else
5627 expr = convert (build_pointer_type
5628 (build_pointer_type
5629 (objc_protocol_template)),
5630 build_unary_op (ADDR_EXPR, protocol_list, 0));
5631 initlist = tree_cons (NULL_TREE, expr, initlist);
5634 if (flag_next_runtime)
5635 /* sel_id = NULL */
5636 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5638 /* gc_object_type = NULL */
5639 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5641 return objc_build_constructor (type, nreverse (initlist));
5644 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5646 static inline tree
5647 lookup_category (tree class, tree cat_name)
5649 tree category = CLASS_CATEGORY_LIST (class);
5651 while (category && CLASS_SUPER_NAME (category) != cat_name)
5652 category = CLASS_CATEGORY_LIST (category);
5653 return category;
5656 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5658 static void
5659 generate_category (tree cat)
5661 tree decl;
5662 tree initlist, cat_name_expr, class_name_expr;
5663 tree protocol_decl, category;
5665 add_class_reference (CLASS_NAME (cat));
5666 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5668 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5670 category = lookup_category (implementation_template,
5671 CLASS_SUPER_NAME (cat));
5673 if (category && CLASS_PROTOCOL_LIST (category))
5675 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5676 protocol_decl = generate_protocol_list (category);
5678 else
5679 protocol_decl = 0;
5681 decl = start_var_decl (objc_category_template,
5682 synth_id_with_class_suffix
5683 ("_OBJC_CATEGORY", objc_implementation_context));
5685 initlist = build_category_initializer (TREE_TYPE (decl),
5686 cat_name_expr, class_name_expr,
5687 UOBJC_INSTANCE_METHODS_decl,
5688 UOBJC_CLASS_METHODS_decl,
5689 protocol_decl);
5691 finish_var_decl (decl, initlist);
5694 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5695 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5697 static void
5698 generate_shared_structures (int cls_flags)
5700 tree sc_spec, decl_specs, decl;
5701 tree name_expr, super_expr, root_expr;
5702 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5703 tree cast_type, initlist, protocol_decl;
5705 my_super_id = CLASS_SUPER_NAME (implementation_template);
5706 if (my_super_id)
5708 add_class_reference (my_super_id);
5710 /* Compute "my_root_id" - this is required for code generation.
5711 the "isa" for all meta class structures points to the root of
5712 the inheritance hierarchy (e.g. "__Object")... */
5713 my_root_id = my_super_id;
5716 tree my_root_int = lookup_interface (my_root_id);
5718 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5719 my_root_id = CLASS_SUPER_NAME (my_root_int);
5720 else
5721 break;
5723 while (1);
5725 else
5726 /* No super class. */
5727 my_root_id = CLASS_NAME (implementation_template);
5729 cast_type = build_pointer_type (objc_class_template);
5730 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5731 class_names);
5733 /* Install class `isa' and `super' pointers at runtime. */
5734 if (my_super_id)
5736 super_expr = add_objc_string (my_super_id, class_names);
5737 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5739 else
5740 super_expr = build_int_cst (NULL_TREE, 0);
5742 root_expr = add_objc_string (my_root_id, class_names);
5743 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5745 if (CLASS_PROTOCOL_LIST (implementation_template))
5747 generate_protocol_references
5748 (CLASS_PROTOCOL_LIST (implementation_template));
5749 protocol_decl = generate_protocol_list (implementation_template);
5751 else
5752 protocol_decl = 0;
5754 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5756 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5757 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5759 decl = start_var_decl (objc_class_template,
5760 IDENTIFIER_POINTER
5761 (DECL_NAME (UOBJC_METACLASS_decl)));
5763 initlist
5764 = build_shared_structure_initializer
5765 (TREE_TYPE (decl),
5766 root_expr, super_expr, name_expr,
5767 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5768 2 /*CLS_META*/,
5769 UOBJC_CLASS_METHODS_decl,
5770 UOBJC_CLASS_VARIABLES_decl,
5771 protocol_decl);
5773 finish_var_decl (decl, initlist);
5775 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5777 decl = start_var_decl (objc_class_template,
5778 IDENTIFIER_POINTER
5779 (DECL_NAME (UOBJC_CLASS_decl)));
5781 initlist
5782 = build_shared_structure_initializer
5783 (TREE_TYPE (decl),
5784 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5785 super_expr, name_expr,
5786 convert (integer_type_node,
5787 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5788 (implementation_template))),
5789 1 /*CLS_FACTORY*/ | cls_flags,
5790 UOBJC_INSTANCE_METHODS_decl,
5791 UOBJC_INSTANCE_VARIABLES_decl,
5792 protocol_decl);
5794 finish_var_decl (decl, initlist);
5798 static const char *
5799 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5801 static char string[BUFSIZE];
5803 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5804 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5806 sprintf (string, "%s_%s", preamble,
5807 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5809 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5810 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5812 /* We have a category. */
5813 const char *const class_name
5814 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5815 const char *const class_super_name
5816 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5817 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5819 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5821 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5822 sprintf (string, "%s_%s", preamble, protocol_name);
5824 else
5825 abort ();
5827 return string;
5830 /* If type is empty or only type qualifiers are present, add default
5831 type of id (otherwise grokdeclarator will default to int). */
5833 static tree
5834 adjust_type_for_id_default (tree type)
5836 if (!type)
5837 type = make_node (TREE_LIST);
5839 if (!TREE_VALUE (type))
5840 TREE_VALUE (type) = objc_object_type;
5841 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5842 && TYPED_OBJECT (TREE_VALUE (type)))
5843 error ("can not use an object as parameter to a method");
5845 return type;
5848 /* Usage:
5849 keyworddecl:
5850 selector ':' '(' typename ')' identifier
5852 Purpose:
5853 Transform an Objective-C keyword argument into
5854 the C equivalent parameter declarator.
5856 In: key_name, an "identifier_node" (optional).
5857 arg_type, a "tree_list" (optional).
5858 arg_name, an "identifier_node".
5860 Note: It would be really nice to strongly type the preceding
5861 arguments in the function prototype; however, then I
5862 could not use the "accessor" macros defined in "tree.h".
5864 Out: an instance of "keyword_decl". */
5866 tree
5867 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5869 tree keyword_decl;
5871 /* If no type is specified, default to "id". */
5872 arg_type = adjust_type_for_id_default (arg_type);
5874 keyword_decl = make_node (KEYWORD_DECL);
5876 TREE_TYPE (keyword_decl) = arg_type;
5877 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5878 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5880 return keyword_decl;
5883 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5885 static tree
5886 build_keyword_selector (tree selector)
5888 int len = 0;
5889 tree key_chain, key_name;
5890 char *buf;
5892 /* Scan the selector to see how much space we'll need. */
5893 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5895 if (TREE_CODE (selector) == KEYWORD_DECL)
5896 key_name = KEYWORD_KEY_NAME (key_chain);
5897 else if (TREE_CODE (selector) == TREE_LIST)
5898 key_name = TREE_PURPOSE (key_chain);
5899 else
5900 abort ();
5902 if (key_name)
5903 len += IDENTIFIER_LENGTH (key_name) + 1;
5904 else
5905 /* Just a ':' arg. */
5906 len++;
5909 buf = (char *) alloca (len + 1);
5910 /* Start the buffer out as an empty string. */
5911 buf[0] = '\0';
5913 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5915 if (TREE_CODE (selector) == KEYWORD_DECL)
5916 key_name = KEYWORD_KEY_NAME (key_chain);
5917 else if (TREE_CODE (selector) == TREE_LIST)
5919 key_name = TREE_PURPOSE (key_chain);
5920 /* The keyword decl chain will later be used as a function argument
5921 chain. Unhook the selector itself so as to not confuse other
5922 parts of the compiler. */
5923 TREE_PURPOSE (key_chain) = NULL_TREE;
5925 else
5926 abort ();
5928 if (key_name)
5929 strcat (buf, IDENTIFIER_POINTER (key_name));
5930 strcat (buf, ":");
5933 return get_identifier (buf);
5936 /* Used for declarations and definitions. */
5938 static tree
5939 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5940 tree add_args, bool ellipsis)
5942 tree method_decl;
5944 /* If no type is specified, default to "id". */
5945 ret_type = adjust_type_for_id_default (ret_type);
5947 method_decl = make_node (code);
5948 TREE_TYPE (method_decl) = ret_type;
5950 /* If we have a keyword selector, create an identifier_node that
5951 represents the full selector name (`:' included)... */
5952 if (TREE_CODE (selector) == KEYWORD_DECL)
5954 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5955 METHOD_SEL_ARGS (method_decl) = selector;
5956 METHOD_ADD_ARGS (method_decl) = add_args;
5957 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5959 else
5961 METHOD_SEL_NAME (method_decl) = selector;
5962 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5963 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5966 return method_decl;
5969 #define METHOD_DEF 0
5970 #define METHOD_REF 1
5972 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5973 an argument list for method METH. CONTEXT is either METHOD_DEF or
5974 METHOD_REF, saying whether we are trying to define a method or call
5975 one. SUPERFLAG says this is for a send to super; this makes a
5976 difference for the NeXT calling sequence in which the lookup and
5977 the method call are done together. If METH is null, user-defined
5978 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5980 static tree
5981 get_arg_type_list (tree meth, int context, int superflag)
5983 tree arglist, akey;
5985 /* Receiver type. */
5986 if (flag_next_runtime && superflag)
5987 arglist = build_tree_list (NULL_TREE, objc_super_type);
5988 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5989 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5990 else
5991 arglist = build_tree_list (NULL_TREE, objc_object_type);
5993 /* Selector type - will eventually change to `int'. */
5994 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5996 /* No actual method prototype given -- assume that remaining arguments
5997 are `...'. */
5998 if (!meth)
5999 return arglist;
6001 /* Build a list of argument types. */
6002 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6004 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6006 /* Decay arrays and functions into pointers. */
6007 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6008 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6009 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6010 arg_type = build_pointer_type (arg_type);
6012 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6015 if (METHOD_ADD_ARGS (meth))
6017 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6018 akey; akey = TREE_CHAIN (akey))
6020 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6022 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6025 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6026 goto lack_of_ellipsis;
6028 else
6030 lack_of_ellipsis:
6031 chainon (arglist, OBJC_VOID_AT_END);
6034 return arglist;
6037 static tree
6038 check_duplicates (hash hsh, int methods, int is_class)
6040 tree meth = NULL_TREE;
6042 if (hsh)
6044 meth = hsh->key;
6046 if (hsh->list)
6048 /* We have two or more methods with the same name but
6049 different types. */
6050 attr loop;
6052 /* But just how different are those types? If
6053 -Wno-strict-selector-match is specified, we shall not
6054 complain if the differences are solely among types with
6055 identical size and alignment. */
6056 if (!warn_strict_selector_match)
6058 for (loop = hsh->list; loop; loop = loop->next)
6059 if (!comp_proto_with_proto (meth, loop->value, 0))
6060 goto issue_warning;
6062 return meth;
6065 issue_warning:
6066 warning (0, "multiple %s named %<%c%s%> found",
6067 methods ? "methods" : "selectors",
6068 (is_class ? '+' : '-'),
6069 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6071 warn_with_method (methods ? "using" : "found",
6072 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6073 ? '-'
6074 : '+'),
6075 meth);
6076 for (loop = hsh->list; loop; loop = loop->next)
6077 warn_with_method ("also found",
6078 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6079 ? '-'
6080 : '+'),
6081 loop->value);
6084 return meth;
6087 /* If RECEIVER is a class reference, return the identifier node for
6088 the referenced class. RECEIVER is created by objc_get_class_reference,
6089 so we check the exact form created depending on which runtimes are
6090 used. */
6092 static tree
6093 receiver_is_class_object (tree receiver, int self, int super)
6095 tree chain, exp, arg;
6097 /* The receiver is 'self' or 'super' in the context of a class method. */
6098 if (objc_method_context
6099 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6100 && (self || super))
6101 return (super
6102 ? CLASS_SUPER_NAME (implementation_template)
6103 : CLASS_NAME (implementation_template));
6105 if (flag_next_runtime)
6107 /* The receiver is a variable created by
6108 build_class_reference_decl. */
6109 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6110 /* Look up the identifier. */
6111 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6112 if (TREE_PURPOSE (chain) == receiver)
6113 return TREE_VALUE (chain);
6116 /* The receiver is a function call that returns an id. Check if
6117 it is a call to objc_getClass, if so, pick up the class name. */
6118 if (TREE_CODE (receiver) == CALL_EXPR
6119 && (exp = TREE_OPERAND (receiver, 0))
6120 && TREE_CODE (exp) == ADDR_EXPR
6121 && (exp = TREE_OPERAND (exp, 0))
6122 && TREE_CODE (exp) == FUNCTION_DECL
6123 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6124 prototypes for objc_get_class(). Thankfully, they seem to share the
6125 same function type. */
6126 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6127 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6128 /* We have a call to objc_get_class/objc_getClass! */
6129 && (arg = TREE_OPERAND (receiver, 1))
6130 && TREE_CODE (arg) == TREE_LIST
6131 && (arg = TREE_VALUE (arg)))
6133 STRIP_NOPS (arg);
6134 if (TREE_CODE (arg) == ADDR_EXPR
6135 && (arg = TREE_OPERAND (arg, 0))
6136 && TREE_CODE (arg) == STRING_CST)
6137 /* Finally, we have the class name. */
6138 return get_identifier (TREE_STRING_POINTER (arg));
6140 return 0;
6143 /* If we are currently building a message expr, this holds
6144 the identifier of the selector of the message. This is
6145 used when printing warnings about argument mismatches. */
6147 static tree current_objc_message_selector = 0;
6149 tree
6150 objc_message_selector (void)
6152 return current_objc_message_selector;
6155 /* Construct an expression for sending a message.
6156 MESS has the object to send to in TREE_PURPOSE
6157 and the argument list (including selector) in TREE_VALUE.
6159 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6160 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6162 tree
6163 objc_build_message_expr (tree mess)
6165 tree receiver = TREE_PURPOSE (mess);
6166 tree sel_name;
6167 #ifdef OBJCPLUS
6168 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6169 #else
6170 tree args = TREE_VALUE (mess);
6171 #endif
6172 tree method_params = NULL_TREE;
6174 if (TREE_CODE (receiver) == ERROR_MARK)
6175 return error_mark_node;
6177 /* Obtain the full selector name. */
6178 if (TREE_CODE (args) == IDENTIFIER_NODE)
6179 /* A unary selector. */
6180 sel_name = args;
6181 else if (TREE_CODE (args) == TREE_LIST)
6182 sel_name = build_keyword_selector (args);
6183 else
6184 abort ();
6186 /* Build the parameter list to give to the method. */
6187 if (TREE_CODE (args) == TREE_LIST)
6188 #ifdef OBJCPLUS
6189 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6190 #else
6192 tree chain = args, prev = NULL_TREE;
6194 /* We have a keyword selector--check for comma expressions. */
6195 while (chain)
6197 tree element = TREE_VALUE (chain);
6199 /* We have a comma expression, must collapse... */
6200 if (TREE_CODE (element) == TREE_LIST)
6202 if (prev)
6203 TREE_CHAIN (prev) = element;
6204 else
6205 args = element;
6207 prev = chain;
6208 chain = TREE_CHAIN (chain);
6210 method_params = args;
6212 #endif
6214 #ifdef OBJCPLUS
6215 if (processing_template_decl)
6216 /* Must wait until template instantiation time. */
6217 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6218 method_params);
6219 #endif
6221 return objc_finish_message_expr (receiver, sel_name, method_params);
6224 /* Look up method SEL_NAME that would be suitable for receiver
6225 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6226 nonzero), and report on any duplicates. */
6228 static tree
6229 lookup_method_in_hash_lists (tree sel_name, int is_class)
6231 hash method_prototype = NULL;
6233 if (!is_class)
6234 method_prototype = hash_lookup (nst_method_hash_list,
6235 sel_name);
6237 if (!method_prototype)
6239 method_prototype = hash_lookup (cls_method_hash_list,
6240 sel_name);
6241 is_class = 1;
6244 return check_duplicates (method_prototype, 1, is_class);
6247 /* The 'objc_finish_message_expr' routine is called from within
6248 'objc_build_message_expr' for non-template functions. In the case of
6249 C++ template functions, it is called from 'build_expr_from_tree'
6250 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6252 tree
6253 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6255 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6256 tree selector, retval, class_tree;
6257 int self, super, have_cast;
6259 /* Extract the receiver of the message, as well as its type
6260 (where the latter may take the form of a cast or be inferred
6261 from the implementation context). */
6262 rtype = receiver;
6263 while (TREE_CODE (rtype) == COMPOUND_EXPR
6264 || TREE_CODE (rtype) == MODIFY_EXPR
6265 || TREE_CODE (rtype) == NOP_EXPR
6266 || TREE_CODE (rtype) == CONVERT_EXPR
6267 || TREE_CODE (rtype) == COMPONENT_REF)
6268 rtype = TREE_OPERAND (rtype, 0);
6269 self = (rtype == self_decl);
6270 super = (rtype == UOBJC_SUPER_decl);
6271 rtype = TREE_TYPE (receiver);
6272 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6273 || (TREE_CODE (receiver) == COMPOUND_EXPR
6274 && !IS_SUPER (rtype)));
6276 /* If we are calling [super dealloc], reset our warning flag. */
6277 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6278 should_call_super_dealloc = 0;
6280 /* If the receiver is a class object, retrieve the corresponding
6281 @interface, if one exists. */
6282 class_tree = receiver_is_class_object (receiver, self, super);
6284 /* Now determine the receiver type (if an explicit cast has not been
6285 provided). */
6286 if (!have_cast)
6288 if (class_tree)
6289 rtype = lookup_interface (class_tree);
6290 /* Handle `self' and `super'. */
6291 else if (super)
6293 if (!CLASS_SUPER_NAME (implementation_template))
6295 error ("no super class declared in @interface for %qs",
6296 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6297 return error_mark_node;
6299 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6301 else if (self)
6302 rtype = lookup_interface (CLASS_NAME (implementation_template));
6305 /* If receiver is of type `id' or `Class' (or if the @interface for a
6306 class is not visible), we shall be satisfied with the existence of
6307 any instance or class method. */
6308 if (objc_is_id (rtype))
6310 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6311 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6312 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6313 : NULL_TREE);
6314 rtype = NULL_TREE;
6316 if (rprotos)
6318 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6319 in protocols themselves for the method prototype. */
6320 method_prototype
6321 = lookup_method_in_protocol_list (rprotos, sel_name,
6322 class_tree != NULL_TREE);
6324 /* If messaging 'Class <Proto>' but did not find a class method
6325 prototype, search for an instance method instead, and warn
6326 about having done so. */
6327 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6329 method_prototype
6330 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6332 if (method_prototype)
6333 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6334 IDENTIFIER_POINTER (sel_name),
6335 IDENTIFIER_POINTER (sel_name));
6339 else if (rtype)
6341 tree orig_rtype = rtype, saved_rtype;
6343 if (TREE_CODE (rtype) == POINTER_TYPE)
6344 rtype = TREE_TYPE (rtype);
6345 /* Traverse typedef aliases */
6346 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6347 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6348 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6349 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6350 saved_rtype = rtype;
6351 if (TYPED_OBJECT (rtype))
6353 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6354 rtype = TYPE_OBJC_INTERFACE (rtype);
6356 /* If we could not find an @interface declaration, we must have
6357 only seen a @class declaration; so, we cannot say anything
6358 more intelligent about which methods the receiver will
6359 understand. */
6360 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6361 rtype = NULL_TREE;
6362 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6363 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6365 /* We have a valid ObjC class name. Look up the method name
6366 in the published @interface for the class (and its
6367 superclasses). */
6368 method_prototype
6369 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6371 /* If the method was not found in the @interface, it may still
6372 exist locally as part of the @implementation. */
6373 if (!method_prototype && objc_implementation_context
6374 && CLASS_NAME (objc_implementation_context)
6375 == OBJC_TYPE_NAME (rtype))
6376 method_prototype
6377 = lookup_method
6378 ((class_tree
6379 ? CLASS_CLS_METHODS (objc_implementation_context)
6380 : CLASS_NST_METHODS (objc_implementation_context)),
6381 sel_name);
6383 /* If we haven't found a candidate method by now, try looking for
6384 it in the protocol list. */
6385 if (!method_prototype && rprotos)
6386 method_prototype
6387 = lookup_method_in_protocol_list (rprotos, sel_name,
6388 class_tree != NULL_TREE);
6390 else
6392 warning (0, "invalid receiver type %qs",
6393 gen_type_name (orig_rtype));
6394 /* After issuing the "invalid receiver" warning, perform method
6395 lookup as if we were messaging 'id'. */
6396 rtype = rprotos = NULL_TREE;
6401 /* For 'id' or 'Class' receivers, search in the global hash table
6402 as a last resort. For all receivers, warn if protocol searches
6403 have failed. */
6404 if (!method_prototype)
6406 if (rprotos)
6407 warning (0, "%<%c%s%> not found in protocol(s)",
6408 (class_tree ? '+' : '-'),
6409 IDENTIFIER_POINTER (sel_name));
6411 if (!rtype)
6412 method_prototype
6413 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6416 if (!method_prototype)
6418 static bool warn_missing_methods = false;
6420 if (rtype)
6421 warning (0, "%qs may not respond to %<%c%s%>",
6422 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6423 (class_tree ? '+' : '-'),
6424 IDENTIFIER_POINTER (sel_name));
6425 /* If we are messaging an 'id' or 'Class' object and made it here,
6426 then we have failed to find _any_ instance or class method,
6427 respectively. */
6428 else
6429 warning (0, "no %<%c%s%> method found",
6430 (class_tree ? '+' : '-'),
6431 IDENTIFIER_POINTER (sel_name));
6433 if (!warn_missing_methods)
6435 warning (0, "(Messages without a matching method signature");
6436 warning (0, "will be assumed to return %<id%> and accept");
6437 warning (0, "%<...%> as arguments.)");
6438 warn_missing_methods = true;
6442 /* Save the selector name for printing error messages. */
6443 current_objc_message_selector = sel_name;
6445 /* Build the parameters list for looking up the method.
6446 These are the object itself and the selector. */
6448 if (flag_typed_selectors)
6449 selector = build_typed_selector_reference (sel_name, method_prototype);
6450 else
6451 selector = build_selector_reference (sel_name);
6453 retval = build_objc_method_call (super, method_prototype,
6454 receiver,
6455 selector, method_params);
6457 current_objc_message_selector = 0;
6459 return retval;
6462 /* Build a tree expression to send OBJECT the operation SELECTOR,
6463 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6464 assuming the method has prototype METHOD_PROTOTYPE.
6465 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6466 Use METHOD_PARAMS as list of args to pass to the method.
6467 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6469 static tree
6470 build_objc_method_call (int super_flag, tree method_prototype,
6471 tree lookup_object, tree selector,
6472 tree method_params)
6474 tree sender = (super_flag ? umsg_super_decl :
6475 (!flag_next_runtime || flag_nil_receivers
6476 ? (flag_objc_direct_dispatch
6477 ? umsg_fast_decl
6478 : umsg_decl)
6479 : umsg_nonnil_decl));
6480 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6482 /* If a prototype for the method to be called exists, then cast
6483 the sender's return type and arguments to match that of the method.
6484 Otherwise, leave sender as is. */
6485 tree ret_type
6486 = (method_prototype
6487 ? TREE_VALUE (TREE_TYPE (method_prototype))
6488 : objc_object_type);
6489 tree sender_cast
6490 = build_pointer_type
6491 (build_function_type
6492 (ret_type,
6493 get_arg_type_list
6494 (method_prototype, METHOD_REF, super_flag)));
6495 tree method, t;
6497 lookup_object = build_c_cast (rcv_p, lookup_object);
6499 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6500 lookup_object = save_expr (lookup_object);
6502 if (flag_next_runtime)
6504 /* If we are returning a struct in memory, and the address
6505 of that memory location is passed as a hidden first
6506 argument, then change which messenger entry point this
6507 expr will call. NB: Note that sender_cast remains
6508 unchanged (it already has a struct return type). */
6509 if (!targetm.calls.struct_value_rtx (0, 0)
6510 && (TREE_CODE (ret_type) == RECORD_TYPE
6511 || TREE_CODE (ret_type) == UNION_TYPE)
6512 && targetm.calls.return_in_memory (ret_type, 0))
6513 sender = (super_flag ? umsg_super_stret_decl :
6514 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6516 method_params = tree_cons (NULL_TREE, lookup_object,
6517 tree_cons (NULL_TREE, selector,
6518 method_params));
6519 method = build_fold_addr_expr (sender);
6521 else
6523 /* This is the portable (GNU) way. */
6524 tree object;
6526 /* First, call the lookup function to get a pointer to the method,
6527 then cast the pointer, then call it with the method arguments. */
6529 object = (super_flag ? self_decl : lookup_object);
6531 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6532 t = tree_cons (NULL_TREE, lookup_object, t);
6533 method = build_function_call (sender, t);
6535 /* Pass the object to the method. */
6536 method_params = tree_cons (NULL_TREE, object,
6537 tree_cons (NULL_TREE, selector,
6538 method_params));
6541 /* ??? Selector is not at this point something we can use inside
6542 the compiler itself. Set it to garbage for the nonce. */
6543 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6544 return build_function_call (t, method_params);
6547 static void
6548 build_protocol_reference (tree p)
6550 tree decl;
6551 const char *proto_name;
6553 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6555 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6556 decl = start_var_decl (objc_protocol_template, proto_name);
6558 PROTOCOL_FORWARD_DECL (p) = decl;
6561 /* This function is called by the parser when (and only when) a
6562 @protocol() expression is found, in order to compile it. */
6563 tree
6564 objc_build_protocol_expr (tree protoname)
6566 tree expr;
6567 tree p = lookup_protocol (protoname);
6569 if (!p)
6571 error ("cannot find protocol declaration for %qs",
6572 IDENTIFIER_POINTER (protoname));
6573 return error_mark_node;
6576 if (!PROTOCOL_FORWARD_DECL (p))
6577 build_protocol_reference (p);
6579 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6581 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6582 if we have it, rather than converting it here. */
6583 expr = convert (objc_protocol_type, expr);
6585 /* The @protocol() expression is being compiled into a pointer to a
6586 statically allocated instance of the Protocol class. To become
6587 usable at runtime, the 'isa' pointer of the instance need to be
6588 fixed up at runtime by the runtime library, to point to the
6589 actual 'Protocol' class. */
6591 /* For the GNU runtime, put the static Protocol instance in the list
6592 of statically allocated instances, so that we make sure that its
6593 'isa' pointer is fixed up at runtime by the GNU runtime library
6594 to point to the Protocol class (at runtime, when loading the
6595 module, the GNU runtime library loops on the statically allocated
6596 instances (as found in the defs field in objc_symtab) and fixups
6597 all the 'isa' pointers of those objects). */
6598 if (! flag_next_runtime)
6600 /* This type is a struct containing the fields of a Protocol
6601 object. (Cfr. objc_protocol_type instead is the type of a pointer
6602 to such a struct). */
6603 tree protocol_struct_type = xref_tag
6604 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6605 tree *chain;
6607 /* Look for the list of Protocol statically allocated instances
6608 to fixup at runtime. Create a new list to hold Protocol
6609 statically allocated instances, if the list is not found. At
6610 present there is only another list, holding NSConstantString
6611 static instances to be fixed up at runtime. */
6612 for (chain = &objc_static_instances;
6613 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6614 chain = &TREE_CHAIN (*chain));
6615 if (!*chain)
6617 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6618 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6619 class_names);
6622 /* Add this statically allocated instance to the Protocol list. */
6623 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6624 PROTOCOL_FORWARD_DECL (p),
6625 TREE_PURPOSE (*chain));
6629 return expr;
6632 /* This function is called by the parser when a @selector() expression
6633 is found, in order to compile it. It is only called by the parser
6634 and only to compile a @selector(). */
6635 tree
6636 objc_build_selector_expr (tree selnamelist)
6638 tree selname;
6640 /* Obtain the full selector name. */
6641 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6642 /* A unary selector. */
6643 selname = selnamelist;
6644 else if (TREE_CODE (selnamelist) == TREE_LIST)
6645 selname = build_keyword_selector (selnamelist);
6646 else
6647 abort ();
6649 /* If we are required to check @selector() expressions as they
6650 are found, check that the selector has been declared. */
6651 if (warn_undeclared_selector)
6653 /* Look the selector up in the list of all known class and
6654 instance methods (up to this line) to check that the selector
6655 exists. */
6656 hash hsh;
6658 /* First try with instance methods. */
6659 hsh = hash_lookup (nst_method_hash_list, selname);
6661 /* If not found, try with class methods. */
6662 if (!hsh)
6664 hsh = hash_lookup (cls_method_hash_list, selname);
6667 /* If still not found, print out a warning. */
6668 if (!hsh)
6670 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6675 if (flag_typed_selectors)
6676 return build_typed_selector_reference (selname, 0);
6677 else
6678 return build_selector_reference (selname);
6681 tree
6682 objc_build_encode_expr (tree type)
6684 tree result;
6685 const char *string;
6687 encode_type (type, obstack_object_size (&util_obstack),
6688 OBJC_ENCODE_INLINE_DEFS);
6689 obstack_1grow (&util_obstack, 0); /* null terminate string */
6690 string = obstack_finish (&util_obstack);
6692 /* Synthesize a string that represents the encoded struct/union. */
6693 result = my_build_string (strlen (string) + 1, string);
6694 obstack_free (&util_obstack, util_firstobj);
6695 return result;
6698 static tree
6699 build_ivar_reference (tree id)
6701 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6703 /* Historically, a class method that produced objects (factory
6704 method) would assign `self' to the instance that it
6705 allocated. This would effectively turn the class method into
6706 an instance method. Following this assignment, the instance
6707 variables could be accessed. That practice, while safe,
6708 violates the simple rule that a class method should not refer
6709 to an instance variable. It's better to catch the cases
6710 where this is done unknowingly than to support the above
6711 paradigm. */
6712 warning (0, "instance variable %qs accessed in class method",
6713 IDENTIFIER_POINTER (id));
6714 self_decl = convert (objc_instance_type, self_decl); /* cast */
6717 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6720 /* Compute a hash value for a given method SEL_NAME. */
6722 static size_t
6723 hash_func (tree sel_name)
6725 const unsigned char *s
6726 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6727 size_t h = 0;
6729 while (*s)
6730 h = h * 67 + *s++ - 113;
6731 return h;
6734 static void
6735 hash_init (void)
6737 nst_method_hash_list
6738 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6739 cls_method_hash_list
6740 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6742 /* Initialize the hash table used to hold the constant string objects. */
6743 string_htab = htab_create_ggc (31, string_hash,
6744 string_eq, NULL);
6746 /* Initialize the hash table used to hold EH-volatilized types. */
6747 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6748 volatilized_eq, NULL);
6751 /* WARNING!!!! hash_enter is called with a method, and will peek
6752 inside to find its selector! But hash_lookup is given a selector
6753 directly, and looks for the selector that's inside the found
6754 entry's key (method) for comparison. */
6756 static void
6757 hash_enter (hash *hashlist, tree method)
6759 hash obj;
6760 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6762 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6763 obj->list = 0;
6764 obj->next = hashlist[slot];
6765 obj->key = method;
6767 hashlist[slot] = obj; /* append to front */
6770 static hash
6771 hash_lookup (hash *hashlist, tree sel_name)
6773 hash target;
6775 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6777 while (target)
6779 if (sel_name == METHOD_SEL_NAME (target->key))
6780 return target;
6782 target = target->next;
6784 return 0;
6787 static void
6788 hash_add_attr (hash entry, tree value)
6790 attr obj;
6792 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6793 obj->next = entry->list;
6794 obj->value = value;
6796 entry->list = obj; /* append to front */
6799 static tree
6800 lookup_method (tree mchain, tree method)
6802 tree key;
6804 if (TREE_CODE (method) == IDENTIFIER_NODE)
6805 key = method;
6806 else
6807 key = METHOD_SEL_NAME (method);
6809 while (mchain)
6811 if (METHOD_SEL_NAME (mchain) == key)
6812 return mchain;
6814 mchain = TREE_CHAIN (mchain);
6816 return NULL_TREE;
6819 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6820 in INTERFACE, along with any categories and protocols attached thereto.
6821 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6822 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6823 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6824 be found in INTERFACE or any of its superclasses, look for an _instance_
6825 method of the same name in the root class as a last resort.
6827 If a suitable method cannot be found, return NULL_TREE. */
6829 static tree
6830 lookup_method_static (tree interface, tree ident, int flags)
6832 tree meth = NULL_TREE, root_inter = NULL_TREE;
6833 tree inter = interface;
6834 int is_class = (flags & OBJC_LOOKUP_CLASS);
6835 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6837 while (inter)
6839 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6840 tree category = inter;
6842 /* First, look up the method in the class itself. */
6843 if ((meth = lookup_method (chain, ident)))
6844 return meth;
6846 /* Failing that, look for the method in each category of the class. */
6847 while ((category = CLASS_CATEGORY_LIST (category)))
6849 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6851 /* Check directly in each category. */
6852 if ((meth = lookup_method (chain, ident)))
6853 return meth;
6855 /* Failing that, check in each category's protocols. */
6856 if (CLASS_PROTOCOL_LIST (category))
6858 if ((meth = (lookup_method_in_protocol_list
6859 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6860 return meth;
6864 /* If not found in categories, check in protocols of the main class. */
6865 if (CLASS_PROTOCOL_LIST (inter))
6867 if ((meth = (lookup_method_in_protocol_list
6868 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6869 return meth;
6872 /* If we were instructed not to look in superclasses, don't. */
6873 if (no_superclasses)
6874 return NULL_TREE;
6876 /* Failing that, climb up the inheritance hierarchy. */
6877 root_inter = inter;
6878 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6880 while (inter);
6882 /* If no class (factory) method was found, check if an _instance_
6883 method of the same name exists in the root class. This is what
6884 the Objective-C runtime will do. If an instance method was not
6885 found, return 0. */
6886 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6889 /* Add the method to the hash list if it doesn't contain an identical
6890 method already. */
6891 static void
6892 add_method_to_hash_list (hash *hash_list, tree method)
6894 hash hsh;
6896 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6898 /* Install on a global chain. */
6899 hash_enter (hash_list, method);
6901 else
6903 /* Check types against those; if different, add to a list. */
6904 attr loop;
6905 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6906 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6907 already_there |= comp_proto_with_proto (method, loop->value, 1);
6908 if (!already_there)
6909 hash_add_attr (hsh, method);
6913 static tree
6914 objc_add_method (tree class, tree method, int is_class)
6916 tree mth;
6918 if (!(mth = lookup_method (is_class
6919 ? CLASS_CLS_METHODS (class)
6920 : CLASS_NST_METHODS (class), method)))
6922 /* put method on list in reverse order */
6923 if (is_class)
6925 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6926 CLASS_CLS_METHODS (class) = method;
6928 else
6930 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6931 CLASS_NST_METHODS (class) = method;
6934 else
6936 /* When processing an @interface for a class or category, give hard
6937 errors on methods with identical selectors but differing argument
6938 and/or return types. We do not do this for @implementations, because
6939 C/C++ will do it for us (i.e., there will be duplicate function
6940 definition errors). */
6941 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6942 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6943 && !comp_proto_with_proto (method, mth, 1))
6944 error ("duplicate declaration of method %<%c%s%>",
6945 is_class ? '+' : '-',
6946 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6949 if (is_class)
6950 add_method_to_hash_list (cls_method_hash_list, method);
6951 else
6953 add_method_to_hash_list (nst_method_hash_list, method);
6955 /* Instance methods in root classes (and categories thereof)
6956 may act as class methods as a last resort. We also add
6957 instance methods listed in @protocol declarations to
6958 the class hash table, on the assumption that @protocols
6959 may be adopted by root classes or categories. */
6960 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6961 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6962 class = lookup_interface (CLASS_NAME (class));
6964 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6965 || !CLASS_SUPER_NAME (class))
6966 add_method_to_hash_list (cls_method_hash_list, method);
6969 return method;
6972 static tree
6973 add_class (tree class_name, tree name)
6975 struct interface_tuple **slot;
6977 /* Put interfaces on list in reverse order. */
6978 TREE_CHAIN (class_name) = interface_chain;
6979 interface_chain = class_name;
6981 if (interface_htab == NULL)
6982 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6983 slot = (struct interface_tuple **)
6984 htab_find_slot_with_hash (interface_htab, name,
6985 htab_hash_pointer (name),
6986 INSERT);
6987 if (!*slot)
6989 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6990 (*slot)->id = name;
6992 (*slot)->class_name = class_name;
6994 return interface_chain;
6997 static void
6998 add_category (tree class, tree category)
7000 /* Put categories on list in reverse order. */
7001 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7003 if (cat)
7005 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7006 IDENTIFIER_POINTER (CLASS_NAME (class)),
7007 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7009 else
7011 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7012 CLASS_CATEGORY_LIST (class) = category;
7016 /* Called after parsing each instance variable declaration. Necessary to
7017 preserve typedefs and implement public/private...
7019 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7021 static tree
7022 add_instance_variable (tree class, int public, tree field_decl)
7024 tree field_type = TREE_TYPE (field_decl);
7025 const char *ivar_name = DECL_NAME (field_decl)
7026 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7027 : "<unnamed>";
7029 #ifdef OBJCPLUS
7030 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7032 error ("illegal reference type specified for instance variable %qs",
7033 ivar_name);
7034 /* Return class as is without adding this ivar. */
7035 return class;
7037 #endif
7039 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7040 || TYPE_SIZE (field_type) == error_mark_node)
7041 /* 'type[0]' is allowed, but 'type[]' is not! */
7043 error ("instance variable %qs has unknown size", ivar_name);
7044 /* Return class as is without adding this ivar. */
7045 return class;
7048 #ifdef OBJCPLUS
7049 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7050 need to either (1) warn the user about it or (2) generate suitable
7051 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7052 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7053 if (IS_AGGR_TYPE (field_type)
7054 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7055 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7056 || TYPE_POLYMORPHIC_P (field_type)))
7058 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7060 if (flag_objc_call_cxx_cdtors)
7062 /* Since the ObjC runtime will be calling the constructors and
7063 destructors for us, the only thing we can't handle is the lack
7064 of a default constructor. */
7065 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7066 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7068 warning (0, "type %qs has no default constructor to call",
7069 type_name);
7071 /* If we cannot call a constructor, we should also avoid
7072 calling the destructor, for symmetry. */
7073 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7074 warning (0, "destructor for %qs shall not be run either",
7075 type_name);
7078 else
7080 static bool warn_cxx_ivars = false;
7082 if (TYPE_POLYMORPHIC_P (field_type))
7084 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7085 initialize them. */
7086 error ("type %qs has virtual member functions", type_name);
7087 error ("illegal aggregate type %qs specified "
7088 "for instance variable %qs",
7089 type_name, ivar_name);
7090 /* Return class as is without adding this ivar. */
7091 return class;
7094 /* User-defined constructors and destructors are not known to Obj-C
7095 and hence will not be called. This may or may not be a problem. */
7096 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7097 warning (0, "type %qs has a user-defined constructor", type_name);
7098 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7099 warning (0, "type %qs has a user-defined destructor", type_name);
7101 if (!warn_cxx_ivars)
7103 warning (0, "C++ constructors and destructors will not "
7104 "be invoked for Objective-C fields");
7105 warn_cxx_ivars = true;
7109 #endif
7111 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7112 switch (public)
7114 case 0:
7115 TREE_PUBLIC (field_decl) = 0;
7116 TREE_PRIVATE (field_decl) = 0;
7117 TREE_PROTECTED (field_decl) = 1;
7118 break;
7120 case 1:
7121 TREE_PUBLIC (field_decl) = 1;
7122 TREE_PRIVATE (field_decl) = 0;
7123 TREE_PROTECTED (field_decl) = 0;
7124 break;
7126 case 2:
7127 TREE_PUBLIC (field_decl) = 0;
7128 TREE_PRIVATE (field_decl) = 1;
7129 TREE_PROTECTED (field_decl) = 0;
7130 break;
7134 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7136 return class;
7139 static tree
7140 is_ivar (tree decl_chain, tree ident)
7142 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7143 if (DECL_NAME (decl_chain) == ident)
7144 return decl_chain;
7145 return NULL_TREE;
7148 /* True if the ivar is private and we are not in its implementation. */
7150 static int
7151 is_private (tree decl)
7153 return (TREE_PRIVATE (decl)
7154 && ! is_ivar (CLASS_IVARS (implementation_template),
7155 DECL_NAME (decl)));
7158 /* We have an instance variable reference;, check to see if it is public. */
7161 objc_is_public (tree expr, tree identifier)
7163 tree basetype, decl;
7165 #ifdef OBJCPLUS
7166 if (processing_template_decl)
7167 return 1;
7168 #endif
7170 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7172 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7174 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7176 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7178 if (!class)
7180 error ("cannot find interface declaration for %qs",
7181 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7182 return 0;
7185 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7187 if (TREE_PUBLIC (decl))
7188 return 1;
7190 /* Important difference between the Stepstone translator:
7191 all instance variables should be public within the context
7192 of the implementation. */
7193 if (objc_implementation_context
7194 && ((TREE_CODE (objc_implementation_context)
7195 == CLASS_IMPLEMENTATION_TYPE)
7196 || (TREE_CODE (objc_implementation_context)
7197 == CATEGORY_IMPLEMENTATION_TYPE)))
7199 tree curtype = TYPE_MAIN_VARIANT
7200 (CLASS_STATIC_TEMPLATE
7201 (implementation_template));
7203 if (basetype == curtype
7204 || DERIVED_FROM_P (basetype, curtype))
7206 int private = is_private (decl);
7208 if (private)
7209 error ("instance variable %qs is declared private",
7210 IDENTIFIER_POINTER (DECL_NAME (decl)));
7212 return !private;
7216 /* The 2.95.2 compiler sometimes allowed C functions to access
7217 non-@public ivars. We will let this slide for now... */
7218 if (!objc_method_context)
7220 warning (0, "instance variable %qs is %s; "
7221 "this will be a hard error in the future",
7222 IDENTIFIER_POINTER (identifier),
7223 TREE_PRIVATE (decl) ? "@private" : "@protected");
7224 return 1;
7227 error ("instance variable %qs is declared %s",
7228 IDENTIFIER_POINTER (identifier),
7229 TREE_PRIVATE (decl) ? "private" : "protected");
7230 return 0;
7235 return 1;
7238 /* Make sure all entries in CHAIN are also in LIST. */
7240 static int
7241 check_methods (tree chain, tree list, int mtype)
7243 int first = 1;
7245 while (chain)
7247 if (!lookup_method (list, chain))
7249 if (first)
7251 if (TREE_CODE (objc_implementation_context)
7252 == CLASS_IMPLEMENTATION_TYPE)
7253 warning (0, "incomplete implementation of class %qs",
7254 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7255 else if (TREE_CODE (objc_implementation_context)
7256 == CATEGORY_IMPLEMENTATION_TYPE)
7257 warning (0, "incomplete implementation of category %qs",
7258 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7259 first = 0;
7262 warning (0, "method definition for %<%c%s%> not found",
7263 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7266 chain = TREE_CHAIN (chain);
7269 return first;
7272 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7274 static int
7275 conforms_to_protocol (tree class, tree protocol)
7277 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7279 tree p = CLASS_PROTOCOL_LIST (class);
7280 while (p && TREE_VALUE (p) != protocol)
7281 p = TREE_CHAIN (p);
7283 if (!p)
7285 tree super = (CLASS_SUPER_NAME (class)
7286 ? lookup_interface (CLASS_SUPER_NAME (class))
7287 : NULL_TREE);
7288 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7289 if (!tmp)
7290 return 0;
7294 return 1;
7297 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7298 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7300 static int
7301 check_methods_accessible (tree chain, tree context, int mtype)
7303 int first = 1;
7304 tree list;
7305 tree base_context = context;
7307 while (chain)
7309 context = base_context;
7310 while (context)
7312 if (mtype == '+')
7313 list = CLASS_CLS_METHODS (context);
7314 else
7315 list = CLASS_NST_METHODS (context);
7317 if (lookup_method (list, chain))
7318 break;
7320 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7321 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7322 context = (CLASS_SUPER_NAME (context)
7323 ? lookup_interface (CLASS_SUPER_NAME (context))
7324 : NULL_TREE);
7326 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7327 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7328 context = (CLASS_NAME (context)
7329 ? lookup_interface (CLASS_NAME (context))
7330 : NULL_TREE);
7331 else
7332 abort ();
7335 if (context == NULL_TREE)
7337 if (first)
7339 if (TREE_CODE (objc_implementation_context)
7340 == CLASS_IMPLEMENTATION_TYPE)
7341 warning (0, "incomplete implementation of class %qs",
7342 IDENTIFIER_POINTER
7343 (CLASS_NAME (objc_implementation_context)));
7344 else if (TREE_CODE (objc_implementation_context)
7345 == CATEGORY_IMPLEMENTATION_TYPE)
7346 warning (0, "incomplete implementation of category %qs",
7347 IDENTIFIER_POINTER
7348 (CLASS_SUPER_NAME (objc_implementation_context)));
7349 first = 0;
7351 warning (0, "method definition for %<%c%s%> not found",
7352 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7355 chain = TREE_CHAIN (chain); /* next method... */
7357 return first;
7360 /* Check whether the current interface (accessible via
7361 'objc_implementation_context') actually implements protocol P, along
7362 with any protocols that P inherits. */
7364 static void
7365 check_protocol (tree p, const char *type, const char *name)
7367 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7369 int f1, f2;
7371 /* Ensure that all protocols have bodies! */
7372 if (warn_protocol)
7374 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7375 CLASS_CLS_METHODS (objc_implementation_context),
7376 '+');
7377 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7378 CLASS_NST_METHODS (objc_implementation_context),
7379 '-');
7381 else
7383 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7384 objc_implementation_context,
7385 '+');
7386 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7387 objc_implementation_context,
7388 '-');
7391 if (!f1 || !f2)
7392 warning (0, "%s %qs does not fully implement the %qs protocol",
7393 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7396 /* Check protocols recursively. */
7397 if (PROTOCOL_LIST (p))
7399 tree subs = PROTOCOL_LIST (p);
7400 tree super_class =
7401 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7403 while (subs)
7405 tree sub = TREE_VALUE (subs);
7407 /* If the superclass does not conform to the protocols
7408 inherited by P, then we must! */
7409 if (!super_class || !conforms_to_protocol (super_class, sub))
7410 check_protocol (sub, type, name);
7411 subs = TREE_CHAIN (subs);
7416 /* Check whether the current interface (accessible via
7417 'objc_implementation_context') actually implements the protocols listed
7418 in PROTO_LIST. */
7420 static void
7421 check_protocols (tree proto_list, const char *type, const char *name)
7423 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7425 tree p = TREE_VALUE (proto_list);
7427 check_protocol (p, type, name);
7431 /* Make sure that the class CLASS_NAME is defined
7432 CODE says which kind of thing CLASS_NAME ought to be.
7433 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7434 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7436 static tree
7437 start_class (enum tree_code code, tree class_name, tree super_name,
7438 tree protocol_list)
7440 tree class, decl;
7442 #ifdef OBJCPLUS
7443 if (current_namespace != global_namespace) {
7444 error ("Objective-C declarations may only appear in global scope");
7446 #endif /* OBJCPLUS */
7448 if (objc_implementation_context)
7450 warning (0, "%<@end%> missing in implementation context");
7451 finish_class (objc_implementation_context);
7452 objc_ivar_chain = NULL_TREE;
7453 objc_implementation_context = NULL_TREE;
7456 class = make_node (code);
7457 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7459 /* Check for existence of the super class, if one was specified. Note
7460 that we must have seen an @interface, not just a @class. If we
7461 are looking at a @compatibility_alias, traverse it first. */
7462 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7463 && super_name)
7465 tree super = objc_is_class_name (super_name);
7467 if (!super || !lookup_interface (super))
7469 error ("cannot find interface declaration for %qs, superclass of %qs",
7470 IDENTIFIER_POINTER (super ? super : super_name),
7471 IDENTIFIER_POINTER (class_name));
7472 super_name = NULL_TREE;
7474 else
7475 super_name = super;
7478 CLASS_NAME (class) = class_name;
7479 CLASS_SUPER_NAME (class) = super_name;
7480 CLASS_CLS_METHODS (class) = NULL_TREE;
7482 if (! objc_is_class_name (class_name)
7483 && (decl = lookup_name (class_name)))
7485 error ("%qs redeclared as different kind of symbol",
7486 IDENTIFIER_POINTER (class_name));
7487 error ("previous declaration of %q+D",
7488 decl);
7491 if (code == CLASS_IMPLEMENTATION_TYPE)
7494 tree chain;
7496 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7497 if (TREE_VALUE (chain) == class_name)
7499 error ("reimplementation of class %qs",
7500 IDENTIFIER_POINTER (class_name));
7501 return error_mark_node;
7503 implemented_classes = tree_cons (NULL_TREE, class_name,
7504 implemented_classes);
7507 /* Reset for multiple classes per file. */
7508 method_slot = 0;
7510 objc_implementation_context = class;
7512 /* Lookup the interface for this implementation. */
7514 if (!(implementation_template = lookup_interface (class_name)))
7516 warning (0, "cannot find interface declaration for %qs",
7517 IDENTIFIER_POINTER (class_name));
7518 add_class (implementation_template = objc_implementation_context,
7519 class_name);
7522 /* If a super class has been specified in the implementation,
7523 insure it conforms to the one specified in the interface. */
7525 if (super_name
7526 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7528 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7529 const char *const name =
7530 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7531 error ("conflicting super class name %qs",
7532 IDENTIFIER_POINTER (super_name));
7533 error ("previous declaration of %qs", name);
7536 else if (! super_name)
7538 CLASS_SUPER_NAME (objc_implementation_context)
7539 = CLASS_SUPER_NAME (implementation_template);
7543 else if (code == CLASS_INTERFACE_TYPE)
7545 if (lookup_interface (class_name))
7546 #ifdef OBJCPLUS
7547 error ("duplicate interface declaration for class %qs",
7548 #else
7549 warning (0, "duplicate interface declaration for class %qs",
7550 #endif
7551 IDENTIFIER_POINTER (class_name));
7552 else
7553 add_class (class, class_name);
7555 if (protocol_list)
7556 CLASS_PROTOCOL_LIST (class)
7557 = lookup_and_install_protocols (protocol_list);
7560 else if (code == CATEGORY_INTERFACE_TYPE)
7562 tree class_category_is_assoc_with;
7564 /* For a category, class_name is really the name of the class that
7565 the following set of methods will be associated with. We must
7566 find the interface so that can derive the objects template. */
7568 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7570 error ("cannot find interface declaration for %qs",
7571 IDENTIFIER_POINTER (class_name));
7572 exit (FATAL_EXIT_CODE);
7574 else
7575 add_category (class_category_is_assoc_with, class);
7577 if (protocol_list)
7578 CLASS_PROTOCOL_LIST (class)
7579 = lookup_and_install_protocols (protocol_list);
7582 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7584 /* Reset for multiple classes per file. */
7585 method_slot = 0;
7587 objc_implementation_context = class;
7589 /* For a category, class_name is really the name of the class that
7590 the following set of methods will be associated with. We must
7591 find the interface so that can derive the objects template. */
7593 if (!(implementation_template = lookup_interface (class_name)))
7595 error ("cannot find interface declaration for %qs",
7596 IDENTIFIER_POINTER (class_name));
7597 exit (FATAL_EXIT_CODE);
7600 return class;
7603 static tree
7604 continue_class (tree class)
7606 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7607 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7609 struct imp_entry *imp_entry;
7611 /* Check consistency of the instance variables. */
7613 if (CLASS_RAW_IVARS (class))
7614 check_ivars (implementation_template, class);
7616 /* code generation */
7618 #ifdef OBJCPLUS
7619 push_lang_context (lang_name_c);
7620 #endif
7622 build_private_template (implementation_template);
7623 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7624 objc_instance_type = build_pointer_type (uprivate_record);
7626 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7628 imp_entry->next = imp_list;
7629 imp_entry->imp_context = class;
7630 imp_entry->imp_template = implementation_template;
7632 synth_forward_declarations ();
7633 imp_entry->class_decl = UOBJC_CLASS_decl;
7634 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7635 imp_entry->has_cxx_cdtors = 0;
7637 /* Append to front and increment count. */
7638 imp_list = imp_entry;
7639 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7640 imp_count++;
7641 else
7642 cat_count++;
7644 #ifdef OBJCPLUS
7645 pop_lang_context ();
7646 #endif /* OBJCPLUS */
7648 return get_class_ivars (implementation_template, true);
7651 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7653 #ifdef OBJCPLUS
7654 push_lang_context (lang_name_c);
7655 #endif /* OBJCPLUS */
7657 build_private_template (class);
7659 #ifdef OBJCPLUS
7660 pop_lang_context ();
7661 #endif /* OBJCPLUS */
7663 return NULL_TREE;
7666 else
7667 return error_mark_node;
7670 /* This is called once we see the "@end" in an interface/implementation. */
7672 static void
7673 finish_class (tree class)
7675 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7677 /* All code generation is done in finish_objc. */
7679 if (implementation_template != objc_implementation_context)
7681 /* Ensure that all method listed in the interface contain bodies. */
7682 check_methods (CLASS_CLS_METHODS (implementation_template),
7683 CLASS_CLS_METHODS (objc_implementation_context), '+');
7684 check_methods (CLASS_NST_METHODS (implementation_template),
7685 CLASS_NST_METHODS (objc_implementation_context), '-');
7687 if (CLASS_PROTOCOL_LIST (implementation_template))
7688 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7689 "class",
7690 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7694 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7696 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7698 if (category)
7700 /* Ensure all method listed in the interface contain bodies. */
7701 check_methods (CLASS_CLS_METHODS (category),
7702 CLASS_CLS_METHODS (objc_implementation_context), '+');
7703 check_methods (CLASS_NST_METHODS (category),
7704 CLASS_NST_METHODS (objc_implementation_context), '-');
7706 if (CLASS_PROTOCOL_LIST (category))
7707 check_protocols (CLASS_PROTOCOL_LIST (category),
7708 "category",
7709 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7714 static tree
7715 add_protocol (tree protocol)
7717 /* Put protocol on list in reverse order. */
7718 TREE_CHAIN (protocol) = protocol_chain;
7719 protocol_chain = protocol;
7720 return protocol_chain;
7723 static tree
7724 lookup_protocol (tree ident)
7726 tree chain;
7728 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7729 if (ident == PROTOCOL_NAME (chain))
7730 return chain;
7732 return NULL_TREE;
7735 /* This function forward declares the protocols named by NAMES. If
7736 they are already declared or defined, the function has no effect. */
7738 void
7739 objc_declare_protocols (tree names)
7741 tree list;
7743 #ifdef OBJCPLUS
7744 if (current_namespace != global_namespace) {
7745 error ("Objective-C declarations may only appear in global scope");
7747 #endif /* OBJCPLUS */
7749 for (list = names; list; list = TREE_CHAIN (list))
7751 tree name = TREE_VALUE (list);
7753 if (lookup_protocol (name) == NULL_TREE)
7755 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7757 TYPE_LANG_SLOT_1 (protocol)
7758 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7759 PROTOCOL_NAME (protocol) = name;
7760 PROTOCOL_LIST (protocol) = NULL_TREE;
7761 add_protocol (protocol);
7762 PROTOCOL_DEFINED (protocol) = 0;
7763 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7768 static tree
7769 start_protocol (enum tree_code code, tree name, tree list)
7771 tree protocol;
7773 #ifdef OBJCPLUS
7774 if (current_namespace != global_namespace) {
7775 error ("Objective-C declarations may only appear in global scope");
7777 #endif /* OBJCPLUS */
7779 protocol = lookup_protocol (name);
7781 if (!protocol)
7783 protocol = make_node (code);
7784 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7786 PROTOCOL_NAME (protocol) = name;
7787 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7788 add_protocol (protocol);
7789 PROTOCOL_DEFINED (protocol) = 1;
7790 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7792 check_protocol_recursively (protocol, list);
7794 else if (! PROTOCOL_DEFINED (protocol))
7796 PROTOCOL_DEFINED (protocol) = 1;
7797 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7799 check_protocol_recursively (protocol, list);
7801 else
7803 warning (0, "duplicate declaration for protocol %qs",
7804 IDENTIFIER_POINTER (name));
7806 return protocol;
7810 /* "Encode" a data type into a string, which grows in util_obstack.
7811 ??? What is the FORMAT? Someone please document this! */
7813 static void
7814 encode_type_qualifiers (tree declspecs)
7816 tree spec;
7818 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7820 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7821 obstack_1grow (&util_obstack, 'n');
7822 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7823 obstack_1grow (&util_obstack, 'N');
7824 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7825 obstack_1grow (&util_obstack, 'o');
7826 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7827 obstack_1grow (&util_obstack, 'O');
7828 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7829 obstack_1grow (&util_obstack, 'R');
7830 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7831 obstack_1grow (&util_obstack, 'V');
7835 /* Encode a pointer type. */
7837 static void
7838 encode_pointer (tree type, int curtype, int format)
7840 tree pointer_to = TREE_TYPE (type);
7842 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7844 if (OBJC_TYPE_NAME (pointer_to)
7845 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7847 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7849 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7851 obstack_1grow (&util_obstack, '@');
7852 return;
7854 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7855 && TYPE_OBJC_INTERFACE (pointer_to))
7857 if (generating_instance_variables)
7859 obstack_1grow (&util_obstack, '@');
7860 obstack_1grow (&util_obstack, '"');
7861 obstack_grow (&util_obstack, name, strlen (name));
7862 obstack_1grow (&util_obstack, '"');
7863 return;
7865 else
7867 obstack_1grow (&util_obstack, '@');
7868 return;
7871 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7873 obstack_1grow (&util_obstack, '#');
7874 return;
7876 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7878 obstack_1grow (&util_obstack, ':');
7879 return;
7883 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7884 && TYPE_MODE (pointer_to) == QImode)
7886 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7887 ? OBJC_TYPE_NAME (pointer_to)
7888 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7890 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7892 /* It appears that "r*" means "const char *" rather than
7893 "char *const". */
7894 if (TYPE_READONLY (pointer_to))
7895 obstack_1grow (&util_obstack, 'r');
7897 obstack_1grow (&util_obstack, '*');
7898 return;
7902 /* We have a type that does not get special treatment. */
7904 /* NeXT extension */
7905 obstack_1grow (&util_obstack, '^');
7906 encode_type (pointer_to, curtype, format);
7909 static void
7910 encode_array (tree type, int curtype, int format)
7912 tree an_int_cst = TYPE_SIZE (type);
7913 tree array_of = TREE_TYPE (type);
7914 char buffer[40];
7916 /* An incomplete array is treated like a pointer. */
7917 if (an_int_cst == NULL)
7919 encode_pointer (type, curtype, format);
7920 return;
7923 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7924 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7925 else
7926 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7927 TREE_INT_CST_LOW (an_int_cst)
7928 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7930 obstack_grow (&util_obstack, buffer, strlen (buffer));
7931 encode_type (array_of, curtype, format);
7932 obstack_1grow (&util_obstack, ']');
7933 return;
7936 static void
7937 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7939 tree field = TYPE_FIELDS (type);
7941 for (; field; field = TREE_CHAIN (field))
7943 #ifdef OBJCPLUS
7944 /* C++ static members, and things that are not field at all,
7945 should not appear in the encoding. */
7946 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7947 continue;
7948 #endif
7950 /* Recursively encode fields of embedded base classes. */
7951 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7952 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7954 encode_aggregate_fields (TREE_TYPE (field),
7955 pointed_to, curtype, format);
7956 continue;
7959 if (generating_instance_variables && !pointed_to)
7961 tree fname = DECL_NAME (field);
7963 obstack_1grow (&util_obstack, '"');
7965 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7966 obstack_grow (&util_obstack,
7967 IDENTIFIER_POINTER (fname),
7968 strlen (IDENTIFIER_POINTER (fname)));
7970 obstack_1grow (&util_obstack, '"');
7973 encode_field_decl (field, curtype, format);
7977 static void
7978 encode_aggregate_within (tree type, int curtype, int format, int left,
7979 int right)
7981 tree name;
7982 /* NB: aggregates that are pointed to have slightly different encoding
7983 rules in that you never encode the names of instance variables. */
7984 int ob_size = obstack_object_size (&util_obstack);
7985 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7986 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7987 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7988 int inline_contents
7989 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7990 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7992 /* Traverse struct aliases; it is important to get the
7993 original struct and its tag name (if any). */
7994 type = TYPE_MAIN_VARIANT (type);
7995 name = OBJC_TYPE_NAME (type);
7996 /* Open parenth/bracket. */
7997 obstack_1grow (&util_obstack, left);
7999 /* Encode the struct/union tag name, or '?' if a tag was
8000 not provided. Typedef aliases do not qualify. */
8001 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8002 #ifdef OBJCPLUS
8003 /* Did this struct have a tag? */
8004 && !TYPE_WAS_ANONYMOUS (type)
8005 #endif
8007 obstack_grow (&util_obstack,
8008 IDENTIFIER_POINTER (name),
8009 strlen (IDENTIFIER_POINTER (name)));
8010 else
8011 obstack_1grow (&util_obstack, '?');
8013 /* Encode the types (and possibly names) of the inner fields,
8014 if required. */
8015 if (inline_contents)
8017 obstack_1grow (&util_obstack, '=');
8018 encode_aggregate_fields (type, pointed_to, curtype, format);
8020 /* Close parenth/bracket. */
8021 obstack_1grow (&util_obstack, right);
8024 static void
8025 encode_aggregate (tree type, int curtype, int format)
8027 enum tree_code code = TREE_CODE (type);
8029 switch (code)
8031 case RECORD_TYPE:
8033 encode_aggregate_within (type, curtype, format, '{', '}');
8034 break;
8036 case UNION_TYPE:
8038 encode_aggregate_within (type, curtype, format, '(', ')');
8039 break;
8042 case ENUMERAL_TYPE:
8043 obstack_1grow (&util_obstack, 'i');
8044 break;
8046 default:
8047 break;
8051 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8052 field type. */
8054 static void
8055 encode_next_bitfield (int width)
8057 char buffer[40];
8058 sprintf (buffer, "b%d", width);
8059 obstack_grow (&util_obstack, buffer, strlen (buffer));
8062 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8063 static void
8064 encode_type (tree type, int curtype, int format)
8066 enum tree_code code = TREE_CODE (type);
8067 char c;
8069 if (TYPE_READONLY (type))
8070 obstack_1grow (&util_obstack, 'r');
8072 if (code == INTEGER_TYPE)
8074 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8076 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8077 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8078 case 32:
8079 if (type == long_unsigned_type_node
8080 || type == long_integer_type_node)
8081 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8082 else
8083 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8084 break;
8085 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8086 default: abort ();
8088 obstack_1grow (&util_obstack, c);
8091 else if (code == REAL_TYPE)
8093 /* Floating point types. */
8094 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8096 case 32: c = 'f'; break;
8097 case 64:
8098 case 96:
8099 case 128: c = 'd'; break;
8100 default: abort ();
8102 obstack_1grow (&util_obstack, c);
8105 else if (code == VOID_TYPE)
8106 obstack_1grow (&util_obstack, 'v');
8108 else if (code == BOOLEAN_TYPE)
8109 obstack_1grow (&util_obstack, 'B');
8111 else if (code == ARRAY_TYPE)
8112 encode_array (type, curtype, format);
8114 else if (code == POINTER_TYPE)
8115 encode_pointer (type, curtype, format);
8117 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8118 encode_aggregate (type, curtype, format);
8120 else if (code == FUNCTION_TYPE) /* '?' */
8121 obstack_1grow (&util_obstack, '?');
8123 else if (code == COMPLEX_TYPE)
8125 obstack_1grow (&util_obstack, 'j');
8126 encode_type (TREE_TYPE (type), curtype, format);
8130 static void
8131 encode_gnu_bitfield (int position, tree type, int size)
8133 enum tree_code code = TREE_CODE (type);
8134 char buffer[40];
8135 char charType = '?';
8137 if (code == INTEGER_TYPE)
8139 if (integer_zerop (TYPE_MIN_VALUE (type)))
8141 /* Unsigned integer types. */
8143 if (TYPE_MODE (type) == QImode)
8144 charType = 'C';
8145 else if (TYPE_MODE (type) == HImode)
8146 charType = 'S';
8147 else if (TYPE_MODE (type) == SImode)
8149 if (type == long_unsigned_type_node)
8150 charType = 'L';
8151 else
8152 charType = 'I';
8154 else if (TYPE_MODE (type) == DImode)
8155 charType = 'Q';
8158 else
8159 /* Signed integer types. */
8161 if (TYPE_MODE (type) == QImode)
8162 charType = 'c';
8163 else if (TYPE_MODE (type) == HImode)
8164 charType = 's';
8165 else if (TYPE_MODE (type) == SImode)
8167 if (type == long_integer_type_node)
8168 charType = 'l';
8169 else
8170 charType = 'i';
8173 else if (TYPE_MODE (type) == DImode)
8174 charType = 'q';
8177 else if (code == ENUMERAL_TYPE)
8178 charType = 'i';
8179 else
8180 abort ();
8182 sprintf (buffer, "b%d%c%d", position, charType, size);
8183 obstack_grow (&util_obstack, buffer, strlen (buffer));
8186 static void
8187 encode_field_decl (tree field_decl, int curtype, int format)
8189 tree type;
8191 #ifdef OBJCPLUS
8192 /* C++ static members, and things that are not fields at all,
8193 should not appear in the encoding. */
8194 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8195 return;
8196 #endif
8198 type = TREE_TYPE (field_decl);
8200 /* Generate the bitfield typing information, if needed. Note the difference
8201 between GNU and NeXT runtimes. */
8202 if (DECL_BIT_FIELD_TYPE (field_decl))
8204 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8206 if (flag_next_runtime)
8207 encode_next_bitfield (size);
8208 else
8209 encode_gnu_bitfield (int_bit_position (field_decl),
8210 DECL_BIT_FIELD_TYPE (field_decl), size);
8212 else
8213 encode_type (TREE_TYPE (field_decl), curtype, format);
8216 static GTY(()) tree objc_parmlist = NULL_TREE;
8218 /* Append PARM to a list of formal parameters of a method, making a necessary
8219 array-to-pointer adjustment along the way. */
8221 static void
8222 objc_push_parm (tree parm)
8224 /* Decay arrays and functions into pointers. */
8225 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8226 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8227 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8228 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8230 DECL_ARG_TYPE (parm)
8231 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8233 /* Record constancy and volatility. */
8234 c_apply_type_quals_to_decl
8235 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8236 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8237 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8239 objc_parmlist = chainon (objc_parmlist, parm);
8242 /* Retrieve the formal parameter list constructed via preceding calls to
8243 objc_push_parm(). */
8245 #ifdef OBJCPLUS
8246 static tree
8247 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8248 #else
8249 static struct c_arg_info *
8250 objc_get_parm_info (int have_ellipsis)
8251 #endif
8253 #ifdef OBJCPLUS
8254 tree parm_info = objc_parmlist;
8255 objc_parmlist = NULL_TREE;
8257 return parm_info;
8258 #else
8259 tree parm_info = objc_parmlist;
8260 struct c_arg_info *arg_info;
8261 /* The C front-end requires an elaborate song and dance at
8262 this point. */
8263 push_scope ();
8264 declare_parm_level ();
8265 while (parm_info)
8267 tree next = TREE_CHAIN (parm_info);
8269 TREE_CHAIN (parm_info) = NULL_TREE;
8270 parm_info = pushdecl (parm_info);
8271 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8272 parm_info = next;
8274 arg_info = get_parm_info (have_ellipsis);
8275 pop_scope ();
8276 objc_parmlist = NULL_TREE;
8277 return arg_info;
8278 #endif
8281 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8282 method definitions. In the case of instance methods, we can be more
8283 specific as to the type of 'self'. */
8285 static void
8286 synth_self_and_ucmd_args (void)
8288 tree self_type;
8290 if (objc_method_context
8291 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8292 self_type = objc_instance_type;
8293 else
8294 /* Really a `struct objc_class *'. However, we allow people to
8295 assign to self, which changes its type midstream. */
8296 self_type = objc_object_type;
8298 /* id self; */
8299 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8301 /* SEL _cmd; */
8302 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8305 /* Transform an Objective-C method definition into a static C function
8306 definition, synthesizing the first two arguments, "self" and "_cmd",
8307 in the process. */
8309 static void
8310 start_method_def (tree method)
8312 tree parmlist;
8313 #ifdef OBJCPLUS
8314 tree parm_info;
8315 #else
8316 struct c_arg_info *parm_info;
8317 #endif
8318 int have_ellipsis = 0;
8320 /* If we are defining a "dealloc" method in a non-root class, we
8321 will need to check if a [super dealloc] is missing, and warn if
8322 it is. */
8323 if(CLASS_SUPER_NAME (objc_implementation_context)
8324 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8325 should_call_super_dealloc = 1;
8326 else
8327 should_call_super_dealloc = 0;
8329 /* Required to implement _msgSuper. */
8330 objc_method_context = method;
8331 UOBJC_SUPER_decl = NULL_TREE;
8333 /* Generate prototype declarations for arguments..."new-style". */
8334 synth_self_and_ucmd_args ();
8336 /* Generate argument declarations if a keyword_decl. */
8337 parmlist = METHOD_SEL_ARGS (method);
8338 while (parmlist)
8340 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8342 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8343 objc_push_parm (parm);
8344 parmlist = TREE_CHAIN (parmlist);
8347 if (METHOD_ADD_ARGS (method))
8349 tree akey;
8351 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8352 akey; akey = TREE_CHAIN (akey))
8354 objc_push_parm (TREE_VALUE (akey));
8357 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8358 have_ellipsis = 1;
8361 parm_info = objc_get_parm_info (have_ellipsis);
8363 really_start_method (objc_method_context, parm_info);
8366 static void
8367 warn_with_method (const char *message, int mtype, tree method)
8369 /* Add a readable method name to the warning. */
8370 warning (0, "%J%s %<%c%s%>", method,
8371 message, mtype, gen_method_decl (method));
8374 /* Return 1 if TYPE1 is equivalent to TYPE2
8375 for purposes of method overloading. */
8377 static int
8378 objc_types_are_equivalent (tree type1, tree type2)
8380 if (type1 == type2)
8381 return 1;
8383 /* Strip away indirections. */
8384 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8385 && (TREE_CODE (type1) == TREE_CODE (type2)))
8386 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8387 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8388 return 0;
8390 type1 = (TYPE_HAS_OBJC_INFO (type1)
8391 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8392 : NULL_TREE);
8393 type2 = (TYPE_HAS_OBJC_INFO (type2)
8394 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8395 : NULL_TREE);
8397 if (list_length (type1) == list_length (type2))
8399 for (; type2; type2 = TREE_CHAIN (type2))
8400 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8401 return 0;
8402 return 1;
8404 return 0;
8407 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8409 static int
8410 objc_types_share_size_and_alignment (tree type1, tree type2)
8412 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8413 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8416 /* Return 1 if PROTO1 is equivalent to PROTO2
8417 for purposes of method overloading. Ordinarily, the type signatures
8418 should match up exactly, unless STRICT is zero, in which case we
8419 shall allow differences in which the size and alignment of a type
8420 is the same. */
8422 static int
8423 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8425 tree type1, type2;
8427 /* The following test is needed in case there are hashing
8428 collisions. */
8429 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8430 return 0;
8432 /* Compare return types. */
8433 type1 = TREE_VALUE (TREE_TYPE (proto1));
8434 type2 = TREE_VALUE (TREE_TYPE (proto2));
8436 if (!objc_types_are_equivalent (type1, type2)
8437 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8438 return 0;
8440 /* Compare argument types. */
8441 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8442 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8443 type1 && type2;
8444 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8446 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8447 && (strict
8448 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8449 TREE_VALUE (type2))))
8450 return 0;
8453 return (!type1 && !type2);
8456 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8457 this occurs. ObjC method dispatches are _not_ like C++ virtual
8458 member function dispatches, and we account for the difference here. */
8459 tree
8460 #ifdef OBJCPLUS
8461 objc_fold_obj_type_ref (tree ref, tree known_type)
8462 #else
8463 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8464 tree known_type ATTRIBUTE_UNUSED)
8465 #endif
8467 #ifdef OBJCPLUS
8468 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8470 /* If the receiver does not have virtual member functions, there
8471 is nothing we can (or need to) do here. */
8472 if (!v)
8473 return NULL_TREE;
8475 /* Let C++ handle C++ virtual functions. */
8476 return cp_fold_obj_type_ref (ref, known_type);
8477 #else
8478 /* For plain ObjC, we currently do not need to do anything. */
8479 return NULL_TREE;
8480 #endif
8483 static void
8484 objc_start_function (tree name, tree type, tree attrs,
8485 #ifdef OBJCPLUS
8486 tree params
8487 #else
8488 struct c_arg_info *params
8489 #endif
8492 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8494 #ifdef OBJCPLUS
8495 DECL_ARGUMENTS (fndecl) = params;
8496 DECL_INITIAL (fndecl) = error_mark_node;
8497 DECL_EXTERNAL (fndecl) = 0;
8498 TREE_STATIC (fndecl) = 1;
8499 retrofit_lang_decl (fndecl);
8500 cplus_decl_attributes (&fndecl, attrs, 0);
8501 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8502 #else
8503 struct c_label_context_se *nstack_se;
8504 struct c_label_context_vm *nstack_vm;
8505 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8506 nstack_se->labels_def = NULL;
8507 nstack_se->labels_used = NULL;
8508 nstack_se->next = label_context_stack_se;
8509 label_context_stack_se = nstack_se;
8510 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8511 nstack_vm->labels_def = NULL;
8512 nstack_vm->labels_used = NULL;
8513 nstack_vm->scope = 0;
8514 nstack_vm->next = label_context_stack_vm;
8515 label_context_stack_vm = nstack_vm;
8516 current_function_returns_value = 0; /* Assume, until we see it does. */
8517 current_function_returns_null = 0;
8519 decl_attributes (&fndecl, attrs, 0);
8520 announce_function (fndecl);
8521 DECL_INITIAL (fndecl) = error_mark_node;
8522 DECL_EXTERNAL (fndecl) = 0;
8523 TREE_STATIC (fndecl) = 1;
8524 current_function_decl = pushdecl (fndecl);
8525 push_scope ();
8526 declare_parm_level ();
8527 DECL_RESULT (current_function_decl)
8528 = build_decl (RESULT_DECL, NULL_TREE,
8529 TREE_TYPE (TREE_TYPE (current_function_decl)));
8530 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8531 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8532 start_fname_decls ();
8533 store_parm_decls_from (params);
8534 #endif
8536 TREE_USED (current_function_decl) = 1;
8539 /* - Generate an identifier for the function. the format is "_n_cls",
8540 where 1 <= n <= nMethods, and cls is the name the implementation we
8541 are processing.
8542 - Install the return type from the method declaration.
8543 - If we have a prototype, check for type consistency. */
8545 static void
8546 really_start_method (tree method,
8547 #ifdef OBJCPLUS
8548 tree parmlist
8549 #else
8550 struct c_arg_info *parmlist
8551 #endif
8554 tree ret_type, meth_type;
8555 tree method_id;
8556 const char *sel_name, *class_name, *cat_name;
8557 char *buf;
8559 /* Synth the storage class & assemble the return type. */
8560 ret_type = TREE_VALUE (TREE_TYPE (method));
8562 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8563 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8564 cat_name = ((TREE_CODE (objc_implementation_context)
8565 == CLASS_IMPLEMENTATION_TYPE)
8566 ? NULL
8567 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8568 method_slot++;
8570 /* Make sure this is big enough for any plausible method label. */
8571 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8572 + (cat_name ? strlen (cat_name) : 0));
8574 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8575 class_name, cat_name, sel_name, method_slot);
8577 method_id = get_identifier (buf);
8579 #ifdef OBJCPLUS
8580 /* Objective-C methods cannot be overloaded, so we don't need
8581 the type encoding appended. It looks bad anyway... */
8582 push_lang_context (lang_name_c);
8583 #endif
8585 meth_type
8586 = build_function_type (ret_type,
8587 get_arg_type_list (method, METHOD_DEF, 0));
8588 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8590 /* Set self_decl from the first argument. */
8591 self_decl = DECL_ARGUMENTS (current_function_decl);
8593 /* Suppress unused warnings. */
8594 TREE_USED (self_decl) = 1;
8595 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8596 #ifdef OBJCPLUS
8597 pop_lang_context ();
8598 #endif
8600 METHOD_DEFINITION (method) = current_function_decl;
8602 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8604 if (implementation_template != objc_implementation_context)
8606 tree proto
8607 = lookup_method_static (implementation_template,
8608 METHOD_SEL_NAME (method),
8609 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8610 | OBJC_LOOKUP_NO_SUPER));
8612 if (proto)
8614 if (!comp_proto_with_proto (method, proto, 1))
8616 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8618 warn_with_method ("conflicting types for", type, method);
8619 warn_with_method ("previous declaration of", type, proto);
8622 else
8624 /* We have a method @implementation even though we did not
8625 see a corresponding @interface declaration (which is allowed
8626 by Objective-C rules). Go ahead and place the method in
8627 the @interface anyway, so that message dispatch lookups
8628 will see it. */
8629 tree interface = implementation_template;
8631 if (TREE_CODE (objc_implementation_context)
8632 == CATEGORY_IMPLEMENTATION_TYPE)
8633 interface = lookup_category
8634 (interface,
8635 CLASS_SUPER_NAME (objc_implementation_context));
8637 if (interface)
8638 objc_add_method (interface, copy_node (method),
8639 TREE_CODE (method) == CLASS_METHOD_DECL);
8644 static void *UOBJC_SUPER_scope = 0;
8646 /* _n_Method (id self, SEL sel, ...)
8648 struct objc_super _S;
8649 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8650 } */
8652 static tree
8653 get_super_receiver (void)
8655 if (objc_method_context)
8657 tree super_expr, super_expr_list;
8659 if (!UOBJC_SUPER_decl)
8661 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8662 objc_super_template);
8663 /* This prevents `unused variable' warnings when compiling with -Wall. */
8664 TREE_USED (UOBJC_SUPER_decl) = 1;
8665 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8666 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8667 UOBJC_SUPER_scope = objc_get_current_scope ();
8670 /* Set receiver to self. */
8671 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8672 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8673 super_expr_list = super_expr;
8675 /* Set class to begin searching. */
8676 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8677 get_identifier ("super_class"));
8679 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8681 /* [_cls, __cls]Super are "pre-built" in
8682 synth_forward_declarations. */
8684 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8685 ((TREE_CODE (objc_method_context)
8686 == INSTANCE_METHOD_DECL)
8687 ? ucls_super_ref
8688 : uucls_super_ref));
8691 else
8692 /* We have a category. */
8694 tree super_name = CLASS_SUPER_NAME (implementation_template);
8695 tree super_class;
8697 /* Barf if super used in a category of Object. */
8698 if (!super_name)
8700 error ("no super class declared in interface for %qs",
8701 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8702 return error_mark_node;
8705 if (flag_next_runtime && !flag_zero_link)
8707 super_class = objc_get_class_reference (super_name);
8708 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8709 /* If we are in a class method, we must retrieve the
8710 _metaclass_ for the current class, pointed at by
8711 the class's "isa" pointer. The following assumes that
8712 "isa" is the first ivar in a class (which it must be). */
8713 super_class
8714 = build_indirect_ref
8715 (build_c_cast (build_pointer_type (objc_class_type),
8716 super_class), "unary *");
8718 else
8720 add_class_reference (super_name);
8721 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8722 ? objc_get_class_decl : objc_get_meta_class_decl);
8723 assemble_external (super_class);
8724 super_class
8725 = build_function_call
8726 (super_class,
8727 build_tree_list
8728 (NULL_TREE,
8729 my_build_string_pointer
8730 (IDENTIFIER_LENGTH (super_name) + 1,
8731 IDENTIFIER_POINTER (super_name))));
8734 super_expr
8735 = build_modify_expr (super_expr, NOP_EXPR,
8736 build_c_cast (TREE_TYPE (super_expr),
8737 super_class));
8740 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8742 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8743 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8745 return super_expr_list;
8747 else
8749 error ("[super ...] must appear in a method context");
8750 return error_mark_node;
8754 /* When exiting a scope, sever links to a 'super' declaration (if any)
8755 therein contained. */
8757 void
8758 objc_clear_super_receiver (void)
8760 if (objc_method_context
8761 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8762 UOBJC_SUPER_decl = 0;
8763 UOBJC_SUPER_scope = 0;
8767 void
8768 objc_finish_method_definition (tree fndecl)
8770 /* We cannot validly inline ObjC methods, at least not without a language
8771 extension to declare that a method need not be dynamically
8772 dispatched, so suppress all thoughts of doing so. */
8773 DECL_INLINE (fndecl) = 0;
8774 DECL_UNINLINABLE (fndecl) = 1;
8776 #ifndef OBJCPLUS
8777 /* The C++ front-end will have called finish_function() for us. */
8778 finish_function ();
8779 #endif
8781 METHOD_ENCODING (objc_method_context)
8782 = encode_method_prototype (objc_method_context);
8784 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8785 since the optimizer may find "may be used before set" errors. */
8786 objc_method_context = NULL_TREE;
8788 if (should_call_super_dealloc)
8789 warning (0, "method possibly missing a [super dealloc] call");
8792 #if 0
8794 lang_report_error_function (tree decl)
8796 if (objc_method_context)
8798 fprintf (stderr, "In method %qs\n",
8799 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8800 return 1;
8803 else
8804 return 0;
8806 #endif
8808 /* Given a tree DECL node, produce a printable description of it in the given
8809 buffer, overwriting the buffer. */
8811 static char *
8812 gen_declaration (tree decl)
8814 errbuf[0] = '\0';
8816 if (DECL_P (decl))
8818 gen_type_name_0 (TREE_TYPE (decl));
8820 if (DECL_NAME (decl))
8822 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8823 strcat (errbuf, " ");
8825 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8828 if (DECL_INITIAL (decl)
8829 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8830 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8831 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8834 return errbuf;
8837 /* Given a tree TYPE node, produce a printable description of it in the given
8838 buffer, overwriting the buffer. */
8840 static char *
8841 gen_type_name_0 (tree type)
8843 tree orig = type, proto;
8845 if (TYPE_P (type) && TYPE_NAME (type))
8846 type = TYPE_NAME (type);
8847 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8849 tree inner = TREE_TYPE (type);
8851 while (TREE_CODE (inner) == ARRAY_TYPE)
8852 inner = TREE_TYPE (inner);
8854 gen_type_name_0 (inner);
8856 if (!POINTER_TYPE_P (inner))
8857 strcat (errbuf, " ");
8859 if (POINTER_TYPE_P (type))
8860 strcat (errbuf, "*");
8861 else
8862 while (type != inner)
8864 strcat (errbuf, "[");
8866 if (TYPE_DOMAIN (type))
8868 char sz[20];
8870 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8871 (TREE_INT_CST_LOW
8872 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8873 strcat (errbuf, sz);
8876 strcat (errbuf, "]");
8877 type = TREE_TYPE (type);
8880 goto exit_function;
8883 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8884 type = DECL_NAME (type);
8886 strcat (errbuf, IDENTIFIER_POINTER (type));
8888 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8889 if (objc_is_id (orig))
8890 orig = TREE_TYPE (orig);
8892 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8894 if (proto)
8896 strcat (errbuf, " <");
8898 while (proto) {
8899 strcat (errbuf,
8900 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8901 proto = TREE_CHAIN (proto);
8902 strcat (errbuf, proto ? ", " : ">");
8906 exit_function:
8907 return errbuf;
8910 static char *
8911 gen_type_name (tree type)
8913 errbuf[0] = '\0';
8915 return gen_type_name_0 (type);
8918 /* Given a method tree, put a printable description into the given
8919 buffer (overwriting) and return a pointer to the buffer. */
8921 static char *
8922 gen_method_decl (tree method)
8924 tree chain;
8926 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8927 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8928 strcat (errbuf, ")");
8929 chain = METHOD_SEL_ARGS (method);
8931 if (chain)
8933 /* We have a chain of keyword_decls. */
8936 if (KEYWORD_KEY_NAME (chain))
8937 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8939 strcat (errbuf, ":(");
8940 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8941 strcat (errbuf, ")");
8943 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8944 if ((chain = TREE_CHAIN (chain)))
8945 strcat (errbuf, " ");
8947 while (chain);
8949 if (METHOD_ADD_ARGS (method))
8951 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8953 /* Know we have a chain of parm_decls. */
8954 while (chain)
8956 strcat (errbuf, ", ");
8957 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8958 chain = TREE_CHAIN (chain);
8961 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8962 strcat (errbuf, ", ...");
8966 else
8967 /* We have a unary selector. */
8968 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8970 return errbuf;
8973 /* Debug info. */
8976 /* Dump an @interface declaration of the supplied class CHAIN to the
8977 supplied file FP. Used to implement the -gen-decls option (which
8978 prints out an @interface declaration of all classes compiled in
8979 this run); potentially useful for debugging the compiler too. */
8980 static void
8981 dump_interface (FILE *fp, tree chain)
8983 /* FIXME: A heap overflow here whenever a method (or ivar)
8984 declaration is so long that it doesn't fit in the buffer. The
8985 code and all the related functions should be rewritten to avoid
8986 using fixed size buffers. */
8987 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8988 tree ivar_decls = CLASS_RAW_IVARS (chain);
8989 tree nst_methods = CLASS_NST_METHODS (chain);
8990 tree cls_methods = CLASS_CLS_METHODS (chain);
8992 fprintf (fp, "\n@interface %s", my_name);
8994 /* CLASS_SUPER_NAME is used to store the superclass name for
8995 classes, and the category name for categories. */
8996 if (CLASS_SUPER_NAME (chain))
8998 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9000 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9001 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9003 fprintf (fp, " (%s)\n", name);
9005 else
9007 fprintf (fp, " : %s\n", name);
9010 else
9011 fprintf (fp, "\n");
9013 /* FIXME - the following doesn't seem to work at the moment. */
9014 if (ivar_decls)
9016 fprintf (fp, "{\n");
9019 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9020 ivar_decls = TREE_CHAIN (ivar_decls);
9022 while (ivar_decls);
9023 fprintf (fp, "}\n");
9026 while (nst_methods)
9028 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9029 nst_methods = TREE_CHAIN (nst_methods);
9032 while (cls_methods)
9034 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9035 cls_methods = TREE_CHAIN (cls_methods);
9038 fprintf (fp, "@end\n");
9041 /* Demangle function for Objective-C */
9042 static const char *
9043 objc_demangle (const char *mangled)
9045 char *demangled, *cp;
9047 if (mangled[0] == '_' &&
9048 (mangled[1] == 'i' || mangled[1] == 'c') &&
9049 mangled[2] == '_')
9051 cp = demangled = xmalloc(strlen(mangled) + 2);
9052 if (mangled[1] == 'i')
9053 *cp++ = '-'; /* for instance method */
9054 else
9055 *cp++ = '+'; /* for class method */
9056 *cp++ = '['; /* opening left brace */
9057 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9058 while (*cp && *cp == '_')
9059 cp++; /* skip any initial underbars in class name */
9060 cp = strchr(cp, '_'); /* find first non-initial underbar */
9061 if (cp == NULL)
9063 free(demangled); /* not mangled name */
9064 return mangled;
9066 if (cp[1] == '_') /* easy case: no category name */
9068 *cp++ = ' '; /* replace two '_' with one ' ' */
9069 strcpy(cp, mangled + (cp - demangled) + 2);
9071 else
9073 *cp++ = '('; /* less easy case: category name */
9074 cp = strchr(cp, '_');
9075 if (cp == 0)
9077 free(demangled); /* not mangled name */
9078 return mangled;
9080 *cp++ = ')';
9081 *cp++ = ' '; /* overwriting 1st char of method name... */
9082 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9084 while (*cp && *cp == '_')
9085 cp++; /* skip any initial underbars in method name */
9086 for (; *cp; cp++)
9087 if (*cp == '_')
9088 *cp = ':'; /* replace remaining '_' with ':' */
9089 *cp++ = ']'; /* closing right brace */
9090 *cp++ = 0; /* string terminator */
9091 return demangled;
9093 else
9094 return mangled; /* not an objc mangled name */
9097 const char *
9098 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9100 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9103 static void
9104 init_objc (void)
9106 gcc_obstack_init (&util_obstack);
9107 util_firstobj = (char *) obstack_finish (&util_obstack);
9109 errbuf = (char *) xmalloc (1024 * 10);
9110 hash_init ();
9111 synth_module_prologue ();
9114 static void
9115 finish_objc (void)
9117 struct imp_entry *impent;
9118 tree chain;
9119 /* The internally generated initializers appear to have missing braces.
9120 Don't warn about this. */
9121 int save_warn_missing_braces = warn_missing_braces;
9122 warn_missing_braces = 0;
9124 /* A missing @end may not be detected by the parser. */
9125 if (objc_implementation_context)
9127 warning (0, "%<@end%> missing in implementation context");
9128 finish_class (objc_implementation_context);
9129 objc_ivar_chain = NULL_TREE;
9130 objc_implementation_context = NULL_TREE;
9133 /* Process the static instances here because initialization of objc_symtab
9134 depends on them. */
9135 if (objc_static_instances)
9136 generate_static_references ();
9138 if (imp_list || class_names_chain
9139 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9140 generate_objc_symtab_decl ();
9142 for (impent = imp_list; impent; impent = impent->next)
9144 objc_implementation_context = impent->imp_context;
9145 implementation_template = impent->imp_template;
9147 UOBJC_CLASS_decl = impent->class_decl;
9148 UOBJC_METACLASS_decl = impent->meta_decl;
9150 /* Dump the @interface of each class as we compile it, if the
9151 -gen-decls option is in use. TODO: Dump the classes in the
9152 order they were found, rather than in reverse order as we
9153 are doing now. */
9154 if (flag_gen_declaration)
9156 dump_interface (gen_declaration_file, objc_implementation_context);
9159 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9161 /* all of the following reference the string pool... */
9162 generate_ivar_lists ();
9163 generate_dispatch_tables ();
9164 generate_shared_structures (impent->has_cxx_cdtors
9165 ? CLS_HAS_CXX_STRUCTORS
9166 : 0);
9168 else
9170 generate_dispatch_tables ();
9171 generate_category (objc_implementation_context);
9175 /* If we are using an array of selectors, we must always
9176 finish up the array decl even if no selectors were used. */
9177 if (! flag_next_runtime || sel_ref_chain)
9178 build_selector_translation_table ();
9180 if (protocol_chain)
9181 generate_protocols ();
9183 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9184 generate_objc_image_info ();
9186 /* Arrange for ObjC data structures to be initialized at run time. */
9187 if (objc_implementation_context || class_names_chain || objc_static_instances
9188 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9190 build_module_descriptor ();
9192 if (!flag_next_runtime)
9193 build_module_initializer_routine ();
9196 /* Dump the class references. This forces the appropriate classes
9197 to be linked into the executable image, preserving unix archive
9198 semantics. This can be removed when we move to a more dynamically
9199 linked environment. */
9201 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9203 handle_class_ref (chain);
9204 if (TREE_PURPOSE (chain))
9205 generate_classref_translation_entry (chain);
9208 for (impent = imp_list; impent; impent = impent->next)
9209 handle_impent (impent);
9211 if (warn_selector)
9213 int slot;
9214 hash hsh;
9216 /* Run through the selector hash tables and print a warning for any
9217 selector which has multiple methods. */
9219 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9221 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9222 check_duplicates (hsh, 0, 1);
9223 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9224 check_duplicates (hsh, 0, 1);
9228 warn_missing_braces = save_warn_missing_braces;
9231 /* Subroutines of finish_objc. */
9233 static void
9234 generate_classref_translation_entry (tree chain)
9236 tree expr, decl, type;
9238 decl = TREE_PURPOSE (chain);
9239 type = TREE_TYPE (decl);
9241 expr = add_objc_string (TREE_VALUE (chain), class_names);
9242 expr = convert (type, expr); /* cast! */
9244 /* The decl that is the one that we
9245 forward declared in build_class_reference. */
9246 finish_var_decl (decl, expr);
9247 return;
9250 static void
9251 handle_class_ref (tree chain)
9253 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9254 char *string = (char *) alloca (strlen (name) + 30);
9255 tree decl;
9256 tree exp;
9258 sprintf (string, "%sobjc_class_name_%s",
9259 (flag_next_runtime ? "." : "__"), name);
9261 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9262 if (flag_next_runtime)
9264 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9265 return;
9267 #endif
9269 /* Make a decl for this name, so we can use its address in a tree. */
9270 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9271 DECL_EXTERNAL (decl) = 1;
9272 TREE_PUBLIC (decl) = 1;
9274 pushdecl (decl);
9275 rest_of_decl_compilation (decl, 0, 0);
9277 /* Make a decl for the address. */
9278 sprintf (string, "%sobjc_class_ref_%s",
9279 (flag_next_runtime ? "." : "__"), name);
9280 exp = build1 (ADDR_EXPR, string_type_node, decl);
9281 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9282 DECL_INITIAL (decl) = exp;
9283 TREE_STATIC (decl) = 1;
9284 TREE_USED (decl) = 1;
9285 /* Force the output of the decl as this forces the reference of the class. */
9286 mark_decl_referenced (decl);
9288 pushdecl (decl);
9289 rest_of_decl_compilation (decl, 0, 0);
9292 static void
9293 handle_impent (struct imp_entry *impent)
9295 char *string;
9297 objc_implementation_context = impent->imp_context;
9298 implementation_template = impent->imp_template;
9300 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9302 const char *const class_name =
9303 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9305 string = (char *) alloca (strlen (class_name) + 30);
9307 sprintf (string, "%sobjc_class_name_%s",
9308 (flag_next_runtime ? "." : "__"), class_name);
9310 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9312 const char *const class_name =
9313 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9314 const char *const class_super_name =
9315 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9317 string = (char *) alloca (strlen (class_name)
9318 + strlen (class_super_name) + 30);
9320 /* Do the same for categories. Even though no references to
9321 these symbols are generated automatically by the compiler, it
9322 gives you a handle to pull them into an archive by hand. */
9323 sprintf (string, "*%sobjc_category_name_%s_%s",
9324 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9326 else
9327 return;
9329 #ifdef ASM_DECLARE_CLASS_REFERENCE
9330 if (flag_next_runtime)
9332 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9333 return;
9335 else
9336 #endif
9338 tree decl, init;
9340 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9341 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9342 TREE_PUBLIC (decl) = 1;
9343 TREE_READONLY (decl) = 1;
9344 TREE_USED (decl) = 1;
9345 TREE_CONSTANT (decl) = 1;
9346 DECL_CONTEXT (decl) = 0;
9347 DECL_ARTIFICIAL (decl) = 1;
9348 DECL_INITIAL (decl) = init;
9349 assemble_variable (decl, 1, 0, 0);
9353 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9354 later requires that ObjC translation units participating in F&C be
9355 specially marked. The following routine accomplishes this. */
9357 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9359 static void
9360 generate_objc_image_info (void)
9362 tree decl, initlist;
9363 int flags
9364 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9365 | (flag_objc_gc ? 2 : 0));
9367 decl = start_var_decl (build_array_type
9368 (integer_type_node,
9369 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9370 "_OBJC_IMAGE_INFO");
9372 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9373 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9374 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9376 finish_var_decl (decl, initlist);
9379 /* Look up ID as an instance variable. OTHER contains the result of
9380 the C or C++ lookup, which we may want to use instead. */
9382 tree
9383 objc_lookup_ivar (tree other, tree id)
9385 tree ivar;
9387 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9388 if (!objc_method_context)
9389 return other;
9391 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9392 /* We have a message to super. */
9393 return get_super_receiver ();
9395 /* In a class method, look up an instance variable only as a last
9396 resort. */
9397 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9398 && other && other != error_mark_node)
9399 return other;
9401 /* Look up the ivar, but do not use it if it is not accessible. */
9402 ivar = is_ivar (objc_ivar_chain, id);
9404 if (!ivar || is_private (ivar))
9405 return other;
9407 /* In an instance method, a local variable (or parameter) may hide the
9408 instance variable. */
9409 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9410 && other && other != error_mark_node
9411 #ifdef OBJCPLUS
9412 && CP_DECL_CONTEXT (other) != global_namespace)
9413 #else
9414 && !DECL_FILE_SCOPE_P (other))
9415 #endif
9417 warning (0, "local declaration of %qs hides instance variable",
9418 IDENTIFIER_POINTER (id));
9420 return other;
9423 /* At this point, we are either in an instance method with no obscuring
9424 local definitions, or in a class method with no alternate definitions
9425 at all. */
9426 return build_ivar_reference (id);
9429 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9430 needs to be done if we are calling a function through a cast. */
9432 tree
9433 objc_rewrite_function_call (tree function, tree params)
9435 if (TREE_CODE (function) == NOP_EXPR
9436 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9437 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9438 == FUNCTION_DECL)
9440 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9441 TREE_OPERAND (function, 0),
9442 TREE_VALUE (params), size_zero_node);
9445 return function;
9448 /* Look for the special case of OBJC_TYPE_REF with the address of
9449 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9450 of its cousins). */
9452 enum gimplify_status
9453 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9455 enum gimplify_status r0, r1;
9456 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9457 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9458 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9459 == FUNCTION_DECL)
9461 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9462 value of the OBJ_TYPE_REF, so force them to be emitted
9463 during subexpression evaluation rather than after the
9464 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9465 C to use direct rather than indirect calls when the
9466 object expression has a postincrement. */
9467 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9468 is_gimple_val, fb_rvalue);
9469 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9470 is_gimple_val, fb_rvalue);
9472 return MIN (r0, r1);
9475 #ifdef OBJCPLUS
9476 return cp_gimplify_expr (expr_p, pre_p, post_p);
9477 #else
9478 return c_gimplify_expr (expr_p, pre_p, post_p);
9479 #endif
9482 /* Given a CALL expression, find the function being called. The ObjC
9483 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9485 tree
9486 objc_get_callee_fndecl (tree call_expr)
9488 tree addr = TREE_OPERAND (call_expr, 0);
9489 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9490 return 0;
9492 addr = OBJ_TYPE_REF_EXPR (addr);
9494 /* If the address is just `&f' for some function `f', then we know
9495 that `f' is being called. */
9496 if (TREE_CODE (addr) == ADDR_EXPR
9497 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9498 return TREE_OPERAND (addr, 0);
9500 return 0;
9503 #include "gt-objc-objc-act.h"