* Make-lang.in (cp/pt.o): Depend on vecprim.h.
[official-gcc.git] / gcc / objc / objc-act.c
bloba90c0614b5e8cec53484c350a6f0b1d6a8caaee5
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 /* Don't provide any file name for security reasons. */
2258 /* name = { ..., "", ... } */
2260 expr = add_objc_string (get_identifier (""), class_names);
2261 initlist = tree_cons (NULL_TREE, expr, initlist);
2263 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2265 if (UOBJC_SYMBOLS_decl)
2266 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2267 else
2268 expr = build_int_cst (NULL_TREE, 0);
2269 initlist = tree_cons (NULL_TREE, expr, initlist);
2271 return objc_build_constructor (type, nreverse (initlist));
2274 /* Write out the data structures to describe Objective C classes defined.
2276 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2278 static void
2279 build_module_descriptor (void)
2281 tree field_decl, field_decl_chain;
2283 #ifdef OBJCPLUS
2284 push_lang_context (lang_name_c); /* extern "C" */
2285 #endif
2287 objc_module_template
2288 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2290 /* long version; */
2291 field_decl = create_field_decl (long_integer_type_node, "version");
2292 field_decl_chain = field_decl;
2294 /* long size; */
2295 field_decl = create_field_decl (long_integer_type_node, "size");
2296 chainon (field_decl_chain, field_decl);
2298 /* char *name; */
2299 field_decl = create_field_decl (string_type_node, "name");
2300 chainon (field_decl_chain, field_decl);
2302 /* struct _objc_symtab *symtab; */
2303 field_decl
2304 = create_field_decl (build_pointer_type
2305 (xref_tag (RECORD_TYPE,
2306 get_identifier (UTAG_SYMTAB))),
2307 "symtab");
2308 chainon (field_decl_chain, field_decl);
2310 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2312 /* Create an instance of "_objc_module". */
2313 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2314 finish_var_decl (UOBJC_MODULES_decl,
2315 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2317 #ifdef OBJCPLUS
2318 pop_lang_context ();
2319 #endif
2322 /* The GNU runtime requires us to provide a static initializer function
2323 for each module:
2325 static void __objc_gnu_init (void) {
2326 __objc_exec_class (&L_OBJC_MODULES);
2327 } */
2329 static void
2330 build_module_initializer_routine (void)
2332 tree body;
2334 #ifdef OBJCPLUS
2335 push_lang_context (lang_name_c); /* extern "C" */
2336 #endif
2338 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2339 objc_start_function (get_identifier (TAG_GNUINIT),
2340 build_function_type (void_type_node,
2341 OBJC_VOID_AT_END),
2342 NULL_TREE, objc_get_parm_info (0));
2344 body = c_begin_compound_stmt (true);
2345 add_stmt (build_function_call
2346 (execclass_decl,
2347 build_tree_list
2348 (NULL_TREE,
2349 build_unary_op (ADDR_EXPR,
2350 UOBJC_MODULES_decl, 0))));
2351 add_stmt (c_end_compound_stmt (body, true));
2353 TREE_PUBLIC (current_function_decl) = 0;
2355 #ifndef OBJCPLUS
2356 /* For Objective-C++, we will need to call __objc_gnu_init
2357 from objc_generate_static_init_call() below. */
2358 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2359 #endif
2361 GNU_INIT_decl = current_function_decl;
2362 finish_function ();
2364 #ifdef OBJCPLUS
2365 pop_lang_context ();
2366 #endif
2369 #ifdef OBJCPLUS
2370 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2371 to be called by the module initializer routine. */
2374 objc_static_init_needed_p (void)
2376 return (GNU_INIT_decl != NULL_TREE);
2379 /* Generate a call to the __objc_gnu_init initializer function. */
2381 tree
2382 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2384 add_stmt (build_stmt (EXPR_STMT,
2385 build_function_call (GNU_INIT_decl, NULL_TREE)));
2387 return ctors;
2389 #endif /* OBJCPLUS */
2391 /* Return the DECL of the string IDENT in the SECTION. */
2393 static tree
2394 get_objc_string_decl (tree ident, enum string_section section)
2396 tree chain;
2398 if (section == class_names)
2399 chain = class_names_chain;
2400 else if (section == meth_var_names)
2401 chain = meth_var_names_chain;
2402 else if (section == meth_var_types)
2403 chain = meth_var_types_chain;
2404 else
2405 abort ();
2407 for (; chain != 0; chain = TREE_CHAIN (chain))
2408 if (TREE_VALUE (chain) == ident)
2409 return (TREE_PURPOSE (chain));
2411 abort ();
2412 return NULL_TREE;
2415 /* Output references to all statically allocated objects. Return the DECL
2416 for the array built. */
2418 static void
2419 generate_static_references (void)
2421 tree decls = NULL_TREE, expr = NULL_TREE;
2422 tree class_name, class, decl, initlist;
2423 tree cl_chain, in_chain, type
2424 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2425 int num_inst, num_class;
2426 char buf[256];
2428 if (flag_next_runtime)
2429 abort ();
2431 for (cl_chain = objc_static_instances, num_class = 0;
2432 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2434 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2435 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2437 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2438 decl = start_var_decl (type, buf);
2440 /* Output {class_name, ...}. */
2441 class = TREE_VALUE (cl_chain);
2442 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2443 initlist = build_tree_list (NULL_TREE,
2444 build_unary_op (ADDR_EXPR, class_name, 1));
2446 /* Output {..., instance, ...}. */
2447 for (in_chain = TREE_PURPOSE (cl_chain);
2448 in_chain; in_chain = TREE_CHAIN (in_chain))
2450 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2451 initlist = tree_cons (NULL_TREE, expr, initlist);
2454 /* Output {..., NULL}. */
2455 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2457 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2458 finish_var_decl (decl, expr);
2459 decls
2460 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2463 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2464 expr = objc_build_constructor (type, nreverse (decls));
2465 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2466 finish_var_decl (static_instances_decl, expr);
2469 static GTY(()) int selector_reference_idx;
2471 static tree
2472 build_selector_reference_decl (void)
2474 tree decl;
2475 char buf[256];
2477 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2478 decl = start_var_decl (objc_selector_type, buf);
2480 return decl;
2483 static void
2484 build_selector_table_decl (void)
2486 tree temp;
2488 if (flag_typed_selectors)
2490 build_selector_template ();
2491 temp = build_array_type (objc_selector_template, NULL_TREE);
2493 else
2494 temp = build_array_type (objc_selector_type, NULL_TREE);
2496 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2499 /* Just a handy wrapper for add_objc_string. */
2501 static tree
2502 build_selector (tree ident)
2504 return convert (objc_selector_type,
2505 add_objc_string (ident, meth_var_names));
2508 static void
2509 build_selector_translation_table (void)
2511 tree chain, initlist = NULL_TREE;
2512 int offset = 0;
2513 tree decl = NULL_TREE;
2515 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2517 tree expr;
2519 if (warn_selector && objc_implementation_context)
2521 tree method_chain;
2522 bool found = false;
2523 for (method_chain = meth_var_names_chain;
2524 method_chain;
2525 method_chain = TREE_CHAIN (method_chain))
2527 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2529 found = true;
2530 break;
2533 if (!found)
2535 location_t *loc;
2536 if (flag_next_runtime && TREE_PURPOSE (chain))
2537 loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2538 else
2539 loc = &input_location;
2540 warning (0, "%Hcreating selector for nonexistent method %qE",
2541 loc, TREE_VALUE (chain));
2545 expr = build_selector (TREE_VALUE (chain));
2546 /* add one for the '\0' character */
2547 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2549 if (flag_next_runtime)
2551 decl = TREE_PURPOSE (chain);
2552 finish_var_decl (decl, expr);
2554 else
2556 if (flag_typed_selectors)
2558 tree eltlist = NULL_TREE;
2559 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2560 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2561 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2562 expr = objc_build_constructor (objc_selector_template,
2563 nreverse (eltlist));
2566 initlist = tree_cons (NULL_TREE, expr, initlist);
2570 if (! flag_next_runtime)
2572 /* Cause the selector table (previously forward-declared)
2573 to be actually output. */
2574 initlist = tree_cons (NULL_TREE,
2575 flag_typed_selectors
2576 ? objc_build_constructor
2577 (objc_selector_template,
2578 tree_cons (NULL_TREE,
2579 build_int_cst (NULL_TREE, 0),
2580 tree_cons (NULL_TREE,
2581 build_int_cst (NULL_TREE, 0),
2582 NULL_TREE)))
2583 : build_int_cst (NULL_TREE, 0), initlist);
2584 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2585 nreverse (initlist));
2586 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2590 static tree
2591 get_proto_encoding (tree proto)
2593 tree encoding;
2594 if (proto)
2596 if (! METHOD_ENCODING (proto))
2598 encoding = encode_method_prototype (proto);
2599 METHOD_ENCODING (proto) = encoding;
2601 else
2602 encoding = METHOD_ENCODING (proto);
2604 return add_objc_string (encoding, meth_var_types);
2606 else
2607 return build_int_cst (NULL_TREE, 0);
2610 /* sel_ref_chain is a list whose "value" fields will be instances of
2611 identifier_node that represent the selector. */
2613 static tree
2614 build_typed_selector_reference (tree ident, tree prototype)
2616 tree *chain = &sel_ref_chain;
2617 tree expr;
2618 int index = 0;
2620 while (*chain)
2622 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2623 goto return_at_index;
2625 index++;
2626 chain = &TREE_CHAIN (*chain);
2629 *chain = tree_cons (prototype, ident, NULL_TREE);
2631 return_at_index:
2632 expr = build_unary_op (ADDR_EXPR,
2633 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2634 build_int_cst (NULL_TREE, index)),
2636 return convert (objc_selector_type, expr);
2639 static tree
2640 build_selector_reference (tree ident)
2642 tree *chain = &sel_ref_chain;
2643 tree expr;
2644 int index = 0;
2646 while (*chain)
2648 if (TREE_VALUE (*chain) == ident)
2649 return (flag_next_runtime
2650 ? TREE_PURPOSE (*chain)
2651 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2652 build_int_cst (NULL_TREE, index)));
2654 index++;
2655 chain = &TREE_CHAIN (*chain);
2658 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2660 *chain = tree_cons (expr, ident, NULL_TREE);
2662 return (flag_next_runtime
2663 ? expr
2664 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2665 build_int_cst (NULL_TREE, index)));
2668 static GTY(()) int class_reference_idx;
2670 static tree
2671 build_class_reference_decl (void)
2673 tree decl;
2674 char buf[256];
2676 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2677 decl = start_var_decl (objc_class_type, buf);
2679 return decl;
2682 /* Create a class reference, but don't create a variable to reference
2683 it. */
2685 static void
2686 add_class_reference (tree ident)
2688 tree chain;
2690 if ((chain = cls_ref_chain))
2692 tree tail;
2695 if (ident == TREE_VALUE (chain))
2696 return;
2698 tail = chain;
2699 chain = TREE_CHAIN (chain);
2701 while (chain);
2703 /* Append to the end of the list */
2704 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2706 else
2707 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2710 /* Get a class reference, creating it if necessary. Also create the
2711 reference variable. */
2713 tree
2714 objc_get_class_reference (tree ident)
2716 tree orig_ident = (DECL_P (ident)
2717 ? DECL_NAME (ident)
2718 : TYPE_P (ident)
2719 ? OBJC_TYPE_NAME (ident)
2720 : ident);
2721 bool local_scope = false;
2723 #ifdef OBJCPLUS
2724 if (processing_template_decl)
2725 /* Must wait until template instantiation time. */
2726 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2727 #endif
2729 if (TREE_CODE (ident) == TYPE_DECL)
2730 ident = (DECL_ORIGINAL_TYPE (ident)
2731 ? DECL_ORIGINAL_TYPE (ident)
2732 : TREE_TYPE (ident));
2734 #ifdef OBJCPLUS
2735 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2736 && TYPE_CONTEXT (ident) != global_namespace)
2737 local_scope = true;
2738 #endif
2740 if (local_scope || !(ident = objc_is_class_name (ident)))
2742 error ("%qs is not an Objective-C class name or alias",
2743 IDENTIFIER_POINTER (orig_ident));
2744 return error_mark_node;
2747 if (flag_next_runtime && !flag_zero_link)
2749 tree *chain;
2750 tree decl;
2752 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2753 if (TREE_VALUE (*chain) == ident)
2755 if (! TREE_PURPOSE (*chain))
2756 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2758 return TREE_PURPOSE (*chain);
2761 decl = build_class_reference_decl ();
2762 *chain = tree_cons (decl, ident, NULL_TREE);
2763 return decl;
2765 else
2767 tree params;
2769 add_class_reference (ident);
2771 params = build_tree_list (NULL_TREE,
2772 my_build_string_pointer
2773 (IDENTIFIER_LENGTH (ident) + 1,
2774 IDENTIFIER_POINTER (ident)));
2776 assemble_external (objc_get_class_decl);
2777 return build_function_call (objc_get_class_decl, params);
2781 /* For each string section we have a chain which maps identifier nodes
2782 to decls for the strings. */
2784 static tree
2785 add_objc_string (tree ident, enum string_section section)
2787 tree *chain, decl, type, string_expr;
2789 if (section == class_names)
2790 chain = &class_names_chain;
2791 else if (section == meth_var_names)
2792 chain = &meth_var_names_chain;
2793 else if (section == meth_var_types)
2794 chain = &meth_var_types_chain;
2795 else
2796 abort ();
2798 while (*chain)
2800 if (TREE_VALUE (*chain) == ident)
2801 return convert (string_type_node,
2802 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2804 chain = &TREE_CHAIN (*chain);
2807 decl = build_objc_string_decl (section);
2809 type = build_array_type
2810 (char_type_node,
2811 build_index_type
2812 (build_int_cst (NULL_TREE,
2813 IDENTIFIER_LENGTH (ident))));
2814 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2815 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2816 IDENTIFIER_POINTER (ident));
2817 finish_var_decl (decl, string_expr);
2819 *chain = tree_cons (decl, ident, NULL_TREE);
2821 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2824 static GTY(()) int class_names_idx;
2825 static GTY(()) int meth_var_names_idx;
2826 static GTY(()) int meth_var_types_idx;
2828 static tree
2829 build_objc_string_decl (enum string_section section)
2831 tree decl, ident;
2832 char buf[256];
2834 if (section == class_names)
2835 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2836 else if (section == meth_var_names)
2837 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2838 else if (section == meth_var_types)
2839 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2841 ident = get_identifier (buf);
2843 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2844 DECL_EXTERNAL (decl) = 1;
2845 TREE_PUBLIC (decl) = 0;
2846 TREE_USED (decl) = 1;
2847 TREE_CONSTANT (decl) = 1;
2848 DECL_CONTEXT (decl) = 0;
2849 DECL_ARTIFICIAL (decl) = 1;
2850 #ifdef OBJCPLUS
2851 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2852 #endif
2854 make_decl_rtl (decl);
2855 pushdecl_top_level (decl);
2857 return decl;
2861 void
2862 objc_declare_alias (tree alias_ident, tree class_ident)
2864 tree underlying_class;
2866 #ifdef OBJCPLUS
2867 if (current_namespace != global_namespace) {
2868 error ("Objective-C declarations may only appear in global scope");
2870 #endif /* OBJCPLUS */
2872 if (!(underlying_class = objc_is_class_name (class_ident)))
2873 warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
2874 else if (objc_is_class_name (alias_ident))
2875 warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
2876 else
2878 /* Implement @compatibility_alias as a typedef. */
2879 #ifdef OBJCPLUS
2880 push_lang_context (lang_name_c); /* extern "C" */
2881 #endif
2882 lang_hooks.decls.pushdecl (build_decl
2883 (TYPE_DECL,
2884 alias_ident,
2885 xref_tag (RECORD_TYPE, underlying_class)));
2886 #ifdef OBJCPLUS
2887 pop_lang_context ();
2888 #endif
2889 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2893 void
2894 objc_declare_class (tree ident_list)
2896 tree list;
2897 #ifdef OBJCPLUS
2898 if (current_namespace != global_namespace) {
2899 error ("Objective-C declarations may only appear in global scope");
2901 #endif /* OBJCPLUS */
2903 for (list = ident_list; list; list = TREE_CHAIN (list))
2905 tree ident = TREE_VALUE (list);
2907 if (! objc_is_class_name (ident))
2909 tree record = lookup_name (ident), type = record;
2911 if (record)
2913 if (TREE_CODE (record) == TYPE_DECL)
2914 type = DECL_ORIGINAL_TYPE (record);
2916 if (!TYPE_HAS_OBJC_INFO (type)
2917 || !TYPE_OBJC_INTERFACE (type))
2919 error ("%qs redeclared as different kind of symbol",
2920 IDENTIFIER_POINTER (ident));
2921 error ("previous declaration of %q+D",
2922 record);
2926 record = xref_tag (RECORD_TYPE, ident);
2927 INIT_TYPE_OBJC_INFO (record);
2928 TYPE_OBJC_INTERFACE (record) = ident;
2929 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2934 tree
2935 objc_is_class_name (tree ident)
2937 tree chain;
2939 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2940 && identifier_global_value (ident))
2941 ident = identifier_global_value (ident);
2942 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2943 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2945 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2946 ident = OBJC_TYPE_NAME (ident);
2947 #ifdef OBJCPLUS
2948 if (ident && TREE_CODE (ident) == TYPE_DECL)
2949 ident = DECL_NAME (ident);
2950 #endif
2951 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2952 return NULL_TREE;
2954 if (lookup_interface (ident))
2955 return ident;
2957 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2959 if (ident == TREE_VALUE (chain))
2960 return ident;
2963 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2965 if (ident == TREE_VALUE (chain))
2966 return TREE_PURPOSE (chain);
2969 return 0;
2972 /* Check whether TYPE is either 'id' or 'Class'. */
2974 tree
2975 objc_is_id (tree type)
2977 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2978 && identifier_global_value (type))
2979 type = identifier_global_value (type);
2981 if (type && TREE_CODE (type) == TYPE_DECL)
2982 type = TREE_TYPE (type);
2984 /* NB: This function may be called before the ObjC front-end has
2985 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2986 return (objc_object_type && type
2987 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2988 ? type
2989 : NULL_TREE);
2992 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2993 class instance. This is needed by other parts of the compiler to
2994 handle ObjC types gracefully. */
2996 tree
2997 objc_is_object_ptr (tree type)
2999 tree ret;
3001 type = TYPE_MAIN_VARIANT (type);
3002 if (!POINTER_TYPE_P (type))
3003 return 0;
3005 ret = objc_is_id (type);
3006 if (!ret)
3007 ret = objc_is_class_name (TREE_TYPE (type));
3009 return ret;
3012 static int
3013 objc_is_gcable_type (tree type, int or_strong_p)
3015 tree name;
3017 if (!TYPE_P (type))
3018 return 0;
3019 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3020 return 1;
3021 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3022 return 1;
3023 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3024 return 0;
3025 type = TREE_TYPE (type);
3026 if (TREE_CODE (type) != RECORD_TYPE)
3027 return 0;
3028 name = TYPE_NAME (type);
3029 return (objc_is_class_name (name) != NULL_TREE);
3032 static tree
3033 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3035 if (expr == oldexpr)
3036 return newexpr;
3038 switch (TREE_CODE (expr))
3040 case COMPONENT_REF:
3041 return objc_build_component_ref
3042 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3043 oldexpr,
3044 newexpr),
3045 DECL_NAME (TREE_OPERAND (expr, 1)));
3046 case ARRAY_REF:
3047 return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3048 oldexpr,
3049 newexpr),
3050 TREE_OPERAND (expr, 1));
3051 case INDIRECT_REF:
3052 return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
3053 oldexpr,
3054 newexpr), "->");
3055 default:
3056 return expr;
3060 static tree
3061 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3063 tree func_params;
3064 /* The LHS parameter contains the expression 'outervar->memberspec';
3065 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3066 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3068 tree offs
3069 = objc_substitute_decl
3070 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3071 tree func
3072 = (flag_objc_direct_dispatch
3073 ? objc_assign_ivar_fast_decl
3074 : objc_assign_ivar_decl);
3076 offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
3077 offs = fold (offs);
3078 func_params = tree_cons (NULL_TREE,
3079 convert (objc_object_type, rhs),
3080 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3081 tree_cons (NULL_TREE, offs,
3082 NULL_TREE)));
3084 assemble_external (func);
3085 return build_function_call (func, func_params);
3088 static tree
3089 objc_build_global_assignment (tree lhs, tree rhs)
3091 tree func_params = tree_cons (NULL_TREE,
3092 convert (objc_object_type, rhs),
3093 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3094 build_unary_op (ADDR_EXPR, lhs, 0)),
3095 NULL_TREE));
3097 assemble_external (objc_assign_global_decl);
3098 return build_function_call (objc_assign_global_decl, func_params);
3101 static tree
3102 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3104 tree func_params = tree_cons (NULL_TREE,
3105 convert (objc_object_type, rhs),
3106 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3107 build_unary_op (ADDR_EXPR, lhs, 0)),
3108 NULL_TREE));
3110 assemble_external (objc_assign_strong_cast_decl);
3111 return build_function_call (objc_assign_strong_cast_decl, func_params);
3114 static int
3115 objc_is_gcable_p (tree expr)
3117 return (TREE_CODE (expr) == COMPONENT_REF
3118 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3119 : TREE_CODE (expr) == ARRAY_REF
3120 ? (objc_is_gcable_p (TREE_TYPE (expr))
3121 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3122 : TREE_CODE (expr) == ARRAY_TYPE
3123 ? objc_is_gcable_p (TREE_TYPE (expr))
3124 : TYPE_P (expr)
3125 ? objc_is_gcable_type (expr, 1)
3126 : (objc_is_gcable_p (TREE_TYPE (expr))
3127 || (DECL_P (expr)
3128 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3131 static int
3132 objc_is_ivar_reference_p (tree expr)
3134 return (TREE_CODE (expr) == ARRAY_REF
3135 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3136 : TREE_CODE (expr) == COMPONENT_REF
3137 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3138 : 0);
3141 static int
3142 objc_is_global_reference_p (tree expr)
3144 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3145 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3146 : DECL_P (expr)
3147 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3148 : 0);
3151 tree
3152 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3154 tree result = NULL_TREE, outer;
3155 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3157 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3158 will have been transformed to the form '*(type *)&expr'. */
3159 if (TREE_CODE (lhs) == INDIRECT_REF)
3161 outer = TREE_OPERAND (lhs, 0);
3163 while (!strong_cast_p
3164 && (TREE_CODE (outer) == CONVERT_EXPR
3165 || TREE_CODE (outer) == NOP_EXPR
3166 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3168 tree lhstype = TREE_TYPE (outer);
3170 /* Descend down the cast chain, and record the first objc_gc
3171 attribute found. */
3172 if (POINTER_TYPE_P (lhstype))
3174 tree attr
3175 = lookup_attribute ("objc_gc",
3176 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3178 if (attr)
3179 strong_cast_p = 1;
3182 outer = TREE_OPERAND (outer, 0);
3186 /* If we have a __strong cast, it trumps all else. */
3187 if (strong_cast_p)
3189 if (modifycode != NOP_EXPR)
3190 goto invalid_pointer_arithmetic;
3192 if (warn_assign_intercept)
3193 warning (0, "strong-cast assignment has been intercepted");
3195 result = objc_build_strong_cast_assignment (lhs, rhs);
3197 goto exit_point;
3200 /* the lhs must be of a suitable type, regardless of its underlying
3201 structure. */
3202 if (!objc_is_gcable_p (lhs))
3203 goto exit_point;
3205 outer = lhs;
3207 while (outer
3208 && (TREE_CODE (outer) == COMPONENT_REF
3209 || TREE_CODE (outer) == ARRAY_REF))
3210 outer = TREE_OPERAND (outer, 0);
3212 if (TREE_CODE (outer) == INDIRECT_REF)
3214 outer = TREE_OPERAND (outer, 0);
3215 indirect_p = 1;
3218 outer_gc_p = objc_is_gcable_p (outer);
3220 /* Handle ivar assignments. */
3221 if (objc_is_ivar_reference_p (lhs))
3223 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3224 doesn't cut it here), the best we can do here is suggest a cast. */
3225 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3227 /* We may still be able to use the global write barrier... */
3228 if (!indirect_p && objc_is_global_reference_p (outer))
3229 goto global_reference;
3231 suggest_cast:
3232 if (modifycode == NOP_EXPR)
3234 if (warn_assign_intercept)
3235 warning (0, "strong-cast may possibly be needed");
3238 goto exit_point;
3241 if (modifycode != NOP_EXPR)
3242 goto invalid_pointer_arithmetic;
3244 if (warn_assign_intercept)
3245 warning (0, "instance variable assignment has been intercepted");
3247 result = objc_build_ivar_assignment (outer, lhs, rhs);
3249 goto exit_point;
3252 /* Likewise, intercept assignment to global/static variables if their type is
3253 GC-marked. */
3254 if (objc_is_global_reference_p (outer))
3256 if (indirect_p)
3257 goto suggest_cast;
3259 global_reference:
3260 if (modifycode != NOP_EXPR)
3262 invalid_pointer_arithmetic:
3263 if (outer_gc_p)
3264 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3266 goto exit_point;
3269 if (warn_assign_intercept)
3270 warning (0, "global/static variable assignment has been intercepted");
3272 result = objc_build_global_assignment (lhs, rhs);
3275 /* In all other cases, fall back to the normal mechanism. */
3276 exit_point:
3277 return result;
3280 struct interface_tuple GTY(())
3282 tree id;
3283 tree class_name;
3286 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3288 static hashval_t
3289 hash_interface (const void *p)
3291 const struct interface_tuple *d = p;
3292 return htab_hash_pointer (d->id);
3295 static int
3296 eq_interface (const void *p1, const void *p2)
3298 const struct interface_tuple *d = p1;
3299 return d->id == p2;
3302 static tree
3303 lookup_interface (tree ident)
3305 #ifdef OBJCPLUS
3306 if (ident && TREE_CODE (ident) == TYPE_DECL)
3307 ident = DECL_NAME (ident);
3308 #endif
3310 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3311 return NULL_TREE;
3314 struct interface_tuple **slot;
3315 tree i = NULL_TREE;
3317 if (interface_htab)
3319 slot = (struct interface_tuple **)
3320 htab_find_slot_with_hash (interface_htab, ident,
3321 htab_hash_pointer (ident),
3322 NO_INSERT);
3323 if (slot && *slot)
3324 i = (*slot)->class_name;
3326 return i;
3330 /* Implement @defs (<classname>) within struct bodies. */
3332 tree
3333 objc_get_class_ivars (tree class_name)
3335 tree interface = lookup_interface (class_name);
3337 if (interface)
3338 return get_class_ivars (interface, true);
3340 error ("cannot find interface declaration for %qs",
3341 IDENTIFIER_POINTER (class_name));
3343 return error_mark_node;
3346 /* Used by: build_private_template, continue_class,
3347 and for @defs constructs. */
3349 static tree
3350 get_class_ivars (tree interface, bool inherited)
3352 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3354 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3355 by the current class (i.e., they do not include super-class ivars).
3356 However, the CLASS_IVARS list will be side-effected by a call to
3357 finish_struct(), which will fill in field offsets. */
3358 if (!CLASS_IVARS (interface))
3359 CLASS_IVARS (interface) = ivar_chain;
3361 if (!inherited)
3362 return ivar_chain;
3364 while (CLASS_SUPER_NAME (interface))
3366 /* Prepend super-class ivars. */
3367 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3368 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3369 ivar_chain);
3372 return ivar_chain;
3375 static tree
3376 objc_create_temporary_var (tree type)
3378 tree decl;
3380 decl = build_decl (VAR_DECL, NULL_TREE, type);
3381 TREE_USED (decl) = 1;
3382 DECL_ARTIFICIAL (decl) = 1;
3383 DECL_IGNORED_P (decl) = 1;
3384 DECL_CONTEXT (decl) = current_function_decl;
3386 return decl;
3389 /* Exception handling constructs. We begin by having the parser do most
3390 of the work and passing us blocks. What we do next depends on whether
3391 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3392 We abstract all of this in a handful of appropriately named routines. */
3394 /* Stack of open try blocks. */
3396 struct objc_try_context
3398 struct objc_try_context *outer;
3400 /* Statements (or statement lists) as processed by the parser. */
3401 tree try_body;
3402 tree finally_body;
3404 /* Some file position locations. */
3405 location_t try_locus;
3406 location_t end_try_locus;
3407 location_t end_catch_locus;
3408 location_t finally_locus;
3409 location_t end_finally_locus;
3411 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3412 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3413 tree catch_list;
3415 /* The CATCH_EXPR of an open @catch clause. */
3416 tree current_catch;
3418 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3419 tree caught_decl;
3420 tree stack_decl;
3421 tree rethrow_decl;
3424 static struct objc_try_context *cur_try_context;
3426 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3427 that represents TYPE. For Objective-C, this is just the class name. */
3428 /* ??? Isn't there a class object or some such? Is it easy to get? */
3430 #ifndef OBJCPLUS
3431 static tree
3432 objc_eh_runtime_type (tree type)
3434 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3436 #endif
3438 /* Initialize exception handling. */
3440 static void
3441 objc_init_exceptions (void)
3443 static bool done = false;
3444 if (done)
3445 return;
3446 done = true;
3448 if (flag_objc_sjlj_exceptions)
3450 /* On Darwin, ObjC exceptions require a sufficiently recent
3451 version of the runtime, so the user must ask for them explicitly. */
3452 if (!flag_objc_exceptions)
3453 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3454 "exception syntax");
3456 #ifndef OBJCPLUS
3457 else
3459 c_eh_initialized_p = true;
3460 eh_personality_libfunc
3461 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3462 ? "__gnu_objc_personality_sj0"
3463 : "__gnu_objc_personality_v0");
3464 default_init_unwind_resume_libfunc ();
3465 using_eh_for_cleanups ();
3466 lang_eh_runtime_type = objc_eh_runtime_type;
3468 #endif
3471 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3472 we'll arrange for it to be initialized (and associated with a binding)
3473 later. */
3475 static tree
3476 objc_build_exc_ptr (void)
3478 if (flag_objc_sjlj_exceptions)
3480 tree var = cur_try_context->caught_decl;
3481 if (!var)
3483 var = objc_create_temporary_var (objc_object_type);
3484 cur_try_context->caught_decl = var;
3486 return var;
3488 else
3489 return build0 (EXC_PTR_EXPR, objc_object_type);
3492 /* Build "objc_exception_try_exit(&_stack)". */
3494 static tree
3495 next_sjlj_build_try_exit (void)
3497 tree t;
3498 t = build_fold_addr_expr (cur_try_context->stack_decl);
3499 t = tree_cons (NULL, t, NULL);
3500 t = build_function_call (objc_exception_try_exit_decl, t);
3501 return t;
3504 /* Build
3505 objc_exception_try_enter (&_stack);
3506 if (_setjmp(&_stack.buf))
3508 else
3510 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3511 empty, ready for the caller to fill them in. */
3513 static tree
3514 next_sjlj_build_enter_and_setjmp (void)
3516 tree t, enter, sj, cond;
3518 t = build_fold_addr_expr (cur_try_context->stack_decl);
3519 t = tree_cons (NULL, t, NULL);
3520 enter = build_function_call (objc_exception_try_enter_decl, t);
3522 t = objc_build_component_ref (cur_try_context->stack_decl,
3523 get_identifier ("buf"));
3524 t = build_fold_addr_expr (t);
3525 #ifdef OBJCPLUS
3526 /* Convert _setjmp argument to type that is expected. */
3527 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3528 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3529 else
3530 t = convert (ptr_type_node, t);
3531 #else
3532 t = convert (ptr_type_node, t);
3533 #endif
3534 t = tree_cons (NULL, t, NULL);
3535 sj = build_function_call (objc_setjmp_decl, t);
3537 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3538 cond = c_common_truthvalue_conversion (cond);
3540 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3543 /* Build
3544 DECL = objc_exception_extract(&_stack);
3547 static tree
3548 next_sjlj_build_exc_extract (tree decl)
3550 tree t;
3552 t = build_fold_addr_expr (cur_try_context->stack_decl);
3553 t = tree_cons (NULL, t, NULL);
3554 t = build_function_call (objc_exception_extract_decl, t);
3555 t = convert (TREE_TYPE (decl), t);
3556 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3558 return t;
3561 /* Build
3562 if (objc_exception_match(obj_get_class(TYPE), _caught)
3563 BODY
3564 else if (...)
3566 else
3568 _rethrow = _caught;
3569 objc_exception_try_exit(&_stack);
3571 from the sequence of CATCH_EXPRs in the current try context. */
3573 static tree
3574 next_sjlj_build_catch_list (void)
3576 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3577 tree catch_seq, t;
3578 tree *last = &catch_seq;
3579 bool saw_id = false;
3581 for (; !tsi_end_p (i); tsi_next (&i))
3583 tree stmt = tsi_stmt (i);
3584 tree type = CATCH_TYPES (stmt);
3585 tree body = CATCH_BODY (stmt);
3587 if (type == NULL)
3589 *last = body;
3590 saw_id = true;
3591 break;
3593 else
3595 tree args, cond;
3597 if (type == error_mark_node)
3598 cond = error_mark_node;
3599 else
3601 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3602 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3603 args = tree_cons (NULL, t, args);
3604 t = build_function_call (objc_exception_match_decl, args);
3605 cond = c_common_truthvalue_conversion (t);
3607 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3608 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3610 *last = t;
3611 last = &COND_EXPR_ELSE (t);
3615 if (!saw_id)
3617 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3618 cur_try_context->caught_decl);
3619 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3620 append_to_statement_list (t, last);
3622 t = next_sjlj_build_try_exit ();
3623 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3624 append_to_statement_list (t, last);
3627 return catch_seq;
3630 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3631 exception handling. We aim to build:
3634 struct _objc_exception_data _stack;
3635 id volatile _rethrow = 0;
3638 objc_exception_try_enter (&_stack);
3639 if (_setjmp(&_stack.buf))
3641 id _caught = objc_exception_extract(&_stack);
3642 objc_exception_try_enter (&_stack);
3643 if (_setjmp(&_stack.buf))
3644 _rethrow = objc_exception_extract(&_stack);
3645 else
3646 CATCH-LIST
3648 else
3649 TRY-BLOCK
3651 finally
3653 if (!_rethrow)
3654 objc_exception_try_exit(&_stack);
3655 FINALLY-BLOCK
3656 if (_rethrow)
3657 objc_exception_throw(_rethrow);
3661 If CATCH-LIST is empty, we can omit all of the block containing
3662 "_caught" except for the setting of _rethrow. Note the use of
3663 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3664 but handles goto and other exits from the block. */
3666 static tree
3667 next_sjlj_build_try_catch_finally (void)
3669 tree rethrow_decl, stack_decl, t;
3670 tree catch_seq, try_fin, bind;
3672 /* Create the declarations involved. */
3673 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3674 stack_decl = objc_create_temporary_var (t);
3675 cur_try_context->stack_decl = stack_decl;
3677 rethrow_decl = objc_create_temporary_var (objc_object_type);
3678 cur_try_context->rethrow_decl = rethrow_decl;
3679 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3680 TREE_CHAIN (rethrow_decl) = stack_decl;
3682 /* Build the outermost variable binding level. */
3683 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3684 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3685 TREE_SIDE_EFFECTS (bind) = 1;
3687 /* Initialize rethrow_decl. */
3688 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3689 convert (objc_object_type, null_pointer_node));
3690 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3691 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3693 /* Build the outermost TRY_FINALLY_EXPR. */
3694 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3695 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3696 TREE_SIDE_EFFECTS (try_fin) = 1;
3697 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3699 /* Create the complete catch sequence. */
3700 if (cur_try_context->catch_list)
3702 tree caught_decl = objc_build_exc_ptr ();
3703 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3704 TREE_SIDE_EFFECTS (catch_seq) = 1;
3706 t = next_sjlj_build_exc_extract (caught_decl);
3707 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3709 t = next_sjlj_build_enter_and_setjmp ();
3710 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3711 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3712 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3714 else
3715 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3716 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3718 /* Build the main register-and-try if statement. */
3719 t = next_sjlj_build_enter_and_setjmp ();
3720 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3721 COND_EXPR_THEN (t) = catch_seq;
3722 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3723 TREE_OPERAND (try_fin, 0) = t;
3725 /* Build the complete FINALLY statement list. */
3726 t = next_sjlj_build_try_exit ();
3727 t = build_stmt (COND_EXPR,
3728 c_common_truthvalue_conversion (rethrow_decl),
3729 NULL, t);
3730 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3731 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3733 append_to_statement_list (cur_try_context->finally_body,
3734 &TREE_OPERAND (try_fin, 1));
3736 t = tree_cons (NULL, rethrow_decl, NULL);
3737 t = build_function_call (objc_exception_throw_decl, t);
3738 t = build_stmt (COND_EXPR,
3739 c_common_truthvalue_conversion (rethrow_decl),
3740 t, NULL);
3741 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3742 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3744 return bind;
3747 /* Called just after parsing the @try and its associated BODY. We now
3748 must prepare for the tricky bits -- handling the catches and finally. */
3750 void
3751 objc_begin_try_stmt (location_t try_locus, tree body)
3753 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3754 c->outer = cur_try_context;
3755 c->try_body = body;
3756 c->try_locus = try_locus;
3757 c->end_try_locus = input_location;
3758 cur_try_context = c;
3760 objc_init_exceptions ();
3762 if (flag_objc_sjlj_exceptions)
3763 objc_mark_locals_volatile (NULL);
3766 /* Called just after parsing "@catch (parm)". Open a binding level,
3767 enter DECL into the binding level, and initialize it. Leave the
3768 binding level open while the body of the compound statement is parsed. */
3770 void
3771 objc_begin_catch_clause (tree decl)
3773 tree compound, type, t;
3775 /* Begin a new scope that the entire catch clause will live in. */
3776 compound = c_begin_compound_stmt (true);
3778 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3779 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3780 lang_hooks.decls.pushdecl (decl);
3782 /* Since a decl is required here by syntax, don't warn if its unused. */
3783 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3784 be what the previous objc implementation did. */
3785 TREE_USED (decl) = 1;
3787 /* Verify that the type of the catch is valid. It must be a pointer
3788 to an Objective-C class, or "id" (which is catch-all). */
3789 type = TREE_TYPE (decl);
3791 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3792 type = NULL;
3793 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3795 error ("@catch parameter is not a known Objective-C class type");
3796 type = error_mark_node;
3798 else if (cur_try_context->catch_list)
3800 /* Examine previous @catch clauses and see if we've already
3801 caught the type in question. */
3802 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3803 for (; !tsi_end_p (i); tsi_next (&i))
3805 tree stmt = tsi_stmt (i);
3806 t = CATCH_TYPES (stmt);
3807 if (t == error_mark_node)
3808 continue;
3809 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3811 warning (0, "exception of type %<%T%> will be caught",
3812 TREE_TYPE (type));
3813 warning (0, "%H by earlier handler for %<%T%>",
3814 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3815 break;
3820 /* Record the data for the catch in the try context so that we can
3821 finalize it later. */
3822 t = build_stmt (CATCH_EXPR, type, compound);
3823 cur_try_context->current_catch = t;
3825 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3826 t = objc_build_exc_ptr ();
3827 t = convert (TREE_TYPE (decl), t);
3828 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3829 add_stmt (t);
3832 /* Called just after parsing the closing brace of a @catch clause. Close
3833 the open binding level, and record a CATCH_EXPR for it. */
3835 void
3836 objc_finish_catch_clause (void)
3838 tree c = cur_try_context->current_catch;
3839 cur_try_context->current_catch = NULL;
3840 cur_try_context->end_catch_locus = input_location;
3842 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3843 append_to_statement_list (c, &cur_try_context->catch_list);
3846 /* Called after parsing a @finally clause and its associated BODY.
3847 Record the body for later placement. */
3849 void
3850 objc_build_finally_clause (location_t finally_locus, tree body)
3852 cur_try_context->finally_body = body;
3853 cur_try_context->finally_locus = finally_locus;
3854 cur_try_context->end_finally_locus = input_location;
3857 /* Called to finalize a @try construct. */
3859 tree
3860 objc_finish_try_stmt (void)
3862 struct objc_try_context *c = cur_try_context;
3863 tree stmt;
3865 if (c->catch_list == NULL && c->finally_body == NULL)
3866 error ("%<@try%> without %<@catch%> or %<@finally%>");
3868 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3869 if (flag_objc_sjlj_exceptions)
3871 if (!cur_try_context->finally_body)
3873 cur_try_context->finally_locus = input_location;
3874 cur_try_context->end_finally_locus = input_location;
3876 stmt = next_sjlj_build_try_catch_finally ();
3878 else
3880 /* Otherwise, nest the CATCH inside a FINALLY. */
3881 stmt = c->try_body;
3882 if (c->catch_list)
3884 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3885 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3887 if (c->finally_body)
3889 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3890 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3893 add_stmt (stmt);
3895 cur_try_context = c->outer;
3896 free (c);
3897 return stmt;
3900 tree
3901 objc_build_throw_stmt (tree throw_expr)
3903 tree args;
3905 objc_init_exceptions ();
3907 if (throw_expr == NULL)
3909 /* If we're not inside a @catch block, there is no "current
3910 exception" to be rethrown. */
3911 if (cur_try_context == NULL
3912 || cur_try_context->current_catch == NULL)
3914 error ("%<@throw%> (rethrow) used outside of a @catch block");
3915 return NULL_TREE;
3918 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3919 value that we get from the runtime. */
3920 throw_expr = objc_build_exc_ptr ();
3923 /* A throw is just a call to the runtime throw function with the
3924 object as a parameter. */
3925 args = tree_cons (NULL, throw_expr, NULL);
3926 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3929 tree
3930 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3932 tree args, call;
3934 /* First lock the mutex. */
3935 mutex = save_expr (mutex);
3936 args = tree_cons (NULL, mutex, NULL);
3937 call = build_function_call (objc_sync_enter_decl, args);
3938 SET_EXPR_LOCATION (call, start_locus);
3939 add_stmt (call);
3941 /* Build the mutex unlock. */
3942 args = tree_cons (NULL, mutex, NULL);
3943 call = build_function_call (objc_sync_exit_decl, args);
3944 SET_EXPR_LOCATION (call, input_location);
3946 /* Put the that and the body in a TRY_FINALLY. */
3947 objc_begin_try_stmt (start_locus, body);
3948 objc_build_finally_clause (input_location, call);
3949 return objc_finish_try_stmt ();
3953 /* Predefine the following data type:
3955 struct _objc_exception_data
3957 int buf[_JBLEN];
3958 void *pointers[4];
3959 }; */
3961 /* The following yuckiness should prevent users from having to #include
3962 <setjmp.h> in their code... */
3964 #ifdef TARGET_POWERPC
3965 /* snarfed from /usr/include/ppc/setjmp.h */
3966 #define _JBLEN (26 + 36 + 129 + 1)
3967 #else
3968 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3969 #define _JBLEN 18
3970 #endif
3972 static void
3973 build_next_objc_exception_stuff (void)
3975 tree field_decl, field_decl_chain, index, temp_type;
3977 objc_exception_data_template
3978 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3980 /* int buf[_JBLEN]; */
3982 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3983 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3984 "buf");
3985 field_decl_chain = field_decl;
3987 /* void *pointers[4]; */
3989 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3990 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3991 "pointers");
3992 chainon (field_decl_chain, field_decl);
3994 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3996 /* int _setjmp(...); */
3997 /* If the user includes <setjmp.h>, this shall be superseded by
3998 'int _setjmp(jmp_buf);' */
3999 temp_type = build_function_type (integer_type_node, NULL_TREE);
4000 objc_setjmp_decl
4001 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4003 /* id objc_exception_extract(struct _objc_exception_data *); */
4004 temp_type
4005 = build_function_type (objc_object_type,
4006 tree_cons (NULL_TREE,
4007 build_pointer_type (objc_exception_data_template),
4008 OBJC_VOID_AT_END));
4009 objc_exception_extract_decl
4010 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4011 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4012 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4013 temp_type
4014 = build_function_type (void_type_node,
4015 tree_cons (NULL_TREE,
4016 build_pointer_type (objc_exception_data_template),
4017 OBJC_VOID_AT_END));
4018 objc_exception_try_enter_decl
4019 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4020 objc_exception_try_exit_decl
4021 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4023 /* int objc_exception_match(id, id); */
4024 temp_type
4025 = build_function_type (integer_type_node,
4026 tree_cons (NULL_TREE, objc_object_type,
4027 tree_cons (NULL_TREE, objc_object_type,
4028 OBJC_VOID_AT_END)));
4029 objc_exception_match_decl
4030 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4032 /* id objc_assign_ivar (id, id, unsigned int); */
4033 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4034 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4035 temp_type
4036 = build_function_type (objc_object_type,
4037 tree_cons
4038 (NULL_TREE, objc_object_type,
4039 tree_cons (NULL_TREE, objc_object_type,
4040 tree_cons (NULL_TREE,
4041 unsigned_type_node,
4042 OBJC_VOID_AT_END))));
4043 objc_assign_ivar_decl
4044 = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4045 NULL, NULL_TREE);
4046 #ifdef OFFS_ASSIGNIVAR_FAST
4047 objc_assign_ivar_fast_decl
4048 = builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4049 NOT_BUILT_IN, NULL, NULL_TREE);
4050 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4051 = tree_cons (get_identifier ("hard_coded_address"),
4052 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4053 NULL_TREE);
4054 #else
4055 /* Default to slower ivar method. */
4056 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4057 #endif
4059 /* id objc_assign_global (id, id *); */
4060 /* id objc_assign_strongCast (id, id *); */
4061 temp_type = build_function_type (objc_object_type,
4062 tree_cons (NULL_TREE, objc_object_type,
4063 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4064 OBJC_VOID_AT_END)));
4065 objc_assign_global_decl
4066 = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4067 objc_assign_strong_cast_decl
4068 = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4071 static void
4072 build_objc_exception_stuff (void)
4074 tree noreturn_list, nothrow_list, temp_type;
4076 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4077 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4079 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4080 /* void objc_sync_enter(id); */
4081 /* void objc_sync_exit(id); */
4082 temp_type = build_function_type (void_type_node,
4083 tree_cons (NULL_TREE, objc_object_type,
4084 OBJC_VOID_AT_END));
4085 objc_exception_throw_decl
4086 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4087 noreturn_list);
4088 objc_sync_enter_decl
4089 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4090 NULL, nothrow_list);
4091 objc_sync_exit_decl
4092 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4093 NULL, nothrow_list);
4096 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4097 name as the class:
4099 struct <classname> {
4100 struct _objc_class *isa;
4102 }; */
4104 static void
4105 build_private_template (tree class)
4107 if (!CLASS_STATIC_TEMPLATE (class))
4109 tree record = objc_build_struct (class,
4110 get_class_ivars (class, false),
4111 CLASS_SUPER_NAME (class));
4113 /* Set the TREE_USED bit for this struct, so that stab generator
4114 can emit stabs for this struct type. */
4115 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4116 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4120 /* Begin code generation for protocols... */
4122 /* struct _objc_protocol {
4123 struct _objc_class *isa;
4124 char *protocol_name;
4125 struct _objc_protocol **protocol_list;
4126 struct _objc__method_prototype_list *instance_methods;
4127 struct _objc__method_prototype_list *class_methods;
4128 }; */
4130 static void
4131 build_protocol_template (void)
4133 tree field_decl, field_decl_chain;
4135 objc_protocol_template = start_struct (RECORD_TYPE,
4136 get_identifier (UTAG_PROTOCOL));
4138 /* struct _objc_class *isa; */
4139 field_decl = create_field_decl (build_pointer_type
4140 (xref_tag (RECORD_TYPE,
4141 get_identifier (UTAG_CLASS))),
4142 "isa");
4143 field_decl_chain = field_decl;
4145 /* char *protocol_name; */
4146 field_decl = create_field_decl (string_type_node, "protocol_name");
4147 chainon (field_decl_chain, field_decl);
4149 /* struct _objc_protocol **protocol_list; */
4150 field_decl = create_field_decl (build_pointer_type
4151 (build_pointer_type
4152 (objc_protocol_template)),
4153 "protocol_list");
4154 chainon (field_decl_chain, field_decl);
4156 /* struct _objc__method_prototype_list *instance_methods; */
4157 field_decl = create_field_decl (objc_method_proto_list_ptr,
4158 "instance_methods");
4159 chainon (field_decl_chain, field_decl);
4161 /* struct _objc__method_prototype_list *class_methods; */
4162 field_decl = create_field_decl (objc_method_proto_list_ptr,
4163 "class_methods");
4164 chainon (field_decl_chain, field_decl);
4166 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
4169 static tree
4170 build_descriptor_table_initializer (tree type, tree entries)
4172 tree initlist = NULL_TREE;
4176 tree eltlist = NULL_TREE;
4178 eltlist
4179 = tree_cons (NULL_TREE,
4180 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4181 eltlist
4182 = tree_cons (NULL_TREE,
4183 add_objc_string (METHOD_ENCODING (entries),
4184 meth_var_types),
4185 eltlist);
4187 initlist
4188 = tree_cons (NULL_TREE,
4189 objc_build_constructor (type, nreverse (eltlist)),
4190 initlist);
4192 entries = TREE_CHAIN (entries);
4194 while (entries);
4196 return objc_build_constructor (build_array_type (type, 0),
4197 nreverse (initlist));
4200 /* struct objc_method_prototype_list {
4201 int count;
4202 struct objc_method_prototype {
4203 SEL name;
4204 char *types;
4205 } list[1];
4206 }; */
4208 static tree
4209 build_method_prototype_list_template (tree list_type, int size)
4211 tree objc_ivar_list_record;
4212 tree field_decl, field_decl_chain;
4214 /* Generate an unnamed struct definition. */
4216 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4218 /* int method_count; */
4219 field_decl = create_field_decl (integer_type_node, "method_count");
4220 field_decl_chain = field_decl;
4222 /* struct objc_method method_list[]; */
4223 field_decl = create_field_decl (build_array_type
4224 (list_type,
4225 build_index_type
4226 (build_int_cst (NULL_TREE, size - 1))),
4227 "method_list");
4228 chainon (field_decl_chain, field_decl);
4230 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4232 return objc_ivar_list_record;
4235 static tree
4236 build_method_prototype_template (void)
4238 tree proto_record;
4239 tree field_decl, field_decl_chain;
4241 proto_record
4242 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
4244 /* SEL _cmd; */
4245 field_decl = create_field_decl (objc_selector_type, "_cmd");
4246 field_decl_chain = field_decl;
4248 /* char *method_types; */
4249 field_decl = create_field_decl (string_type_node, "method_types");
4250 chainon (field_decl_chain, field_decl);
4252 finish_struct (proto_record, field_decl_chain, NULL_TREE);
4254 return proto_record;
4257 static tree
4258 objc_method_parm_type (tree type)
4260 type = TREE_VALUE (TREE_TYPE (type));
4261 if (TREE_CODE (type) == TYPE_DECL)
4262 type = TREE_TYPE (type);
4263 return type;
4266 static int
4267 objc_encoded_type_size (tree type)
4269 int sz = int_size_in_bytes (type);
4271 /* Make all integer and enum types at least as large
4272 as an int. */
4273 if (sz > 0 && INTEGRAL_TYPE_P (type))
4274 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4275 /* Treat arrays as pointers, since that's how they're
4276 passed in. */
4277 else if (TREE_CODE (type) == ARRAY_TYPE)
4278 sz = int_size_in_bytes (ptr_type_node);
4279 return sz;
4282 static tree
4283 encode_method_prototype (tree method_decl)
4285 tree parms;
4286 int parm_offset, i;
4287 char buf[40];
4288 tree result;
4290 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4291 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4293 /* Encode return type. */
4294 encode_type (objc_method_parm_type (method_decl),
4295 obstack_object_size (&util_obstack),
4296 OBJC_ENCODE_INLINE_DEFS);
4298 /* Stack size. */
4299 /* The first two arguments (self and _cmd) are pointers; account for
4300 their size. */
4301 i = int_size_in_bytes (ptr_type_node);
4302 parm_offset = 2 * i;
4303 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4304 parms = TREE_CHAIN (parms))
4306 tree type = objc_method_parm_type (parms);
4307 int sz = objc_encoded_type_size (type);
4309 /* If a type size is not known, bail out. */
4310 if (sz < 0)
4312 error ("type %q+D does not have a known size",
4313 type);
4314 /* Pretend that the encoding succeeded; the compilation will
4315 fail nevertheless. */
4316 goto finish_encoding;
4318 parm_offset += sz;
4321 sprintf (buf, "%d@0:%d", parm_offset, i);
4322 obstack_grow (&util_obstack, buf, strlen (buf));
4324 /* Argument types. */
4325 parm_offset = 2 * i;
4326 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4327 parms = TREE_CHAIN (parms))
4329 tree type = objc_method_parm_type (parms);
4331 /* Process argument qualifiers for user supplied arguments. */
4332 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4334 /* Type. */
4335 encode_type (type, obstack_object_size (&util_obstack),
4336 OBJC_ENCODE_INLINE_DEFS);
4338 /* Compute offset. */
4339 sprintf (buf, "%d", parm_offset);
4340 parm_offset += objc_encoded_type_size (type);
4342 obstack_grow (&util_obstack, buf, strlen (buf));
4345 finish_encoding:
4346 obstack_1grow (&util_obstack, '\0');
4347 result = get_identifier (obstack_finish (&util_obstack));
4348 obstack_free (&util_obstack, util_firstobj);
4349 return result;
4352 static tree
4353 generate_descriptor_table (tree type, const char *name, int size, tree list,
4354 tree proto)
4356 tree decl, initlist;
4358 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4360 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4361 initlist = tree_cons (NULL_TREE, list, initlist);
4363 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4365 return decl;
4368 static void
4369 generate_method_descriptors (tree protocol)
4371 tree initlist, chain, method_list_template;
4372 int size;
4374 if (!objc_method_prototype_template)
4375 objc_method_prototype_template = build_method_prototype_template ();
4377 chain = PROTOCOL_CLS_METHODS (protocol);
4378 if (chain)
4380 size = list_length (chain);
4382 method_list_template
4383 = build_method_prototype_list_template (objc_method_prototype_template,
4384 size);
4386 initlist
4387 = build_descriptor_table_initializer (objc_method_prototype_template,
4388 chain);
4390 UOBJC_CLASS_METHODS_decl
4391 = generate_descriptor_table (method_list_template,
4392 "_OBJC_PROTOCOL_CLASS_METHODS",
4393 size, initlist, protocol);
4395 else
4396 UOBJC_CLASS_METHODS_decl = 0;
4398 chain = PROTOCOL_NST_METHODS (protocol);
4399 if (chain)
4401 size = list_length (chain);
4403 method_list_template
4404 = build_method_prototype_list_template (objc_method_prototype_template,
4405 size);
4406 initlist
4407 = build_descriptor_table_initializer (objc_method_prototype_template,
4408 chain);
4410 UOBJC_INSTANCE_METHODS_decl
4411 = generate_descriptor_table (method_list_template,
4412 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4413 size, initlist, protocol);
4415 else
4416 UOBJC_INSTANCE_METHODS_decl = 0;
4419 static void
4420 generate_protocol_references (tree plist)
4422 tree lproto;
4424 /* Forward declare protocols referenced. */
4425 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4427 tree proto = TREE_VALUE (lproto);
4429 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4430 && PROTOCOL_NAME (proto))
4432 if (! PROTOCOL_FORWARD_DECL (proto))
4433 build_protocol_reference (proto);
4435 if (PROTOCOL_LIST (proto))
4436 generate_protocol_references (PROTOCOL_LIST (proto));
4441 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4442 current class. */
4443 #ifdef OBJCPLUS
4444 static void
4445 objc_generate_cxx_ctor_or_dtor (bool dtor)
4447 tree fn, body, compound_stmt, ivar;
4449 /* - (id) .cxx_construct { ... return self; } */
4450 /* - (void) .cxx_construct { ... } */
4452 objc_set_method_type (MINUS_EXPR);
4453 objc_start_method_definition
4454 (objc_build_method_signature (build_tree_list (NULL_TREE,
4455 dtor
4456 ? void_type_node
4457 : objc_object_type),
4458 get_identifier (dtor
4459 ? TAG_CXX_DESTRUCT
4460 : TAG_CXX_CONSTRUCT),
4461 make_node (TREE_LIST),
4462 false));
4463 body = begin_function_body ();
4464 compound_stmt = begin_compound_stmt (0);
4466 ivar = CLASS_IVARS (implementation_template);
4467 /* Destroy ivars in reverse order. */
4468 if (dtor)
4469 ivar = nreverse (copy_list (ivar));
4471 for (; ivar; ivar = TREE_CHAIN (ivar))
4473 if (TREE_CODE (ivar) == FIELD_DECL)
4475 tree type = TREE_TYPE (ivar);
4477 /* Call the ivar's default constructor or destructor. Do not
4478 call the destructor unless a corresponding constructor call
4479 has also been made (or is not needed). */
4480 if (IS_AGGR_TYPE (type)
4481 && (dtor
4482 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4483 && (!TYPE_NEEDS_CONSTRUCTING (type)
4484 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4485 : (TYPE_NEEDS_CONSTRUCTING (type)
4486 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4487 finish_expr_stmt
4488 (build_special_member_call
4489 (build_ivar_reference (DECL_NAME (ivar)),
4490 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4491 NULL_TREE, type, LOOKUP_NORMAL));
4495 /* The constructor returns 'self'. */
4496 if (!dtor)
4497 finish_return_stmt (self_decl);
4499 finish_compound_stmt (compound_stmt);
4500 finish_function_body (body);
4501 fn = current_function_decl;
4502 finish_function ();
4503 objc_finish_method_definition (fn);
4506 /* The following routine will examine the current @interface for any
4507 non-POD C++ ivars requiring non-trivial construction and/or
4508 destruction, and then synthesize special '- .cxx_construct' and/or
4509 '- .cxx_destruct' methods which will run the appropriate
4510 construction or destruction code. Note that ivars inherited from
4511 super-classes are _not_ considered. */
4512 static void
4513 objc_generate_cxx_cdtors (void)
4515 bool need_ctor = false, need_dtor = false;
4516 tree ivar;
4518 /* We do not want to do this for categories, since they do not have
4519 their own ivars. */
4521 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4522 return;
4524 /* First, determine if we even need a constructor and/or destructor. */
4526 for (ivar = CLASS_IVARS (implementation_template); ivar;
4527 ivar = TREE_CHAIN (ivar))
4529 if (TREE_CODE (ivar) == FIELD_DECL)
4531 tree type = TREE_TYPE (ivar);
4533 if (IS_AGGR_TYPE (type))
4535 if (TYPE_NEEDS_CONSTRUCTING (type)
4536 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4537 /* NB: If a default constructor is not available, we will not
4538 be able to initialize this ivar; the add_instance_variable()
4539 routine will already have warned about this. */
4540 need_ctor = true;
4542 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4543 && (!TYPE_NEEDS_CONSTRUCTING (type)
4544 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4545 /* NB: If a default constructor is not available, we will not
4546 call the destructor either, for symmetry. */
4547 need_dtor = true;
4552 /* Generate '- .cxx_construct' if needed. */
4554 if (need_ctor)
4555 objc_generate_cxx_ctor_or_dtor (false);
4557 /* Generate '- .cxx_destruct' if needed. */
4559 if (need_dtor)
4560 objc_generate_cxx_ctor_or_dtor (true);
4562 /* The 'imp_list' variable points at an imp_entry record for the current
4563 @implementation. Record the existence of '- .cxx_construct' and/or
4564 '- .cxx_destruct' methods therein; it will be included in the
4565 metadata for the class. */
4566 if (flag_next_runtime)
4567 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4569 #endif
4571 /* For each protocol which was referenced either from a @protocol()
4572 expression, or because a class/category implements it (then a
4573 pointer to the protocol is stored in the struct describing the
4574 class/category), we create a statically allocated instance of the
4575 Protocol class. The code is written in such a way as to generate
4576 as few Protocol objects as possible; we generate a unique Protocol
4577 instance for each protocol, and we don't generate a Protocol
4578 instance if the protocol is never referenced (either from a
4579 @protocol() or from a class/category implementation). These
4580 statically allocated objects can be referred to via the static
4581 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4583 The statically allocated Protocol objects that we generate here
4584 need to be fixed up at runtime in order to be used: the 'isa'
4585 pointer of the objects need to be set up to point to the 'Protocol'
4586 class, as known at runtime.
4588 The NeXT runtime fixes up all protocols at program startup time,
4589 before main() is entered. It uses a low-level trick to look up all
4590 those symbols, then loops on them and fixes them up.
4592 The GNU runtime as well fixes up all protocols before user code
4593 from the module is executed; it requires pointers to those symbols
4594 to be put in the objc_symtab (which is then passed as argument to
4595 the function __objc_exec_class() which the compiler sets up to be
4596 executed automatically when the module is loaded); setup of those
4597 Protocol objects happen in two ways in the GNU runtime: all
4598 Protocol objects referred to by a class or category implementation
4599 are fixed up when the class/category is loaded; all Protocol
4600 objects referred to by a @protocol() expression are added by the
4601 compiler to the list of statically allocated instances to fixup
4602 (the same list holding the statically allocated constant string
4603 objects). Because, as explained above, the compiler generates as
4604 few Protocol objects as possible, some Protocol object might end up
4605 being referenced multiple times when compiled with the GNU runtime,
4606 and end up being fixed up multiple times at runtime initialization.
4607 But that doesn't hurt, it's just a little inefficient. */
4609 static void
4610 generate_protocols (void)
4612 tree p, encoding;
4613 tree decl;
4614 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4616 /* If a protocol was directly referenced, pull in indirect references. */
4617 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4618 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4619 generate_protocol_references (PROTOCOL_LIST (p));
4621 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4623 tree nst_methods = PROTOCOL_NST_METHODS (p);
4624 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4626 /* If protocol wasn't referenced, don't generate any code. */
4627 decl = PROTOCOL_FORWARD_DECL (p);
4629 if (!decl)
4630 continue;
4632 /* Make sure we link in the Protocol class. */
4633 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4635 while (nst_methods)
4637 if (! METHOD_ENCODING (nst_methods))
4639 encoding = encode_method_prototype (nst_methods);
4640 METHOD_ENCODING (nst_methods) = encoding;
4642 nst_methods = TREE_CHAIN (nst_methods);
4645 while (cls_methods)
4647 if (! METHOD_ENCODING (cls_methods))
4649 encoding = encode_method_prototype (cls_methods);
4650 METHOD_ENCODING (cls_methods) = encoding;
4653 cls_methods = TREE_CHAIN (cls_methods);
4655 generate_method_descriptors (p);
4657 if (PROTOCOL_LIST (p))
4658 refs_decl = generate_protocol_list (p);
4659 else
4660 refs_decl = 0;
4662 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4663 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4665 if (refs_decl)
4666 refs_expr = convert (build_pointer_type (build_pointer_type
4667 (objc_protocol_template)),
4668 build_unary_op (ADDR_EXPR, refs_decl, 0));
4669 else
4670 refs_expr = build_int_cst (NULL_TREE, 0);
4672 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4673 by generate_method_descriptors, which is called above. */
4674 initlist = build_protocol_initializer (TREE_TYPE (decl),
4675 protocol_name_expr, refs_expr,
4676 UOBJC_INSTANCE_METHODS_decl,
4677 UOBJC_CLASS_METHODS_decl);
4678 finish_var_decl (decl, initlist);
4682 static tree
4683 build_protocol_initializer (tree type, tree protocol_name,
4684 tree protocol_list, tree instance_methods,
4685 tree class_methods)
4687 tree initlist = NULL_TREE, expr;
4688 tree cast_type = build_pointer_type
4689 (xref_tag (RECORD_TYPE,
4690 get_identifier (UTAG_CLASS)));
4692 /* Filling the "isa" in with one allows the runtime system to
4693 detect that the version change...should remove before final release. */
4695 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4696 initlist = tree_cons (NULL_TREE, expr, initlist);
4697 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4698 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4700 if (!instance_methods)
4701 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4702 else
4704 expr = convert (objc_method_proto_list_ptr,
4705 build_unary_op (ADDR_EXPR, instance_methods, 0));
4706 initlist = tree_cons (NULL_TREE, expr, initlist);
4709 if (!class_methods)
4710 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4711 else
4713 expr = convert (objc_method_proto_list_ptr,
4714 build_unary_op (ADDR_EXPR, class_methods, 0));
4715 initlist = tree_cons (NULL_TREE, expr, initlist);
4718 return objc_build_constructor (type, nreverse (initlist));
4721 /* struct _objc_category {
4722 char *category_name;
4723 char *class_name;
4724 struct _objc_method_list *instance_methods;
4725 struct _objc_method_list *class_methods;
4726 struct _objc_protocol_list *protocols;
4727 }; */
4729 static void
4730 build_category_template (void)
4732 tree field_decl, field_decl_chain;
4734 objc_category_template = start_struct (RECORD_TYPE,
4735 get_identifier (UTAG_CATEGORY));
4737 /* char *category_name; */
4738 field_decl = create_field_decl (string_type_node, "category_name");
4739 field_decl_chain = field_decl;
4741 /* char *class_name; */
4742 field_decl = create_field_decl (string_type_node, "class_name");
4743 chainon (field_decl_chain, field_decl);
4745 /* struct _objc_method_list *instance_methods; */
4746 field_decl = create_field_decl (objc_method_list_ptr,
4747 "instance_methods");
4748 chainon (field_decl_chain, field_decl);
4750 /* struct _objc_method_list *class_methods; */
4751 field_decl = create_field_decl (objc_method_list_ptr,
4752 "class_methods");
4753 chainon (field_decl_chain, field_decl);
4755 /* struct _objc_protocol **protocol_list; */
4756 field_decl = create_field_decl (build_pointer_type
4757 (build_pointer_type
4758 (objc_protocol_template)),
4759 "protocol_list");
4760 chainon (field_decl_chain, field_decl);
4762 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4765 /* struct _objc_selector {
4766 SEL sel_id;
4767 char *sel_type;
4768 }; */
4770 static void
4771 build_selector_template (void)
4774 tree field_decl, field_decl_chain;
4776 objc_selector_template
4777 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4779 /* SEL sel_id; */
4780 field_decl = create_field_decl (objc_selector_type, "sel_id");
4781 field_decl_chain = field_decl;
4783 /* char *sel_type; */
4784 field_decl = create_field_decl (string_type_node, "sel_type");
4785 chainon (field_decl_chain, field_decl);
4787 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4790 /* struct _objc_class {
4791 struct _objc_class *isa;
4792 struct _objc_class *super_class;
4793 char *name;
4794 long version;
4795 long info;
4796 long instance_size;
4797 struct _objc_ivar_list *ivars;
4798 struct _objc_method_list *methods;
4799 #ifdef __NEXT_RUNTIME__
4800 struct objc_cache *cache;
4801 #else
4802 struct sarray *dtable;
4803 struct _objc_class *subclass_list;
4804 struct _objc_class *sibling_class;
4805 #endif
4806 struct _objc_protocol_list *protocols;
4807 #ifdef __NEXT_RUNTIME__
4808 void *sel_id;
4809 #endif
4810 void *gc_object_type;
4811 }; */
4813 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4814 the NeXT/Apple runtime; still, the compiler must generate them to
4815 maintain backward binary compatibility (and to allow for future
4816 expansion). */
4818 static void
4819 build_class_template (void)
4821 tree field_decl, field_decl_chain;
4823 objc_class_template
4824 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4826 /* struct _objc_class *isa; */
4827 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4828 "isa");
4829 field_decl_chain = field_decl;
4831 /* struct _objc_class *super_class; */
4832 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4833 "super_class");
4834 chainon (field_decl_chain, field_decl);
4836 /* char *name; */
4837 field_decl = create_field_decl (string_type_node, "name");
4838 chainon (field_decl_chain, field_decl);
4840 /* long version; */
4841 field_decl = create_field_decl (long_integer_type_node, "version");
4842 chainon (field_decl_chain, field_decl);
4844 /* long info; */
4845 field_decl = create_field_decl (long_integer_type_node, "info");
4846 chainon (field_decl_chain, field_decl);
4848 /* long instance_size; */
4849 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4850 chainon (field_decl_chain, field_decl);
4852 /* struct _objc_ivar_list *ivars; */
4853 field_decl = create_field_decl (objc_ivar_list_ptr,
4854 "ivars");
4855 chainon (field_decl_chain, field_decl);
4857 /* struct _objc_method_list *methods; */
4858 field_decl = create_field_decl (objc_method_list_ptr,
4859 "methods");
4860 chainon (field_decl_chain, field_decl);
4862 if (flag_next_runtime)
4864 /* struct objc_cache *cache; */
4865 field_decl = create_field_decl (build_pointer_type
4866 (xref_tag (RECORD_TYPE,
4867 get_identifier
4868 ("objc_cache"))),
4869 "cache");
4870 chainon (field_decl_chain, field_decl);
4872 else
4874 /* struct sarray *dtable; */
4875 field_decl = create_field_decl (build_pointer_type
4876 (xref_tag (RECORD_TYPE,
4877 get_identifier
4878 ("sarray"))),
4879 "dtable");
4880 chainon (field_decl_chain, field_decl);
4882 /* struct objc_class *subclass_list; */
4883 field_decl = create_field_decl (build_pointer_type
4884 (objc_class_template),
4885 "subclass_list");
4886 chainon (field_decl_chain, field_decl);
4888 /* struct objc_class *sibling_class; */
4889 field_decl = create_field_decl (build_pointer_type
4890 (objc_class_template),
4891 "sibling_class");
4892 chainon (field_decl_chain, field_decl);
4895 /* struct _objc_protocol **protocol_list; */
4896 field_decl = create_field_decl (build_pointer_type
4897 (build_pointer_type
4898 (xref_tag (RECORD_TYPE,
4899 get_identifier
4900 (UTAG_PROTOCOL)))),
4901 "protocol_list");
4902 chainon (field_decl_chain, field_decl);
4904 if (flag_next_runtime)
4906 /* void *sel_id; */
4907 field_decl = create_field_decl (build_pointer_type (void_type_node),
4908 "sel_id");
4909 chainon (field_decl_chain, field_decl);
4912 /* void *gc_object_type; */
4913 field_decl = create_field_decl (build_pointer_type (void_type_node),
4914 "gc_object_type");
4915 chainon (field_decl_chain, field_decl);
4917 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4920 /* Generate appropriate forward declarations for an implementation. */
4922 static void
4923 synth_forward_declarations (void)
4925 tree an_id;
4927 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4928 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4929 objc_class_template);
4931 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4932 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4933 objc_class_template);
4935 /* Pre-build the following entities - for speed/convenience. */
4937 an_id = get_identifier ("super_class");
4938 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
4939 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
4942 static void
4943 error_with_ivar (const char *message, tree decl)
4945 error ("%J%s %qs", decl,
4946 message, gen_declaration (decl));
4950 static void
4951 check_ivars (tree inter, tree imp)
4953 tree intdecls = CLASS_RAW_IVARS (inter);
4954 tree impdecls = CLASS_RAW_IVARS (imp);
4956 while (1)
4958 tree t1, t2;
4960 #ifdef OBJCPLUS
4961 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4962 intdecls = TREE_CHAIN (intdecls);
4963 #endif
4964 if (intdecls == 0 && impdecls == 0)
4965 break;
4966 if (intdecls == 0 || impdecls == 0)
4968 error ("inconsistent instance variable specification");
4969 break;
4972 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4974 if (!comptypes (t1, t2)
4975 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4976 DECL_INITIAL (impdecls)))
4978 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4980 error_with_ivar ("conflicting instance variable type",
4981 impdecls);
4982 error_with_ivar ("previous declaration of",
4983 intdecls);
4985 else /* both the type and the name don't match */
4987 error ("inconsistent instance variable specification");
4988 break;
4992 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4994 error_with_ivar ("conflicting instance variable name",
4995 impdecls);
4996 error_with_ivar ("previous declaration of",
4997 intdecls);
5000 intdecls = TREE_CHAIN (intdecls);
5001 impdecls = TREE_CHAIN (impdecls);
5005 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5006 This needs to be done just once per compilation. */
5008 /* struct _objc_super {
5009 struct _objc_object *self;
5010 struct _objc_class *super_class;
5011 }; */
5013 static void
5014 build_super_template (void)
5016 tree field_decl, field_decl_chain;
5018 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
5020 /* struct _objc_object *self; */
5021 field_decl = create_field_decl (objc_object_type, "self");
5022 field_decl_chain = field_decl;
5024 /* struct _objc_class *super_class; */
5025 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5026 "super_class");
5027 chainon (field_decl_chain, field_decl);
5029 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
5032 /* struct _objc_ivar {
5033 char *ivar_name;
5034 char *ivar_type;
5035 int ivar_offset;
5036 }; */
5038 static tree
5039 build_ivar_template (void)
5041 tree objc_ivar_id, objc_ivar_record;
5042 tree field_decl, field_decl_chain;
5044 objc_ivar_id = get_identifier (UTAG_IVAR);
5045 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
5047 /* char *ivar_name; */
5048 field_decl = create_field_decl (string_type_node, "ivar_name");
5049 field_decl_chain = field_decl;
5051 /* char *ivar_type; */
5052 field_decl = create_field_decl (string_type_node, "ivar_type");
5053 chainon (field_decl_chain, field_decl);
5055 /* int ivar_offset; */
5056 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5057 chainon (field_decl_chain, field_decl);
5059 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
5061 return objc_ivar_record;
5064 /* struct {
5065 int ivar_count;
5066 struct objc_ivar ivar_list[ivar_count];
5067 }; */
5069 static tree
5070 build_ivar_list_template (tree list_type, int size)
5072 tree objc_ivar_list_record;
5073 tree field_decl, field_decl_chain;
5075 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5077 /* int ivar_count; */
5078 field_decl = create_field_decl (integer_type_node, "ivar_count");
5079 field_decl_chain = field_decl;
5081 /* struct objc_ivar ivar_list[]; */
5082 field_decl = create_field_decl (build_array_type
5083 (list_type,
5084 build_index_type
5085 (build_int_cst (NULL_TREE, size - 1))),
5086 "ivar_list");
5087 chainon (field_decl_chain, field_decl);
5089 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5091 return objc_ivar_list_record;
5094 /* struct {
5095 struct _objc__method_prototype_list *method_next;
5096 int method_count;
5097 struct objc_method method_list[method_count];
5098 }; */
5100 static tree
5101 build_method_list_template (tree list_type, int size)
5103 tree objc_ivar_list_record;
5104 tree field_decl, field_decl_chain;
5106 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
5108 /* struct _objc__method_prototype_list *method_next; */
5109 field_decl = create_field_decl (objc_method_proto_list_ptr,
5110 "method_next");
5111 field_decl_chain = field_decl;
5113 /* int method_count; */
5114 field_decl = create_field_decl (integer_type_node, "method_count");
5115 chainon (field_decl_chain, field_decl);
5117 /* struct objc_method method_list[]; */
5118 field_decl = create_field_decl (build_array_type
5119 (list_type,
5120 build_index_type
5121 (build_int_cst (NULL_TREE, size - 1))),
5122 "method_list");
5123 chainon (field_decl_chain, field_decl);
5125 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
5127 return objc_ivar_list_record;
5130 static tree
5131 build_ivar_list_initializer (tree type, tree field_decl)
5133 tree initlist = NULL_TREE;
5137 tree ivar = NULL_TREE;
5139 /* Set name. */
5140 if (DECL_NAME (field_decl))
5141 ivar = tree_cons (NULL_TREE,
5142 add_objc_string (DECL_NAME (field_decl),
5143 meth_var_names),
5144 ivar);
5145 else
5146 /* Unnamed bit-field ivar (yuck). */
5147 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5149 /* Set type. */
5150 encode_field_decl (field_decl,
5151 obstack_object_size (&util_obstack),
5152 OBJC_ENCODE_DONT_INLINE_DEFS);
5154 /* Null terminate string. */
5155 obstack_1grow (&util_obstack, 0);
5156 ivar
5157 = tree_cons
5158 (NULL_TREE,
5159 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
5160 meth_var_types),
5161 ivar);
5162 obstack_free (&util_obstack, util_firstobj);
5164 /* Set offset. */
5165 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5166 initlist = tree_cons (NULL_TREE,
5167 objc_build_constructor (type, nreverse (ivar)),
5168 initlist);
5170 field_decl = TREE_CHAIN (field_decl);
5171 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5173 while (field_decl);
5175 return objc_build_constructor (build_array_type (type, 0),
5176 nreverse (initlist));
5179 static tree
5180 generate_ivars_list (tree type, const char *name, int size, tree list)
5182 tree decl, initlist;
5184 decl = start_var_decl (type, synth_id_with_class_suffix
5185 (name, objc_implementation_context));
5187 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5188 initlist = tree_cons (NULL_TREE, list, initlist);
5190 finish_var_decl (decl,
5191 objc_build_constructor (TREE_TYPE (decl),
5192 nreverse (initlist)));
5194 return decl;
5197 /* Count only the fields occurring in T. */
5198 static int
5199 ivar_list_length (tree t)
5201 int count = 0;
5203 for (; t; t = TREE_CHAIN (t))
5204 if (TREE_CODE (t) == FIELD_DECL)
5205 ++count;
5207 return count;
5210 static void
5211 generate_ivar_lists (void)
5213 tree initlist, ivar_list_template, chain;
5214 int size;
5216 generating_instance_variables = 1;
5218 if (!objc_ivar_template)
5219 objc_ivar_template = build_ivar_template ();
5221 /* Only generate class variables for the root of the inheritance
5222 hierarchy since these will be the same for every class. */
5224 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5225 && (chain = TYPE_FIELDS (objc_class_template)))
5227 size = ivar_list_length (chain);
5229 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5230 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5232 UOBJC_CLASS_VARIABLES_decl
5233 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5234 size, initlist);
5236 else
5237 UOBJC_CLASS_VARIABLES_decl = 0;
5239 chain = CLASS_IVARS (implementation_template);
5240 if (chain)
5242 size = ivar_list_length (chain);
5243 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5244 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5246 UOBJC_INSTANCE_VARIABLES_decl
5247 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5248 size, initlist);
5250 else
5251 UOBJC_INSTANCE_VARIABLES_decl = 0;
5253 generating_instance_variables = 0;
5256 static tree
5257 build_dispatch_table_initializer (tree type, tree entries)
5259 tree initlist = NULL_TREE;
5263 tree elemlist = NULL_TREE;
5265 elemlist = tree_cons (NULL_TREE,
5266 build_selector (METHOD_SEL_NAME (entries)),
5267 NULL_TREE);
5269 /* Generate the method encoding if we don't have one already. */
5270 if (! METHOD_ENCODING (entries))
5271 METHOD_ENCODING (entries) =
5272 encode_method_prototype (entries);
5274 elemlist = tree_cons (NULL_TREE,
5275 add_objc_string (METHOD_ENCODING (entries),
5276 meth_var_types),
5277 elemlist);
5279 elemlist
5280 = tree_cons (NULL_TREE,
5281 convert (ptr_type_node,
5282 build_unary_op (ADDR_EXPR,
5283 METHOD_DEFINITION (entries), 1)),
5284 elemlist);
5286 initlist = tree_cons (NULL_TREE,
5287 objc_build_constructor (type, nreverse (elemlist)),
5288 initlist);
5290 entries = TREE_CHAIN (entries);
5292 while (entries);
5294 return objc_build_constructor (build_array_type (type, 0),
5295 nreverse (initlist));
5298 /* To accomplish method prototyping without generating all kinds of
5299 inane warnings, the definition of the dispatch table entries were
5300 changed from:
5302 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5304 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5306 static tree
5307 build_method_template (void)
5309 tree _SLT_record;
5310 tree field_decl, field_decl_chain;
5312 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
5314 /* SEL _cmd; */
5315 field_decl = create_field_decl (objc_selector_type, "_cmd");
5316 field_decl_chain = field_decl;
5318 /* char *method_types; */
5319 field_decl = create_field_decl (string_type_node, "method_types");
5320 chainon (field_decl_chain, field_decl);
5322 /* void *_imp; */
5323 field_decl = create_field_decl (build_pointer_type (void_type_node),
5324 "_imp");
5325 chainon (field_decl_chain, field_decl);
5327 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
5329 return _SLT_record;
5333 static tree
5334 generate_dispatch_table (tree type, const char *name, int size, tree list)
5336 tree decl, initlist;
5338 decl = start_var_decl (type, synth_id_with_class_suffix
5339 (name, objc_implementation_context));
5341 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5342 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5343 initlist = tree_cons (NULL_TREE, list, initlist);
5345 finish_var_decl (decl,
5346 objc_build_constructor (TREE_TYPE (decl),
5347 nreverse (initlist)));
5349 return decl;
5352 static void
5353 mark_referenced_methods (void)
5355 struct imp_entry *impent;
5356 tree chain;
5358 for (impent = imp_list; impent; impent = impent->next)
5360 chain = CLASS_CLS_METHODS (impent->imp_context);
5361 while (chain)
5363 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5364 chain = TREE_CHAIN (chain);
5367 chain = CLASS_NST_METHODS (impent->imp_context);
5368 while (chain)
5370 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5371 chain = TREE_CHAIN (chain);
5376 static void
5377 generate_dispatch_tables (void)
5379 tree initlist, chain, method_list_template;
5380 int size;
5382 if (!objc_method_template)
5383 objc_method_template = build_method_template ();
5385 chain = CLASS_CLS_METHODS (objc_implementation_context);
5386 if (chain)
5388 size = list_length (chain);
5390 method_list_template
5391 = build_method_list_template (objc_method_template, size);
5392 initlist
5393 = build_dispatch_table_initializer (objc_method_template, chain);
5395 UOBJC_CLASS_METHODS_decl
5396 = generate_dispatch_table (method_list_template,
5397 ((TREE_CODE (objc_implementation_context)
5398 == CLASS_IMPLEMENTATION_TYPE)
5399 ? "_OBJC_CLASS_METHODS"
5400 : "_OBJC_CATEGORY_CLASS_METHODS"),
5401 size, initlist);
5403 else
5404 UOBJC_CLASS_METHODS_decl = 0;
5406 chain = CLASS_NST_METHODS (objc_implementation_context);
5407 if (chain)
5409 size = list_length (chain);
5411 method_list_template
5412 = build_method_list_template (objc_method_template, size);
5413 initlist
5414 = build_dispatch_table_initializer (objc_method_template, chain);
5416 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5417 UOBJC_INSTANCE_METHODS_decl
5418 = generate_dispatch_table (method_list_template,
5419 "_OBJC_INSTANCE_METHODS",
5420 size, initlist);
5421 else
5422 /* We have a category. */
5423 UOBJC_INSTANCE_METHODS_decl
5424 = generate_dispatch_table (method_list_template,
5425 "_OBJC_CATEGORY_INSTANCE_METHODS",
5426 size, initlist);
5428 else
5429 UOBJC_INSTANCE_METHODS_decl = 0;
5432 static tree
5433 generate_protocol_list (tree i_or_p)
5435 tree initlist;
5436 tree refs_decl, lproto, e, plist;
5437 int size = 0;
5438 const char *ref_name;
5440 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5441 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5442 plist = CLASS_PROTOCOL_LIST (i_or_p);
5443 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5444 plist = PROTOCOL_LIST (i_or_p);
5445 else
5446 abort ();
5448 /* Compute size. */
5449 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5450 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5451 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5452 size++;
5454 /* Build initializer. */
5455 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5456 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5457 initlist = tree_cons (NULL_TREE, e, initlist);
5459 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5461 tree pval = TREE_VALUE (lproto);
5463 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5464 && PROTOCOL_FORWARD_DECL (pval))
5466 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
5467 initlist = tree_cons (NULL_TREE, e, initlist);
5471 /* static struct objc_protocol *refs[n]; */
5473 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5474 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5475 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5476 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5477 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5478 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5479 else
5480 abort ();
5482 refs_decl = start_var_decl
5483 (build_array_type
5484 (build_pointer_type (objc_protocol_template),
5485 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5486 ref_name);
5488 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5489 nreverse (initlist)));
5491 return refs_decl;
5494 static tree
5495 build_category_initializer (tree type, tree cat_name, tree class_name,
5496 tree instance_methods, tree class_methods,
5497 tree protocol_list)
5499 tree initlist = NULL_TREE, expr;
5501 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5502 initlist = tree_cons (NULL_TREE, class_name, initlist);
5504 if (!instance_methods)
5505 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5506 else
5508 expr = convert (objc_method_list_ptr,
5509 build_unary_op (ADDR_EXPR, instance_methods, 0));
5510 initlist = tree_cons (NULL_TREE, expr, initlist);
5512 if (!class_methods)
5513 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5514 else
5516 expr = convert (objc_method_list_ptr,
5517 build_unary_op (ADDR_EXPR, class_methods, 0));
5518 initlist = tree_cons (NULL_TREE, expr, initlist);
5521 /* protocol_list = */
5522 if (!protocol_list)
5523 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5524 else
5526 expr = convert (build_pointer_type
5527 (build_pointer_type
5528 (objc_protocol_template)),
5529 build_unary_op (ADDR_EXPR, protocol_list, 0));
5530 initlist = tree_cons (NULL_TREE, expr, initlist);
5533 return objc_build_constructor (type, nreverse (initlist));
5536 /* struct _objc_class {
5537 struct objc_class *isa;
5538 struct objc_class *super_class;
5539 char *name;
5540 long version;
5541 long info;
5542 long instance_size;
5543 struct objc_ivar_list *ivars;
5544 struct objc_method_list *methods;
5545 if (flag_next_runtime)
5546 struct objc_cache *cache;
5547 else {
5548 struct sarray *dtable;
5549 struct objc_class *subclass_list;
5550 struct objc_class *sibling_class;
5552 struct objc_protocol_list *protocols;
5553 if (flag_next_runtime)
5554 void *sel_id;
5555 void *gc_object_type;
5556 }; */
5558 static tree
5559 build_shared_structure_initializer (tree type, tree isa, tree super,
5560 tree name, tree size, int status,
5561 tree dispatch_table, tree ivar_list,
5562 tree protocol_list)
5564 tree initlist = NULL_TREE, expr;
5566 /* isa = */
5567 initlist = tree_cons (NULL_TREE, isa, initlist);
5569 /* super_class = */
5570 initlist = tree_cons (NULL_TREE, super, initlist);
5572 /* name = */
5573 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5575 /* version = */
5576 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5577 initlist);
5579 /* info = */
5580 initlist = tree_cons (NULL_TREE,
5581 build_int_cst (long_integer_type_node, status),
5582 initlist);
5584 /* instance_size = */
5585 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5586 initlist);
5588 /* objc_ivar_list = */
5589 if (!ivar_list)
5590 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5591 else
5593 expr = convert (objc_ivar_list_ptr,
5594 build_unary_op (ADDR_EXPR, ivar_list, 0));
5595 initlist = tree_cons (NULL_TREE, expr, initlist);
5598 /* objc_method_list = */
5599 if (!dispatch_table)
5600 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5601 else
5603 expr = convert (objc_method_list_ptr,
5604 build_unary_op (ADDR_EXPR, dispatch_table, 0));
5605 initlist = tree_cons (NULL_TREE, expr, initlist);
5608 if (flag_next_runtime)
5609 /* method_cache = */
5610 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5611 else
5613 /* dtable = */
5614 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5616 /* subclass_list = */
5617 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5619 /* sibling_class = */
5620 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5623 /* protocol_list = */
5624 if (! protocol_list)
5625 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5626 else
5628 expr = convert (build_pointer_type
5629 (build_pointer_type
5630 (objc_protocol_template)),
5631 build_unary_op (ADDR_EXPR, protocol_list, 0));
5632 initlist = tree_cons (NULL_TREE, expr, initlist);
5635 if (flag_next_runtime)
5636 /* sel_id = NULL */
5637 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5639 /* gc_object_type = NULL */
5640 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5642 return objc_build_constructor (type, nreverse (initlist));
5645 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5647 static inline tree
5648 lookup_category (tree class, tree cat_name)
5650 tree category = CLASS_CATEGORY_LIST (class);
5652 while (category && CLASS_SUPER_NAME (category) != cat_name)
5653 category = CLASS_CATEGORY_LIST (category);
5654 return category;
5657 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5659 static void
5660 generate_category (tree cat)
5662 tree decl;
5663 tree initlist, cat_name_expr, class_name_expr;
5664 tree protocol_decl, category;
5666 add_class_reference (CLASS_NAME (cat));
5667 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5669 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5671 category = lookup_category (implementation_template,
5672 CLASS_SUPER_NAME (cat));
5674 if (category && CLASS_PROTOCOL_LIST (category))
5676 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5677 protocol_decl = generate_protocol_list (category);
5679 else
5680 protocol_decl = 0;
5682 decl = start_var_decl (objc_category_template,
5683 synth_id_with_class_suffix
5684 ("_OBJC_CATEGORY", objc_implementation_context));
5686 initlist = build_category_initializer (TREE_TYPE (decl),
5687 cat_name_expr, class_name_expr,
5688 UOBJC_INSTANCE_METHODS_decl,
5689 UOBJC_CLASS_METHODS_decl,
5690 protocol_decl);
5692 finish_var_decl (decl, initlist);
5695 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5696 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5698 static void
5699 generate_shared_structures (int cls_flags)
5701 tree sc_spec, decl_specs, decl;
5702 tree name_expr, super_expr, root_expr;
5703 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5704 tree cast_type, initlist, protocol_decl;
5706 my_super_id = CLASS_SUPER_NAME (implementation_template);
5707 if (my_super_id)
5709 add_class_reference (my_super_id);
5711 /* Compute "my_root_id" - this is required for code generation.
5712 the "isa" for all meta class structures points to the root of
5713 the inheritance hierarchy (e.g. "__Object")... */
5714 my_root_id = my_super_id;
5717 tree my_root_int = lookup_interface (my_root_id);
5719 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5720 my_root_id = CLASS_SUPER_NAME (my_root_int);
5721 else
5722 break;
5724 while (1);
5726 else
5727 /* No super class. */
5728 my_root_id = CLASS_NAME (implementation_template);
5730 cast_type = build_pointer_type (objc_class_template);
5731 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5732 class_names);
5734 /* Install class `isa' and `super' pointers at runtime. */
5735 if (my_super_id)
5737 super_expr = add_objc_string (my_super_id, class_names);
5738 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5740 else
5741 super_expr = build_int_cst (NULL_TREE, 0);
5743 root_expr = add_objc_string (my_root_id, class_names);
5744 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5746 if (CLASS_PROTOCOL_LIST (implementation_template))
5748 generate_protocol_references
5749 (CLASS_PROTOCOL_LIST (implementation_template));
5750 protocol_decl = generate_protocol_list (implementation_template);
5752 else
5753 protocol_decl = 0;
5755 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5757 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5758 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5760 decl = start_var_decl (objc_class_template,
5761 IDENTIFIER_POINTER
5762 (DECL_NAME (UOBJC_METACLASS_decl)));
5764 initlist
5765 = build_shared_structure_initializer
5766 (TREE_TYPE (decl),
5767 root_expr, super_expr, name_expr,
5768 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5769 2 /*CLS_META*/,
5770 UOBJC_CLASS_METHODS_decl,
5771 UOBJC_CLASS_VARIABLES_decl,
5772 protocol_decl);
5774 finish_var_decl (decl, initlist);
5776 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5778 decl = start_var_decl (objc_class_template,
5779 IDENTIFIER_POINTER
5780 (DECL_NAME (UOBJC_CLASS_decl)));
5782 initlist
5783 = build_shared_structure_initializer
5784 (TREE_TYPE (decl),
5785 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5786 super_expr, name_expr,
5787 convert (integer_type_node,
5788 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5789 (implementation_template))),
5790 1 /*CLS_FACTORY*/ | cls_flags,
5791 UOBJC_INSTANCE_METHODS_decl,
5792 UOBJC_INSTANCE_VARIABLES_decl,
5793 protocol_decl);
5795 finish_var_decl (decl, initlist);
5799 static const char *
5800 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5802 static char string[BUFSIZE];
5804 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5805 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5807 sprintf (string, "%s_%s", preamble,
5808 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5810 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5811 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5813 /* We have a category. */
5814 const char *const class_name
5815 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5816 const char *const class_super_name
5817 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5818 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5820 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5822 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5823 sprintf (string, "%s_%s", preamble, protocol_name);
5825 else
5826 abort ();
5828 return string;
5831 /* If type is empty or only type qualifiers are present, add default
5832 type of id (otherwise grokdeclarator will default to int). */
5834 static tree
5835 adjust_type_for_id_default (tree type)
5837 if (!type)
5838 type = make_node (TREE_LIST);
5840 if (!TREE_VALUE (type))
5841 TREE_VALUE (type) = objc_object_type;
5842 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5843 && TYPED_OBJECT (TREE_VALUE (type)))
5844 error ("can not use an object as parameter to a method");
5846 return type;
5849 /* Usage:
5850 keyworddecl:
5851 selector ':' '(' typename ')' identifier
5853 Purpose:
5854 Transform an Objective-C keyword argument into
5855 the C equivalent parameter declarator.
5857 In: key_name, an "identifier_node" (optional).
5858 arg_type, a "tree_list" (optional).
5859 arg_name, an "identifier_node".
5861 Note: It would be really nice to strongly type the preceding
5862 arguments in the function prototype; however, then I
5863 could not use the "accessor" macros defined in "tree.h".
5865 Out: an instance of "keyword_decl". */
5867 tree
5868 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5870 tree keyword_decl;
5872 /* If no type is specified, default to "id". */
5873 arg_type = adjust_type_for_id_default (arg_type);
5875 keyword_decl = make_node (KEYWORD_DECL);
5877 TREE_TYPE (keyword_decl) = arg_type;
5878 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5879 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5881 return keyword_decl;
5884 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5886 static tree
5887 build_keyword_selector (tree selector)
5889 int len = 0;
5890 tree key_chain, key_name;
5891 char *buf;
5893 /* Scan the selector to see how much space we'll need. */
5894 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5896 if (TREE_CODE (selector) == KEYWORD_DECL)
5897 key_name = KEYWORD_KEY_NAME (key_chain);
5898 else if (TREE_CODE (selector) == TREE_LIST)
5899 key_name = TREE_PURPOSE (key_chain);
5900 else
5901 abort ();
5903 if (key_name)
5904 len += IDENTIFIER_LENGTH (key_name) + 1;
5905 else
5906 /* Just a ':' arg. */
5907 len++;
5910 buf = (char *) alloca (len + 1);
5911 /* Start the buffer out as an empty string. */
5912 buf[0] = '\0';
5914 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5916 if (TREE_CODE (selector) == KEYWORD_DECL)
5917 key_name = KEYWORD_KEY_NAME (key_chain);
5918 else if (TREE_CODE (selector) == TREE_LIST)
5920 key_name = TREE_PURPOSE (key_chain);
5921 /* The keyword decl chain will later be used as a function argument
5922 chain. Unhook the selector itself so as to not confuse other
5923 parts of the compiler. */
5924 TREE_PURPOSE (key_chain) = NULL_TREE;
5926 else
5927 abort ();
5929 if (key_name)
5930 strcat (buf, IDENTIFIER_POINTER (key_name));
5931 strcat (buf, ":");
5934 return get_identifier (buf);
5937 /* Used for declarations and definitions. */
5939 static tree
5940 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5941 tree add_args, bool ellipsis)
5943 tree method_decl;
5945 /* If no type is specified, default to "id". */
5946 ret_type = adjust_type_for_id_default (ret_type);
5948 method_decl = make_node (code);
5949 TREE_TYPE (method_decl) = ret_type;
5951 /* If we have a keyword selector, create an identifier_node that
5952 represents the full selector name (`:' included)... */
5953 if (TREE_CODE (selector) == KEYWORD_DECL)
5955 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5956 METHOD_SEL_ARGS (method_decl) = selector;
5957 METHOD_ADD_ARGS (method_decl) = add_args;
5958 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
5960 else
5962 METHOD_SEL_NAME (method_decl) = selector;
5963 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5964 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5967 return method_decl;
5970 #define METHOD_DEF 0
5971 #define METHOD_REF 1
5973 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5974 an argument list for method METH. CONTEXT is either METHOD_DEF or
5975 METHOD_REF, saying whether we are trying to define a method or call
5976 one. SUPERFLAG says this is for a send to super; this makes a
5977 difference for the NeXT calling sequence in which the lookup and
5978 the method call are done together. If METH is null, user-defined
5979 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5981 static tree
5982 get_arg_type_list (tree meth, int context, int superflag)
5984 tree arglist, akey;
5986 /* Receiver type. */
5987 if (flag_next_runtime && superflag)
5988 arglist = build_tree_list (NULL_TREE, objc_super_type);
5989 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5990 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5991 else
5992 arglist = build_tree_list (NULL_TREE, objc_object_type);
5994 /* Selector type - will eventually change to `int'. */
5995 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5997 /* No actual method prototype given -- assume that remaining arguments
5998 are `...'. */
5999 if (!meth)
6000 return arglist;
6002 /* Build a list of argument types. */
6003 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6005 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6007 /* Decay arrays and functions into pointers. */
6008 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6009 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6010 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6011 arg_type = build_pointer_type (arg_type);
6013 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6016 if (METHOD_ADD_ARGS (meth))
6018 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6019 akey; akey = TREE_CHAIN (akey))
6021 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6023 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6026 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6027 goto lack_of_ellipsis;
6029 else
6031 lack_of_ellipsis:
6032 chainon (arglist, OBJC_VOID_AT_END);
6035 return arglist;
6038 static tree
6039 check_duplicates (hash hsh, int methods, int is_class)
6041 tree meth = NULL_TREE;
6043 if (hsh)
6045 meth = hsh->key;
6047 if (hsh->list)
6049 /* We have two or more methods with the same name but
6050 different types. */
6051 attr loop;
6053 /* But just how different are those types? If
6054 -Wno-strict-selector-match is specified, we shall not
6055 complain if the differences are solely among types with
6056 identical size and alignment. */
6057 if (!warn_strict_selector_match)
6059 for (loop = hsh->list; loop; loop = loop->next)
6060 if (!comp_proto_with_proto (meth, loop->value, 0))
6061 goto issue_warning;
6063 return meth;
6066 issue_warning:
6067 warning (0, "multiple %s named %<%c%s%> found",
6068 methods ? "methods" : "selectors",
6069 (is_class ? '+' : '-'),
6070 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
6072 warn_with_method (methods ? "using" : "found",
6073 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6074 ? '-'
6075 : '+'),
6076 meth);
6077 for (loop = hsh->list; loop; loop = loop->next)
6078 warn_with_method ("also found",
6079 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
6080 ? '-'
6081 : '+'),
6082 loop->value);
6085 return meth;
6088 /* If RECEIVER is a class reference, return the identifier node for
6089 the referenced class. RECEIVER is created by objc_get_class_reference,
6090 so we check the exact form created depending on which runtimes are
6091 used. */
6093 static tree
6094 receiver_is_class_object (tree receiver, int self, int super)
6096 tree chain, exp, arg;
6098 /* The receiver is 'self' or 'super' in the context of a class method. */
6099 if (objc_method_context
6100 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6101 && (self || super))
6102 return (super
6103 ? CLASS_SUPER_NAME (implementation_template)
6104 : CLASS_NAME (implementation_template));
6106 if (flag_next_runtime)
6108 /* The receiver is a variable created by
6109 build_class_reference_decl. */
6110 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6111 /* Look up the identifier. */
6112 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6113 if (TREE_PURPOSE (chain) == receiver)
6114 return TREE_VALUE (chain);
6117 /* The receiver is a function call that returns an id. Check if
6118 it is a call to objc_getClass, if so, pick up the class name. */
6119 if (TREE_CODE (receiver) == CALL_EXPR
6120 && (exp = TREE_OPERAND (receiver, 0))
6121 && TREE_CODE (exp) == ADDR_EXPR
6122 && (exp = TREE_OPERAND (exp, 0))
6123 && TREE_CODE (exp) == FUNCTION_DECL
6124 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6125 prototypes for objc_get_class(). Thankfully, they seem to share the
6126 same function type. */
6127 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6128 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6129 /* We have a call to objc_get_class/objc_getClass! */
6130 && (arg = TREE_OPERAND (receiver, 1))
6131 && TREE_CODE (arg) == TREE_LIST
6132 && (arg = TREE_VALUE (arg)))
6134 STRIP_NOPS (arg);
6135 if (TREE_CODE (arg) == ADDR_EXPR
6136 && (arg = TREE_OPERAND (arg, 0))
6137 && TREE_CODE (arg) == STRING_CST)
6138 /* Finally, we have the class name. */
6139 return get_identifier (TREE_STRING_POINTER (arg));
6141 return 0;
6144 /* If we are currently building a message expr, this holds
6145 the identifier of the selector of the message. This is
6146 used when printing warnings about argument mismatches. */
6148 static tree current_objc_message_selector = 0;
6150 tree
6151 objc_message_selector (void)
6153 return current_objc_message_selector;
6156 /* Construct an expression for sending a message.
6157 MESS has the object to send to in TREE_PURPOSE
6158 and the argument list (including selector) in TREE_VALUE.
6160 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6161 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6163 tree
6164 objc_build_message_expr (tree mess)
6166 tree receiver = TREE_PURPOSE (mess);
6167 tree sel_name;
6168 #ifdef OBJCPLUS
6169 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6170 #else
6171 tree args = TREE_VALUE (mess);
6172 #endif
6173 tree method_params = NULL_TREE;
6175 if (TREE_CODE (receiver) == ERROR_MARK)
6176 return error_mark_node;
6178 /* Obtain the full selector name. */
6179 if (TREE_CODE (args) == IDENTIFIER_NODE)
6180 /* A unary selector. */
6181 sel_name = args;
6182 else if (TREE_CODE (args) == TREE_LIST)
6183 sel_name = build_keyword_selector (args);
6184 else
6185 abort ();
6187 /* Build the parameter list to give to the method. */
6188 if (TREE_CODE (args) == TREE_LIST)
6189 #ifdef OBJCPLUS
6190 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6191 #else
6193 tree chain = args, prev = NULL_TREE;
6195 /* We have a keyword selector--check for comma expressions. */
6196 while (chain)
6198 tree element = TREE_VALUE (chain);
6200 /* We have a comma expression, must collapse... */
6201 if (TREE_CODE (element) == TREE_LIST)
6203 if (prev)
6204 TREE_CHAIN (prev) = element;
6205 else
6206 args = element;
6208 prev = chain;
6209 chain = TREE_CHAIN (chain);
6211 method_params = args;
6213 #endif
6215 #ifdef OBJCPLUS
6216 if (processing_template_decl)
6217 /* Must wait until template instantiation time. */
6218 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6219 method_params);
6220 #endif
6222 return objc_finish_message_expr (receiver, sel_name, method_params);
6225 /* Look up method SEL_NAME that would be suitable for receiver
6226 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6227 nonzero), and report on any duplicates. */
6229 static tree
6230 lookup_method_in_hash_lists (tree sel_name, int is_class)
6232 hash method_prototype = NULL;
6234 if (!is_class)
6235 method_prototype = hash_lookup (nst_method_hash_list,
6236 sel_name);
6238 if (!method_prototype)
6240 method_prototype = hash_lookup (cls_method_hash_list,
6241 sel_name);
6242 is_class = 1;
6245 return check_duplicates (method_prototype, 1, is_class);
6248 /* The 'objc_finish_message_expr' routine is called from within
6249 'objc_build_message_expr' for non-template functions. In the case of
6250 C++ template functions, it is called from 'build_expr_from_tree'
6251 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6253 tree
6254 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6256 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6257 tree selector, retval, class_tree;
6258 int self, super, have_cast;
6260 /* Extract the receiver of the message, as well as its type
6261 (where the latter may take the form of a cast or be inferred
6262 from the implementation context). */
6263 rtype = receiver;
6264 while (TREE_CODE (rtype) == COMPOUND_EXPR
6265 || TREE_CODE (rtype) == MODIFY_EXPR
6266 || TREE_CODE (rtype) == NOP_EXPR
6267 || TREE_CODE (rtype) == CONVERT_EXPR
6268 || TREE_CODE (rtype) == COMPONENT_REF)
6269 rtype = TREE_OPERAND (rtype, 0);
6270 self = (rtype == self_decl);
6271 super = (rtype == UOBJC_SUPER_decl);
6272 rtype = TREE_TYPE (receiver);
6273 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6274 || (TREE_CODE (receiver) == COMPOUND_EXPR
6275 && !IS_SUPER (rtype)));
6277 /* If we are calling [super dealloc], reset our warning flag. */
6278 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6279 should_call_super_dealloc = 0;
6281 /* If the receiver is a class object, retrieve the corresponding
6282 @interface, if one exists. */
6283 class_tree = receiver_is_class_object (receiver, self, super);
6285 /* Now determine the receiver type (if an explicit cast has not been
6286 provided). */
6287 if (!have_cast)
6289 if (class_tree)
6290 rtype = lookup_interface (class_tree);
6291 /* Handle `self' and `super'. */
6292 else if (super)
6294 if (!CLASS_SUPER_NAME (implementation_template))
6296 error ("no super class declared in @interface for %qs",
6297 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
6298 return error_mark_node;
6300 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6302 else if (self)
6303 rtype = lookup_interface (CLASS_NAME (implementation_template));
6306 /* If receiver is of type `id' or `Class' (or if the @interface for a
6307 class is not visible), we shall be satisfied with the existence of
6308 any instance or class method. */
6309 if (objc_is_id (rtype))
6311 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6312 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6313 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6314 : NULL_TREE);
6315 rtype = NULL_TREE;
6317 if (rprotos)
6319 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6320 in protocols themselves for the method prototype. */
6321 method_prototype
6322 = lookup_method_in_protocol_list (rprotos, sel_name,
6323 class_tree != NULL_TREE);
6325 /* If messaging 'Class <Proto>' but did not find a class method
6326 prototype, search for an instance method instead, and warn
6327 about having done so. */
6328 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6330 method_prototype
6331 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6333 if (method_prototype)
6334 warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
6335 IDENTIFIER_POINTER (sel_name),
6336 IDENTIFIER_POINTER (sel_name));
6340 else if (rtype)
6342 tree orig_rtype = rtype, saved_rtype;
6344 if (TREE_CODE (rtype) == POINTER_TYPE)
6345 rtype = TREE_TYPE (rtype);
6346 /* Traverse typedef aliases */
6347 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6348 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6349 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6350 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6351 saved_rtype = rtype;
6352 if (TYPED_OBJECT (rtype))
6354 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6355 rtype = TYPE_OBJC_INTERFACE (rtype);
6357 /* If we could not find an @interface declaration, we must have
6358 only seen a @class declaration; so, we cannot say anything
6359 more intelligent about which methods the receiver will
6360 understand. */
6361 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6362 rtype = NULL_TREE;
6363 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6364 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6366 /* We have a valid ObjC class name. Look up the method name
6367 in the published @interface for the class (and its
6368 superclasses). */
6369 method_prototype
6370 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6372 /* If the method was not found in the @interface, it may still
6373 exist locally as part of the @implementation. */
6374 if (!method_prototype && objc_implementation_context
6375 && CLASS_NAME (objc_implementation_context)
6376 == OBJC_TYPE_NAME (rtype))
6377 method_prototype
6378 = lookup_method
6379 ((class_tree
6380 ? CLASS_CLS_METHODS (objc_implementation_context)
6381 : CLASS_NST_METHODS (objc_implementation_context)),
6382 sel_name);
6384 /* If we haven't found a candidate method by now, try looking for
6385 it in the protocol list. */
6386 if (!method_prototype && rprotos)
6387 method_prototype
6388 = lookup_method_in_protocol_list (rprotos, sel_name,
6389 class_tree != NULL_TREE);
6391 else
6393 warning (0, "invalid receiver type %qs",
6394 gen_type_name (orig_rtype));
6395 /* After issuing the "invalid receiver" warning, perform method
6396 lookup as if we were messaging 'id'. */
6397 rtype = rprotos = NULL_TREE;
6402 /* For 'id' or 'Class' receivers, search in the global hash table
6403 as a last resort. For all receivers, warn if protocol searches
6404 have failed. */
6405 if (!method_prototype)
6407 if (rprotos)
6408 warning (0, "%<%c%s%> not found in protocol(s)",
6409 (class_tree ? '+' : '-'),
6410 IDENTIFIER_POINTER (sel_name));
6412 if (!rtype)
6413 method_prototype
6414 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6417 if (!method_prototype)
6419 static bool warn_missing_methods = false;
6421 if (rtype)
6422 warning (0, "%qs may not respond to %<%c%s%>",
6423 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
6424 (class_tree ? '+' : '-'),
6425 IDENTIFIER_POINTER (sel_name));
6426 /* If we are messaging an 'id' or 'Class' object and made it here,
6427 then we have failed to find _any_ instance or class method,
6428 respectively. */
6429 else
6430 warning (0, "no %<%c%s%> method found",
6431 (class_tree ? '+' : '-'),
6432 IDENTIFIER_POINTER (sel_name));
6434 if (!warn_missing_methods)
6436 warning (0, "(Messages without a matching method signature");
6437 warning (0, "will be assumed to return %<id%> and accept");
6438 warning (0, "%<...%> as arguments.)");
6439 warn_missing_methods = true;
6443 /* Save the selector name for printing error messages. */
6444 current_objc_message_selector = sel_name;
6446 /* Build the parameters list for looking up the method.
6447 These are the object itself and the selector. */
6449 if (flag_typed_selectors)
6450 selector = build_typed_selector_reference (sel_name, method_prototype);
6451 else
6452 selector = build_selector_reference (sel_name);
6454 retval = build_objc_method_call (super, method_prototype,
6455 receiver,
6456 selector, method_params);
6458 current_objc_message_selector = 0;
6460 return retval;
6463 /* Build a tree expression to send OBJECT the operation SELECTOR,
6464 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6465 assuming the method has prototype METHOD_PROTOTYPE.
6466 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6467 Use METHOD_PARAMS as list of args to pass to the method.
6468 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6470 static tree
6471 build_objc_method_call (int super_flag, tree method_prototype,
6472 tree lookup_object, tree selector,
6473 tree method_params)
6475 tree sender = (super_flag ? umsg_super_decl :
6476 (!flag_next_runtime || flag_nil_receivers
6477 ? (flag_objc_direct_dispatch
6478 ? umsg_fast_decl
6479 : umsg_decl)
6480 : umsg_nonnil_decl));
6481 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6483 /* If a prototype for the method to be called exists, then cast
6484 the sender's return type and arguments to match that of the method.
6485 Otherwise, leave sender as is. */
6486 tree ret_type
6487 = (method_prototype
6488 ? TREE_VALUE (TREE_TYPE (method_prototype))
6489 : objc_object_type);
6490 tree sender_cast
6491 = build_pointer_type
6492 (build_function_type
6493 (ret_type,
6494 get_arg_type_list
6495 (method_prototype, METHOD_REF, super_flag)));
6496 tree method, t;
6498 lookup_object = build_c_cast (rcv_p, lookup_object);
6500 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6501 lookup_object = save_expr (lookup_object);
6503 if (flag_next_runtime)
6505 /* If we are returning a struct in memory, and the address
6506 of that memory location is passed as a hidden first
6507 argument, then change which messenger entry point this
6508 expr will call. NB: Note that sender_cast remains
6509 unchanged (it already has a struct return type). */
6510 if (!targetm.calls.struct_value_rtx (0, 0)
6511 && (TREE_CODE (ret_type) == RECORD_TYPE
6512 || TREE_CODE (ret_type) == UNION_TYPE)
6513 && targetm.calls.return_in_memory (ret_type, 0))
6514 sender = (super_flag ? umsg_super_stret_decl :
6515 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6517 method_params = tree_cons (NULL_TREE, lookup_object,
6518 tree_cons (NULL_TREE, selector,
6519 method_params));
6520 method = build_fold_addr_expr (sender);
6522 else
6524 /* This is the portable (GNU) way. */
6525 tree object;
6527 /* First, call the lookup function to get a pointer to the method,
6528 then cast the pointer, then call it with the method arguments. */
6530 object = (super_flag ? self_decl : lookup_object);
6532 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6533 t = tree_cons (NULL_TREE, lookup_object, t);
6534 method = build_function_call (sender, t);
6536 /* Pass the object to the method. */
6537 method_params = tree_cons (NULL_TREE, object,
6538 tree_cons (NULL_TREE, selector,
6539 method_params));
6542 /* ??? Selector is not at this point something we can use inside
6543 the compiler itself. Set it to garbage for the nonce. */
6544 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6545 return build_function_call (t, method_params);
6548 static void
6549 build_protocol_reference (tree p)
6551 tree decl;
6552 const char *proto_name;
6554 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6556 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6557 decl = start_var_decl (objc_protocol_template, proto_name);
6559 PROTOCOL_FORWARD_DECL (p) = decl;
6562 /* This function is called by the parser when (and only when) a
6563 @protocol() expression is found, in order to compile it. */
6564 tree
6565 objc_build_protocol_expr (tree protoname)
6567 tree expr;
6568 tree p = lookup_protocol (protoname);
6570 if (!p)
6572 error ("cannot find protocol declaration for %qs",
6573 IDENTIFIER_POINTER (protoname));
6574 return error_mark_node;
6577 if (!PROTOCOL_FORWARD_DECL (p))
6578 build_protocol_reference (p);
6580 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6582 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6583 if we have it, rather than converting it here. */
6584 expr = convert (objc_protocol_type, expr);
6586 /* The @protocol() expression is being compiled into a pointer to a
6587 statically allocated instance of the Protocol class. To become
6588 usable at runtime, the 'isa' pointer of the instance need to be
6589 fixed up at runtime by the runtime library, to point to the
6590 actual 'Protocol' class. */
6592 /* For the GNU runtime, put the static Protocol instance in the list
6593 of statically allocated instances, so that we make sure that its
6594 'isa' pointer is fixed up at runtime by the GNU runtime library
6595 to point to the Protocol class (at runtime, when loading the
6596 module, the GNU runtime library loops on the statically allocated
6597 instances (as found in the defs field in objc_symtab) and fixups
6598 all the 'isa' pointers of those objects). */
6599 if (! flag_next_runtime)
6601 /* This type is a struct containing the fields of a Protocol
6602 object. (Cfr. objc_protocol_type instead is the type of a pointer
6603 to such a struct). */
6604 tree protocol_struct_type = xref_tag
6605 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6606 tree *chain;
6608 /* Look for the list of Protocol statically allocated instances
6609 to fixup at runtime. Create a new list to hold Protocol
6610 statically allocated instances, if the list is not found. At
6611 present there is only another list, holding NSConstantString
6612 static instances to be fixed up at runtime. */
6613 for (chain = &objc_static_instances;
6614 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6615 chain = &TREE_CHAIN (*chain));
6616 if (!*chain)
6618 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6619 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6620 class_names);
6623 /* Add this statically allocated instance to the Protocol list. */
6624 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6625 PROTOCOL_FORWARD_DECL (p),
6626 TREE_PURPOSE (*chain));
6630 return expr;
6633 /* This function is called by the parser when a @selector() expression
6634 is found, in order to compile it. It is only called by the parser
6635 and only to compile a @selector(). */
6636 tree
6637 objc_build_selector_expr (tree selnamelist)
6639 tree selname;
6641 /* Obtain the full selector name. */
6642 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6643 /* A unary selector. */
6644 selname = selnamelist;
6645 else if (TREE_CODE (selnamelist) == TREE_LIST)
6646 selname = build_keyword_selector (selnamelist);
6647 else
6648 abort ();
6650 /* If we are required to check @selector() expressions as they
6651 are found, check that the selector has been declared. */
6652 if (warn_undeclared_selector)
6654 /* Look the selector up in the list of all known class and
6655 instance methods (up to this line) to check that the selector
6656 exists. */
6657 hash hsh;
6659 /* First try with instance methods. */
6660 hsh = hash_lookup (nst_method_hash_list, selname);
6662 /* If not found, try with class methods. */
6663 if (!hsh)
6665 hsh = hash_lookup (cls_method_hash_list, selname);
6668 /* If still not found, print out a warning. */
6669 if (!hsh)
6671 warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
6676 if (flag_typed_selectors)
6677 return build_typed_selector_reference (selname, 0);
6678 else
6679 return build_selector_reference (selname);
6682 tree
6683 objc_build_encode_expr (tree type)
6685 tree result;
6686 const char *string;
6688 encode_type (type, obstack_object_size (&util_obstack),
6689 OBJC_ENCODE_INLINE_DEFS);
6690 obstack_1grow (&util_obstack, 0); /* null terminate string */
6691 string = obstack_finish (&util_obstack);
6693 /* Synthesize a string that represents the encoded struct/union. */
6694 result = my_build_string (strlen (string) + 1, string);
6695 obstack_free (&util_obstack, util_firstobj);
6696 return result;
6699 static tree
6700 build_ivar_reference (tree id)
6702 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6704 /* Historically, a class method that produced objects (factory
6705 method) would assign `self' to the instance that it
6706 allocated. This would effectively turn the class method into
6707 an instance method. Following this assignment, the instance
6708 variables could be accessed. That practice, while safe,
6709 violates the simple rule that a class method should not refer
6710 to an instance variable. It's better to catch the cases
6711 where this is done unknowingly than to support the above
6712 paradigm. */
6713 warning (0, "instance variable %qs accessed in class method",
6714 IDENTIFIER_POINTER (id));
6715 self_decl = convert (objc_instance_type, self_decl); /* cast */
6718 return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
6721 /* Compute a hash value for a given method SEL_NAME. */
6723 static size_t
6724 hash_func (tree sel_name)
6726 const unsigned char *s
6727 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6728 size_t h = 0;
6730 while (*s)
6731 h = h * 67 + *s++ - 113;
6732 return h;
6735 static void
6736 hash_init (void)
6738 nst_method_hash_list
6739 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6740 cls_method_hash_list
6741 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6743 /* Initialize the hash table used to hold the constant string objects. */
6744 string_htab = htab_create_ggc (31, string_hash,
6745 string_eq, NULL);
6747 /* Initialize the hash table used to hold EH-volatilized types. */
6748 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6749 volatilized_eq, NULL);
6752 /* WARNING!!!! hash_enter is called with a method, and will peek
6753 inside to find its selector! But hash_lookup is given a selector
6754 directly, and looks for the selector that's inside the found
6755 entry's key (method) for comparison. */
6757 static void
6758 hash_enter (hash *hashlist, tree method)
6760 hash obj;
6761 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6763 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6764 obj->list = 0;
6765 obj->next = hashlist[slot];
6766 obj->key = method;
6768 hashlist[slot] = obj; /* append to front */
6771 static hash
6772 hash_lookup (hash *hashlist, tree sel_name)
6774 hash target;
6776 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6778 while (target)
6780 if (sel_name == METHOD_SEL_NAME (target->key))
6781 return target;
6783 target = target->next;
6785 return 0;
6788 static void
6789 hash_add_attr (hash entry, tree value)
6791 attr obj;
6793 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6794 obj->next = entry->list;
6795 obj->value = value;
6797 entry->list = obj; /* append to front */
6800 static tree
6801 lookup_method (tree mchain, tree method)
6803 tree key;
6805 if (TREE_CODE (method) == IDENTIFIER_NODE)
6806 key = method;
6807 else
6808 key = METHOD_SEL_NAME (method);
6810 while (mchain)
6812 if (METHOD_SEL_NAME (mchain) == key)
6813 return mchain;
6815 mchain = TREE_CHAIN (mchain);
6817 return NULL_TREE;
6820 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6821 in INTERFACE, along with any categories and protocols attached thereto.
6822 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6823 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6824 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6825 be found in INTERFACE or any of its superclasses, look for an _instance_
6826 method of the same name in the root class as a last resort.
6828 If a suitable method cannot be found, return NULL_TREE. */
6830 static tree
6831 lookup_method_static (tree interface, tree ident, int flags)
6833 tree meth = NULL_TREE, root_inter = NULL_TREE;
6834 tree inter = interface;
6835 int is_class = (flags & OBJC_LOOKUP_CLASS);
6836 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6838 while (inter)
6840 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6841 tree category = inter;
6843 /* First, look up the method in the class itself. */
6844 if ((meth = lookup_method (chain, ident)))
6845 return meth;
6847 /* Failing that, look for the method in each category of the class. */
6848 while ((category = CLASS_CATEGORY_LIST (category)))
6850 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6852 /* Check directly in each category. */
6853 if ((meth = lookup_method (chain, ident)))
6854 return meth;
6856 /* Failing that, check in each category's protocols. */
6857 if (CLASS_PROTOCOL_LIST (category))
6859 if ((meth = (lookup_method_in_protocol_list
6860 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6861 return meth;
6865 /* If not found in categories, check in protocols of the main class. */
6866 if (CLASS_PROTOCOL_LIST (inter))
6868 if ((meth = (lookup_method_in_protocol_list
6869 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6870 return meth;
6873 /* If we were instructed not to look in superclasses, don't. */
6874 if (no_superclasses)
6875 return NULL_TREE;
6877 /* Failing that, climb up the inheritance hierarchy. */
6878 root_inter = inter;
6879 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6881 while (inter);
6883 /* If no class (factory) method was found, check if an _instance_
6884 method of the same name exists in the root class. This is what
6885 the Objective-C runtime will do. If an instance method was not
6886 found, return 0. */
6887 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6890 /* Add the method to the hash list if it doesn't contain an identical
6891 method already. */
6892 static void
6893 add_method_to_hash_list (hash *hash_list, tree method)
6895 hash hsh;
6897 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6899 /* Install on a global chain. */
6900 hash_enter (hash_list, method);
6902 else
6904 /* Check types against those; if different, add to a list. */
6905 attr loop;
6906 int already_there = comp_proto_with_proto (method, hsh->key, 1);
6907 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6908 already_there |= comp_proto_with_proto (method, loop->value, 1);
6909 if (!already_there)
6910 hash_add_attr (hsh, method);
6914 static tree
6915 objc_add_method (tree class, tree method, int is_class)
6917 tree mth;
6919 if (!(mth = lookup_method (is_class
6920 ? CLASS_CLS_METHODS (class)
6921 : CLASS_NST_METHODS (class), method)))
6923 /* put method on list in reverse order */
6924 if (is_class)
6926 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6927 CLASS_CLS_METHODS (class) = method;
6929 else
6931 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6932 CLASS_NST_METHODS (class) = method;
6935 else
6937 /* When processing an @interface for a class or category, give hard
6938 errors on methods with identical selectors but differing argument
6939 and/or return types. We do not do this for @implementations, because
6940 C/C++ will do it for us (i.e., there will be duplicate function
6941 definition errors). */
6942 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6943 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6944 && !comp_proto_with_proto (method, mth, 1))
6945 error ("duplicate declaration of method %<%c%s%>",
6946 is_class ? '+' : '-',
6947 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6950 if (is_class)
6951 add_method_to_hash_list (cls_method_hash_list, method);
6952 else
6954 add_method_to_hash_list (nst_method_hash_list, method);
6956 /* Instance methods in root classes (and categories thereof)
6957 may act as class methods as a last resort. We also add
6958 instance methods listed in @protocol declarations to
6959 the class hash table, on the assumption that @protocols
6960 may be adopted by root classes or categories. */
6961 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6962 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6963 class = lookup_interface (CLASS_NAME (class));
6965 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6966 || !CLASS_SUPER_NAME (class))
6967 add_method_to_hash_list (cls_method_hash_list, method);
6970 return method;
6973 static tree
6974 add_class (tree class_name, tree name)
6976 struct interface_tuple **slot;
6978 /* Put interfaces on list in reverse order. */
6979 TREE_CHAIN (class_name) = interface_chain;
6980 interface_chain = class_name;
6982 if (interface_htab == NULL)
6983 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
6984 slot = (struct interface_tuple **)
6985 htab_find_slot_with_hash (interface_htab, name,
6986 htab_hash_pointer (name),
6987 INSERT);
6988 if (!*slot)
6990 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
6991 (*slot)->id = name;
6993 (*slot)->class_name = class_name;
6995 return interface_chain;
6998 static void
6999 add_category (tree class, tree category)
7001 /* Put categories on list in reverse order. */
7002 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
7004 if (cat)
7006 warning (0, "duplicate interface declaration for category %<%s(%s)%>",
7007 IDENTIFIER_POINTER (CLASS_NAME (class)),
7008 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
7010 else
7012 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
7013 CLASS_CATEGORY_LIST (class) = category;
7017 /* Called after parsing each instance variable declaration. Necessary to
7018 preserve typedefs and implement public/private...
7020 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
7022 static tree
7023 add_instance_variable (tree class, int public, tree field_decl)
7025 tree field_type = TREE_TYPE (field_decl);
7026 const char *ivar_name = DECL_NAME (field_decl)
7027 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
7028 : "<unnamed>";
7030 #ifdef OBJCPLUS
7031 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7033 error ("illegal reference type specified for instance variable %qs",
7034 ivar_name);
7035 /* Return class as is without adding this ivar. */
7036 return class;
7038 #endif
7040 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7041 || TYPE_SIZE (field_type) == error_mark_node)
7042 /* 'type[0]' is allowed, but 'type[]' is not! */
7044 error ("instance variable %qs has unknown size", ivar_name);
7045 /* Return class as is without adding this ivar. */
7046 return class;
7049 #ifdef OBJCPLUS
7050 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7051 need to either (1) warn the user about it or (2) generate suitable
7052 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7053 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7054 if (IS_AGGR_TYPE (field_type)
7055 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7056 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7057 || TYPE_POLYMORPHIC_P (field_type)))
7059 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
7061 if (flag_objc_call_cxx_cdtors)
7063 /* Since the ObjC runtime will be calling the constructors and
7064 destructors for us, the only thing we can't handle is the lack
7065 of a default constructor. */
7066 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7067 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7069 warning (0, "type %qs has no default constructor to call",
7070 type_name);
7072 /* If we cannot call a constructor, we should also avoid
7073 calling the destructor, for symmetry. */
7074 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7075 warning (0, "destructor for %qs shall not be run either",
7076 type_name);
7079 else
7081 static bool warn_cxx_ivars = false;
7083 if (TYPE_POLYMORPHIC_P (field_type))
7085 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7086 initialize them. */
7087 error ("type %qs has virtual member functions", type_name);
7088 error ("illegal aggregate type %qs specified "
7089 "for instance variable %qs",
7090 type_name, ivar_name);
7091 /* Return class as is without adding this ivar. */
7092 return class;
7095 /* User-defined constructors and destructors are not known to Obj-C
7096 and hence will not be called. This may or may not be a problem. */
7097 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7098 warning (0, "type %qs has a user-defined constructor", type_name);
7099 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7100 warning (0, "type %qs has a user-defined destructor", type_name);
7102 if (!warn_cxx_ivars)
7104 warning (0, "C++ constructors and destructors will not "
7105 "be invoked for Objective-C fields");
7106 warn_cxx_ivars = true;
7110 #endif
7112 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7113 switch (public)
7115 case 0:
7116 TREE_PUBLIC (field_decl) = 0;
7117 TREE_PRIVATE (field_decl) = 0;
7118 TREE_PROTECTED (field_decl) = 1;
7119 break;
7121 case 1:
7122 TREE_PUBLIC (field_decl) = 1;
7123 TREE_PRIVATE (field_decl) = 0;
7124 TREE_PROTECTED (field_decl) = 0;
7125 break;
7127 case 2:
7128 TREE_PUBLIC (field_decl) = 0;
7129 TREE_PRIVATE (field_decl) = 1;
7130 TREE_PROTECTED (field_decl) = 0;
7131 break;
7135 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
7137 return class;
7140 static tree
7141 is_ivar (tree decl_chain, tree ident)
7143 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7144 if (DECL_NAME (decl_chain) == ident)
7145 return decl_chain;
7146 return NULL_TREE;
7149 /* True if the ivar is private and we are not in its implementation. */
7151 static int
7152 is_private (tree decl)
7154 return (TREE_PRIVATE (decl)
7155 && ! is_ivar (CLASS_IVARS (implementation_template),
7156 DECL_NAME (decl)));
7159 /* We have an instance variable reference;, check to see if it is public. */
7162 objc_is_public (tree expr, tree identifier)
7164 tree basetype, decl;
7166 #ifdef OBJCPLUS
7167 if (processing_template_decl)
7168 return 1;
7169 #endif
7171 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7173 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7175 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7177 tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
7179 if (!class)
7181 error ("cannot find interface declaration for %qs",
7182 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
7183 return 0;
7186 if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
7188 if (TREE_PUBLIC (decl))
7189 return 1;
7191 /* Important difference between the Stepstone translator:
7192 all instance variables should be public within the context
7193 of the implementation. */
7194 if (objc_implementation_context
7195 && ((TREE_CODE (objc_implementation_context)
7196 == CLASS_IMPLEMENTATION_TYPE)
7197 || (TREE_CODE (objc_implementation_context)
7198 == CATEGORY_IMPLEMENTATION_TYPE)))
7200 tree curtype = TYPE_MAIN_VARIANT
7201 (CLASS_STATIC_TEMPLATE
7202 (implementation_template));
7204 if (basetype == curtype
7205 || DERIVED_FROM_P (basetype, curtype))
7207 int private = is_private (decl);
7209 if (private)
7210 error ("instance variable %qs is declared private",
7211 IDENTIFIER_POINTER (DECL_NAME (decl)));
7213 return !private;
7217 /* The 2.95.2 compiler sometimes allowed C functions to access
7218 non-@public ivars. We will let this slide for now... */
7219 if (!objc_method_context)
7221 warning (0, "instance variable %qs is %s; "
7222 "this will be a hard error in the future",
7223 IDENTIFIER_POINTER (identifier),
7224 TREE_PRIVATE (decl) ? "@private" : "@protected");
7225 return 1;
7228 error ("instance variable %qs is declared %s",
7229 IDENTIFIER_POINTER (identifier),
7230 TREE_PRIVATE (decl) ? "private" : "protected");
7231 return 0;
7236 return 1;
7239 /* Make sure all entries in CHAIN are also in LIST. */
7241 static int
7242 check_methods (tree chain, tree list, int mtype)
7244 int first = 1;
7246 while (chain)
7248 if (!lookup_method (list, chain))
7250 if (first)
7252 if (TREE_CODE (objc_implementation_context)
7253 == CLASS_IMPLEMENTATION_TYPE)
7254 warning (0, "incomplete implementation of class %qs",
7255 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7256 else if (TREE_CODE (objc_implementation_context)
7257 == CATEGORY_IMPLEMENTATION_TYPE)
7258 warning (0, "incomplete implementation of category %qs",
7259 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7260 first = 0;
7263 warning (0, "method definition for %<%c%s%> not found",
7264 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7267 chain = TREE_CHAIN (chain);
7270 return first;
7273 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7275 static int
7276 conforms_to_protocol (tree class, tree protocol)
7278 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7280 tree p = CLASS_PROTOCOL_LIST (class);
7281 while (p && TREE_VALUE (p) != protocol)
7282 p = TREE_CHAIN (p);
7284 if (!p)
7286 tree super = (CLASS_SUPER_NAME (class)
7287 ? lookup_interface (CLASS_SUPER_NAME (class))
7288 : NULL_TREE);
7289 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7290 if (!tmp)
7291 return 0;
7295 return 1;
7298 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7299 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7301 static int
7302 check_methods_accessible (tree chain, tree context, int mtype)
7304 int first = 1;
7305 tree list;
7306 tree base_context = context;
7308 while (chain)
7310 context = base_context;
7311 while (context)
7313 if (mtype == '+')
7314 list = CLASS_CLS_METHODS (context);
7315 else
7316 list = CLASS_NST_METHODS (context);
7318 if (lookup_method (list, chain))
7319 break;
7321 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7322 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7323 context = (CLASS_SUPER_NAME (context)
7324 ? lookup_interface (CLASS_SUPER_NAME (context))
7325 : NULL_TREE);
7327 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7328 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7329 context = (CLASS_NAME (context)
7330 ? lookup_interface (CLASS_NAME (context))
7331 : NULL_TREE);
7332 else
7333 abort ();
7336 if (context == NULL_TREE)
7338 if (first)
7340 if (TREE_CODE (objc_implementation_context)
7341 == CLASS_IMPLEMENTATION_TYPE)
7342 warning (0, "incomplete implementation of class %qs",
7343 IDENTIFIER_POINTER
7344 (CLASS_NAME (objc_implementation_context)));
7345 else if (TREE_CODE (objc_implementation_context)
7346 == CATEGORY_IMPLEMENTATION_TYPE)
7347 warning (0, "incomplete implementation of category %qs",
7348 IDENTIFIER_POINTER
7349 (CLASS_SUPER_NAME (objc_implementation_context)));
7350 first = 0;
7352 warning (0, "method definition for %<%c%s%> not found",
7353 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
7356 chain = TREE_CHAIN (chain); /* next method... */
7358 return first;
7361 /* Check whether the current interface (accessible via
7362 'objc_implementation_context') actually implements protocol P, along
7363 with any protocols that P inherits. */
7365 static void
7366 check_protocol (tree p, const char *type, const char *name)
7368 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7370 int f1, f2;
7372 /* Ensure that all protocols have bodies! */
7373 if (warn_protocol)
7375 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7376 CLASS_CLS_METHODS (objc_implementation_context),
7377 '+');
7378 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7379 CLASS_NST_METHODS (objc_implementation_context),
7380 '-');
7382 else
7384 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7385 objc_implementation_context,
7386 '+');
7387 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7388 objc_implementation_context,
7389 '-');
7392 if (!f1 || !f2)
7393 warning (0, "%s %qs does not fully implement the %qs protocol",
7394 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
7397 /* Check protocols recursively. */
7398 if (PROTOCOL_LIST (p))
7400 tree subs = PROTOCOL_LIST (p);
7401 tree super_class =
7402 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7404 while (subs)
7406 tree sub = TREE_VALUE (subs);
7408 /* If the superclass does not conform to the protocols
7409 inherited by P, then we must! */
7410 if (!super_class || !conforms_to_protocol (super_class, sub))
7411 check_protocol (sub, type, name);
7412 subs = TREE_CHAIN (subs);
7417 /* Check whether the current interface (accessible via
7418 'objc_implementation_context') actually implements the protocols listed
7419 in PROTO_LIST. */
7421 static void
7422 check_protocols (tree proto_list, const char *type, const char *name)
7424 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7426 tree p = TREE_VALUE (proto_list);
7428 check_protocol (p, type, name);
7432 /* Make sure that the class CLASS_NAME is defined
7433 CODE says which kind of thing CLASS_NAME ought to be.
7434 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7435 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7437 static tree
7438 start_class (enum tree_code code, tree class_name, tree super_name,
7439 tree protocol_list)
7441 tree class, decl;
7443 #ifdef OBJCPLUS
7444 if (current_namespace != global_namespace) {
7445 error ("Objective-C declarations may only appear in global scope");
7447 #endif /* OBJCPLUS */
7449 if (objc_implementation_context)
7451 warning (0, "%<@end%> missing in implementation context");
7452 finish_class (objc_implementation_context);
7453 objc_ivar_chain = NULL_TREE;
7454 objc_implementation_context = NULL_TREE;
7457 class = make_node (code);
7458 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7460 /* Check for existence of the super class, if one was specified. Note
7461 that we must have seen an @interface, not just a @class. If we
7462 are looking at a @compatibility_alias, traverse it first. */
7463 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7464 && super_name)
7466 tree super = objc_is_class_name (super_name);
7468 if (!super || !lookup_interface (super))
7470 error ("cannot find interface declaration for %qs, superclass of %qs",
7471 IDENTIFIER_POINTER (super ? super : super_name),
7472 IDENTIFIER_POINTER (class_name));
7473 super_name = NULL_TREE;
7475 else
7476 super_name = super;
7479 CLASS_NAME (class) = class_name;
7480 CLASS_SUPER_NAME (class) = super_name;
7481 CLASS_CLS_METHODS (class) = NULL_TREE;
7483 if (! objc_is_class_name (class_name)
7484 && (decl = lookup_name (class_name)))
7486 error ("%qs redeclared as different kind of symbol",
7487 IDENTIFIER_POINTER (class_name));
7488 error ("previous declaration of %q+D",
7489 decl);
7492 if (code == CLASS_IMPLEMENTATION_TYPE)
7495 tree chain;
7497 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7498 if (TREE_VALUE (chain) == class_name)
7500 error ("reimplementation of class %qs",
7501 IDENTIFIER_POINTER (class_name));
7502 return error_mark_node;
7504 implemented_classes = tree_cons (NULL_TREE, class_name,
7505 implemented_classes);
7508 /* Reset for multiple classes per file. */
7509 method_slot = 0;
7511 objc_implementation_context = class;
7513 /* Lookup the interface for this implementation. */
7515 if (!(implementation_template = lookup_interface (class_name)))
7517 warning (0, "cannot find interface declaration for %qs",
7518 IDENTIFIER_POINTER (class_name));
7519 add_class (implementation_template = objc_implementation_context,
7520 class_name);
7523 /* If a super class has been specified in the implementation,
7524 insure it conforms to the one specified in the interface. */
7526 if (super_name
7527 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7529 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7530 const char *const name =
7531 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
7532 error ("conflicting super class name %qs",
7533 IDENTIFIER_POINTER (super_name));
7534 error ("previous declaration of %qs", name);
7537 else if (! super_name)
7539 CLASS_SUPER_NAME (objc_implementation_context)
7540 = CLASS_SUPER_NAME (implementation_template);
7544 else if (code == CLASS_INTERFACE_TYPE)
7546 if (lookup_interface (class_name))
7547 #ifdef OBJCPLUS
7548 error ("duplicate interface declaration for class %qs",
7549 #else
7550 warning (0, "duplicate interface declaration for class %qs",
7551 #endif
7552 IDENTIFIER_POINTER (class_name));
7553 else
7554 add_class (class, class_name);
7556 if (protocol_list)
7557 CLASS_PROTOCOL_LIST (class)
7558 = lookup_and_install_protocols (protocol_list);
7561 else if (code == CATEGORY_INTERFACE_TYPE)
7563 tree class_category_is_assoc_with;
7565 /* For a category, class_name is really the name of the class that
7566 the following set of methods will be associated with. We must
7567 find the interface so that can derive the objects template. */
7569 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7571 error ("cannot find interface declaration for %qs",
7572 IDENTIFIER_POINTER (class_name));
7573 exit (FATAL_EXIT_CODE);
7575 else
7576 add_category (class_category_is_assoc_with, class);
7578 if (protocol_list)
7579 CLASS_PROTOCOL_LIST (class)
7580 = lookup_and_install_protocols (protocol_list);
7583 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7585 /* Reset for multiple classes per file. */
7586 method_slot = 0;
7588 objc_implementation_context = class;
7590 /* For a category, class_name is really the name of the class that
7591 the following set of methods will be associated with. We must
7592 find the interface so that can derive the objects template. */
7594 if (!(implementation_template = lookup_interface (class_name)))
7596 error ("cannot find interface declaration for %qs",
7597 IDENTIFIER_POINTER (class_name));
7598 exit (FATAL_EXIT_CODE);
7601 return class;
7604 static tree
7605 continue_class (tree class)
7607 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
7608 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7610 struct imp_entry *imp_entry;
7612 /* Check consistency of the instance variables. */
7614 if (CLASS_RAW_IVARS (class))
7615 check_ivars (implementation_template, class);
7617 /* code generation */
7619 #ifdef OBJCPLUS
7620 push_lang_context (lang_name_c);
7621 #endif
7623 build_private_template (implementation_template);
7624 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7625 objc_instance_type = build_pointer_type (uprivate_record);
7627 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7629 imp_entry->next = imp_list;
7630 imp_entry->imp_context = class;
7631 imp_entry->imp_template = implementation_template;
7633 synth_forward_declarations ();
7634 imp_entry->class_decl = UOBJC_CLASS_decl;
7635 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7636 imp_entry->has_cxx_cdtors = 0;
7638 /* Append to front and increment count. */
7639 imp_list = imp_entry;
7640 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7641 imp_count++;
7642 else
7643 cat_count++;
7645 #ifdef OBJCPLUS
7646 pop_lang_context ();
7647 #endif /* OBJCPLUS */
7649 return get_class_ivars (implementation_template, true);
7652 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
7654 #ifdef OBJCPLUS
7655 push_lang_context (lang_name_c);
7656 #endif /* OBJCPLUS */
7658 build_private_template (class);
7660 #ifdef OBJCPLUS
7661 pop_lang_context ();
7662 #endif /* OBJCPLUS */
7664 return NULL_TREE;
7667 else
7668 return error_mark_node;
7671 /* This is called once we see the "@end" in an interface/implementation. */
7673 static void
7674 finish_class (tree class)
7676 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
7678 /* All code generation is done in finish_objc. */
7680 if (implementation_template != objc_implementation_context)
7682 /* Ensure that all method listed in the interface contain bodies. */
7683 check_methods (CLASS_CLS_METHODS (implementation_template),
7684 CLASS_CLS_METHODS (objc_implementation_context), '+');
7685 check_methods (CLASS_NST_METHODS (implementation_template),
7686 CLASS_NST_METHODS (objc_implementation_context), '-');
7688 if (CLASS_PROTOCOL_LIST (implementation_template))
7689 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7690 "class",
7691 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
7695 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
7697 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
7699 if (category)
7701 /* Ensure all method listed in the interface contain bodies. */
7702 check_methods (CLASS_CLS_METHODS (category),
7703 CLASS_CLS_METHODS (objc_implementation_context), '+');
7704 check_methods (CLASS_NST_METHODS (category),
7705 CLASS_NST_METHODS (objc_implementation_context), '-');
7707 if (CLASS_PROTOCOL_LIST (category))
7708 check_protocols (CLASS_PROTOCOL_LIST (category),
7709 "category",
7710 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7715 static tree
7716 add_protocol (tree protocol)
7718 /* Put protocol on list in reverse order. */
7719 TREE_CHAIN (protocol) = protocol_chain;
7720 protocol_chain = protocol;
7721 return protocol_chain;
7724 static tree
7725 lookup_protocol (tree ident)
7727 tree chain;
7729 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7730 if (ident == PROTOCOL_NAME (chain))
7731 return chain;
7733 return NULL_TREE;
7736 /* This function forward declares the protocols named by NAMES. If
7737 they are already declared or defined, the function has no effect. */
7739 void
7740 objc_declare_protocols (tree names)
7742 tree list;
7744 #ifdef OBJCPLUS
7745 if (current_namespace != global_namespace) {
7746 error ("Objective-C declarations may only appear in global scope");
7748 #endif /* OBJCPLUS */
7750 for (list = names; list; list = TREE_CHAIN (list))
7752 tree name = TREE_VALUE (list);
7754 if (lookup_protocol (name) == NULL_TREE)
7756 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7758 TYPE_LANG_SLOT_1 (protocol)
7759 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7760 PROTOCOL_NAME (protocol) = name;
7761 PROTOCOL_LIST (protocol) = NULL_TREE;
7762 add_protocol (protocol);
7763 PROTOCOL_DEFINED (protocol) = 0;
7764 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7769 static tree
7770 start_protocol (enum tree_code code, tree name, tree list)
7772 tree protocol;
7774 #ifdef OBJCPLUS
7775 if (current_namespace != global_namespace) {
7776 error ("Objective-C declarations may only appear in global scope");
7778 #endif /* OBJCPLUS */
7780 protocol = lookup_protocol (name);
7782 if (!protocol)
7784 protocol = make_node (code);
7785 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7787 PROTOCOL_NAME (protocol) = name;
7788 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7789 add_protocol (protocol);
7790 PROTOCOL_DEFINED (protocol) = 1;
7791 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7793 check_protocol_recursively (protocol, list);
7795 else if (! PROTOCOL_DEFINED (protocol))
7797 PROTOCOL_DEFINED (protocol) = 1;
7798 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7800 check_protocol_recursively (protocol, list);
7802 else
7804 warning (0, "duplicate declaration for protocol %qs",
7805 IDENTIFIER_POINTER (name));
7807 return protocol;
7811 /* "Encode" a data type into a string, which grows in util_obstack.
7812 ??? What is the FORMAT? Someone please document this! */
7814 static void
7815 encode_type_qualifiers (tree declspecs)
7817 tree spec;
7819 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7821 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7822 obstack_1grow (&util_obstack, 'n');
7823 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7824 obstack_1grow (&util_obstack, 'N');
7825 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7826 obstack_1grow (&util_obstack, 'o');
7827 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7828 obstack_1grow (&util_obstack, 'O');
7829 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7830 obstack_1grow (&util_obstack, 'R');
7831 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7832 obstack_1grow (&util_obstack, 'V');
7836 /* Encode a pointer type. */
7838 static void
7839 encode_pointer (tree type, int curtype, int format)
7841 tree pointer_to = TREE_TYPE (type);
7843 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7845 if (OBJC_TYPE_NAME (pointer_to)
7846 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7848 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7850 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7852 obstack_1grow (&util_obstack, '@');
7853 return;
7855 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7856 && TYPE_OBJC_INTERFACE (pointer_to))
7858 if (generating_instance_variables)
7860 obstack_1grow (&util_obstack, '@');
7861 obstack_1grow (&util_obstack, '"');
7862 obstack_grow (&util_obstack, name, strlen (name));
7863 obstack_1grow (&util_obstack, '"');
7864 return;
7866 else
7868 obstack_1grow (&util_obstack, '@');
7869 return;
7872 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7874 obstack_1grow (&util_obstack, '#');
7875 return;
7877 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7879 obstack_1grow (&util_obstack, ':');
7880 return;
7884 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7885 && TYPE_MODE (pointer_to) == QImode)
7887 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7888 ? OBJC_TYPE_NAME (pointer_to)
7889 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7891 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7893 /* It appears that "r*" means "const char *" rather than
7894 "char *const". */
7895 if (TYPE_READONLY (pointer_to))
7896 obstack_1grow (&util_obstack, 'r');
7898 obstack_1grow (&util_obstack, '*');
7899 return;
7903 /* We have a type that does not get special treatment. */
7905 /* NeXT extension */
7906 obstack_1grow (&util_obstack, '^');
7907 encode_type (pointer_to, curtype, format);
7910 static void
7911 encode_array (tree type, int curtype, int format)
7913 tree an_int_cst = TYPE_SIZE (type);
7914 tree array_of = TREE_TYPE (type);
7915 char buffer[40];
7917 /* An incomplete array is treated like a pointer. */
7918 if (an_int_cst == NULL)
7920 encode_pointer (type, curtype, format);
7921 return;
7924 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
7925 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
7926 else
7927 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7928 TREE_INT_CST_LOW (an_int_cst)
7929 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
7931 obstack_grow (&util_obstack, buffer, strlen (buffer));
7932 encode_type (array_of, curtype, format);
7933 obstack_1grow (&util_obstack, ']');
7934 return;
7937 static void
7938 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
7940 tree field = TYPE_FIELDS (type);
7942 for (; field; field = TREE_CHAIN (field))
7944 #ifdef OBJCPLUS
7945 /* C++ static members, and things that are not field at all,
7946 should not appear in the encoding. */
7947 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
7948 continue;
7949 #endif
7951 /* Recursively encode fields of embedded base classes. */
7952 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
7953 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
7955 encode_aggregate_fields (TREE_TYPE (field),
7956 pointed_to, curtype, format);
7957 continue;
7960 if (generating_instance_variables && !pointed_to)
7962 tree fname = DECL_NAME (field);
7964 obstack_1grow (&util_obstack, '"');
7966 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7967 obstack_grow (&util_obstack,
7968 IDENTIFIER_POINTER (fname),
7969 strlen (IDENTIFIER_POINTER (fname)));
7971 obstack_1grow (&util_obstack, '"');
7974 encode_field_decl (field, curtype, format);
7978 static void
7979 encode_aggregate_within (tree type, int curtype, int format, int left,
7980 int right)
7982 tree name;
7983 /* NB: aggregates that are pointed to have slightly different encoding
7984 rules in that you never encode the names of instance variables. */
7985 int ob_size = obstack_object_size (&util_obstack);
7986 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
7987 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
7988 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
7989 int inline_contents
7990 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7991 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
7993 /* Traverse struct aliases; it is important to get the
7994 original struct and its tag name (if any). */
7995 type = TYPE_MAIN_VARIANT (type);
7996 name = OBJC_TYPE_NAME (type);
7997 /* Open parenth/bracket. */
7998 obstack_1grow (&util_obstack, left);
8000 /* Encode the struct/union tag name, or '?' if a tag was
8001 not provided. Typedef aliases do not qualify. */
8002 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8003 #ifdef OBJCPLUS
8004 /* Did this struct have a tag? */
8005 && !TYPE_WAS_ANONYMOUS (type)
8006 #endif
8008 obstack_grow (&util_obstack,
8009 IDENTIFIER_POINTER (name),
8010 strlen (IDENTIFIER_POINTER (name)));
8011 else
8012 obstack_1grow (&util_obstack, '?');
8014 /* Encode the types (and possibly names) of the inner fields,
8015 if required. */
8016 if (inline_contents)
8018 obstack_1grow (&util_obstack, '=');
8019 encode_aggregate_fields (type, pointed_to, curtype, format);
8021 /* Close parenth/bracket. */
8022 obstack_1grow (&util_obstack, right);
8025 static void
8026 encode_aggregate (tree type, int curtype, int format)
8028 enum tree_code code = TREE_CODE (type);
8030 switch (code)
8032 case RECORD_TYPE:
8034 encode_aggregate_within (type, curtype, format, '{', '}');
8035 break;
8037 case UNION_TYPE:
8039 encode_aggregate_within (type, curtype, format, '(', ')');
8040 break;
8043 case ENUMERAL_TYPE:
8044 obstack_1grow (&util_obstack, 'i');
8045 break;
8047 default:
8048 break;
8052 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8053 field type. */
8055 static void
8056 encode_next_bitfield (int width)
8058 char buffer[40];
8059 sprintf (buffer, "b%d", width);
8060 obstack_grow (&util_obstack, buffer, strlen (buffer));
8063 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8064 static void
8065 encode_type (tree type, int curtype, int format)
8067 enum tree_code code = TREE_CODE (type);
8068 char c;
8070 if (TYPE_READONLY (type))
8071 obstack_1grow (&util_obstack, 'r');
8073 if (code == INTEGER_TYPE)
8075 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8077 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8078 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8079 case 32:
8080 if (type == long_unsigned_type_node
8081 || type == long_integer_type_node)
8082 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8083 else
8084 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8085 break;
8086 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8087 default: abort ();
8089 obstack_1grow (&util_obstack, c);
8092 else if (code == REAL_TYPE)
8094 /* Floating point types. */
8095 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8097 case 32: c = 'f'; break;
8098 case 64:
8099 case 96:
8100 case 128: c = 'd'; break;
8101 default: abort ();
8103 obstack_1grow (&util_obstack, c);
8106 else if (code == VOID_TYPE)
8107 obstack_1grow (&util_obstack, 'v');
8109 else if (code == BOOLEAN_TYPE)
8110 obstack_1grow (&util_obstack, 'B');
8112 else if (code == ARRAY_TYPE)
8113 encode_array (type, curtype, format);
8115 else if (code == POINTER_TYPE)
8116 encode_pointer (type, curtype, format);
8118 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8119 encode_aggregate (type, curtype, format);
8121 else if (code == FUNCTION_TYPE) /* '?' */
8122 obstack_1grow (&util_obstack, '?');
8124 else if (code == COMPLEX_TYPE)
8126 obstack_1grow (&util_obstack, 'j');
8127 encode_type (TREE_TYPE (type), curtype, format);
8131 static void
8132 encode_gnu_bitfield (int position, tree type, int size)
8134 enum tree_code code = TREE_CODE (type);
8135 char buffer[40];
8136 char charType = '?';
8138 if (code == INTEGER_TYPE)
8140 if (integer_zerop (TYPE_MIN_VALUE (type)))
8142 /* Unsigned integer types. */
8144 if (TYPE_MODE (type) == QImode)
8145 charType = 'C';
8146 else if (TYPE_MODE (type) == HImode)
8147 charType = 'S';
8148 else if (TYPE_MODE (type) == SImode)
8150 if (type == long_unsigned_type_node)
8151 charType = 'L';
8152 else
8153 charType = 'I';
8155 else if (TYPE_MODE (type) == DImode)
8156 charType = 'Q';
8159 else
8160 /* Signed integer types. */
8162 if (TYPE_MODE (type) == QImode)
8163 charType = 'c';
8164 else if (TYPE_MODE (type) == HImode)
8165 charType = 's';
8166 else if (TYPE_MODE (type) == SImode)
8168 if (type == long_integer_type_node)
8169 charType = 'l';
8170 else
8171 charType = 'i';
8174 else if (TYPE_MODE (type) == DImode)
8175 charType = 'q';
8178 else if (code == ENUMERAL_TYPE)
8179 charType = 'i';
8180 else
8181 abort ();
8183 sprintf (buffer, "b%d%c%d", position, charType, size);
8184 obstack_grow (&util_obstack, buffer, strlen (buffer));
8187 static void
8188 encode_field_decl (tree field_decl, int curtype, int format)
8190 tree type;
8192 #ifdef OBJCPLUS
8193 /* C++ static members, and things that are not fields at all,
8194 should not appear in the encoding. */
8195 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8196 return;
8197 #endif
8199 type = TREE_TYPE (field_decl);
8201 /* Generate the bitfield typing information, if needed. Note the difference
8202 between GNU and NeXT runtimes. */
8203 if (DECL_BIT_FIELD_TYPE (field_decl))
8205 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8207 if (flag_next_runtime)
8208 encode_next_bitfield (size);
8209 else
8210 encode_gnu_bitfield (int_bit_position (field_decl),
8211 DECL_BIT_FIELD_TYPE (field_decl), size);
8213 else
8214 encode_type (TREE_TYPE (field_decl), curtype, format);
8217 static GTY(()) tree objc_parmlist = NULL_TREE;
8219 /* Append PARM to a list of formal parameters of a method, making a necessary
8220 array-to-pointer adjustment along the way. */
8222 static void
8223 objc_push_parm (tree parm)
8225 /* Decay arrays and functions into pointers. */
8226 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8227 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8228 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8229 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8231 DECL_ARG_TYPE (parm)
8232 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8234 /* Record constancy and volatility. */
8235 c_apply_type_quals_to_decl
8236 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8237 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8238 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8240 objc_parmlist = chainon (objc_parmlist, parm);
8243 /* Retrieve the formal parameter list constructed via preceding calls to
8244 objc_push_parm(). */
8246 #ifdef OBJCPLUS
8247 static tree
8248 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8249 #else
8250 static struct c_arg_info *
8251 objc_get_parm_info (int have_ellipsis)
8252 #endif
8254 #ifdef OBJCPLUS
8255 tree parm_info = objc_parmlist;
8256 objc_parmlist = NULL_TREE;
8258 return parm_info;
8259 #else
8260 tree parm_info = objc_parmlist;
8261 struct c_arg_info *arg_info;
8262 /* The C front-end requires an elaborate song and dance at
8263 this point. */
8264 push_scope ();
8265 declare_parm_level ();
8266 while (parm_info)
8268 tree next = TREE_CHAIN (parm_info);
8270 TREE_CHAIN (parm_info) = NULL_TREE;
8271 parm_info = pushdecl (parm_info);
8272 finish_decl (parm_info, NULL_TREE, NULL_TREE);
8273 parm_info = next;
8275 arg_info = get_parm_info (have_ellipsis);
8276 pop_scope ();
8277 objc_parmlist = NULL_TREE;
8278 return arg_info;
8279 #endif
8282 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8283 method definitions. In the case of instance methods, we can be more
8284 specific as to the type of 'self'. */
8286 static void
8287 synth_self_and_ucmd_args (void)
8289 tree self_type;
8291 if (objc_method_context
8292 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8293 self_type = objc_instance_type;
8294 else
8295 /* Really a `struct objc_class *'. However, we allow people to
8296 assign to self, which changes its type midstream. */
8297 self_type = objc_object_type;
8299 /* id self; */
8300 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
8302 /* SEL _cmd; */
8303 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
8306 /* Transform an Objective-C method definition into a static C function
8307 definition, synthesizing the first two arguments, "self" and "_cmd",
8308 in the process. */
8310 static void
8311 start_method_def (tree method)
8313 tree parmlist;
8314 #ifdef OBJCPLUS
8315 tree parm_info;
8316 #else
8317 struct c_arg_info *parm_info;
8318 #endif
8319 int have_ellipsis = 0;
8321 /* If we are defining a "dealloc" method in a non-root class, we
8322 will need to check if a [super dealloc] is missing, and warn if
8323 it is. */
8324 if(CLASS_SUPER_NAME (objc_implementation_context)
8325 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8326 should_call_super_dealloc = 1;
8327 else
8328 should_call_super_dealloc = 0;
8330 /* Required to implement _msgSuper. */
8331 objc_method_context = method;
8332 UOBJC_SUPER_decl = NULL_TREE;
8334 /* Generate prototype declarations for arguments..."new-style". */
8335 synth_self_and_ucmd_args ();
8337 /* Generate argument declarations if a keyword_decl. */
8338 parmlist = METHOD_SEL_ARGS (method);
8339 while (parmlist)
8341 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8343 parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8344 objc_push_parm (parm);
8345 parmlist = TREE_CHAIN (parmlist);
8348 if (METHOD_ADD_ARGS (method))
8350 tree akey;
8352 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8353 akey; akey = TREE_CHAIN (akey))
8355 objc_push_parm (TREE_VALUE (akey));
8358 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8359 have_ellipsis = 1;
8362 parm_info = objc_get_parm_info (have_ellipsis);
8364 really_start_method (objc_method_context, parm_info);
8367 static void
8368 warn_with_method (const char *message, int mtype, tree method)
8370 /* Add a readable method name to the warning. */
8371 warning (0, "%J%s %<%c%s%>", method,
8372 message, mtype, gen_method_decl (method));
8375 /* Return 1 if TYPE1 is equivalent to TYPE2
8376 for purposes of method overloading. */
8378 static int
8379 objc_types_are_equivalent (tree type1, tree type2)
8381 if (type1 == type2)
8382 return 1;
8384 /* Strip away indirections. */
8385 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8386 && (TREE_CODE (type1) == TREE_CODE (type2)))
8387 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8388 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8389 return 0;
8391 type1 = (TYPE_HAS_OBJC_INFO (type1)
8392 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8393 : NULL_TREE);
8394 type2 = (TYPE_HAS_OBJC_INFO (type2)
8395 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8396 : NULL_TREE);
8398 if (list_length (type1) == list_length (type2))
8400 for (; type2; type2 = TREE_CHAIN (type2))
8401 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8402 return 0;
8403 return 1;
8405 return 0;
8408 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8410 static int
8411 objc_types_share_size_and_alignment (tree type1, tree type2)
8413 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8414 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8417 /* Return 1 if PROTO1 is equivalent to PROTO2
8418 for purposes of method overloading. Ordinarily, the type signatures
8419 should match up exactly, unless STRICT is zero, in which case we
8420 shall allow differences in which the size and alignment of a type
8421 is the same. */
8423 static int
8424 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8426 tree type1, type2;
8428 /* The following test is needed in case there are hashing
8429 collisions. */
8430 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8431 return 0;
8433 /* Compare return types. */
8434 type1 = TREE_VALUE (TREE_TYPE (proto1));
8435 type2 = TREE_VALUE (TREE_TYPE (proto2));
8437 if (!objc_types_are_equivalent (type1, type2)
8438 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8439 return 0;
8441 /* Compare argument types. */
8442 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8443 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8444 type1 && type2;
8445 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8447 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8448 && (strict
8449 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8450 TREE_VALUE (type2))))
8451 return 0;
8454 return (!type1 && !type2);
8457 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8458 this occurs. ObjC method dispatches are _not_ like C++ virtual
8459 member function dispatches, and we account for the difference here. */
8460 tree
8461 #ifdef OBJCPLUS
8462 objc_fold_obj_type_ref (tree ref, tree known_type)
8463 #else
8464 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8465 tree known_type ATTRIBUTE_UNUSED)
8466 #endif
8468 #ifdef OBJCPLUS
8469 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8471 /* If the receiver does not have virtual member functions, there
8472 is nothing we can (or need to) do here. */
8473 if (!v)
8474 return NULL_TREE;
8476 /* Let C++ handle C++ virtual functions. */
8477 return cp_fold_obj_type_ref (ref, known_type);
8478 #else
8479 /* For plain ObjC, we currently do not need to do anything. */
8480 return NULL_TREE;
8481 #endif
8484 static void
8485 objc_start_function (tree name, tree type, tree attrs,
8486 #ifdef OBJCPLUS
8487 tree params
8488 #else
8489 struct c_arg_info *params
8490 #endif
8493 tree fndecl = build_decl (FUNCTION_DECL, name, type);
8495 #ifdef OBJCPLUS
8496 DECL_ARGUMENTS (fndecl) = params;
8497 DECL_INITIAL (fndecl) = error_mark_node;
8498 DECL_EXTERNAL (fndecl) = 0;
8499 TREE_STATIC (fndecl) = 1;
8500 retrofit_lang_decl (fndecl);
8501 cplus_decl_attributes (&fndecl, attrs, 0);
8502 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8503 #else
8504 struct c_label_context_se *nstack_se;
8505 struct c_label_context_vm *nstack_vm;
8506 nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
8507 nstack_se->labels_def = NULL;
8508 nstack_se->labels_used = NULL;
8509 nstack_se->next = label_context_stack_se;
8510 label_context_stack_se = nstack_se;
8511 nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
8512 nstack_vm->labels_def = NULL;
8513 nstack_vm->labels_used = NULL;
8514 nstack_vm->scope = 0;
8515 nstack_vm->next = label_context_stack_vm;
8516 label_context_stack_vm = nstack_vm;
8517 current_function_returns_value = 0; /* Assume, until we see it does. */
8518 current_function_returns_null = 0;
8520 decl_attributes (&fndecl, attrs, 0);
8521 announce_function (fndecl);
8522 DECL_INITIAL (fndecl) = error_mark_node;
8523 DECL_EXTERNAL (fndecl) = 0;
8524 TREE_STATIC (fndecl) = 1;
8525 current_function_decl = pushdecl (fndecl);
8526 push_scope ();
8527 declare_parm_level ();
8528 DECL_RESULT (current_function_decl)
8529 = build_decl (RESULT_DECL, NULL_TREE,
8530 TREE_TYPE (TREE_TYPE (current_function_decl)));
8531 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8532 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8533 start_fname_decls ();
8534 store_parm_decls_from (params);
8535 #endif
8537 TREE_USED (current_function_decl) = 1;
8540 /* - Generate an identifier for the function. the format is "_n_cls",
8541 where 1 <= n <= nMethods, and cls is the name the implementation we
8542 are processing.
8543 - Install the return type from the method declaration.
8544 - If we have a prototype, check for type consistency. */
8546 static void
8547 really_start_method (tree method,
8548 #ifdef OBJCPLUS
8549 tree parmlist
8550 #else
8551 struct c_arg_info *parmlist
8552 #endif
8555 tree ret_type, meth_type;
8556 tree method_id;
8557 const char *sel_name, *class_name, *cat_name;
8558 char *buf;
8560 /* Synth the storage class & assemble the return type. */
8561 ret_type = TREE_VALUE (TREE_TYPE (method));
8563 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8564 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8565 cat_name = ((TREE_CODE (objc_implementation_context)
8566 == CLASS_IMPLEMENTATION_TYPE)
8567 ? NULL
8568 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8569 method_slot++;
8571 /* Make sure this is big enough for any plausible method label. */
8572 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8573 + (cat_name ? strlen (cat_name) : 0));
8575 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8576 class_name, cat_name, sel_name, method_slot);
8578 method_id = get_identifier (buf);
8580 #ifdef OBJCPLUS
8581 /* Objective-C methods cannot be overloaded, so we don't need
8582 the type encoding appended. It looks bad anyway... */
8583 push_lang_context (lang_name_c);
8584 #endif
8586 meth_type
8587 = build_function_type (ret_type,
8588 get_arg_type_list (method, METHOD_DEF, 0));
8589 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8591 /* Set self_decl from the first argument. */
8592 self_decl = DECL_ARGUMENTS (current_function_decl);
8594 /* Suppress unused warnings. */
8595 TREE_USED (self_decl) = 1;
8596 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8597 #ifdef OBJCPLUS
8598 pop_lang_context ();
8599 #endif
8601 METHOD_DEFINITION (method) = current_function_decl;
8603 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8605 if (implementation_template != objc_implementation_context)
8607 tree proto
8608 = lookup_method_static (implementation_template,
8609 METHOD_SEL_NAME (method),
8610 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8611 | OBJC_LOOKUP_NO_SUPER));
8613 if (proto)
8615 if (!comp_proto_with_proto (method, proto, 1))
8617 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
8619 warn_with_method ("conflicting types for", type, method);
8620 warn_with_method ("previous declaration of", type, proto);
8623 else
8625 /* We have a method @implementation even though we did not
8626 see a corresponding @interface declaration (which is allowed
8627 by Objective-C rules). Go ahead and place the method in
8628 the @interface anyway, so that message dispatch lookups
8629 will see it. */
8630 tree interface = implementation_template;
8632 if (TREE_CODE (objc_implementation_context)
8633 == CATEGORY_IMPLEMENTATION_TYPE)
8634 interface = lookup_category
8635 (interface,
8636 CLASS_SUPER_NAME (objc_implementation_context));
8638 if (interface)
8639 objc_add_method (interface, copy_node (method),
8640 TREE_CODE (method) == CLASS_METHOD_DECL);
8645 static void *UOBJC_SUPER_scope = 0;
8647 /* _n_Method (id self, SEL sel, ...)
8649 struct objc_super _S;
8650 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8651 } */
8653 static tree
8654 get_super_receiver (void)
8656 if (objc_method_context)
8658 tree super_expr, super_expr_list;
8660 if (!UOBJC_SUPER_decl)
8662 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
8663 objc_super_template);
8664 /* This prevents `unused variable' warnings when compiling with -Wall. */
8665 TREE_USED (UOBJC_SUPER_decl) = 1;
8666 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8667 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
8668 UOBJC_SUPER_scope = objc_get_current_scope ();
8671 /* Set receiver to self. */
8672 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8673 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
8674 super_expr_list = super_expr;
8676 /* Set class to begin searching. */
8677 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8678 get_identifier ("super_class"));
8680 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8682 /* [_cls, __cls]Super are "pre-built" in
8683 synth_forward_declarations. */
8685 super_expr = build_modify_expr (super_expr, NOP_EXPR,
8686 ((TREE_CODE (objc_method_context)
8687 == INSTANCE_METHOD_DECL)
8688 ? ucls_super_ref
8689 : uucls_super_ref));
8692 else
8693 /* We have a category. */
8695 tree super_name = CLASS_SUPER_NAME (implementation_template);
8696 tree super_class;
8698 /* Barf if super used in a category of Object. */
8699 if (!super_name)
8701 error ("no super class declared in interface for %qs",
8702 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
8703 return error_mark_node;
8706 if (flag_next_runtime && !flag_zero_link)
8708 super_class = objc_get_class_reference (super_name);
8709 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8710 /* If we are in a class method, we must retrieve the
8711 _metaclass_ for the current class, pointed at by
8712 the class's "isa" pointer. The following assumes that
8713 "isa" is the first ivar in a class (which it must be). */
8714 super_class
8715 = build_indirect_ref
8716 (build_c_cast (build_pointer_type (objc_class_type),
8717 super_class), "unary *");
8719 else
8721 add_class_reference (super_name);
8722 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8723 ? objc_get_class_decl : objc_get_meta_class_decl);
8724 assemble_external (super_class);
8725 super_class
8726 = build_function_call
8727 (super_class,
8728 build_tree_list
8729 (NULL_TREE,
8730 my_build_string_pointer
8731 (IDENTIFIER_LENGTH (super_name) + 1,
8732 IDENTIFIER_POINTER (super_name))));
8735 super_expr
8736 = build_modify_expr (super_expr, NOP_EXPR,
8737 build_c_cast (TREE_TYPE (super_expr),
8738 super_class));
8741 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8743 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
8744 super_expr_list = build_compound_expr (super_expr_list, super_expr);
8746 return super_expr_list;
8748 else
8750 error ("[super ...] must appear in a method context");
8751 return error_mark_node;
8755 /* When exiting a scope, sever links to a 'super' declaration (if any)
8756 therein contained. */
8758 void
8759 objc_clear_super_receiver (void)
8761 if (objc_method_context
8762 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8763 UOBJC_SUPER_decl = 0;
8764 UOBJC_SUPER_scope = 0;
8768 void
8769 objc_finish_method_definition (tree fndecl)
8771 /* We cannot validly inline ObjC methods, at least not without a language
8772 extension to declare that a method need not be dynamically
8773 dispatched, so suppress all thoughts of doing so. */
8774 DECL_INLINE (fndecl) = 0;
8775 DECL_UNINLINABLE (fndecl) = 1;
8777 #ifndef OBJCPLUS
8778 /* The C++ front-end will have called finish_function() for us. */
8779 finish_function ();
8780 #endif
8782 METHOD_ENCODING (objc_method_context)
8783 = encode_method_prototype (objc_method_context);
8785 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8786 since the optimizer may find "may be used before set" errors. */
8787 objc_method_context = NULL_TREE;
8789 if (should_call_super_dealloc)
8790 warning (0, "method possibly missing a [super dealloc] call");
8793 #if 0
8795 lang_report_error_function (tree decl)
8797 if (objc_method_context)
8799 fprintf (stderr, "In method %qs\n",
8800 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
8801 return 1;
8804 else
8805 return 0;
8807 #endif
8809 /* Given a tree DECL node, produce a printable description of it in the given
8810 buffer, overwriting the buffer. */
8812 static char *
8813 gen_declaration (tree decl)
8815 errbuf[0] = '\0';
8817 if (DECL_P (decl))
8819 gen_type_name_0 (TREE_TYPE (decl));
8821 if (DECL_NAME (decl))
8823 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8824 strcat (errbuf, " ");
8826 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8829 if (DECL_INITIAL (decl)
8830 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8831 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8832 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8835 return errbuf;
8838 /* Given a tree TYPE node, produce a printable description of it in the given
8839 buffer, overwriting the buffer. */
8841 static char *
8842 gen_type_name_0 (tree type)
8844 tree orig = type, proto;
8846 if (TYPE_P (type) && TYPE_NAME (type))
8847 type = TYPE_NAME (type);
8848 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8850 tree inner = TREE_TYPE (type);
8852 while (TREE_CODE (inner) == ARRAY_TYPE)
8853 inner = TREE_TYPE (inner);
8855 gen_type_name_0 (inner);
8857 if (!POINTER_TYPE_P (inner))
8858 strcat (errbuf, " ");
8860 if (POINTER_TYPE_P (type))
8861 strcat (errbuf, "*");
8862 else
8863 while (type != inner)
8865 strcat (errbuf, "[");
8867 if (TYPE_DOMAIN (type))
8869 char sz[20];
8871 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8872 (TREE_INT_CST_LOW
8873 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8874 strcat (errbuf, sz);
8877 strcat (errbuf, "]");
8878 type = TREE_TYPE (type);
8881 goto exit_function;
8884 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
8885 type = DECL_NAME (type);
8887 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
8888 ? IDENTIFIER_POINTER (type)
8889 : "");
8891 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8892 if (objc_is_id (orig))
8893 orig = TREE_TYPE (orig);
8895 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
8897 if (proto)
8899 strcat (errbuf, " <");
8901 while (proto) {
8902 strcat (errbuf,
8903 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
8904 proto = TREE_CHAIN (proto);
8905 strcat (errbuf, proto ? ", " : ">");
8909 exit_function:
8910 return errbuf;
8913 static char *
8914 gen_type_name (tree type)
8916 errbuf[0] = '\0';
8918 return gen_type_name_0 (type);
8921 /* Given a method tree, put a printable description into the given
8922 buffer (overwriting) and return a pointer to the buffer. */
8924 static char *
8925 gen_method_decl (tree method)
8927 tree chain;
8929 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
8930 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
8931 strcat (errbuf, ")");
8932 chain = METHOD_SEL_ARGS (method);
8934 if (chain)
8936 /* We have a chain of keyword_decls. */
8939 if (KEYWORD_KEY_NAME (chain))
8940 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
8942 strcat (errbuf, ":(");
8943 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
8944 strcat (errbuf, ")");
8946 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
8947 if ((chain = TREE_CHAIN (chain)))
8948 strcat (errbuf, " ");
8950 while (chain);
8952 if (METHOD_ADD_ARGS (method))
8954 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8956 /* Know we have a chain of parm_decls. */
8957 while (chain)
8959 strcat (errbuf, ", ");
8960 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8961 chain = TREE_CHAIN (chain);
8964 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8965 strcat (errbuf, ", ...");
8969 else
8970 /* We have a unary selector. */
8971 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8973 return errbuf;
8976 /* Debug info. */
8979 /* Dump an @interface declaration of the supplied class CHAIN to the
8980 supplied file FP. Used to implement the -gen-decls option (which
8981 prints out an @interface declaration of all classes compiled in
8982 this run); potentially useful for debugging the compiler too. */
8983 static void
8984 dump_interface (FILE *fp, tree chain)
8986 /* FIXME: A heap overflow here whenever a method (or ivar)
8987 declaration is so long that it doesn't fit in the buffer. The
8988 code and all the related functions should be rewritten to avoid
8989 using fixed size buffers. */
8990 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8991 tree ivar_decls = CLASS_RAW_IVARS (chain);
8992 tree nst_methods = CLASS_NST_METHODS (chain);
8993 tree cls_methods = CLASS_CLS_METHODS (chain);
8995 fprintf (fp, "\n@interface %s", my_name);
8997 /* CLASS_SUPER_NAME is used to store the superclass name for
8998 classes, and the category name for categories. */
8999 if (CLASS_SUPER_NAME (chain))
9001 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9003 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9004 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9006 fprintf (fp, " (%s)\n", name);
9008 else
9010 fprintf (fp, " : %s\n", name);
9013 else
9014 fprintf (fp, "\n");
9016 /* FIXME - the following doesn't seem to work at the moment. */
9017 if (ivar_decls)
9019 fprintf (fp, "{\n");
9022 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9023 ivar_decls = TREE_CHAIN (ivar_decls);
9025 while (ivar_decls);
9026 fprintf (fp, "}\n");
9029 while (nst_methods)
9031 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9032 nst_methods = TREE_CHAIN (nst_methods);
9035 while (cls_methods)
9037 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9038 cls_methods = TREE_CHAIN (cls_methods);
9041 fprintf (fp, "@end\n");
9044 /* Demangle function for Objective-C */
9045 static const char *
9046 objc_demangle (const char *mangled)
9048 char *demangled, *cp;
9050 if (mangled[0] == '_' &&
9051 (mangled[1] == 'i' || mangled[1] == 'c') &&
9052 mangled[2] == '_')
9054 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9055 if (mangled[1] == 'i')
9056 *cp++ = '-'; /* for instance method */
9057 else
9058 *cp++ = '+'; /* for class method */
9059 *cp++ = '['; /* opening left brace */
9060 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9061 while (*cp && *cp == '_')
9062 cp++; /* skip any initial underbars in class name */
9063 cp = strchr(cp, '_'); /* find first non-initial underbar */
9064 if (cp == NULL)
9066 free(demangled); /* not mangled name */
9067 return mangled;
9069 if (cp[1] == '_') /* easy case: no category name */
9071 *cp++ = ' '; /* replace two '_' with one ' ' */
9072 strcpy(cp, mangled + (cp - demangled) + 2);
9074 else
9076 *cp++ = '('; /* less easy case: category name */
9077 cp = strchr(cp, '_');
9078 if (cp == 0)
9080 free(demangled); /* not mangled name */
9081 return mangled;
9083 *cp++ = ')';
9084 *cp++ = ' '; /* overwriting 1st char of method name... */
9085 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9087 while (*cp && *cp == '_')
9088 cp++; /* skip any initial underbars in method name */
9089 for (; *cp; cp++)
9090 if (*cp == '_')
9091 *cp = ':'; /* replace remaining '_' with ':' */
9092 *cp++ = ']'; /* closing right brace */
9093 *cp++ = 0; /* string terminator */
9094 return demangled;
9096 else
9097 return mangled; /* not an objc mangled name */
9100 const char *
9101 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9103 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9106 static void
9107 init_objc (void)
9109 gcc_obstack_init (&util_obstack);
9110 util_firstobj = (char *) obstack_finish (&util_obstack);
9112 errbuf = XNEWVEC (char, 1024 * 10);
9113 hash_init ();
9114 synth_module_prologue ();
9117 static void
9118 finish_objc (void)
9120 struct imp_entry *impent;
9121 tree chain;
9122 /* The internally generated initializers appear to have missing braces.
9123 Don't warn about this. */
9124 int save_warn_missing_braces = warn_missing_braces;
9125 warn_missing_braces = 0;
9127 /* A missing @end may not be detected by the parser. */
9128 if (objc_implementation_context)
9130 warning (0, "%<@end%> missing in implementation context");
9131 finish_class (objc_implementation_context);
9132 objc_ivar_chain = NULL_TREE;
9133 objc_implementation_context = NULL_TREE;
9136 /* Process the static instances here because initialization of objc_symtab
9137 depends on them. */
9138 if (objc_static_instances)
9139 generate_static_references ();
9141 if (imp_list || class_names_chain
9142 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9143 generate_objc_symtab_decl ();
9145 for (impent = imp_list; impent; impent = impent->next)
9147 objc_implementation_context = impent->imp_context;
9148 implementation_template = impent->imp_template;
9150 UOBJC_CLASS_decl = impent->class_decl;
9151 UOBJC_METACLASS_decl = impent->meta_decl;
9153 /* Dump the @interface of each class as we compile it, if the
9154 -gen-decls option is in use. TODO: Dump the classes in the
9155 order they were found, rather than in reverse order as we
9156 are doing now. */
9157 if (flag_gen_declaration)
9159 dump_interface (gen_declaration_file, objc_implementation_context);
9162 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9164 /* all of the following reference the string pool... */
9165 generate_ivar_lists ();
9166 generate_dispatch_tables ();
9167 generate_shared_structures (impent->has_cxx_cdtors
9168 ? CLS_HAS_CXX_STRUCTORS
9169 : 0);
9171 else
9173 generate_dispatch_tables ();
9174 generate_category (objc_implementation_context);
9178 /* If we are using an array of selectors, we must always
9179 finish up the array decl even if no selectors were used. */
9180 if (! flag_next_runtime || sel_ref_chain)
9181 build_selector_translation_table ();
9183 if (protocol_chain)
9184 generate_protocols ();
9186 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9187 generate_objc_image_info ();
9189 /* Arrange for ObjC data structures to be initialized at run time. */
9190 if (objc_implementation_context || class_names_chain || objc_static_instances
9191 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9193 build_module_descriptor ();
9195 if (!flag_next_runtime)
9196 build_module_initializer_routine ();
9199 /* Dump the class references. This forces the appropriate classes
9200 to be linked into the executable image, preserving unix archive
9201 semantics. This can be removed when we move to a more dynamically
9202 linked environment. */
9204 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9206 handle_class_ref (chain);
9207 if (TREE_PURPOSE (chain))
9208 generate_classref_translation_entry (chain);
9211 for (impent = imp_list; impent; impent = impent->next)
9212 handle_impent (impent);
9214 if (warn_selector)
9216 int slot;
9217 hash hsh;
9219 /* Run through the selector hash tables and print a warning for any
9220 selector which has multiple methods. */
9222 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9224 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9225 check_duplicates (hsh, 0, 1);
9226 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9227 check_duplicates (hsh, 0, 1);
9231 warn_missing_braces = save_warn_missing_braces;
9234 /* Subroutines of finish_objc. */
9236 static void
9237 generate_classref_translation_entry (tree chain)
9239 tree expr, decl, type;
9241 decl = TREE_PURPOSE (chain);
9242 type = TREE_TYPE (decl);
9244 expr = add_objc_string (TREE_VALUE (chain), class_names);
9245 expr = convert (type, expr); /* cast! */
9247 /* The decl that is the one that we
9248 forward declared in build_class_reference. */
9249 finish_var_decl (decl, expr);
9250 return;
9253 static void
9254 handle_class_ref (tree chain)
9256 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9257 char *string = (char *) alloca (strlen (name) + 30);
9258 tree decl;
9259 tree exp;
9261 sprintf (string, "%sobjc_class_name_%s",
9262 (flag_next_runtime ? "." : "__"), name);
9264 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9265 if (flag_next_runtime)
9267 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9268 return;
9270 #endif
9272 /* Make a decl for this name, so we can use its address in a tree. */
9273 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
9274 DECL_EXTERNAL (decl) = 1;
9275 TREE_PUBLIC (decl) = 1;
9277 pushdecl (decl);
9278 rest_of_decl_compilation (decl, 0, 0);
9280 /* Make a decl for the address. */
9281 sprintf (string, "%sobjc_class_ref_%s",
9282 (flag_next_runtime ? "." : "__"), name);
9283 exp = build1 (ADDR_EXPR, string_type_node, decl);
9284 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
9285 DECL_INITIAL (decl) = exp;
9286 TREE_STATIC (decl) = 1;
9287 TREE_USED (decl) = 1;
9288 /* Force the output of the decl as this forces the reference of the class. */
9289 mark_decl_referenced (decl);
9291 pushdecl (decl);
9292 rest_of_decl_compilation (decl, 0, 0);
9295 static void
9296 handle_impent (struct imp_entry *impent)
9298 char *string;
9300 objc_implementation_context = impent->imp_context;
9301 implementation_template = impent->imp_template;
9303 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9305 const char *const class_name =
9306 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9308 string = (char *) alloca (strlen (class_name) + 30);
9310 sprintf (string, "%sobjc_class_name_%s",
9311 (flag_next_runtime ? "." : "__"), class_name);
9313 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9315 const char *const class_name =
9316 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9317 const char *const class_super_name =
9318 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9320 string = (char *) alloca (strlen (class_name)
9321 + strlen (class_super_name) + 30);
9323 /* Do the same for categories. Even though no references to
9324 these symbols are generated automatically by the compiler, it
9325 gives you a handle to pull them into an archive by hand. */
9326 sprintf (string, "*%sobjc_category_name_%s_%s",
9327 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9329 else
9330 return;
9332 #ifdef ASM_DECLARE_CLASS_REFERENCE
9333 if (flag_next_runtime)
9335 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9336 return;
9338 else
9339 #endif
9341 tree decl, init;
9343 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9344 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
9345 TREE_PUBLIC (decl) = 1;
9346 TREE_READONLY (decl) = 1;
9347 TREE_USED (decl) = 1;
9348 TREE_CONSTANT (decl) = 1;
9349 DECL_CONTEXT (decl) = 0;
9350 DECL_ARTIFICIAL (decl) = 1;
9351 DECL_INITIAL (decl) = init;
9352 assemble_variable (decl, 1, 0, 0);
9356 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9357 later requires that ObjC translation units participating in F&C be
9358 specially marked. The following routine accomplishes this. */
9360 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9362 static void
9363 generate_objc_image_info (void)
9365 tree decl, initlist;
9366 int flags
9367 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9368 | (flag_objc_gc ? 2 : 0));
9370 decl = start_var_decl (build_array_type
9371 (integer_type_node,
9372 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9373 "_OBJC_IMAGE_INFO");
9375 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9376 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9377 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9379 finish_var_decl (decl, initlist);
9382 /* Look up ID as an instance variable. OTHER contains the result of
9383 the C or C++ lookup, which we may want to use instead. */
9385 tree
9386 objc_lookup_ivar (tree other, tree id)
9388 tree ivar;
9390 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9391 if (!objc_method_context)
9392 return other;
9394 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9395 /* We have a message to super. */
9396 return get_super_receiver ();
9398 /* In a class method, look up an instance variable only as a last
9399 resort. */
9400 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9401 && other && other != error_mark_node)
9402 return other;
9404 /* Look up the ivar, but do not use it if it is not accessible. */
9405 ivar = is_ivar (objc_ivar_chain, id);
9407 if (!ivar || is_private (ivar))
9408 return other;
9410 /* In an instance method, a local variable (or parameter) may hide the
9411 instance variable. */
9412 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9413 && other && other != error_mark_node
9414 #ifdef OBJCPLUS
9415 && CP_DECL_CONTEXT (other) != global_namespace)
9416 #else
9417 && !DECL_FILE_SCOPE_P (other))
9418 #endif
9420 warning (0, "local declaration of %qs hides instance variable",
9421 IDENTIFIER_POINTER (id));
9423 return other;
9426 /* At this point, we are either in an instance method with no obscuring
9427 local definitions, or in a class method with no alternate definitions
9428 at all. */
9429 return build_ivar_reference (id);
9432 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9433 needs to be done if we are calling a function through a cast. */
9435 tree
9436 objc_rewrite_function_call (tree function, tree params)
9438 if (TREE_CODE (function) == NOP_EXPR
9439 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9440 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9441 == FUNCTION_DECL)
9443 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9444 TREE_OPERAND (function, 0),
9445 TREE_VALUE (params), size_zero_node);
9448 return function;
9451 /* Look for the special case of OBJC_TYPE_REF with the address of
9452 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9453 of its cousins). */
9455 enum gimplify_status
9456 objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
9458 enum gimplify_status r0, r1;
9459 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9460 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9461 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9462 == FUNCTION_DECL)
9464 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9465 value of the OBJ_TYPE_REF, so force them to be emitted
9466 during subexpression evaluation rather than after the
9467 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9468 C to use direct rather than indirect calls when the
9469 object expression has a postincrement. */
9470 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9471 is_gimple_val, fb_rvalue);
9472 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9473 is_gimple_val, fb_rvalue);
9475 return MIN (r0, r1);
9478 #ifdef OBJCPLUS
9479 return cp_gimplify_expr (expr_p, pre_p, post_p);
9480 #else
9481 return c_gimplify_expr (expr_p, pre_p, post_p);
9482 #endif
9485 /* Given a CALL expression, find the function being called. The ObjC
9486 version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
9488 tree
9489 objc_get_callee_fndecl (tree call_expr)
9491 tree addr = TREE_OPERAND (call_expr, 0);
9492 if (TREE_CODE (addr) != OBJ_TYPE_REF)
9493 return 0;
9495 addr = OBJ_TYPE_REF_EXPR (addr);
9497 /* If the address is just `&f' for some function `f', then we know
9498 that `f' is being called. */
9499 if (TREE_CODE (addr) == ADDR_EXPR
9500 && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
9501 return TREE_OPERAND (addr, 0);
9503 return 0;
9506 #include "gt-objc-objc-act.h"