]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/objc/objc-act.c
2009-07-07 Manuel López-Ibáñez <manu@gcc.gnu.org>
[thirdparty/gcc.git] / gcc / objc / objc-act.c
1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
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.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22
23 /* Purpose: This module implements the Objective-C 4.0 language.
24
25 compatibility issues (with the Stepstone translator):
26
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.
37
38 code generation `options':
39
40 */
41
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"
50
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #endif
56
57 #include "c-common.h"
58 #include "c-pragma.h"
59 #include "flags.h"
60 #include "langhooks.h"
61 #include "objc-act.h"
62 #include "input.h"
63 #include "except.h"
64 #include "function.h"
65 #include "output.h"
66 #include "toplev.h"
67 #include "ggc.h"
68 #include "varray.h"
69 #include "debug.h"
70 #include "target.h"
71 #include "diagnostic.h"
72 #include "intl.h"
73 #include "cgraph.h"
74 #include "tree-iterator.h"
75 #include "libfuncs.h"
76 #include "hashtab.h"
77 #include "langhooks-def.h"
78
79 #define OBJC_VOID_AT_END void_list_node
80
81 static unsigned int should_call_super_dealloc = 0;
82
83 /* When building Objective-C++, we need in_late_binary_op. */
84 #ifdef OBJCPLUS
85 bool in_late_binary_op = false;
86 #endif /* OBJCPLUS */
87
88 /* When building Objective-C++, we are not linking against the C front-end
89 and so need to replicate the C tree-construction functions in some way. */
90 #ifdef OBJCPLUS
91 #define OBJCP_REMAP_FUNCTIONS
92 #include "objcp-decl.h"
93 #endif /* OBJCPLUS */
94
95 /* This is the default way of generating a method name. */
96 /* I am not sure it is really correct.
97 Perhaps there's a danger that it will make name conflicts
98 if method names contain underscores. -- rms. */
99 #ifndef OBJC_GEN_METHOD_LABEL
100 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
101 do { \
102 char *temp; \
103 sprintf ((BUF), "_%s_%s_%s_%s", \
104 ((IS_INST) ? "i" : "c"), \
105 (CLASS_NAME), \
106 ((CAT_NAME)? (CAT_NAME) : ""), \
107 (SEL_NAME)); \
108 for (temp = (BUF); *temp; temp++) \
109 if (*temp == ':') *temp = '_'; \
110 } while (0)
111 #endif
112
113 /* These need specifying. */
114 #ifndef OBJC_FORWARDING_STACK_OFFSET
115 #define OBJC_FORWARDING_STACK_OFFSET 0
116 #endif
117
118 #ifndef OBJC_FORWARDING_MIN_OFFSET
119 #define OBJC_FORWARDING_MIN_OFFSET 0
120 #endif
121 \f
122 /* Set up for use of obstacks. */
123
124 #include "obstack.h"
125
126 /* This obstack is used to accumulate the encoding of a data type. */
127 static struct obstack util_obstack;
128
129 /* This points to the beginning of obstack contents, so we can free
130 the whole contents. */
131 char *util_firstobj;
132
133 /* The version identifies which language generation and runtime
134 the module (file) was compiled for, and is recorded in the
135 module descriptor. */
136
137 #define OBJC_VERSION (flag_next_runtime ? 6 : 8)
138 #define PROTOCOL_VERSION 2
139
140 /* (Decide if these can ever be validly changed.) */
141 #define OBJC_ENCODE_INLINE_DEFS 0
142 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
143
144 /*** Private Interface (procedures) ***/
145
146 /* Used by compile_file. */
147
148 static void init_objc (void);
149 static void finish_objc (void);
150
151 /* Code generation. */
152
153 static tree objc_build_constructor (tree, tree);
154 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
155 static tree get_proto_encoding (tree);
156 static tree lookup_interface (tree);
157 static tree objc_add_static_instance (tree, tree);
158
159 static tree start_class (enum tree_code, tree, tree, tree);
160 static tree continue_class (tree);
161 static void finish_class (tree);
162 static void start_method_def (tree);
163 #ifdef OBJCPLUS
164 static void objc_start_function (tree, tree, tree, tree);
165 #else
166 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
167 #endif
168 static tree start_protocol (enum tree_code, tree, tree);
169 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
170 static tree objc_add_method (tree, tree, int);
171 static tree add_instance_variable (tree, int, tree);
172 static tree build_ivar_reference (tree);
173 static tree is_ivar (tree, tree);
174
175 static void build_objc_exception_stuff (void);
176 static void build_next_objc_exception_stuff (void);
177
178 /* We only need the following for ObjC; ObjC++ will use C++'s definition
179 of DERIVED_FROM_P. */
180 #ifndef OBJCPLUS
181 static bool objc_derived_from_p (tree, tree);
182 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
183 #endif
184 static void objc_xref_basetypes (tree, tree);
185
186 static void build_class_template (void);
187 static void build_selector_template (void);
188 static void build_category_template (void);
189 static void build_super_template (void);
190 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
191 static tree get_class_ivars (tree, bool);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
194
195 #ifdef OBJCPLUS
196 static void objc_generate_cxx_cdtors (void);
197 #endif
198
199 static const char *synth_id_with_class_suffix (const char *, tree);
200
201 /* Hash tables to manage the global pool of method prototypes. */
202
203 hash *nst_method_hash_list = 0;
204 hash *cls_method_hash_list = 0;
205
206 static hash hash_lookup (hash *, tree);
207 static tree lookup_method (tree, tree);
208 static tree lookup_method_static (tree, tree, int);
209
210 enum string_section
211 {
212 class_names, /* class, category, protocol, module names */
213 meth_var_names, /* method and variable names */
214 meth_var_types /* method and variable type descriptors */
215 };
216
217 static tree add_objc_string (tree, enum string_section);
218 static tree build_objc_string_decl (enum string_section);
219 static void build_selector_table_decl (void);
220
221 /* Protocol additions. */
222
223 static tree lookup_protocol (tree);
224 static tree lookup_and_install_protocols (tree);
225
226 /* Type encoding. */
227
228 static void encode_type_qualifiers (tree);
229 static void encode_type (tree, int, int);
230 static void encode_field_decl (tree, int, int);
231
232 #ifdef OBJCPLUS
233 static void really_start_method (tree, tree);
234 #else
235 static void really_start_method (tree, struct c_arg_info *);
236 #endif
237 static int comp_proto_with_proto (tree, tree, int);
238 static void objc_push_parm (tree);
239 #ifdef OBJCPLUS
240 static tree objc_get_parm_info (int);
241 #else
242 static struct c_arg_info *objc_get_parm_info (int);
243 #endif
244
245 /* Utilities for debugging and error diagnostics. */
246
247 static char *gen_type_name (tree);
248 static char *gen_type_name_0 (tree);
249 static char *gen_method_decl (tree);
250 static char *gen_declaration (tree);
251
252 /* Everything else. */
253
254 static tree create_field_decl (tree, const char *);
255 static void add_class_reference (tree);
256 static void build_protocol_template (void);
257 static tree encode_method_prototype (tree);
258 static void generate_classref_translation_entry (tree);
259 static void handle_class_ref (tree);
260 static void generate_struct_by_value_array (void)
261 ATTRIBUTE_NORETURN;
262 static void mark_referenced_methods (void);
263 static void generate_objc_image_info (void);
264
265 /*** Private Interface (data) ***/
266
267 /* Reserved tag definitions. */
268
269 #define OBJECT_TYPEDEF_NAME "id"
270 #define CLASS_TYPEDEF_NAME "Class"
271
272 #define TAG_OBJECT "objc_object"
273 #define TAG_CLASS "objc_class"
274 #define TAG_SUPER "objc_super"
275 #define TAG_SELECTOR "objc_selector"
276
277 #define UTAG_CLASS "_objc_class"
278 #define UTAG_IVAR "_objc_ivar"
279 #define UTAG_IVAR_LIST "_objc_ivar_list"
280 #define UTAG_METHOD "_objc_method"
281 #define UTAG_METHOD_LIST "_objc_method_list"
282 #define UTAG_CATEGORY "_objc_category"
283 #define UTAG_MODULE "_objc_module"
284 #define UTAG_SYMTAB "_objc_symtab"
285 #define UTAG_SUPER "_objc_super"
286 #define UTAG_SELECTOR "_objc_selector"
287
288 #define UTAG_PROTOCOL "_objc_protocol"
289 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
290 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
291
292 /* Note that the string object global name is only needed for the
293 NeXT runtime. */
294 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
295
296 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
297
298 static const char *TAG_GETCLASS;
299 static const char *TAG_GETMETACLASS;
300 static const char *TAG_MSGSEND;
301 static const char *TAG_MSGSENDSUPER;
302 /* The NeXT Objective-C messenger may have two extra entry points, for use
303 when returning a structure. */
304 static const char *TAG_MSGSEND_STRET;
305 static const char *TAG_MSGSENDSUPER_STRET;
306 static const char *default_constant_string_class_name;
307
308 /* Runtime metadata flags. */
309 #define CLS_FACTORY 0x0001L
310 #define CLS_META 0x0002L
311 #define CLS_HAS_CXX_STRUCTORS 0x2000L
312
313 #define OBJC_MODIFIER_STATIC 0x00000001
314 #define OBJC_MODIFIER_FINAL 0x00000002
315 #define OBJC_MODIFIER_PUBLIC 0x00000004
316 #define OBJC_MODIFIER_PRIVATE 0x00000008
317 #define OBJC_MODIFIER_PROTECTED 0x00000010
318 #define OBJC_MODIFIER_NATIVE 0x00000020
319 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
320 #define OBJC_MODIFIER_ABSTRACT 0x00000080
321 #define OBJC_MODIFIER_VOLATILE 0x00000100
322 #define OBJC_MODIFIER_TRANSIENT 0x00000200
323 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
324
325 /* NeXT-specific tags. */
326
327 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
328 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
329 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
330 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
331 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
332 #define TAG_EXCEPTIONMATCH "objc_exception_match"
333 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
334 #define TAG_SYNCENTER "objc_sync_enter"
335 #define TAG_SYNCEXIT "objc_sync_exit"
336 #define TAG_SETJMP "_setjmp"
337 #define UTAG_EXCDATA "_objc_exception_data"
338
339 #define TAG_ASSIGNIVAR "objc_assign_ivar"
340 #define TAG_ASSIGNGLOBAL "objc_assign_global"
341 #define TAG_ASSIGNSTRONGCAST "objc_assign_strongCast"
342
343 /* Branch entry points. All that matters here are the addresses;
344 functions with these names do not really exist in libobjc. */
345
346 #define TAG_MSGSEND_FAST "objc_msgSend_Fast"
347 #define TAG_ASSIGNIVAR_FAST "objc_assign_ivar_Fast"
348
349 #define TAG_CXX_CONSTRUCT ".cxx_construct"
350 #define TAG_CXX_DESTRUCT ".cxx_destruct"
351
352 /* GNU-specific tags. */
353
354 #define TAG_EXECCLASS "__objc_exec_class"
355 #define TAG_GNUINIT "__objc_gnu_init"
356
357 /* Flags for lookup_method_static(). */
358 #define OBJC_LOOKUP_CLASS 1 /* Look for class methods. */
359 #define OBJC_LOOKUP_NO_SUPER 2 /* Do not examine superclasses. */
360
361 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
362 tree objc_global_trees[OCTI_MAX];
363
364 static void handle_impent (struct imp_entry *);
365
366 struct imp_entry *imp_list = 0;
367 int imp_count = 0; /* `@implementation' */
368 int cat_count = 0; /* `@category' */
369
370 enum tree_code objc_inherit_code;
371 int objc_public_flag;
372
373 /* Use to generate method labels. */
374 static int method_slot = 0;
375
376 #define BUFSIZE 1024
377
378 static char *errbuf; /* Buffer for error diagnostics */
379
380 /* Data imported from tree.c. */
381
382 extern enum debug_info_type write_symbols;
383
384 /* Data imported from toplev.c. */
385
386 extern const char *dump_base_name;
387 \f
388 static int flag_typed_selectors;
389
390 /* Store all constructed constant strings in a hash table so that
391 they get uniqued properly. */
392
393 struct GTY(()) string_descriptor {
394 /* The literal argument . */
395 tree literal;
396
397 /* The resulting constant string. */
398 tree constructor;
399 };
400
401 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
402
403 /* Store the EH-volatilized types in a hash table, for easy retrieval. */
404 struct GTY(()) volatilized_type {
405 tree type;
406 };
407
408 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
409
410 FILE *gen_declaration_file;
411
412 /* Tells "encode_pointer/encode_aggregate" whether we are generating
413 type descriptors for instance variables (as opposed to methods).
414 Type descriptors for instance variables contain more information
415 than methods (for static typing and embedded structures). */
416
417 static int generating_instance_variables = 0;
418
419 /* For building an objc struct. These may not be used when this file
420 is compiled as part of obj-c++. */
421
422 static bool objc_building_struct;
423 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
424
425 /* Start building a struct for objc. */
426
427 static tree
428 objc_start_struct (tree name)
429 {
430 gcc_assert (!objc_building_struct);
431 objc_building_struct = true;
432 return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
433 }
434
435 /* Finish building a struct for objc. */
436
437 static tree
438 objc_finish_struct (tree type, tree fieldlist)
439 {
440 gcc_assert (objc_building_struct);
441 objc_building_struct = false;
442 return finish_struct (input_location, type, fieldlist, NULL_TREE,
443 objc_struct_info);
444 }
445
446 /* Some platforms pass small structures through registers versus
447 through an invisible pointer. Determine at what size structure is
448 the transition point between the two possibilities. */
449
450 static void
451 generate_struct_by_value_array (void)
452 {
453 tree type;
454 tree field_decl, field_decl_chain;
455 int i, j;
456 int aggregate_in_mem[32];
457 int found = 0;
458
459 /* Presumably no platform passes 32 byte structures in a register. */
460 for (i = 1; i < 32; i++)
461 {
462 char buffer[5];
463
464 /* Create an unnamed struct that has `i' character components */
465 type = objc_start_struct (NULL_TREE);
466
467 strcpy (buffer, "c1");
468 field_decl = create_field_decl (char_type_node,
469 buffer);
470 field_decl_chain = field_decl;
471
472 for (j = 1; j < i; j++)
473 {
474 sprintf (buffer, "c%d", j + 1);
475 field_decl = create_field_decl (char_type_node,
476 buffer);
477 chainon (field_decl_chain, field_decl);
478 }
479 objc_finish_struct (type, field_decl_chain);
480
481 aggregate_in_mem[i] = aggregate_value_p (type, 0);
482 if (!aggregate_in_mem[i])
483 found = 1;
484 }
485
486 /* We found some structures that are returned in registers instead of memory
487 so output the necessary data. */
488 if (found)
489 {
490 for (i = 31; i >= 0; i--)
491 if (!aggregate_in_mem[i])
492 break;
493 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
494
495 /* The first member of the structure is always 0 because we don't handle
496 structures with 0 members */
497 printf ("static int struct_forward_array[] = {\n 0");
498
499 for (j = 1; j <= i; j++)
500 printf (", %d", aggregate_in_mem[j]);
501 printf ("\n};\n");
502 }
503
504 exit (0);
505 }
506
507 bool
508 objc_init (void)
509 {
510 #ifdef OBJCPLUS
511 if (cxx_init () == false)
512 #else
513 if (c_objc_common_init () == false)
514 #endif
515 return false;
516
517 /* If gen_declaration desired, open the output file. */
518 if (flag_gen_declaration)
519 {
520 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
521 gen_declaration_file = fopen (dumpname, "w");
522 if (gen_declaration_file == 0)
523 fatal_error ("can't open %s: %m", dumpname);
524 free (dumpname);
525 }
526
527 if (flag_next_runtime)
528 {
529 TAG_GETCLASS = "objc_getClass";
530 TAG_GETMETACLASS = "objc_getMetaClass";
531 TAG_MSGSEND = "objc_msgSend";
532 TAG_MSGSENDSUPER = "objc_msgSendSuper";
533 TAG_MSGSEND_STRET = "objc_msgSend_stret";
534 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
535 default_constant_string_class_name = "NSConstantString";
536 }
537 else
538 {
539 TAG_GETCLASS = "objc_get_class";
540 TAG_GETMETACLASS = "objc_get_meta_class";
541 TAG_MSGSEND = "objc_msg_lookup";
542 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
543 /* GNU runtime does not provide special functions to support
544 structure-returning methods. */
545 default_constant_string_class_name = "NXConstantString";
546 flag_typed_selectors = 1;
547 }
548
549 init_objc ();
550
551 if (print_struct_values && !flag_compare_debug)
552 generate_struct_by_value_array ();
553
554 return true;
555 }
556
557 void
558 objc_finish_file (void)
559 {
560 mark_referenced_methods ();
561
562 #ifdef OBJCPLUS
563 /* We need to instantiate templates _before_ we emit ObjC metadata;
564 if we do not, some metadata (such as selectors) may go missing. */
565 at_eof = 1;
566 instantiate_pending_templates (0);
567 #endif
568
569 /* Finalize Objective-C runtime data. No need to generate tables
570 and code if only checking syntax, or if generating a PCH file. */
571 if (!flag_syntax_only && !pch_file)
572 finish_objc ();
573
574 if (gen_declaration_file)
575 fclose (gen_declaration_file);
576 }
577 \f
578 /* Return the first occurrence of a method declaration corresponding
579 to sel_name in rproto_list. Search rproto_list recursively.
580 If is_class is 0, search for instance methods, otherwise for class
581 methods. */
582 static tree
583 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
584 int is_class)
585 {
586 tree rproto, p;
587 tree fnd = 0;
588
589 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
590 {
591 p = TREE_VALUE (rproto);
592
593 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
594 {
595 if ((fnd = lookup_method (is_class
596 ? PROTOCOL_CLS_METHODS (p)
597 : PROTOCOL_NST_METHODS (p), sel_name)))
598 ;
599 else if (PROTOCOL_LIST (p))
600 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
601 sel_name, is_class);
602 }
603 else
604 {
605 ; /* An identifier...if we could not find a protocol. */
606 }
607
608 if (fnd)
609 return fnd;
610 }
611
612 return 0;
613 }
614
615 static tree
616 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
617 {
618 tree rproto, p;
619
620 /* Make sure the protocol is supported by the object on the rhs. */
621 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
622 {
623 tree fnd = 0;
624 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
625 {
626 p = TREE_VALUE (rproto);
627
628 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
629 {
630 if (lproto == p)
631 fnd = lproto;
632
633 else if (PROTOCOL_LIST (p))
634 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
635 }
636
637 if (fnd)
638 return fnd;
639 }
640 }
641 else
642 {
643 ; /* An identifier...if we could not find a protocol. */
644 }
645
646 return 0;
647 }
648
649 void
650 objc_start_class_interface (tree klass, tree super_class, tree protos)
651 {
652 objc_interface_context
653 = objc_ivar_context
654 = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
655 objc_public_flag = 0;
656 }
657
658 void
659 objc_start_category_interface (tree klass, tree categ, tree protos)
660 {
661 objc_interface_context
662 = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
663 objc_ivar_chain
664 = continue_class (objc_interface_context);
665 }
666
667 void
668 objc_start_protocol (tree name, tree protos)
669 {
670 objc_interface_context
671 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
672 }
673
674 void
675 objc_continue_interface (void)
676 {
677 objc_ivar_chain
678 = continue_class (objc_interface_context);
679 }
680
681 void
682 objc_finish_interface (void)
683 {
684 finish_class (objc_interface_context);
685 objc_interface_context = NULL_TREE;
686 }
687
688 void
689 objc_start_class_implementation (tree klass, tree super_class)
690 {
691 objc_implementation_context
692 = objc_ivar_context
693 = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
694 objc_public_flag = 0;
695 }
696
697 void
698 objc_start_category_implementation (tree klass, tree categ)
699 {
700 objc_implementation_context
701 = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
702 objc_ivar_chain
703 = continue_class (objc_implementation_context);
704 }
705
706 void
707 objc_continue_implementation (void)
708 {
709 objc_ivar_chain
710 = continue_class (objc_implementation_context);
711 }
712
713 void
714 objc_finish_implementation (void)
715 {
716 #ifdef OBJCPLUS
717 if (flag_objc_call_cxx_cdtors)
718 objc_generate_cxx_cdtors ();
719 #endif
720
721 if (objc_implementation_context)
722 {
723 finish_class (objc_implementation_context);
724 objc_ivar_chain = NULL_TREE;
725 objc_implementation_context = NULL_TREE;
726 }
727 else
728 warning (0, "%<@end%> must appear in an @implementation context");
729 }
730
731 void
732 objc_set_visibility (int visibility)
733 {
734 objc_public_flag = visibility;
735 }
736
737 void
738 objc_set_method_type (enum tree_code type)
739 {
740 objc_inherit_code = (type == PLUS_EXPR
741 ? CLASS_METHOD_DECL
742 : INSTANCE_METHOD_DECL);
743 }
744
745 tree
746 objc_build_method_signature (tree rettype, tree selector,
747 tree optparms, bool ellipsis)
748 {
749 return build_method_decl (objc_inherit_code, rettype, selector,
750 optparms, ellipsis);
751 }
752
753 void
754 objc_add_method_declaration (tree decl)
755 {
756 if (!objc_interface_context)
757 fatal_error ("method declaration not in @interface context");
758
759 objc_add_method (objc_interface_context,
760 decl,
761 objc_inherit_code == CLASS_METHOD_DECL);
762 }
763
764 void
765 objc_start_method_definition (tree decl)
766 {
767 if (!objc_implementation_context)
768 fatal_error ("method definition not in @implementation context");
769
770 objc_add_method (objc_implementation_context,
771 decl,
772 objc_inherit_code == CLASS_METHOD_DECL);
773 start_method_def (decl);
774 }
775
776 void
777 objc_add_instance_variable (tree decl)
778 {
779 (void) add_instance_variable (objc_ivar_context,
780 objc_public_flag,
781 decl);
782 }
783
784 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
785 an '@'. */
786
787 int
788 objc_is_reserved_word (tree ident)
789 {
790 unsigned char code = C_RID_CODE (ident);
791
792 return (OBJC_IS_AT_KEYWORD (code)
793 || code == RID_CLASS || code == RID_PUBLIC
794 || code == RID_PROTECTED || code == RID_PRIVATE
795 || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
796 }
797
798 /* Return true if TYPE is 'id'. */
799
800 static bool
801 objc_is_object_id (tree type)
802 {
803 return OBJC_TYPE_NAME (type) == objc_object_id;
804 }
805
806 static bool
807 objc_is_class_id (tree type)
808 {
809 return OBJC_TYPE_NAME (type) == objc_class_id;
810 }
811
812 /* Construct a C struct with same name as KLASS, a base struct with tag
813 SUPER_NAME (if any), and FIELDS indicated. */
814
815 static tree
816 objc_build_struct (tree klass, tree fields, tree super_name)
817 {
818 tree name = CLASS_NAME (klass);
819 tree s = objc_start_struct (name);
820 tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
821 tree t, objc_info = NULL_TREE;
822
823 if (super)
824 {
825 /* Prepend a packed variant of the base class into the layout. This
826 is necessary to preserve ObjC ABI compatibility. */
827 tree base = build_decl (input_location,
828 FIELD_DECL, NULL_TREE, super);
829 tree field = TYPE_FIELDS (super);
830
831 while (field && TREE_CHAIN (field)
832 && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
833 field = TREE_CHAIN (field);
834
835 /* For ObjC ABI purposes, the "packed" size of a base class is
836 the sum of the offset and the size (in bits) of the last field
837 in the class. */
838 DECL_SIZE (base)
839 = (field && TREE_CODE (field) == FIELD_DECL
840 ? size_binop (PLUS_EXPR,
841 size_binop (PLUS_EXPR,
842 size_binop
843 (MULT_EXPR,
844 convert (bitsizetype,
845 DECL_FIELD_OFFSET (field)),
846 bitsize_int (BITS_PER_UNIT)),
847 DECL_FIELD_BIT_OFFSET (field)),
848 DECL_SIZE (field))
849 : bitsize_zero_node);
850 DECL_SIZE_UNIT (base)
851 = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
852 size_int (BITS_PER_UNIT));
853 DECL_ARTIFICIAL (base) = 1;
854 DECL_ALIGN (base) = 1;
855 DECL_FIELD_CONTEXT (base) = s;
856 #ifdef OBJCPLUS
857 DECL_FIELD_IS_BASE (base) = 1;
858
859 if (fields)
860 TREE_NO_WARNING (fields) = 1; /* Suppress C++ ABI warnings -- we */
861 #endif /* are following the ObjC ABI here. */
862 TREE_CHAIN (base) = fields;
863 fields = base;
864 }
865
866 /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
867 in all variants of this RECORD_TYPE to be clobbered, but it is therein
868 that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
869 Hence, we must squirrel away the ObjC-specific information before calling
870 finish_struct(), and then reinstate it afterwards. */
871
872 for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
873 objc_info
874 = chainon (objc_info,
875 build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
876
877 /* Point the struct at its related Objective-C class. */
878 INIT_TYPE_OBJC_INFO (s);
879 TYPE_OBJC_INTERFACE (s) = klass;
880
881 s = objc_finish_struct (s, fields);
882
883 for (t = TYPE_NEXT_VARIANT (s); t;
884 t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
885 {
886 TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
887 /* Replace the IDENTIFIER_NODE with an actual @interface. */
888 TYPE_OBJC_INTERFACE (t) = klass;
889 }
890
891 /* Use TYPE_BINFO structures to point at the super class, if any. */
892 objc_xref_basetypes (s, super);
893
894 /* Mark this struct as a class template. */
895 CLASS_STATIC_TEMPLATE (klass) = s;
896
897 return s;
898 }
899
900 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
901 Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
902 process. */
903 static tree
904 objc_build_volatilized_type (tree type)
905 {
906 tree t;
907
908 /* Check if we have not constructed the desired variant already. */
909 for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
910 {
911 /* The type qualifiers must (obviously) match up. */
912 if (!TYPE_VOLATILE (t)
913 || (TYPE_READONLY (t) != TYPE_READONLY (type))
914 || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
915 continue;
916
917 /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
918 info, if any) must match up. */
919 if (POINTER_TYPE_P (t)
920 && (TREE_TYPE (t) != TREE_TYPE (type)))
921 continue;
922
923 /* Everything matches up! */
924 return t;
925 }
926
927 /* Ok, we could not re-use any of the pre-existing variants. Create
928 a new one. */
929 t = build_variant_type_copy (type);
930 TYPE_VOLATILE (t) = 1;
931
932 /* Set up the canonical type information. */
933 if (TYPE_STRUCTURAL_EQUALITY_P (type))
934 SET_TYPE_STRUCTURAL_EQUALITY (t);
935 else if (TYPE_CANONICAL (type) != type)
936 TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
937 else
938 TYPE_CANONICAL (t) = t;
939
940 return t;
941 }
942
943 /* Mark DECL as being 'volatile' for purposes of Darwin
944 _setjmp()/_longjmp() exception handling. Called from
945 objc_mark_locals_volatile(). */
946 void
947 objc_volatilize_decl (tree decl)
948 {
949 /* Do not mess with variables that are 'static' or (already)
950 'volatile'. */
951 if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
952 && (TREE_CODE (decl) == VAR_DECL
953 || TREE_CODE (decl) == PARM_DECL))
954 {
955 tree t = TREE_TYPE (decl);
956 struct volatilized_type key;
957 void **loc;
958
959 t = objc_build_volatilized_type (t);
960 key.type = t;
961 loc = htab_find_slot (volatilized_htab, &key, INSERT);
962
963 if (!*loc)
964 {
965 *loc = ggc_alloc (sizeof (key));
966 ((struct volatilized_type *) *loc)->type = t;
967 }
968
969 TREE_TYPE (decl) = t;
970 TREE_THIS_VOLATILE (decl) = 1;
971 TREE_SIDE_EFFECTS (decl) = 1;
972 DECL_REGISTER (decl) = 0;
973 #ifndef OBJCPLUS
974 C_DECL_REGISTER (decl) = 0;
975 #endif
976 }
977 }
978
979 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
980 (including its categories and superclasses) or by object type TYP.
981 Issue a warning if PROTO is not adopted anywhere and WARN is set. */
982
983 static bool
984 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
985 {
986 bool class_type = (cls != NULL_TREE);
987
988 while (cls)
989 {
990 tree c;
991
992 /* Check protocols adopted by the class and its categories. */
993 for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
994 {
995 if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
996 return true;
997 }
998
999 /* Repeat for superclasses. */
1000 cls = lookup_interface (CLASS_SUPER_NAME (cls));
1001 }
1002
1003 /* Check for any protocols attached directly to the object type. */
1004 if (TYPE_HAS_OBJC_INFO (typ))
1005 {
1006 if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1007 return true;
1008 }
1009
1010 if (warn)
1011 {
1012 *errbuf = 0;
1013 gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1014 /* NB: Types 'id' and 'Class' cannot reasonably be described as
1015 "implementing" a given protocol, since they do not have an
1016 implementation. */
1017 if (class_type)
1018 warning (0, "class %qs does not implement the %qE protocol",
1019 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1020 else
1021 warning (0, "type %qs does not conform to the %qE protocol",
1022 identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1023 }
1024
1025 return false;
1026 }
1027
1028 /* Check if class RCLS and instance struct type RTYP conform to at least the
1029 same protocols that LCLS and LTYP conform to. */
1030
1031 static bool
1032 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1033 {
1034 tree p;
1035 bool have_lproto = false;
1036
1037 while (lcls)
1038 {
1039 /* NB: We do _not_ look at categories defined for LCLS; these may or
1040 may not get loaded in, and therefore it is unreasonable to require
1041 that RCLS/RTYP must implement any of their protocols. */
1042 for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1043 {
1044 have_lproto = true;
1045
1046 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1047 return warn;
1048 }
1049
1050 /* Repeat for superclasses. */
1051 lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1052 }
1053
1054 /* Check for any protocols attached directly to the object type. */
1055 if (TYPE_HAS_OBJC_INFO (ltyp))
1056 {
1057 for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1058 {
1059 have_lproto = true;
1060
1061 if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1062 return warn;
1063 }
1064 }
1065
1066 /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1067 vacuously, _unless_ RTYP is a protocol-qualified 'id'. We can get
1068 away with simply checking for 'id' or 'Class' (!RCLS), since this
1069 routine will not get called in other cases. */
1070 return have_lproto || (rcls != NULL_TREE);
1071 }
1072
1073 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1074 an instance of RTYP to an instance of LTYP or to compare the two
1075 (if ARGNO is equal to -3), per ObjC type system rules. Before
1076 returning 'true', this routine may issue warnings related to, e.g.,
1077 protocol conformance. When returning 'false', the routine must
1078 produce absolutely no warnings; the C or C++ front-end will do so
1079 instead, if needed. If either LTYP or RTYP is not an Objective-C type,
1080 the routine must return 'false'.
1081
1082 The ARGNO parameter is encoded as follows:
1083 >= 1 Parameter number (CALLEE contains function being called);
1084 0 Return value;
1085 -1 Assignment;
1086 -2 Initialization;
1087 -3 Comparison (LTYP and RTYP may match in either direction). */
1088
1089 bool
1090 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1091 {
1092 tree lcls, rcls, lproto, rproto;
1093 bool pointers_compatible;
1094
1095 /* We must be dealing with pointer types */
1096 if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1097 return false;
1098
1099 do
1100 {
1101 ltyp = TREE_TYPE (ltyp); /* Remove indirections. */
1102 rtyp = TREE_TYPE (rtyp);
1103 }
1104 while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1105
1106 /* Past this point, we are only interested in ObjC class instances,
1107 or 'id' or 'Class'. */
1108 if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1109 return false;
1110
1111 if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1112 && !TYPE_HAS_OBJC_INFO (ltyp))
1113 return false;
1114
1115 if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1116 && !TYPE_HAS_OBJC_INFO (rtyp))
1117 return false;
1118
1119 /* Past this point, we are committed to returning 'true' to the caller.
1120 However, we can still warn about type and/or protocol mismatches. */
1121
1122 if (TYPE_HAS_OBJC_INFO (ltyp))
1123 {
1124 lcls = TYPE_OBJC_INTERFACE (ltyp);
1125 lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1126 }
1127 else
1128 lcls = lproto = NULL_TREE;
1129
1130 if (TYPE_HAS_OBJC_INFO (rtyp))
1131 {
1132 rcls = TYPE_OBJC_INTERFACE (rtyp);
1133 rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1134 }
1135 else
1136 rcls = rproto = NULL_TREE;
1137
1138 /* If we could not find an @interface declaration, we must have
1139 only seen a @class declaration; for purposes of type comparison,
1140 treat it as a stand-alone (root) class. */
1141
1142 if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1143 lcls = NULL_TREE;
1144
1145 if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1146 rcls = NULL_TREE;
1147
1148 /* If either type is an unqualified 'id', we're done. */
1149 if ((!lproto && objc_is_object_id (ltyp))
1150 || (!rproto && objc_is_object_id (rtyp)))
1151 return true;
1152
1153 pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1154
1155 /* If the underlying types are the same, and at most one of them has
1156 a protocol list, we do not need to issue any diagnostics. */
1157 if (pointers_compatible && (!lproto || !rproto))
1158 return true;
1159
1160 /* If exactly one of the types is 'Class', issue a diagnostic; any
1161 exceptions of this rule have already been handled. */
1162 if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1163 pointers_compatible = false;
1164 /* Otherwise, check for inheritance relations. */
1165 else
1166 {
1167 if (!pointers_compatible)
1168 pointers_compatible
1169 = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1170
1171 if (!pointers_compatible)
1172 pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1173
1174 if (!pointers_compatible && argno == -3)
1175 pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1176 }
1177
1178 /* If the pointers match modulo protocols, check for protocol conformance
1179 mismatches. */
1180 if (pointers_compatible)
1181 {
1182 pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1183 argno != -3);
1184
1185 if (!pointers_compatible && argno == -3)
1186 pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1187 argno != -3);
1188 }
1189
1190 if (!pointers_compatible)
1191 {
1192 /* NB: For the time being, we shall make our warnings look like their
1193 C counterparts. In the future, we may wish to make them more
1194 ObjC-specific. */
1195 switch (argno)
1196 {
1197 case -3:
1198 warning (0, "comparison of distinct Objective-C types lacks a cast");
1199 break;
1200
1201 case -2:
1202 warning (0, "initialization from distinct Objective-C type");
1203 break;
1204
1205 case -1:
1206 warning (0, "assignment from distinct Objective-C type");
1207 break;
1208
1209 case 0:
1210 warning (0, "distinct Objective-C type in return");
1211 break;
1212
1213 default:
1214 warning (0, "passing argument %d of %qE from distinct "
1215 "Objective-C type", argno, callee);
1216 break;
1217 }
1218 }
1219
1220 return true;
1221 }
1222
1223 /* Check if LTYP and RTYP have the same type qualifiers. If either type
1224 lives in the volatilized hash table, ignore the 'volatile' bit when
1225 making the comparison. */
1226
1227 bool
1228 objc_type_quals_match (tree ltyp, tree rtyp)
1229 {
1230 int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1231 struct volatilized_type key;
1232
1233 key.type = ltyp;
1234
1235 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1236 lquals &= ~TYPE_QUAL_VOLATILE;
1237
1238 key.type = rtyp;
1239
1240 if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1241 rquals &= ~TYPE_QUAL_VOLATILE;
1242
1243 return (lquals == rquals);
1244 }
1245
1246 #ifndef OBJCPLUS
1247 /* Determine if CHILD is derived from PARENT. The routine assumes that
1248 both parameters are RECORD_TYPEs, and is non-reflexive. */
1249
1250 static bool
1251 objc_derived_from_p (tree parent, tree child)
1252 {
1253 parent = TYPE_MAIN_VARIANT (parent);
1254
1255 for (child = TYPE_MAIN_VARIANT (child);
1256 TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1257 {
1258 child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1259 (TYPE_BINFO (child),
1260 0)));
1261
1262 if (child == parent)
1263 return true;
1264 }
1265
1266 return false;
1267 }
1268 #endif
1269
1270 static tree
1271 objc_build_component_ref (tree datum, tree component)
1272 {
1273 /* If COMPONENT is NULL, the caller is referring to the anonymous
1274 base class field. */
1275 if (!component)
1276 {
1277 tree base = TYPE_FIELDS (TREE_TYPE (datum));
1278
1279 return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1280 }
1281
1282 /* The 'build_component_ref' routine has been removed from the C++
1283 front-end, but 'finish_class_member_access_expr' seems to be
1284 a worthy substitute. */
1285 #ifdef OBJCPLUS
1286 return finish_class_member_access_expr (datum, component, false,
1287 tf_warning_or_error);
1288 #else
1289 return build_component_ref (input_location, datum, component);
1290 #endif
1291 }
1292
1293 /* Recursively copy inheritance information rooted at BINFO. To do this,
1294 we emulate the song and dance performed by cp/tree.c:copy_binfo(). */
1295
1296 static tree
1297 objc_copy_binfo (tree binfo)
1298 {
1299 tree btype = BINFO_TYPE (binfo);
1300 tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1301 tree base_binfo;
1302 int ix;
1303
1304 BINFO_TYPE (binfo2) = btype;
1305 BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1306 BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1307
1308 /* Recursively copy base binfos of BINFO. */
1309 for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1310 {
1311 tree base_binfo2 = objc_copy_binfo (base_binfo);
1312
1313 BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1314 BINFO_BASE_APPEND (binfo2, base_binfo2);
1315 }
1316
1317 return binfo2;
1318 }
1319
1320 /* Record superclass information provided in BASETYPE for ObjC class REF.
1321 This is loosely based on cp/decl.c:xref_basetypes(). */
1322
1323 static void
1324 objc_xref_basetypes (tree ref, tree basetype)
1325 {
1326 tree binfo = make_tree_binfo (basetype ? 1 : 0);
1327
1328 TYPE_BINFO (ref) = binfo;
1329 BINFO_OFFSET (binfo) = size_zero_node;
1330 BINFO_TYPE (binfo) = ref;
1331
1332 if (basetype)
1333 {
1334 tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1335
1336 BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1337 BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1338 BINFO_BASE_APPEND (binfo, base_binfo);
1339 BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1340 }
1341 }
1342
1343 static hashval_t
1344 volatilized_hash (const void *ptr)
1345 {
1346 const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1347
1348 return htab_hash_pointer(typ);
1349 }
1350
1351 static int
1352 volatilized_eq (const void *ptr1, const void *ptr2)
1353 {
1354 const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1355 const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1356
1357 return typ1 == typ2;
1358 }
1359
1360 /* Called from finish_decl. */
1361
1362 void
1363 objc_check_decl (tree decl)
1364 {
1365 tree type = TREE_TYPE (decl);
1366
1367 if (TREE_CODE (type) != RECORD_TYPE)
1368 return;
1369 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1370 error ("statically allocated instance of Objective-C class %qE",
1371 type);
1372 }
1373
1374 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1375 either name an Objective-C class, or refer to the special 'id' or 'Class'
1376 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1377
1378 tree
1379 objc_get_protocol_qualified_type (tree interface, tree protocols)
1380 {
1381 /* If INTERFACE is not provided, default to 'id'. */
1382 tree type = (interface ? objc_is_id (interface) : objc_object_type);
1383 bool is_ptr = (type != NULL_TREE);
1384
1385 if (!is_ptr)
1386 {
1387 type = objc_is_class_name (interface);
1388
1389 if (type)
1390 type = xref_tag (RECORD_TYPE, type);
1391 else
1392 return interface;
1393 }
1394
1395 if (protocols)
1396 {
1397 type = build_variant_type_copy (type);
1398
1399 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1400 to the pointee. */
1401 if (is_ptr)
1402 {
1403 tree orig_pointee_type = TREE_TYPE (type);
1404 TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1405
1406 /* Set up the canonical type information. */
1407 TYPE_CANONICAL (type)
1408 = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1409
1410 TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1411 type = TREE_TYPE (type);
1412 }
1413
1414 /* Look up protocols and install in lang specific list. */
1415 DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1416 TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1417
1418 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1419 return the pointer to the new pointee variant. */
1420 if (is_ptr)
1421 type = TYPE_POINTER_TO (type);
1422 else
1423 TYPE_OBJC_INTERFACE (type)
1424 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1425 }
1426
1427 return type;
1428 }
1429
1430 /* Check for circular dependencies in protocols. The arguments are
1431 PROTO, the protocol to check, and LIST, a list of protocol it
1432 conforms to. */
1433
1434 static void
1435 check_protocol_recursively (tree proto, tree list)
1436 {
1437 tree p;
1438
1439 for (p = list; p; p = TREE_CHAIN (p))
1440 {
1441 tree pp = TREE_VALUE (p);
1442
1443 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1444 pp = lookup_protocol (pp);
1445
1446 if (pp == proto)
1447 fatal_error ("protocol %qE has circular dependency",
1448 PROTOCOL_NAME (pp));
1449 if (pp)
1450 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1451 }
1452 }
1453
1454 /* Look up PROTOCOLS, and return a list of those that are found.
1455 If none are found, return NULL. */
1456
1457 static tree
1458 lookup_and_install_protocols (tree protocols)
1459 {
1460 tree proto;
1461 tree return_value = NULL_TREE;
1462
1463 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1464 {
1465 tree ident = TREE_VALUE (proto);
1466 tree p = lookup_protocol (ident);
1467
1468 if (p)
1469 return_value = chainon (return_value,
1470 build_tree_list (NULL_TREE, p));
1471 else if (ident != error_mark_node)
1472 error ("cannot find protocol declaration for %qE",
1473 ident);
1474 }
1475
1476 return return_value;
1477 }
1478
1479 /* Create a declaration for field NAME of a given TYPE. */
1480
1481 static tree
1482 create_field_decl (tree type, const char *name)
1483 {
1484 return build_decl (input_location,
1485 FIELD_DECL, get_identifier (name), type);
1486 }
1487
1488 /* Create a global, static declaration for variable NAME of a given TYPE. The
1489 finish_var_decl() routine will need to be called on it afterwards. */
1490
1491 static tree
1492 start_var_decl (tree type, const char *name)
1493 {
1494 tree var = build_decl (input_location,
1495 VAR_DECL, get_identifier (name), type);
1496
1497 TREE_STATIC (var) = 1;
1498 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1499 DECL_IGNORED_P (var) = 1;
1500 DECL_ARTIFICIAL (var) = 1;
1501 DECL_CONTEXT (var) = NULL_TREE;
1502 #ifdef OBJCPLUS
1503 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1504 #endif
1505
1506 return var;
1507 }
1508
1509 /* Finish off the variable declaration created by start_var_decl(). */
1510
1511 static void
1512 finish_var_decl (tree var, tree initializer)
1513 {
1514 finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
1515 /* Ensure that the variable actually gets output. */
1516 mark_decl_referenced (var);
1517 /* Mark the decl to avoid "defined but not used" warning. */
1518 TREE_USED (var) = 1;
1519 }
1520
1521 /* Find the decl for the constant string class reference. This is only
1522 used for the NeXT runtime. */
1523
1524 static tree
1525 setup_string_decl (void)
1526 {
1527 char *name;
1528 size_t length;
1529
1530 /* %s in format will provide room for terminating null */
1531 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1532 + strlen (constant_string_class_name);
1533 name = XNEWVEC (char, length);
1534 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1535 constant_string_class_name);
1536 constant_string_global_id = get_identifier (name);
1537 string_class_decl = lookup_name (constant_string_global_id);
1538
1539 return string_class_decl;
1540 }
1541
1542 /* Purpose: "play" parser, creating/installing representations
1543 of the declarations that are required by Objective-C.
1544
1545 Model:
1546
1547 type_spec--------->sc_spec
1548 (tree_list) (tree_list)
1549 | |
1550 | |
1551 identifier_node identifier_node */
1552
1553 static void
1554 synth_module_prologue (void)
1555 {
1556 tree type;
1557 enum debug_info_type save_write_symbols = write_symbols;
1558 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1559
1560 /* Suppress outputting debug symbols, because
1561 dbxout_init hasn't been called yet. */
1562 write_symbols = NO_DEBUG;
1563 debug_hooks = &do_nothing_debug_hooks;
1564
1565 #ifdef OBJCPLUS
1566 push_lang_context (lang_name_c); /* extern "C" */
1567 #endif
1568
1569 /* The following are also defined in <objc/objc.h> and friends. */
1570
1571 objc_object_id = get_identifier (TAG_OBJECT);
1572 objc_class_id = get_identifier (TAG_CLASS);
1573
1574 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1575 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1576
1577 objc_object_type = build_pointer_type (objc_object_reference);
1578 objc_class_type = build_pointer_type (objc_class_reference);
1579
1580 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1581 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1582
1583 /* Declare the 'id' and 'Class' typedefs. */
1584
1585 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1586 TYPE_DECL,
1587 objc_object_name,
1588 objc_object_type));
1589 TREE_NO_WARNING (type) = 1;
1590 type = lang_hooks.decls.pushdecl (build_decl (input_location,
1591 TYPE_DECL,
1592 objc_class_name,
1593 objc_class_type));
1594 TREE_NO_WARNING (type) = 1;
1595
1596 /* Forward-declare '@interface Protocol'. */
1597
1598 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1599 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1600 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1601 type));
1602
1603 /* Declare type of selector-objects that represent an operation name. */
1604
1605 if (flag_next_runtime)
1606 /* `struct objc_selector *' */
1607 objc_selector_type
1608 = build_pointer_type (xref_tag (RECORD_TYPE,
1609 get_identifier (TAG_SELECTOR)));
1610 else
1611 /* `const struct objc_selector *' */
1612 objc_selector_type
1613 = build_pointer_type
1614 (build_qualified_type (xref_tag (RECORD_TYPE,
1615 get_identifier (TAG_SELECTOR)),
1616 TYPE_QUAL_CONST));
1617
1618 /* Declare receiver type used for dispatching messages to 'super'. */
1619
1620 /* `struct objc_super *' */
1621 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1622 get_identifier (TAG_SUPER)));
1623
1624 /* Declare pointers to method and ivar lists. */
1625 objc_method_list_ptr = build_pointer_type
1626 (xref_tag (RECORD_TYPE,
1627 get_identifier (UTAG_METHOD_LIST)));
1628 objc_method_proto_list_ptr
1629 = build_pointer_type (xref_tag (RECORD_TYPE,
1630 get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1631 objc_ivar_list_ptr = build_pointer_type
1632 (xref_tag (RECORD_TYPE,
1633 get_identifier (UTAG_IVAR_LIST)));
1634
1635 /* TREE_NOTHROW is cleared for the message-sending functions,
1636 because the function that gets called can throw in Obj-C++, or
1637 could itself call something that can throw even in Obj-C. */
1638
1639 if (flag_next_runtime)
1640 {
1641 /* NB: In order to call one of the ..._stret (struct-returning)
1642 functions, the function *MUST* first be cast to a signature that
1643 corresponds to the actual ObjC method being invoked. This is
1644 what is done by the build_objc_method_call() routine below. */
1645
1646 /* id objc_msgSend (id, SEL, ...); */
1647 /* id objc_msgSendNonNil (id, SEL, ...); */
1648 /* id objc_msgSend_stret (id, SEL, ...); */
1649 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1650 type
1651 = build_function_type (objc_object_type,
1652 tree_cons (NULL_TREE, objc_object_type,
1653 tree_cons (NULL_TREE, objc_selector_type,
1654 NULL_TREE)));
1655 umsg_decl = add_builtin_function (TAG_MSGSEND,
1656 type, 0, NOT_BUILT_IN,
1657 NULL, NULL_TREE);
1658 umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1659 type, 0, NOT_BUILT_IN,
1660 NULL, NULL_TREE);
1661 umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1662 type, 0, NOT_BUILT_IN,
1663 NULL, NULL_TREE);
1664 umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1665 type, 0, NOT_BUILT_IN,
1666 NULL, NULL_TREE);
1667
1668 /* These can throw, because the function that gets called can throw
1669 in Obj-C++, or could itself call something that can throw even
1670 in Obj-C. */
1671 TREE_NOTHROW (umsg_decl) = 0;
1672 TREE_NOTHROW (umsg_nonnil_decl) = 0;
1673 TREE_NOTHROW (umsg_stret_decl) = 0;
1674 TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1675
1676 /* id objc_msgSend_Fast (id, SEL, ...)
1677 __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1678 #ifdef OFFS_MSGSEND_FAST
1679 umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1680 type, 0, NOT_BUILT_IN,
1681 NULL, NULL_TREE);
1682 TREE_NOTHROW (umsg_fast_decl) = 0;
1683 DECL_ATTRIBUTES (umsg_fast_decl)
1684 = tree_cons (get_identifier ("hard_coded_address"),
1685 build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1686 NULL_TREE);
1687 #else
1688 /* No direct dispatch available. */
1689 umsg_fast_decl = umsg_decl;
1690 #endif
1691
1692 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1693 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1694 type
1695 = build_function_type (objc_object_type,
1696 tree_cons (NULL_TREE, objc_super_type,
1697 tree_cons (NULL_TREE, objc_selector_type,
1698 NULL_TREE)));
1699 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1700 type, 0, NOT_BUILT_IN,
1701 NULL, NULL_TREE);
1702 umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1703 type, 0, NOT_BUILT_IN, 0,
1704 NULL_TREE);
1705 TREE_NOTHROW (umsg_super_decl) = 0;
1706 TREE_NOTHROW (umsg_super_stret_decl) = 0;
1707 }
1708 else
1709 {
1710 /* GNU runtime messenger entry points. */
1711
1712 /* typedef id (*IMP)(id, SEL, ...); */
1713 tree IMP_type
1714 = build_pointer_type
1715 (build_function_type (objc_object_type,
1716 tree_cons (NULL_TREE, objc_object_type,
1717 tree_cons (NULL_TREE, objc_selector_type,
1718 NULL_TREE))));
1719
1720 /* IMP objc_msg_lookup (id, SEL); */
1721 type
1722 = build_function_type (IMP_type,
1723 tree_cons (NULL_TREE, objc_object_type,
1724 tree_cons (NULL_TREE, objc_selector_type,
1725 OBJC_VOID_AT_END)));
1726 umsg_decl = add_builtin_function (TAG_MSGSEND,
1727 type, 0, NOT_BUILT_IN,
1728 NULL, NULL_TREE);
1729 TREE_NOTHROW (umsg_decl) = 0;
1730
1731 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1732 type
1733 = build_function_type (IMP_type,
1734 tree_cons (NULL_TREE, objc_super_type,
1735 tree_cons (NULL_TREE, objc_selector_type,
1736 OBJC_VOID_AT_END)));
1737 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1738 type, 0, NOT_BUILT_IN,
1739 NULL, NULL_TREE);
1740 TREE_NOTHROW (umsg_super_decl) = 0;
1741
1742 /* The following GNU runtime entry point is called to initialize
1743 each module:
1744
1745 __objc_exec_class (void *); */
1746 type
1747 = build_function_type (void_type_node,
1748 tree_cons (NULL_TREE, ptr_type_node,
1749 OBJC_VOID_AT_END));
1750 execclass_decl = add_builtin_function (TAG_EXECCLASS,
1751 type, 0, NOT_BUILT_IN,
1752 NULL, NULL_TREE);
1753 }
1754
1755 /* id objc_getClass (const char *); */
1756
1757 type = build_function_type (objc_object_type,
1758 tree_cons (NULL_TREE,
1759 const_string_type_node,
1760 OBJC_VOID_AT_END));
1761
1762 objc_get_class_decl
1763 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1764 NULL, NULL_TREE);
1765
1766 /* id objc_getMetaClass (const char *); */
1767
1768 objc_get_meta_class_decl
1769 = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1770
1771 build_class_template ();
1772 build_super_template ();
1773 build_protocol_template ();
1774 build_category_template ();
1775 build_objc_exception_stuff ();
1776
1777 if (flag_next_runtime)
1778 build_next_objc_exception_stuff ();
1779
1780 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1781
1782 if (! flag_next_runtime)
1783 build_selector_table_decl ();
1784
1785 /* Forward declare constant_string_id and constant_string_type. */
1786 if (!constant_string_class_name)
1787 constant_string_class_name = default_constant_string_class_name;
1788
1789 constant_string_id = get_identifier (constant_string_class_name);
1790 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1791
1792 /* Pre-build the following entities - for speed/convenience. */
1793 self_id = get_identifier ("self");
1794 ucmd_id = get_identifier ("_cmd");
1795
1796 #ifdef OBJCPLUS
1797 pop_lang_context ();
1798 #endif
1799
1800 write_symbols = save_write_symbols;
1801 debug_hooks = save_hooks;
1802 }
1803
1804 /* Ensure that the ivar list for NSConstantString/NXConstantString
1805 (or whatever was specified via `-fconstant-string-class')
1806 contains fields at least as large as the following three, so that
1807 the runtime can stomp on them with confidence:
1808
1809 struct STRING_OBJECT_CLASS_NAME
1810 {
1811 Object isa;
1812 char *cString;
1813 unsigned int length;
1814 }; */
1815
1816 static int
1817 check_string_class_template (void)
1818 {
1819 tree field_decl = objc_get_class_ivars (constant_string_id);
1820
1821 #define AT_LEAST_AS_LARGE_AS(F, T) \
1822 (F && TREE_CODE (F) == FIELD_DECL \
1823 && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1824 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1825
1826 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1827 return 0;
1828
1829 field_decl = TREE_CHAIN (field_decl);
1830 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1831 return 0;
1832
1833 field_decl = TREE_CHAIN (field_decl);
1834 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1835
1836 #undef AT_LEAST_AS_LARGE_AS
1837 }
1838
1839 /* Avoid calling `check_string_class_template ()' more than once. */
1840 static GTY(()) int string_layout_checked;
1841
1842 /* Construct an internal string layout to be used as a template for
1843 creating NSConstantString/NXConstantString instances. */
1844
1845 static tree
1846 objc_build_internal_const_str_type (void)
1847 {
1848 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1849 tree fields = build_decl (input_location,
1850 FIELD_DECL, NULL_TREE, ptr_type_node);
1851 tree field = build_decl (input_location,
1852 FIELD_DECL, NULL_TREE, ptr_type_node);
1853
1854 TREE_CHAIN (field) = fields; fields = field;
1855 field = build_decl (input_location,
1856 FIELD_DECL, NULL_TREE, unsigned_type_node);
1857 TREE_CHAIN (field) = fields; fields = field;
1858 /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1859 reverse order! */
1860 finish_builtin_struct (type, "__builtin_ObjCString",
1861 fields, NULL_TREE);
1862
1863 return type;
1864 }
1865
1866 /* Custom build_string which sets TREE_TYPE! */
1867
1868 static tree
1869 my_build_string (int len, const char *str)
1870 {
1871 return fix_string_type (build_string (len, str));
1872 }
1873
1874 /* Build a string with contents STR and length LEN and convert it to a
1875 pointer. */
1876
1877 static tree
1878 my_build_string_pointer (int len, const char *str)
1879 {
1880 tree string = my_build_string (len, str);
1881 tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1882 return build1 (ADDR_EXPR, ptrtype, string);
1883 }
1884
1885 static hashval_t
1886 string_hash (const void *ptr)
1887 {
1888 const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1889 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1890 int i, len = TREE_STRING_LENGTH (str);
1891 hashval_t h = len;
1892
1893 for (i = 0; i < len; i++)
1894 h = ((h * 613) + p[i]);
1895
1896 return h;
1897 }
1898
1899 static int
1900 string_eq (const void *ptr1, const void *ptr2)
1901 {
1902 const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1903 const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1904 int len1 = TREE_STRING_LENGTH (str1);
1905
1906 return (len1 == TREE_STRING_LENGTH (str2)
1907 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1908 len1));
1909 }
1910
1911 /* Given a chain of STRING_CST's, build a static instance of
1912 NXConstantString which points at the concatenation of those
1913 strings. We place the string object in the __string_objects
1914 section of the __OBJC segment. The Objective-C runtime will
1915 initialize the isa pointers of the string objects to point at the
1916 NXConstantString class object. */
1917
1918 tree
1919 objc_build_string_object (tree string)
1920 {
1921 tree initlist, constructor, constant_string_class;
1922 int length;
1923 tree fields, addr;
1924 struct string_descriptor *desc, key;
1925 void **loc;
1926
1927 /* Prep the string argument. */
1928 string = fix_string_type (string);
1929 TREE_SET_CODE (string, STRING_CST);
1930 length = TREE_STRING_LENGTH (string) - 1;
1931
1932 /* Check whether the string class being used actually exists and has the
1933 correct ivar layout. */
1934 if (!string_layout_checked)
1935 {
1936 string_layout_checked = -1;
1937 constant_string_class = lookup_interface (constant_string_id);
1938 internal_const_str_type = objc_build_internal_const_str_type ();
1939
1940 if (!constant_string_class
1941 || !(constant_string_type
1942 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1943 error ("cannot find interface declaration for %qE",
1944 constant_string_id);
1945 /* The NSConstantString/NXConstantString ivar layout is now known. */
1946 else if (!check_string_class_template ())
1947 error ("interface %qE does not have valid constant string layout",
1948 constant_string_id);
1949 /* For the NeXT runtime, we can generate a literal reference
1950 to the string class, don't need to run a constructor. */
1951 else if (flag_next_runtime && !setup_string_decl ())
1952 error ("cannot find reference tag for class %qE",
1953 constant_string_id);
1954 else
1955 {
1956 string_layout_checked = 1; /* Success! */
1957 add_class_reference (constant_string_id);
1958 }
1959 }
1960
1961 if (string_layout_checked == -1)
1962 return error_mark_node;
1963
1964 /* Perhaps we already constructed a constant string just like this one? */
1965 key.literal = string;
1966 loc = htab_find_slot (string_htab, &key, INSERT);
1967 desc = (struct string_descriptor *) *loc;
1968
1969 if (!desc)
1970 {
1971 tree var;
1972 *loc = desc = GGC_NEW (struct string_descriptor);
1973 desc->literal = string;
1974
1975 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
1976 /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
1977 fields = TYPE_FIELDS (internal_const_str_type);
1978 initlist
1979 = build_tree_list (fields,
1980 flag_next_runtime
1981 ? build_unary_op (input_location,
1982 ADDR_EXPR, string_class_decl, 0)
1983 : build_int_cst (NULL_TREE, 0));
1984 fields = TREE_CHAIN (fields);
1985 initlist = tree_cons (fields, build_unary_op (input_location,
1986 ADDR_EXPR, string, 1),
1987 initlist);
1988 fields = TREE_CHAIN (fields);
1989 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1990 initlist);
1991 constructor = objc_build_constructor (internal_const_str_type,
1992 nreverse (initlist));
1993
1994 if (!flag_next_runtime)
1995 constructor
1996 = objc_add_static_instance (constructor, constant_string_type);
1997 else
1998 {
1999 var = build_decl (input_location,
2000 CONST_DECL, NULL, TREE_TYPE (constructor));
2001 DECL_INITIAL (var) = constructor;
2002 TREE_STATIC (var) = 1;
2003 pushdecl_top_level (var);
2004 constructor = var;
2005 }
2006 desc->constructor = constructor;
2007 }
2008
2009 addr = convert (build_pointer_type (constant_string_type),
2010 build_unary_op (input_location,
2011 ADDR_EXPR, desc->constructor, 1));
2012
2013 return addr;
2014 }
2015
2016 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
2017
2018 static GTY(()) int num_static_inst;
2019
2020 static tree
2021 objc_add_static_instance (tree constructor, tree class_decl)
2022 {
2023 tree *chain, decl;
2024 char buf[256];
2025
2026 /* Find the list of static instances for the CLASS_DECL. Create one if
2027 not found. */
2028 for (chain = &objc_static_instances;
2029 *chain && TREE_VALUE (*chain) != class_decl;
2030 chain = &TREE_CHAIN (*chain));
2031 if (!*chain)
2032 {
2033 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2034 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2035 }
2036
2037 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2038 decl = build_decl (input_location,
2039 VAR_DECL, get_identifier (buf), class_decl);
2040 DECL_COMMON (decl) = 1;
2041 TREE_STATIC (decl) = 1;
2042 DECL_ARTIFICIAL (decl) = 1;
2043 TREE_USED (decl) = 1;
2044 DECL_INITIAL (decl) = constructor;
2045
2046 /* We may be writing something else just now.
2047 Postpone till end of input. */
2048 DECL_DEFER_OUTPUT (decl) = 1;
2049 pushdecl_top_level (decl);
2050 rest_of_decl_compilation (decl, 1, 0);
2051
2052 /* Add the DECL to the head of this CLASS' list. */
2053 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2054
2055 return decl;
2056 }
2057
2058 /* Build a static constant CONSTRUCTOR
2059 with type TYPE and elements ELTS. */
2060
2061 static tree
2062 objc_build_constructor (tree type, tree elts)
2063 {
2064 tree constructor = build_constructor_from_list (type, elts);
2065
2066 TREE_CONSTANT (constructor) = 1;
2067 TREE_STATIC (constructor) = 1;
2068 TREE_READONLY (constructor) = 1;
2069
2070 #ifdef OBJCPLUS
2071 /* Adjust for impedance mismatch. We should figure out how to build
2072 CONSTRUCTORs that consistently please both the C and C++ gods. */
2073 if (!TREE_PURPOSE (elts))
2074 TREE_TYPE (constructor) = init_list_type_node;
2075 #endif
2076
2077 return constructor;
2078 }
2079 \f
2080 /* Take care of defining and initializing _OBJC_SYMBOLS. */
2081
2082 /* Predefine the following data type:
2083
2084 struct _objc_symtab
2085 {
2086 long sel_ref_cnt;
2087 SEL *refs;
2088 short cls_def_cnt;
2089 short cat_def_cnt;
2090 void *defs[cls_def_cnt + cat_def_cnt];
2091 }; */
2092
2093 static void
2094 build_objc_symtab_template (void)
2095 {
2096 tree field_decl, field_decl_chain;
2097
2098 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2099
2100 /* long sel_ref_cnt; */
2101 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2102 field_decl_chain = field_decl;
2103
2104 /* SEL *refs; */
2105 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2106 "refs");
2107 chainon (field_decl_chain, field_decl);
2108
2109 /* short cls_def_cnt; */
2110 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2111 chainon (field_decl_chain, field_decl);
2112
2113 /* short cat_def_cnt; */
2114 field_decl = create_field_decl (short_integer_type_node,
2115 "cat_def_cnt");
2116 chainon (field_decl_chain, field_decl);
2117
2118 if (imp_count || cat_count || !flag_next_runtime)
2119 {
2120 /* void *defs[imp_count + cat_count (+ 1)]; */
2121 /* NB: The index is one less than the size of the array. */
2122 int index = imp_count + cat_count
2123 + (flag_next_runtime? -1: 0);
2124 field_decl = create_field_decl
2125 (build_array_type
2126 (ptr_type_node,
2127 build_index_type (build_int_cst (NULL_TREE, index))),
2128 "defs");
2129 chainon (field_decl_chain, field_decl);
2130 }
2131
2132 objc_finish_struct (objc_symtab_template, field_decl_chain);
2133 }
2134
2135 /* Create the initial value for the `defs' field of _objc_symtab.
2136 This is a CONSTRUCTOR. */
2137
2138 static tree
2139 init_def_list (tree type)
2140 {
2141 tree expr, initlist = NULL_TREE;
2142 struct imp_entry *impent;
2143
2144 if (imp_count)
2145 for (impent = imp_list; impent; impent = impent->next)
2146 {
2147 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2148 {
2149 expr = build_unary_op (input_location,
2150 ADDR_EXPR, impent->class_decl, 0);
2151 initlist = tree_cons (NULL_TREE, expr, initlist);
2152 }
2153 }
2154
2155 if (cat_count)
2156 for (impent = imp_list; impent; impent = impent->next)
2157 {
2158 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2159 {
2160 expr = build_unary_op (input_location,
2161 ADDR_EXPR, impent->class_decl, 0);
2162 initlist = tree_cons (NULL_TREE, expr, initlist);
2163 }
2164 }
2165
2166 if (!flag_next_runtime)
2167 {
2168 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
2169 tree expr;
2170
2171 if (static_instances_decl)
2172 expr = build_unary_op (input_location,
2173 ADDR_EXPR, static_instances_decl, 0);
2174 else
2175 expr = build_int_cst (NULL_TREE, 0);
2176
2177 initlist = tree_cons (NULL_TREE, expr, initlist);
2178 }
2179
2180 return objc_build_constructor (type, nreverse (initlist));
2181 }
2182
2183 /* Construct the initial value for all of _objc_symtab. */
2184
2185 static tree
2186 init_objc_symtab (tree type)
2187 {
2188 tree initlist;
2189
2190 /* sel_ref_cnt = { ..., 5, ... } */
2191
2192 initlist = build_tree_list (NULL_TREE,
2193 build_int_cst (long_integer_type_node, 0));
2194
2195 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2196
2197 if (flag_next_runtime || ! sel_ref_chain)
2198 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2199 else
2200 initlist
2201 = tree_cons (NULL_TREE,
2202 convert (build_pointer_type (objc_selector_type),
2203 build_unary_op (input_location, ADDR_EXPR,
2204 UOBJC_SELECTOR_TABLE_decl, 1)),
2205 initlist);
2206
2207 /* cls_def_cnt = { ..., 5, ... } */
2208
2209 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2210
2211 /* cat_def_cnt = { ..., 5, ... } */
2212
2213 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2214
2215 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2216
2217 if (imp_count || cat_count || !flag_next_runtime)
2218 {
2219
2220 tree field = TYPE_FIELDS (type);
2221 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2222
2223 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2224 initlist);
2225 }
2226
2227 return objc_build_constructor (type, nreverse (initlist));
2228 }
2229
2230 /* Generate forward declarations for metadata such as
2231 'OBJC_CLASS_...'. */
2232
2233 static tree
2234 build_metadata_decl (const char *name, tree type)
2235 {
2236 tree decl;
2237
2238 /* struct TYPE NAME_<name>; */
2239 decl = start_var_decl (type, synth_id_with_class_suffix
2240 (name,
2241 objc_implementation_context));
2242
2243 return decl;
2244 }
2245
2246 /* Push forward-declarations of all the categories so that
2247 init_def_list can use them in a CONSTRUCTOR. */
2248
2249 static void
2250 forward_declare_categories (void)
2251 {
2252 struct imp_entry *impent;
2253 tree sav = objc_implementation_context;
2254
2255 for (impent = imp_list; impent; impent = impent->next)
2256 {
2257 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2258 {
2259 /* Set an invisible arg to synth_id_with_class_suffix. */
2260 objc_implementation_context = impent->imp_context;
2261 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2262 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2263 objc_category_template);
2264 }
2265 }
2266 objc_implementation_context = sav;
2267 }
2268
2269 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2270 and initialized appropriately. */
2271
2272 static void
2273 generate_objc_symtab_decl (void)
2274 {
2275 /* forward declare categories */
2276 if (cat_count)
2277 forward_declare_categories ();
2278
2279 build_objc_symtab_template ();
2280 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2281 finish_var_decl (UOBJC_SYMBOLS_decl,
2282 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2283 }
2284 \f
2285 static tree
2286 init_module_descriptor (tree type)
2287 {
2288 tree initlist, expr;
2289
2290 /* version = { 1, ... } */
2291
2292 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2293 initlist = build_tree_list (NULL_TREE, expr);
2294
2295 /* size = { ..., sizeof (struct _objc_module), ... } */
2296
2297 expr = convert (long_integer_type_node,
2298 size_in_bytes (objc_module_template));
2299 initlist = tree_cons (NULL_TREE, expr, initlist);
2300
2301 /* Don't provide any file name for security reasons. */
2302 /* name = { ..., "", ... } */
2303
2304 expr = add_objc_string (get_identifier (""), class_names);
2305 initlist = tree_cons (NULL_TREE, expr, initlist);
2306
2307 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2308
2309 if (UOBJC_SYMBOLS_decl)
2310 expr = build_unary_op (input_location,
2311 ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2312 else
2313 expr = build_int_cst (NULL_TREE, 0);
2314 initlist = tree_cons (NULL_TREE, expr, initlist);
2315
2316 return objc_build_constructor (type, nreverse (initlist));
2317 }
2318
2319 /* Write out the data structures to describe Objective C classes defined.
2320
2321 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2322
2323 static void
2324 build_module_descriptor (void)
2325 {
2326 tree field_decl, field_decl_chain;
2327
2328 #ifdef OBJCPLUS
2329 push_lang_context (lang_name_c); /* extern "C" */
2330 #endif
2331
2332 objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2333
2334 /* long version; */
2335 field_decl = create_field_decl (long_integer_type_node, "version");
2336 field_decl_chain = field_decl;
2337
2338 /* long size; */
2339 field_decl = create_field_decl (long_integer_type_node, "size");
2340 chainon (field_decl_chain, field_decl);
2341
2342 /* char *name; */
2343 field_decl = create_field_decl (string_type_node, "name");
2344 chainon (field_decl_chain, field_decl);
2345
2346 /* struct _objc_symtab *symtab; */
2347 field_decl
2348 = create_field_decl (build_pointer_type
2349 (xref_tag (RECORD_TYPE,
2350 get_identifier (UTAG_SYMTAB))),
2351 "symtab");
2352 chainon (field_decl_chain, field_decl);
2353
2354 objc_finish_struct (objc_module_template, field_decl_chain);
2355
2356 /* Create an instance of "_objc_module". */
2357 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2358 finish_var_decl (UOBJC_MODULES_decl,
2359 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2360
2361 #ifdef OBJCPLUS
2362 pop_lang_context ();
2363 #endif
2364 }
2365
2366 /* The GNU runtime requires us to provide a static initializer function
2367 for each module:
2368
2369 static void __objc_gnu_init (void) {
2370 __objc_exec_class (&L_OBJC_MODULES);
2371 } */
2372
2373 static void
2374 build_module_initializer_routine (void)
2375 {
2376 tree body;
2377
2378 #ifdef OBJCPLUS
2379 push_lang_context (lang_name_c); /* extern "C" */
2380 #endif
2381
2382 objc_push_parm (build_decl (input_location,
2383 PARM_DECL, NULL_TREE, void_type_node));
2384 objc_start_function (get_identifier (TAG_GNUINIT),
2385 build_function_type (void_type_node,
2386 OBJC_VOID_AT_END),
2387 NULL_TREE, objc_get_parm_info (0));
2388
2389 body = c_begin_compound_stmt (true);
2390 add_stmt (build_function_call
2391 (input_location,
2392 execclass_decl,
2393 build_tree_list
2394 (NULL_TREE,
2395 build_unary_op (input_location, ADDR_EXPR,
2396 UOBJC_MODULES_decl, 0))));
2397 add_stmt (c_end_compound_stmt (input_location, body, true));
2398
2399 TREE_PUBLIC (current_function_decl) = 0;
2400
2401 #ifndef OBJCPLUS
2402 /* For Objective-C++, we will need to call __objc_gnu_init
2403 from objc_generate_static_init_call() below. */
2404 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2405 #endif
2406
2407 GNU_INIT_decl = current_function_decl;
2408 finish_function ();
2409
2410 #ifdef OBJCPLUS
2411 pop_lang_context ();
2412 #endif
2413 }
2414
2415 #ifdef OBJCPLUS
2416 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2417 to be called by the module initializer routine. */
2418
2419 int
2420 objc_static_init_needed_p (void)
2421 {
2422 return (GNU_INIT_decl != NULL_TREE);
2423 }
2424
2425 /* Generate a call to the __objc_gnu_init initializer function. */
2426
2427 tree
2428 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2429 {
2430 add_stmt (build_stmt (input_location, EXPR_STMT,
2431 build_function_call (input_location,
2432 GNU_INIT_decl, NULL_TREE)));
2433
2434 return ctors;
2435 }
2436 #endif /* OBJCPLUS */
2437
2438 /* Return the DECL of the string IDENT in the SECTION. */
2439
2440 static tree
2441 get_objc_string_decl (tree ident, enum string_section section)
2442 {
2443 tree chain;
2444
2445 if (section == class_names)
2446 chain = class_names_chain;
2447 else if (section == meth_var_names)
2448 chain = meth_var_names_chain;
2449 else if (section == meth_var_types)
2450 chain = meth_var_types_chain;
2451 else
2452 abort ();
2453
2454 for (; chain != 0; chain = TREE_CHAIN (chain))
2455 if (TREE_VALUE (chain) == ident)
2456 return (TREE_PURPOSE (chain));
2457
2458 abort ();
2459 return NULL_TREE;
2460 }
2461
2462 /* Output references to all statically allocated objects. Return the DECL
2463 for the array built. */
2464
2465 static void
2466 generate_static_references (void)
2467 {
2468 tree decls = NULL_TREE, expr = NULL_TREE;
2469 tree class_name, klass, decl, initlist;
2470 tree cl_chain, in_chain, type
2471 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2472 int num_inst, num_class;
2473 char buf[256];
2474
2475 if (flag_next_runtime)
2476 abort ();
2477
2478 for (cl_chain = objc_static_instances, num_class = 0;
2479 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2480 {
2481 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2482 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2483
2484 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2485 decl = start_var_decl (type, buf);
2486
2487 /* Output {class_name, ...}. */
2488 klass = TREE_VALUE (cl_chain);
2489 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2490 initlist = build_tree_list (NULL_TREE,
2491 build_unary_op (input_location,
2492 ADDR_EXPR, class_name, 1));
2493
2494 /* Output {..., instance, ...}. */
2495 for (in_chain = TREE_PURPOSE (cl_chain);
2496 in_chain; in_chain = TREE_CHAIN (in_chain))
2497 {
2498 expr = build_unary_op (input_location,
2499 ADDR_EXPR, TREE_VALUE (in_chain), 1);
2500 initlist = tree_cons (NULL_TREE, expr, initlist);
2501 }
2502
2503 /* Output {..., NULL}. */
2504 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2505
2506 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2507 finish_var_decl (decl, expr);
2508 decls
2509 = tree_cons (NULL_TREE, build_unary_op (input_location,
2510 ADDR_EXPR, decl, 1), decls);
2511 }
2512
2513 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2514 expr = objc_build_constructor (type, nreverse (decls));
2515 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2516 finish_var_decl (static_instances_decl, expr);
2517 }
2518
2519 static GTY(()) int selector_reference_idx;
2520
2521 static tree
2522 build_selector_reference_decl (void)
2523 {
2524 tree decl;
2525 char buf[256];
2526
2527 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2528 decl = start_var_decl (objc_selector_type, buf);
2529
2530 return decl;
2531 }
2532
2533 static void
2534 build_selector_table_decl (void)
2535 {
2536 tree temp;
2537
2538 if (flag_typed_selectors)
2539 {
2540 build_selector_template ();
2541 temp = build_array_type (objc_selector_template, NULL_TREE);
2542 }
2543 else
2544 temp = build_array_type (objc_selector_type, NULL_TREE);
2545
2546 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2547 }
2548
2549 /* Just a handy wrapper for add_objc_string. */
2550
2551 static tree
2552 build_selector (tree ident)
2553 {
2554 return convert (objc_selector_type,
2555 add_objc_string (ident, meth_var_names));
2556 }
2557
2558 static void
2559 build_selector_translation_table (void)
2560 {
2561 tree chain, initlist = NULL_TREE;
2562 int offset = 0;
2563 tree decl = NULL_TREE;
2564
2565 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2566 {
2567 tree expr;
2568
2569 if (warn_selector && objc_implementation_context)
2570 {
2571 tree method_chain;
2572 bool found = false;
2573 for (method_chain = meth_var_names_chain;
2574 method_chain;
2575 method_chain = TREE_CHAIN (method_chain))
2576 {
2577 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2578 {
2579 found = true;
2580 break;
2581 }
2582 }
2583 if (!found)
2584 {
2585 location_t loc;
2586 if (flag_next_runtime && TREE_PURPOSE (chain))
2587 loc = DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2588 else
2589 loc = input_location;
2590 warning_at (loc, 0, "creating selector for nonexistent method %qE",
2591 TREE_VALUE (chain));
2592 }
2593 }
2594
2595 expr = build_selector (TREE_VALUE (chain));
2596 /* add one for the '\0' character */
2597 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2598
2599 if (flag_next_runtime)
2600 {
2601 decl = TREE_PURPOSE (chain);
2602 finish_var_decl (decl, expr);
2603 }
2604 else
2605 {
2606 if (flag_typed_selectors)
2607 {
2608 tree eltlist = NULL_TREE;
2609 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2610 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2611 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2612 expr = objc_build_constructor (objc_selector_template,
2613 nreverse (eltlist));
2614 }
2615
2616 initlist = tree_cons (NULL_TREE, expr, initlist);
2617 }
2618 }
2619
2620 if (! flag_next_runtime)
2621 {
2622 /* Cause the selector table (previously forward-declared)
2623 to be actually output. */
2624 initlist = tree_cons (NULL_TREE,
2625 flag_typed_selectors
2626 ? objc_build_constructor
2627 (objc_selector_template,
2628 tree_cons (NULL_TREE,
2629 build_int_cst (NULL_TREE, 0),
2630 tree_cons (NULL_TREE,
2631 build_int_cst (NULL_TREE, 0),
2632 NULL_TREE)))
2633 : build_int_cst (NULL_TREE, 0), initlist);
2634 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2635 nreverse (initlist));
2636 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2637 }
2638 }
2639
2640 static tree
2641 get_proto_encoding (tree proto)
2642 {
2643 tree encoding;
2644 if (proto)
2645 {
2646 if (! METHOD_ENCODING (proto))
2647 {
2648 encoding = encode_method_prototype (proto);
2649 METHOD_ENCODING (proto) = encoding;
2650 }
2651 else
2652 encoding = METHOD_ENCODING (proto);
2653
2654 return add_objc_string (encoding, meth_var_types);
2655 }
2656 else
2657 return build_int_cst (NULL_TREE, 0);
2658 }
2659
2660 /* sel_ref_chain is a list whose "value" fields will be instances of
2661 identifier_node that represent the selector. LOC is the location of
2662 the @selector. */
2663
2664 static tree
2665 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
2666 {
2667 tree *chain = &sel_ref_chain;
2668 tree expr;
2669 int index = 0;
2670
2671 while (*chain)
2672 {
2673 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2674 goto return_at_index;
2675
2676 index++;
2677 chain = &TREE_CHAIN (*chain);
2678 }
2679
2680 *chain = tree_cons (prototype, ident, NULL_TREE);
2681
2682 return_at_index:
2683 expr = build_unary_op (loc, ADDR_EXPR,
2684 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2685 build_int_cst (NULL_TREE, index)),
2686 1);
2687 return convert (objc_selector_type, expr);
2688 }
2689
2690 static tree
2691 build_selector_reference (location_t loc, tree ident)
2692 {
2693 tree *chain = &sel_ref_chain;
2694 tree expr;
2695 int index = 0;
2696
2697 while (*chain)
2698 {
2699 if (TREE_VALUE (*chain) == ident)
2700 return (flag_next_runtime
2701 ? TREE_PURPOSE (*chain)
2702 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2703 build_int_cst (NULL_TREE, index)));
2704
2705 index++;
2706 chain = &TREE_CHAIN (*chain);
2707 }
2708
2709 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2710
2711 *chain = tree_cons (expr, ident, NULL_TREE);
2712
2713 return (flag_next_runtime
2714 ? expr
2715 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2716 build_int_cst (NULL_TREE, index)));
2717 }
2718
2719 static GTY(()) int class_reference_idx;
2720
2721 static tree
2722 build_class_reference_decl (void)
2723 {
2724 tree decl;
2725 char buf[256];
2726
2727 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2728 decl = start_var_decl (objc_class_type, buf);
2729
2730 return decl;
2731 }
2732
2733 /* Create a class reference, but don't create a variable to reference
2734 it. */
2735
2736 static void
2737 add_class_reference (tree ident)
2738 {
2739 tree chain;
2740
2741 if ((chain = cls_ref_chain))
2742 {
2743 tree tail;
2744 do
2745 {
2746 if (ident == TREE_VALUE (chain))
2747 return;
2748
2749 tail = chain;
2750 chain = TREE_CHAIN (chain);
2751 }
2752 while (chain);
2753
2754 /* Append to the end of the list */
2755 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2756 }
2757 else
2758 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2759 }
2760
2761 /* Get a class reference, creating it if necessary. Also create the
2762 reference variable. */
2763
2764 tree
2765 objc_get_class_reference (tree ident)
2766 {
2767 tree orig_ident = (DECL_P (ident)
2768 ? DECL_NAME (ident)
2769 : TYPE_P (ident)
2770 ? OBJC_TYPE_NAME (ident)
2771 : ident);
2772 bool local_scope = false;
2773
2774 #ifdef OBJCPLUS
2775 if (processing_template_decl)
2776 /* Must wait until template instantiation time. */
2777 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2778 #endif
2779
2780 if (TREE_CODE (ident) == TYPE_DECL)
2781 ident = (DECL_ORIGINAL_TYPE (ident)
2782 ? DECL_ORIGINAL_TYPE (ident)
2783 : TREE_TYPE (ident));
2784
2785 #ifdef OBJCPLUS
2786 if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2787 && TYPE_CONTEXT (ident) != global_namespace)
2788 local_scope = true;
2789 #endif
2790
2791 if (local_scope || !(ident = objc_is_class_name (ident)))
2792 {
2793 error ("%qE is not an Objective-C class name or alias",
2794 orig_ident);
2795 return error_mark_node;
2796 }
2797
2798 if (flag_next_runtime && !flag_zero_link)
2799 {
2800 tree *chain;
2801 tree decl;
2802
2803 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2804 if (TREE_VALUE (*chain) == ident)
2805 {
2806 if (! TREE_PURPOSE (*chain))
2807 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2808
2809 return TREE_PURPOSE (*chain);
2810 }
2811
2812 decl = build_class_reference_decl ();
2813 *chain = tree_cons (decl, ident, NULL_TREE);
2814 return decl;
2815 }
2816 else
2817 {
2818 tree params;
2819
2820 add_class_reference (ident);
2821
2822 params = build_tree_list (NULL_TREE,
2823 my_build_string_pointer
2824 (IDENTIFIER_LENGTH (ident) + 1,
2825 IDENTIFIER_POINTER (ident)));
2826
2827 assemble_external (objc_get_class_decl);
2828 return build_function_call (input_location, objc_get_class_decl, params);
2829 }
2830 }
2831
2832 /* For each string section we have a chain which maps identifier nodes
2833 to decls for the strings. */
2834
2835 static tree
2836 add_objc_string (tree ident, enum string_section section)
2837 {
2838 tree *chain, decl, type, string_expr;
2839
2840 if (section == class_names)
2841 chain = &class_names_chain;
2842 else if (section == meth_var_names)
2843 chain = &meth_var_names_chain;
2844 else if (section == meth_var_types)
2845 chain = &meth_var_types_chain;
2846 else
2847 abort ();
2848
2849 while (*chain)
2850 {
2851 if (TREE_VALUE (*chain) == ident)
2852 return convert (string_type_node,
2853 build_unary_op (input_location,
2854 ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2855
2856 chain = &TREE_CHAIN (*chain);
2857 }
2858
2859 decl = build_objc_string_decl (section);
2860
2861 type = build_array_type
2862 (char_type_node,
2863 build_index_type
2864 (build_int_cst (NULL_TREE,
2865 IDENTIFIER_LENGTH (ident))));
2866 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2867 string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2868 IDENTIFIER_POINTER (ident));
2869 finish_var_decl (decl, string_expr);
2870
2871 *chain = tree_cons (decl, ident, NULL_TREE);
2872
2873 return convert (string_type_node, build_unary_op (input_location,
2874 ADDR_EXPR, decl, 1));
2875 }
2876
2877 static GTY(()) int class_names_idx;
2878 static GTY(()) int meth_var_names_idx;
2879 static GTY(()) int meth_var_types_idx;
2880
2881 static tree
2882 build_objc_string_decl (enum string_section section)
2883 {
2884 tree decl, ident;
2885 char buf[256];
2886
2887 if (section == class_names)
2888 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2889 else if (section == meth_var_names)
2890 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2891 else if (section == meth_var_types)
2892 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2893
2894 ident = get_identifier (buf);
2895
2896 decl = build_decl (input_location,
2897 VAR_DECL, ident, build_array_type (char_type_node, 0));
2898 DECL_EXTERNAL (decl) = 1;
2899 TREE_PUBLIC (decl) = 0;
2900 TREE_USED (decl) = 1;
2901 TREE_CONSTANT (decl) = 1;
2902 DECL_CONTEXT (decl) = 0;
2903 DECL_ARTIFICIAL (decl) = 1;
2904 #ifdef OBJCPLUS
2905 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2906 #endif
2907
2908 make_decl_rtl (decl);
2909 pushdecl_top_level (decl);
2910
2911 return decl;
2912 }
2913
2914
2915 void
2916 objc_declare_alias (tree alias_ident, tree class_ident)
2917 {
2918 tree underlying_class;
2919
2920 #ifdef OBJCPLUS
2921 if (current_namespace != global_namespace) {
2922 error ("Objective-C declarations may only appear in global scope");
2923 }
2924 #endif /* OBJCPLUS */
2925
2926 if (!(underlying_class = objc_is_class_name (class_ident)))
2927 warning (0, "cannot find class %qE", class_ident);
2928 else if (objc_is_class_name (alias_ident))
2929 warning (0, "class %qE already exists", alias_ident);
2930 else
2931 {
2932 /* Implement @compatibility_alias as a typedef. */
2933 #ifdef OBJCPLUS
2934 push_lang_context (lang_name_c); /* extern "C" */
2935 #endif
2936 lang_hooks.decls.pushdecl (build_decl
2937 (input_location,
2938 TYPE_DECL,
2939 alias_ident,
2940 xref_tag (RECORD_TYPE, underlying_class)));
2941 #ifdef OBJCPLUS
2942 pop_lang_context ();
2943 #endif
2944 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2945 }
2946 }
2947
2948 void
2949 objc_declare_class (tree ident_list)
2950 {
2951 tree list;
2952 #ifdef OBJCPLUS
2953 if (current_namespace != global_namespace) {
2954 error ("Objective-C declarations may only appear in global scope");
2955 }
2956 #endif /* OBJCPLUS */
2957
2958 for (list = ident_list; list; list = TREE_CHAIN (list))
2959 {
2960 tree ident = TREE_VALUE (list);
2961
2962 if (! objc_is_class_name (ident))
2963 {
2964 tree record = lookup_name (ident), type = record;
2965
2966 if (record)
2967 {
2968 if (TREE_CODE (record) == TYPE_DECL)
2969 type = DECL_ORIGINAL_TYPE (record);
2970
2971 if (!TYPE_HAS_OBJC_INFO (type)
2972 || !TYPE_OBJC_INTERFACE (type))
2973 {
2974 error ("%qE redeclared as different kind of symbol",
2975 ident);
2976 error ("previous declaration of %q+D",
2977 record);
2978 }
2979 }
2980
2981 record = xref_tag (RECORD_TYPE, ident);
2982 INIT_TYPE_OBJC_INFO (record);
2983 TYPE_OBJC_INTERFACE (record) = ident;
2984 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2985 }
2986 }
2987 }
2988
2989 tree
2990 objc_is_class_name (tree ident)
2991 {
2992 tree chain;
2993
2994 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2995 && identifier_global_value (ident))
2996 ident = identifier_global_value (ident);
2997 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2998 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2999
3000 if (ident && TREE_CODE (ident) == RECORD_TYPE)
3001 ident = OBJC_TYPE_NAME (ident);
3002 #ifdef OBJCPLUS
3003 if (ident && TREE_CODE (ident) == TYPE_DECL)
3004 ident = DECL_NAME (ident);
3005 #endif
3006 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3007 return NULL_TREE;
3008
3009 if (lookup_interface (ident))
3010 return ident;
3011
3012 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3013 {
3014 if (ident == TREE_VALUE (chain))
3015 return ident;
3016 }
3017
3018 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3019 {
3020 if (ident == TREE_VALUE (chain))
3021 return TREE_PURPOSE (chain);
3022 }
3023
3024 return 0;
3025 }
3026
3027 /* Check whether TYPE is either 'id' or 'Class'. */
3028
3029 tree
3030 objc_is_id (tree type)
3031 {
3032 if (type && TREE_CODE (type) == IDENTIFIER_NODE
3033 && identifier_global_value (type))
3034 type = identifier_global_value (type);
3035
3036 if (type && TREE_CODE (type) == TYPE_DECL)
3037 type = TREE_TYPE (type);
3038
3039 /* NB: This function may be called before the ObjC front-end has
3040 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
3041 return (objc_object_type && type
3042 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3043 ? type
3044 : NULL_TREE);
3045 }
3046
3047 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3048 class instance. This is needed by other parts of the compiler to
3049 handle ObjC types gracefully. */
3050
3051 tree
3052 objc_is_object_ptr (tree type)
3053 {
3054 tree ret;
3055
3056 type = TYPE_MAIN_VARIANT (type);
3057 if (!POINTER_TYPE_P (type))
3058 return 0;
3059
3060 ret = objc_is_id (type);
3061 if (!ret)
3062 ret = objc_is_class_name (TREE_TYPE (type));
3063
3064 return ret;
3065 }
3066
3067 static int
3068 objc_is_gcable_type (tree type, int or_strong_p)
3069 {
3070 tree name;
3071
3072 if (!TYPE_P (type))
3073 return 0;
3074 if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3075 return 1;
3076 if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3077 return 1;
3078 if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3079 return 0;
3080 type = TREE_TYPE (type);
3081 if (TREE_CODE (type) != RECORD_TYPE)
3082 return 0;
3083 name = TYPE_NAME (type);
3084 return (objc_is_class_name (name) != NULL_TREE);
3085 }
3086
3087 static tree
3088 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3089 {
3090 if (expr == oldexpr)
3091 return newexpr;
3092
3093 switch (TREE_CODE (expr))
3094 {
3095 case COMPONENT_REF:
3096 return objc_build_component_ref
3097 (objc_substitute_decl (TREE_OPERAND (expr, 0),
3098 oldexpr,
3099 newexpr),
3100 DECL_NAME (TREE_OPERAND (expr, 1)));
3101 case ARRAY_REF:
3102 return build_array_ref (input_location,
3103 objc_substitute_decl (TREE_OPERAND (expr, 0),
3104 oldexpr,
3105 newexpr),
3106 TREE_OPERAND (expr, 1));
3107 case INDIRECT_REF:
3108 return build_indirect_ref (input_location,
3109 objc_substitute_decl (TREE_OPERAND (expr, 0),
3110 oldexpr,
3111 newexpr), "->");
3112 default:
3113 return expr;
3114 }
3115 }
3116
3117 static tree
3118 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3119 {
3120 tree func_params;
3121 /* The LHS parameter contains the expression 'outervar->memberspec';
3122 we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3123 where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3124 */
3125 tree offs
3126 = objc_substitute_decl
3127 (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3128 tree func
3129 = (flag_objc_direct_dispatch
3130 ? objc_assign_ivar_fast_decl
3131 : objc_assign_ivar_decl);
3132
3133 offs = convert (integer_type_node, build_unary_op (input_location,
3134 ADDR_EXPR, offs, 0));
3135 offs = fold (offs);
3136 func_params = tree_cons (NULL_TREE,
3137 convert (objc_object_type, rhs),
3138 tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3139 tree_cons (NULL_TREE, offs,
3140 NULL_TREE)));
3141
3142 assemble_external (func);
3143 return build_function_call (input_location, func, func_params);
3144 }
3145
3146 static tree
3147 objc_build_global_assignment (tree lhs, tree rhs)
3148 {
3149 tree func_params = tree_cons (NULL_TREE,
3150 convert (objc_object_type, rhs),
3151 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3152 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3153 NULL_TREE));
3154
3155 assemble_external (objc_assign_global_decl);
3156 return build_function_call (input_location,
3157 objc_assign_global_decl, func_params);
3158 }
3159
3160 static tree
3161 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3162 {
3163 tree func_params = tree_cons (NULL_TREE,
3164 convert (objc_object_type, rhs),
3165 tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3166 build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3167 NULL_TREE));
3168
3169 assemble_external (objc_assign_strong_cast_decl);
3170 return build_function_call (input_location,
3171 objc_assign_strong_cast_decl, func_params);
3172 }
3173
3174 static int
3175 objc_is_gcable_p (tree expr)
3176 {
3177 return (TREE_CODE (expr) == COMPONENT_REF
3178 ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3179 : TREE_CODE (expr) == ARRAY_REF
3180 ? (objc_is_gcable_p (TREE_TYPE (expr))
3181 || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3182 : TREE_CODE (expr) == ARRAY_TYPE
3183 ? objc_is_gcable_p (TREE_TYPE (expr))
3184 : TYPE_P (expr)
3185 ? objc_is_gcable_type (expr, 1)
3186 : (objc_is_gcable_p (TREE_TYPE (expr))
3187 || (DECL_P (expr)
3188 && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3189 }
3190
3191 static int
3192 objc_is_ivar_reference_p (tree expr)
3193 {
3194 return (TREE_CODE (expr) == ARRAY_REF
3195 ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3196 : TREE_CODE (expr) == COMPONENT_REF
3197 ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3198 : 0);
3199 }
3200
3201 static int
3202 objc_is_global_reference_p (tree expr)
3203 {
3204 return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3205 ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3206 : DECL_P (expr)
3207 ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3208 : 0);
3209 }
3210
3211 tree
3212 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3213 {
3214 tree result = NULL_TREE, outer;
3215 int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3216
3217 /* See if we have any lhs casts, and strip them out. NB: The lvalue casts
3218 will have been transformed to the form '*(type *)&expr'. */
3219 if (TREE_CODE (lhs) == INDIRECT_REF)
3220 {
3221 outer = TREE_OPERAND (lhs, 0);
3222
3223 while (!strong_cast_p
3224 && (CONVERT_EXPR_P (outer)
3225 || TREE_CODE (outer) == NON_LVALUE_EXPR))
3226 {
3227 tree lhstype = TREE_TYPE (outer);
3228
3229 /* Descend down the cast chain, and record the first objc_gc
3230 attribute found. */
3231 if (POINTER_TYPE_P (lhstype))
3232 {
3233 tree attr
3234 = lookup_attribute ("objc_gc",
3235 TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3236
3237 if (attr)
3238 strong_cast_p = 1;
3239 }
3240
3241 outer = TREE_OPERAND (outer, 0);
3242 }
3243 }
3244
3245 /* If we have a __strong cast, it trumps all else. */
3246 if (strong_cast_p)
3247 {
3248 if (modifycode != NOP_EXPR)
3249 goto invalid_pointer_arithmetic;
3250
3251 if (warn_assign_intercept)
3252 warning (0, "strong-cast assignment has been intercepted");
3253
3254 result = objc_build_strong_cast_assignment (lhs, rhs);
3255
3256 goto exit_point;
3257 }
3258
3259 /* the lhs must be of a suitable type, regardless of its underlying
3260 structure. */
3261 if (!objc_is_gcable_p (lhs))
3262 goto exit_point;
3263
3264 outer = lhs;
3265
3266 while (outer
3267 && (TREE_CODE (outer) == COMPONENT_REF
3268 || TREE_CODE (outer) == ARRAY_REF))
3269 outer = TREE_OPERAND (outer, 0);
3270
3271 if (TREE_CODE (outer) == INDIRECT_REF)
3272 {
3273 outer = TREE_OPERAND (outer, 0);
3274 indirect_p = 1;
3275 }
3276
3277 outer_gc_p = objc_is_gcable_p (outer);
3278
3279 /* Handle ivar assignments. */
3280 if (objc_is_ivar_reference_p (lhs))
3281 {
3282 /* if the struct to the left of the ivar is not an Objective-C object (__strong
3283 doesn't cut it here), the best we can do here is suggest a cast. */
3284 if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3285 {
3286 /* We may still be able to use the global write barrier... */
3287 if (!indirect_p && objc_is_global_reference_p (outer))
3288 goto global_reference;
3289
3290 suggest_cast:
3291 if (modifycode == NOP_EXPR)
3292 {
3293 if (warn_assign_intercept)
3294 warning (0, "strong-cast may possibly be needed");
3295 }
3296
3297 goto exit_point;
3298 }
3299
3300 if (modifycode != NOP_EXPR)
3301 goto invalid_pointer_arithmetic;
3302
3303 if (warn_assign_intercept)
3304 warning (0, "instance variable assignment has been intercepted");
3305
3306 result = objc_build_ivar_assignment (outer, lhs, rhs);
3307
3308 goto exit_point;
3309 }
3310
3311 /* Likewise, intercept assignment to global/static variables if their type is
3312 GC-marked. */
3313 if (objc_is_global_reference_p (outer))
3314 {
3315 if (indirect_p)
3316 goto suggest_cast;
3317
3318 global_reference:
3319 if (modifycode != NOP_EXPR)
3320 {
3321 invalid_pointer_arithmetic:
3322 if (outer_gc_p)
3323 warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3324
3325 goto exit_point;
3326 }
3327
3328 if (warn_assign_intercept)
3329 warning (0, "global/static variable assignment has been intercepted");
3330
3331 result = objc_build_global_assignment (lhs, rhs);
3332 }
3333
3334 /* In all other cases, fall back to the normal mechanism. */
3335 exit_point:
3336 return result;
3337 }
3338
3339 struct GTY(()) interface_tuple {
3340 tree id;
3341 tree class_name;
3342 };
3343
3344 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3345
3346 static hashval_t
3347 hash_interface (const void *p)
3348 {
3349 const struct interface_tuple *d = (const struct interface_tuple *) p;
3350 return IDENTIFIER_HASH_VALUE (d->id);
3351 }
3352
3353 static int
3354 eq_interface (const void *p1, const void *p2)
3355 {
3356 const struct interface_tuple *d = (const struct interface_tuple *) p1;
3357 return d->id == p2;
3358 }
3359
3360 static tree
3361 lookup_interface (tree ident)
3362 {
3363 #ifdef OBJCPLUS
3364 if (ident && TREE_CODE (ident) == TYPE_DECL)
3365 ident = DECL_NAME (ident);
3366 #endif
3367
3368 if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3369 return NULL_TREE;
3370
3371 {
3372 struct interface_tuple **slot;
3373 tree i = NULL_TREE;
3374
3375 if (interface_htab)
3376 {
3377 slot = (struct interface_tuple **)
3378 htab_find_slot_with_hash (interface_htab, ident,
3379 IDENTIFIER_HASH_VALUE (ident),
3380 NO_INSERT);
3381 if (slot && *slot)
3382 i = (*slot)->class_name;
3383 }
3384 return i;
3385 }
3386 }
3387
3388 /* Implement @defs (<classname>) within struct bodies. */
3389
3390 tree
3391 objc_get_class_ivars (tree class_name)
3392 {
3393 tree interface = lookup_interface (class_name);
3394
3395 if (interface)
3396 return get_class_ivars (interface, true);
3397
3398 error ("cannot find interface declaration for %qE",
3399 class_name);
3400
3401 return error_mark_node;
3402 }
3403
3404 /* Used by: build_private_template, continue_class,
3405 and for @defs constructs. */
3406
3407 static tree
3408 get_class_ivars (tree interface, bool inherited)
3409 {
3410 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3411
3412 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3413 by the current class (i.e., they do not include super-class ivars).
3414 However, the CLASS_IVARS list will be side-effected by a call to
3415 finish_struct(), which will fill in field offsets. */
3416 if (!CLASS_IVARS (interface))
3417 CLASS_IVARS (interface) = ivar_chain;
3418
3419 if (!inherited)
3420 return ivar_chain;
3421
3422 while (CLASS_SUPER_NAME (interface))
3423 {
3424 /* Prepend super-class ivars. */
3425 interface = lookup_interface (CLASS_SUPER_NAME (interface));
3426 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3427 ivar_chain);
3428 }
3429
3430 return ivar_chain;
3431 }
3432
3433 static tree
3434 objc_create_temporary_var (tree type)
3435 {
3436 tree decl;
3437
3438 decl = build_decl (input_location,
3439 VAR_DECL, NULL_TREE, type);
3440 TREE_USED (decl) = 1;
3441 DECL_ARTIFICIAL (decl) = 1;
3442 DECL_IGNORED_P (decl) = 1;
3443 DECL_CONTEXT (decl) = current_function_decl;
3444
3445 return decl;
3446 }
3447 \f
3448 /* Exception handling constructs. We begin by having the parser do most
3449 of the work and passing us blocks. What we do next depends on whether
3450 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3451 We abstract all of this in a handful of appropriately named routines. */
3452
3453 /* Stack of open try blocks. */
3454
3455 struct objc_try_context
3456 {
3457 struct objc_try_context *outer;
3458
3459 /* Statements (or statement lists) as processed by the parser. */
3460 tree try_body;
3461 tree finally_body;
3462
3463 /* Some file position locations. */
3464 location_t try_locus;
3465 location_t end_try_locus;
3466 location_t end_catch_locus;
3467 location_t finally_locus;
3468 location_t end_finally_locus;
3469
3470 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3471 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
3472 tree catch_list;
3473
3474 /* The CATCH_EXPR of an open @catch clause. */
3475 tree current_catch;
3476
3477 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
3478 tree caught_decl;
3479 tree stack_decl;
3480 tree rethrow_decl;
3481 };
3482
3483 static struct objc_try_context *cur_try_context;
3484
3485 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3486 that represents TYPE. For Objective-C, this is just the class name. */
3487 /* ??? Isn't there a class object or some such? Is it easy to get? */
3488
3489 #ifndef OBJCPLUS
3490 static tree
3491 objc_eh_runtime_type (tree type)
3492 {
3493 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3494 }
3495 #endif
3496
3497 /* Initialize exception handling. */
3498
3499 static void
3500 objc_init_exceptions (void)
3501 {
3502 static bool done = false;
3503 if (done)
3504 return;
3505 done = true;
3506
3507 if (flag_objc_sjlj_exceptions)
3508 {
3509 /* On Darwin, ObjC exceptions require a sufficiently recent
3510 version of the runtime, so the user must ask for them explicitly. */
3511 if (!flag_objc_exceptions)
3512 warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
3513 "exception syntax");
3514 }
3515 #ifndef OBJCPLUS
3516 else
3517 {
3518 c_eh_initialized_p = true;
3519 eh_personality_libfunc
3520 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
3521 ? "__gnu_objc_personality_sj0"
3522 : "__gnu_objc_personality_v0");
3523 default_init_unwind_resume_libfunc ();
3524 using_eh_for_cleanups ();
3525 lang_eh_runtime_type = objc_eh_runtime_type;
3526 }
3527 #endif
3528 }
3529
3530 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
3531 we'll arrange for it to be initialized (and associated with a binding)
3532 later. */
3533
3534 static tree
3535 objc_build_exc_ptr (void)
3536 {
3537 if (flag_objc_sjlj_exceptions)
3538 {
3539 tree var = cur_try_context->caught_decl;
3540 if (!var)
3541 {
3542 var = objc_create_temporary_var (objc_object_type);
3543 cur_try_context->caught_decl = var;
3544 }
3545 return var;
3546 }
3547 else
3548 return build0 (EXC_PTR_EXPR, objc_object_type);
3549 }
3550
3551 /* Build "objc_exception_try_exit(&_stack)". */
3552
3553 static tree
3554 next_sjlj_build_try_exit (void)
3555 {
3556 tree t;
3557 t = build_fold_addr_expr (cur_try_context->stack_decl);
3558 t = tree_cons (NULL, t, NULL);
3559 t = build_function_call (input_location,
3560 objc_exception_try_exit_decl, t);
3561 return t;
3562 }
3563
3564 /* Build
3565 objc_exception_try_enter (&_stack);
3566 if (_setjmp(&_stack.buf))
3567 ;
3568 else
3569 ;
3570 Return the COND_EXPR. Note that the THEN and ELSE fields are left
3571 empty, ready for the caller to fill them in. */
3572
3573 static tree
3574 next_sjlj_build_enter_and_setjmp (void)
3575 {
3576 tree t, enter, sj, cond;
3577
3578 t = build_fold_addr_expr (cur_try_context->stack_decl);
3579 t = tree_cons (NULL, t, NULL);
3580 enter = build_function_call (input_location,
3581 objc_exception_try_enter_decl, t);
3582
3583 t = objc_build_component_ref (cur_try_context->stack_decl,
3584 get_identifier ("buf"));
3585 t = build_fold_addr_expr (t);
3586 #ifdef OBJCPLUS
3587 /* Convert _setjmp argument to type that is expected. */
3588 if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
3589 t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
3590 else
3591 t = convert (ptr_type_node, t);
3592 #else
3593 t = convert (ptr_type_node, t);
3594 #endif
3595 t = tree_cons (NULL, t, NULL);
3596 sj = build_function_call (input_location,
3597 objc_setjmp_decl, t);
3598
3599 cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
3600 cond = c_common_truthvalue_conversion (input_location, cond);
3601
3602 return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
3603 }
3604
3605 /* Build:
3606
3607 DECL = objc_exception_extract(&_stack); */
3608
3609 static tree
3610 next_sjlj_build_exc_extract (tree decl)
3611 {
3612 tree t;
3613
3614 t = build_fold_addr_expr (cur_try_context->stack_decl);
3615 t = tree_cons (NULL, t, NULL);
3616 t = build_function_call (input_location,
3617 objc_exception_extract_decl, t);
3618 t = convert (TREE_TYPE (decl), t);
3619 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3620
3621 return t;
3622 }
3623
3624 /* Build
3625 if (objc_exception_match(obj_get_class(TYPE), _caught)
3626 BODY
3627 else if (...)
3628 ...
3629 else
3630 {
3631 _rethrow = _caught;
3632 objc_exception_try_exit(&_stack);
3633 }
3634 from the sequence of CATCH_EXPRs in the current try context. */
3635
3636 static tree
3637 next_sjlj_build_catch_list (void)
3638 {
3639 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3640 tree catch_seq, t;
3641 tree *last = &catch_seq;
3642 bool saw_id = false;
3643
3644 for (; !tsi_end_p (i); tsi_next (&i))
3645 {
3646 tree stmt = tsi_stmt (i);
3647 tree type = CATCH_TYPES (stmt);
3648 tree body = CATCH_BODY (stmt);
3649
3650 if (type == NULL)
3651 {
3652 *last = body;
3653 saw_id = true;
3654 break;
3655 }
3656 else
3657 {
3658 tree args, cond;
3659
3660 if (type == error_mark_node)
3661 cond = error_mark_node;
3662 else
3663 {
3664 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3665 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3666 args = tree_cons (NULL, t, args);
3667 t = build_function_call (input_location,
3668 objc_exception_match_decl, args);
3669 cond = c_common_truthvalue_conversion (input_location, t);
3670 }
3671 t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
3672 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3673
3674 *last = t;
3675 last = &COND_EXPR_ELSE (t);
3676 }
3677 }
3678
3679 if (!saw_id)
3680 {
3681 t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3682 cur_try_context->caught_decl);
3683 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3684 append_to_statement_list (t, last);
3685
3686 t = next_sjlj_build_try_exit ();
3687 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3688 append_to_statement_list (t, last);
3689 }
3690
3691 return catch_seq;
3692 }
3693
3694 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3695 exception handling. We aim to build:
3696
3697 {
3698 struct _objc_exception_data _stack;
3699 id _rethrow = 0;
3700 try
3701 {
3702 objc_exception_try_enter (&_stack);
3703 if (_setjmp(&_stack.buf))
3704 {
3705 id _caught = objc_exception_extract(&_stack);
3706 objc_exception_try_enter (&_stack);
3707 if (_setjmp(&_stack.buf))
3708 _rethrow = objc_exception_extract(&_stack);
3709 else
3710 CATCH-LIST
3711 }
3712 else
3713 TRY-BLOCK
3714 }
3715 finally
3716 {
3717 if (!_rethrow)
3718 objc_exception_try_exit(&_stack);
3719 FINALLY-BLOCK
3720 if (_rethrow)
3721 objc_exception_throw(_rethrow);
3722 }
3723 }
3724
3725 If CATCH-LIST is empty, we can omit all of the block containing
3726 "_caught" except for the setting of _rethrow. Note the use of
3727 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3728 but handles goto and other exits from the block. */
3729
3730 static tree
3731 next_sjlj_build_try_catch_finally (void)
3732 {
3733 tree rethrow_decl, stack_decl, t;
3734 tree catch_seq, try_fin, bind;
3735
3736 /* Create the declarations involved. */
3737 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3738 stack_decl = objc_create_temporary_var (t);
3739 cur_try_context->stack_decl = stack_decl;
3740
3741 rethrow_decl = objc_create_temporary_var (objc_object_type);
3742 cur_try_context->rethrow_decl = rethrow_decl;
3743 TREE_CHAIN (rethrow_decl) = stack_decl;
3744
3745 /* Build the outermost variable binding level. */
3746 bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3747 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3748 TREE_SIDE_EFFECTS (bind) = 1;
3749
3750 /* Initialize rethrow_decl. */
3751 t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
3752 convert (objc_object_type, null_pointer_node));
3753 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3754 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3755
3756 /* Build the outermost TRY_FINALLY_EXPR. */
3757 try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3758 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3759 TREE_SIDE_EFFECTS (try_fin) = 1;
3760 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3761
3762 /* Create the complete catch sequence. */
3763 if (cur_try_context->catch_list)
3764 {
3765 tree caught_decl = objc_build_exc_ptr ();
3766 catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
3767 TREE_SIDE_EFFECTS (catch_seq) = 1;
3768
3769 t = next_sjlj_build_exc_extract (caught_decl);
3770 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3771
3772 t = next_sjlj_build_enter_and_setjmp ();
3773 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3774 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3775 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3776 }
3777 else
3778 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3779 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3780
3781 /* Build the main register-and-try if statement. */
3782 t = next_sjlj_build_enter_and_setjmp ();
3783 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3784 COND_EXPR_THEN (t) = catch_seq;
3785 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3786 TREE_OPERAND (try_fin, 0) = t;
3787
3788 /* Build the complete FINALLY statement list. */
3789 t = next_sjlj_build_try_exit ();
3790 t = build_stmt (input_location, COND_EXPR,
3791 c_common_truthvalue_conversion
3792 (input_location, rethrow_decl),
3793 NULL, t);
3794 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3795 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3796
3797 append_to_statement_list (cur_try_context->finally_body,
3798 &TREE_OPERAND (try_fin, 1));
3799
3800 t = tree_cons (NULL, rethrow_decl, NULL);
3801 t = build_function_call (input_location,
3802 objc_exception_throw_decl, t);
3803 t = build_stmt (input_location, COND_EXPR,
3804 c_common_truthvalue_conversion (input_location,
3805 rethrow_decl),
3806 t, NULL);
3807 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3808 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3809
3810 return bind;
3811 }
3812
3813 /* Called just after parsing the @try and its associated BODY. We now
3814 must prepare for the tricky bits -- handling the catches and finally. */
3815
3816 void
3817 objc_begin_try_stmt (location_t try_locus, tree body)
3818 {
3819 struct objc_try_context *c = XCNEW (struct objc_try_context);
3820 c->outer = cur_try_context;
3821 c->try_body = body;
3822 c->try_locus = try_locus;
3823 c->end_try_locus = input_location;
3824 cur_try_context = c;
3825
3826 objc_init_exceptions ();
3827
3828 if (flag_objc_sjlj_exceptions)
3829 objc_mark_locals_volatile (NULL);
3830 }
3831
3832 /* Called just after parsing "@catch (parm)". Open a binding level,
3833 enter DECL into the binding level, and initialize it. Leave the
3834 binding level open while the body of the compound statement is parsed. */
3835
3836 void
3837 objc_begin_catch_clause (tree decl)
3838 {
3839 tree compound, type, t;
3840
3841 /* Begin a new scope that the entire catch clause will live in. */
3842 compound = c_begin_compound_stmt (true);
3843
3844 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3845 decl = build_decl (input_location,
3846 VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3847 lang_hooks.decls.pushdecl (decl);
3848
3849 /* Since a decl is required here by syntax, don't warn if its unused. */
3850 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3851 be what the previous objc implementation did. */
3852 TREE_USED (decl) = 1;
3853
3854 /* Verify that the type of the catch is valid. It must be a pointer
3855 to an Objective-C class, or "id" (which is catch-all). */
3856 type = TREE_TYPE (decl);
3857
3858 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3859 type = NULL;
3860 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3861 {
3862 error ("@catch parameter is not a known Objective-C class type");
3863 type = error_mark_node;
3864 }
3865 else if (cur_try_context->catch_list)
3866 {
3867 /* Examine previous @catch clauses and see if we've already
3868 caught the type in question. */
3869 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3870 for (; !tsi_end_p (i); tsi_next (&i))
3871 {
3872 tree stmt = tsi_stmt (i);
3873 t = CATCH_TYPES (stmt);
3874 if (t == error_mark_node)
3875 continue;
3876 if (!t || DERIVED_FROM_P (TREE_TYPE (t), TREE_TYPE (type)))
3877 {
3878 warning (0, "exception of type %<%T%> will be caught",
3879 TREE_TYPE (type));
3880 warning_at (EXPR_LOCATION (stmt), 0, " by earlier handler for %<%T%>",
3881 TREE_TYPE (t ? t : objc_object_type));
3882 break;
3883 }
3884 }
3885 }
3886
3887 /* Record the data for the catch in the try context so that we can
3888 finalize it later. */
3889 t = build_stmt (input_location, CATCH_EXPR, type, compound);
3890 cur_try_context->current_catch = t;
3891
3892 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3893 t = objc_build_exc_ptr ();
3894 t = convert (TREE_TYPE (decl), t);
3895 t = build2 (MODIFY_EXPR, void_type_node, decl, t);
3896 add_stmt (t);
3897 }
3898
3899 /* Called just after parsing the closing brace of a @catch clause. Close
3900 the open binding level, and record a CATCH_EXPR for it. */
3901
3902 void
3903 objc_finish_catch_clause (void)
3904 {
3905 tree c = cur_try_context->current_catch;
3906 cur_try_context->current_catch = NULL;
3907 cur_try_context->end_catch_locus = input_location;
3908
3909 CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
3910 append_to_statement_list (c, &cur_try_context->catch_list);
3911 }
3912
3913 /* Called after parsing a @finally clause and its associated BODY.
3914 Record the body for later placement. */
3915
3916 void
3917 objc_build_finally_clause (location_t finally_locus, tree body)
3918 {
3919 cur_try_context->finally_body = body;
3920 cur_try_context->finally_locus = finally_locus;
3921 cur_try_context->end_finally_locus = input_location;
3922 }
3923
3924 /* Called to finalize a @try construct. */
3925
3926 tree
3927 objc_finish_try_stmt (void)
3928 {
3929 struct objc_try_context *c = cur_try_context;
3930 tree stmt;
3931
3932 if (c->catch_list == NULL && c->finally_body == NULL)
3933 error ("%<@try%> without %<@catch%> or %<@finally%>");
3934
3935 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3936 if (flag_objc_sjlj_exceptions)
3937 {
3938 bool save = in_late_binary_op;
3939 in_late_binary_op = true;
3940 if (!cur_try_context->finally_body)
3941 {
3942 cur_try_context->finally_locus = input_location;
3943 cur_try_context->end_finally_locus = input_location;
3944 }
3945 stmt = next_sjlj_build_try_catch_finally ();
3946 in_late_binary_op = save;
3947 }
3948 else
3949 {
3950 /* Otherwise, nest the CATCH inside a FINALLY. */
3951 stmt = c->try_body;
3952 if (c->catch_list)
3953 {
3954 stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
3955 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3956 }
3957 if (c->finally_body)
3958 {
3959 stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
3960 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3961 }
3962 }
3963 add_stmt (stmt);
3964
3965 cur_try_context = c->outer;
3966 free (c);
3967 return stmt;
3968 }
3969
3970 tree
3971 objc_build_throw_stmt (location_t loc, tree throw_expr)
3972 {
3973 tree args;
3974
3975 objc_init_exceptions ();
3976
3977 if (throw_expr == NULL)
3978 {
3979 /* If we're not inside a @catch block, there is no "current
3980 exception" to be rethrown. */
3981 if (cur_try_context == NULL
3982 || cur_try_context->current_catch == NULL)
3983 {
3984 error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
3985 return NULL_TREE;
3986 }
3987
3988 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3989 value that we get from the runtime. */
3990 throw_expr = objc_build_exc_ptr ();
3991 }
3992
3993 /* A throw is just a call to the runtime throw function with the
3994 object as a parameter. */
3995 args = tree_cons (NULL, throw_expr, NULL);
3996 return add_stmt (build_function_call (loc,
3997 objc_exception_throw_decl, args));
3998 }
3999
4000 tree
4001 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
4002 {
4003 tree args, call;
4004
4005 /* First lock the mutex. */
4006 mutex = save_expr (mutex);
4007 args = tree_cons (NULL, mutex, NULL);
4008 call = build_function_call (input_location,
4009 objc_sync_enter_decl, args);
4010 SET_EXPR_LOCATION (call, start_locus);
4011 add_stmt (call);
4012
4013 /* Build the mutex unlock. */
4014 args = tree_cons (NULL, mutex, NULL);
4015 call = build_function_call (input_location,
4016 objc_sync_exit_decl, args);
4017 SET_EXPR_LOCATION (call, input_location);
4018
4019 /* Put the that and the body in a TRY_FINALLY. */
4020 objc_begin_try_stmt (start_locus, body);
4021 objc_build_finally_clause (input_location, call);
4022 return objc_finish_try_stmt ();
4023 }
4024
4025 \f
4026 /* Predefine the following data type:
4027
4028 struct _objc_exception_data
4029 {
4030 int buf[OBJC_JBLEN];
4031 void *pointers[4];
4032 }; */
4033
4034 /* The following yuckiness should prevent users from having to #include
4035 <setjmp.h> in their code... */
4036
4037 /* Define to a harmless positive value so the below code doesn't die. */
4038 #ifndef OBJC_JBLEN
4039 #define OBJC_JBLEN 18
4040 #endif
4041
4042 static void
4043 build_next_objc_exception_stuff (void)
4044 {
4045 tree field_decl, field_decl_chain, index, temp_type;
4046
4047 objc_exception_data_template
4048 = objc_start_struct (get_identifier (UTAG_EXCDATA));
4049
4050 /* int buf[OBJC_JBLEN]; */
4051
4052 index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
4053 field_decl = create_field_decl (build_array_type (integer_type_node, index),
4054 "buf");
4055 field_decl_chain = field_decl;
4056
4057 /* void *pointers[4]; */
4058
4059 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
4060 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
4061 "pointers");
4062 chainon (field_decl_chain, field_decl);
4063
4064 objc_finish_struct (objc_exception_data_template, field_decl_chain);
4065
4066 /* int _setjmp(...); */
4067 /* If the user includes <setjmp.h>, this shall be superseded by
4068 'int _setjmp(jmp_buf);' */
4069 temp_type = build_function_type (integer_type_node, NULL_TREE);
4070 objc_setjmp_decl
4071 = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
4072
4073 /* id objc_exception_extract(struct _objc_exception_data *); */
4074 temp_type
4075 = build_function_type (objc_object_type,
4076 tree_cons (NULL_TREE,
4077 build_pointer_type (objc_exception_data_template),
4078 OBJC_VOID_AT_END));
4079 objc_exception_extract_decl
4080 = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
4081 NULL_TREE);
4082 /* void objc_exception_try_enter(struct _objc_exception_data *); */
4083 /* void objc_exception_try_exit(struct _objc_exception_data *); */
4084 temp_type
4085 = build_function_type (void_type_node,
4086 tree_cons (NULL_TREE,
4087 build_pointer_type (objc_exception_data_template),
4088 OBJC_VOID_AT_END));
4089 objc_exception_try_enter_decl
4090 = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
4091 NULL_TREE);
4092 objc_exception_try_exit_decl
4093 = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL,
4094 NULL_TREE);
4095
4096 /* int objc_exception_match(id, id); */
4097 temp_type
4098 = build_function_type (integer_type_node,
4099 tree_cons (NULL_TREE, objc_object_type,
4100 tree_cons (NULL_TREE, objc_object_type,
4101 OBJC_VOID_AT_END)));
4102 objc_exception_match_decl
4103 = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
4104 NULL_TREE);
4105
4106 /* id objc_assign_ivar (id, id, unsigned int); */
4107 /* id objc_assign_ivar_Fast (id, id, unsigned int)
4108 __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */
4109 temp_type
4110 = build_function_type (objc_object_type,
4111 tree_cons
4112 (NULL_TREE, objc_object_type,
4113 tree_cons (NULL_TREE, objc_object_type,
4114 tree_cons (NULL_TREE,
4115 unsigned_type_node,
4116 OBJC_VOID_AT_END))));
4117 objc_assign_ivar_decl
4118 = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
4119 NULL, NULL_TREE);
4120 #ifdef OFFS_ASSIGNIVAR_FAST
4121 objc_assign_ivar_fast_decl
4122 = add_builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
4123 NOT_BUILT_IN, NULL, NULL_TREE);
4124 DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
4125 = tree_cons (get_identifier ("hard_coded_address"),
4126 build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
4127 NULL_TREE);
4128 #else
4129 /* Default to slower ivar method. */
4130 objc_assign_ivar_fast_decl = objc_assign_ivar_decl;
4131 #endif
4132
4133 /* id objc_assign_global (id, id *); */
4134 /* id objc_assign_strongCast (id, id *); */
4135 temp_type = build_function_type (objc_object_type,
4136 tree_cons (NULL_TREE, objc_object_type,
4137 tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
4138 OBJC_VOID_AT_END)));
4139 objc_assign_global_decl
4140 = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
4141 NULL_TREE);
4142 objc_assign_strong_cast_decl
4143 = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
4144 NULL_TREE);
4145 }
4146
4147 static void
4148 build_objc_exception_stuff (void)
4149 {
4150 tree noreturn_list, nothrow_list, temp_type;
4151
4152 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
4153 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
4154
4155 /* void objc_exception_throw(id) __attribute__((noreturn)); */
4156 /* void objc_sync_enter(id); */
4157 /* void objc_sync_exit(id); */
4158 temp_type = build_function_type (void_type_node,
4159 tree_cons (NULL_TREE, objc_object_type,
4160 OBJC_VOID_AT_END));
4161 objc_exception_throw_decl
4162 = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
4163 noreturn_list);
4164 objc_sync_enter_decl
4165 = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
4166 NULL, nothrow_list);
4167 objc_sync_exit_decl
4168 = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
4169 NULL, nothrow_list);
4170 }
4171
4172 /* Construct a C struct corresponding to ObjC class CLASS, with the same
4173 name as the class:
4174
4175 struct <classname> {
4176 struct _objc_class *isa;
4177 ...
4178 }; */
4179
4180 static void
4181 build_private_template (tree klass)
4182 {
4183 if (!CLASS_STATIC_TEMPLATE (klass))
4184 {
4185 tree record = objc_build_struct (klass,
4186 get_class_ivars (klass, false),
4187 CLASS_SUPER_NAME (klass));
4188
4189 /* Set the TREE_USED bit for this struct, so that stab generator
4190 can emit stabs for this struct type. */
4191 if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
4192 TREE_USED (TYPE_STUB_DECL (record)) = 1;
4193 }
4194 }
4195 \f
4196 /* Begin code generation for protocols... */
4197
4198 /* struct _objc_protocol {
4199 struct _objc_class *isa;
4200 char *protocol_name;
4201 struct _objc_protocol **protocol_list;
4202 struct _objc__method_prototype_list *instance_methods;
4203 struct _objc__method_prototype_list *class_methods;
4204 }; */
4205
4206 static void
4207 build_protocol_template (void)
4208 {
4209 tree field_decl, field_decl_chain;
4210
4211 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
4212
4213 /* struct _objc_class *isa; */
4214 field_decl = create_field_decl (build_pointer_type
4215 (xref_tag (RECORD_TYPE,
4216 get_identifier (UTAG_CLASS))),
4217 "isa");
4218 field_decl_chain = field_decl;
4219
4220 /* char *protocol_name; */
4221 field_decl = create_field_decl (string_type_node, "protocol_name");
4222 chainon (field_decl_chain, field_decl);
4223
4224 /* struct _objc_protocol **protocol_list; */
4225 field_decl = create_field_decl (build_pointer_type
4226 (build_pointer_type
4227 (objc_protocol_template)),
4228 "protocol_list");
4229 chainon (field_decl_chain, field_decl);
4230
4231 /* struct _objc__method_prototype_list *instance_methods; */
4232 field_decl = create_field_decl (objc_method_proto_list_ptr,
4233 "instance_methods");
4234 chainon (field_decl_chain, field_decl);
4235
4236 /* struct _objc__method_prototype_list *class_methods; */
4237 field_decl = create_field_decl (objc_method_proto_list_ptr,
4238 "class_methods");
4239 chainon (field_decl_chain, field_decl);
4240
4241 objc_finish_struct (objc_protocol_template, field_decl_chain);
4242 }
4243
4244 static tree
4245 build_descriptor_table_initializer (tree type, tree entries)
4246 {
4247 tree initlist = NULL_TREE;
4248
4249 do
4250 {
4251 tree eltlist = NULL_TREE;
4252
4253 eltlist
4254 = tree_cons (NULL_TREE,
4255 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
4256 eltlist
4257 = tree_cons (NULL_TREE,
4258 add_objc_string (METHOD_ENCODING (entries),
4259 meth_var_types),
4260 eltlist);
4261
4262 initlist
4263 = tree_cons (NULL_TREE,
4264 objc_build_constructor (type, nreverse (eltlist)),
4265 initlist);
4266
4267 entries = TREE_CHAIN (entries);
4268 }
4269 while (entries);
4270
4271 return objc_build_constructor (build_array_type (type, 0),
4272 nreverse (initlist));
4273 }
4274
4275 /* struct objc_method_prototype_list {
4276 int count;
4277 struct objc_method_prototype {
4278 SEL name;
4279 char *types;
4280 } list[1];
4281 }; */
4282
4283 static tree
4284 build_method_prototype_list_template (tree list_type, int size)
4285 {
4286 tree objc_ivar_list_record;
4287 tree field_decl, field_decl_chain;
4288
4289 /* Generate an unnamed struct definition. */
4290
4291 objc_ivar_list_record = objc_start_struct (NULL_TREE);
4292
4293 /* int method_count; */
4294 field_decl = create_field_decl (integer_type_node, "method_count");
4295 field_decl_chain = field_decl;
4296
4297 /* struct objc_method method_list[]; */
4298 field_decl = create_field_decl (build_array_type
4299 (list_type,
4300 build_index_type
4301 (build_int_cst (NULL_TREE, size - 1))),
4302 "method_list");
4303 chainon (field_decl_chain, field_decl);
4304
4305 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
4306
4307 return objc_ivar_list_record;
4308 }
4309
4310 static tree
4311 build_method_prototype_template (void)
4312 {
4313 tree proto_record;
4314 tree field_decl, field_decl_chain;
4315
4316 proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
4317
4318 /* SEL _cmd; */
4319 field_decl = create_field_decl (objc_selector_type, "_cmd");
4320 field_decl_chain = field_decl;
4321
4322 /* char *method_types; */
4323 field_decl = create_field_decl (string_type_node, "method_types");
4324 chainon (field_decl_chain, field_decl);
4325
4326 objc_finish_struct (proto_record, field_decl_chain);
4327
4328 return proto_record;
4329 }
4330
4331 static tree
4332 objc_method_parm_type (tree type)
4333 {
4334 type = TREE_VALUE (TREE_TYPE (type));
4335 if (TREE_CODE (type) == TYPE_DECL)
4336 type = TREE_TYPE (type);
4337 return type;
4338 }
4339
4340 static int
4341 objc_encoded_type_size (tree type)
4342 {
4343 int sz = int_size_in_bytes (type);
4344
4345 /* Make all integer and enum types at least as large
4346 as an int. */
4347 if (sz > 0 && INTEGRAL_TYPE_P (type))
4348 sz = MAX (sz, int_size_in_bytes (integer_type_node));
4349 /* Treat arrays as pointers, since that's how they're
4350 passed in. */
4351 else if (TREE_CODE (type) == ARRAY_TYPE)
4352 sz = int_size_in_bytes (ptr_type_node);
4353 return sz;
4354 }
4355
4356 static tree
4357 encode_method_prototype (tree method_decl)
4358 {
4359 tree parms;
4360 int parm_offset, i;
4361 char buf[40];
4362 tree result;
4363
4364 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
4365 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
4366
4367 /* Encode return type. */
4368 encode_type (objc_method_parm_type (method_decl),
4369 obstack_object_size (&util_obstack),
4370 OBJC_ENCODE_INLINE_DEFS);
4371
4372 /* Stack size. */
4373 /* The first two arguments (self and _cmd) are pointers; account for
4374 their size. */
4375 i = int_size_in_bytes (ptr_type_node);
4376 parm_offset = 2 * i;
4377 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4378 parms = TREE_CHAIN (parms))
4379 {
4380 tree type = objc_method_parm_type (parms);
4381 int sz = objc_encoded_type_size (type);
4382
4383 /* If a type size is not known, bail out. */
4384 if (sz < 0)
4385 {
4386 error ("type %q+D does not have a known size",
4387 type);
4388 /* Pretend that the encoding succeeded; the compilation will
4389 fail nevertheless. */
4390 goto finish_encoding;
4391 }
4392 parm_offset += sz;
4393 }
4394
4395 sprintf (buf, "%d@0:%d", parm_offset, i);
4396 obstack_grow (&util_obstack, buf, strlen (buf));
4397
4398 /* Argument types. */
4399 parm_offset = 2 * i;
4400 for (parms = METHOD_SEL_ARGS (method_decl); parms;
4401 parms = TREE_CHAIN (parms))
4402 {
4403 tree type = objc_method_parm_type (parms);
4404
4405 /* Process argument qualifiers for user supplied arguments. */
4406 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
4407
4408 /* Type. */
4409 encode_type (type, obstack_object_size (&util_obstack),
4410 OBJC_ENCODE_INLINE_DEFS);
4411
4412 /* Compute offset. */
4413 sprintf (buf, "%d", parm_offset);
4414 parm_offset += objc_encoded_type_size (type);
4415
4416 obstack_grow (&util_obstack, buf, strlen (buf));
4417 }
4418
4419 finish_encoding:
4420 obstack_1grow (&util_obstack, '\0');
4421 result = get_identifier (XOBFINISH (&util_obstack, char *));
4422 obstack_free (&util_obstack, util_firstobj);
4423 return result;
4424 }
4425
4426 static tree
4427 generate_descriptor_table (tree type, const char *name, int size, tree list,
4428 tree proto)
4429 {
4430 tree decl, initlist;
4431
4432 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
4433
4434 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4435 initlist = tree_cons (NULL_TREE, list, initlist);
4436
4437 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
4438
4439 return decl;
4440 }
4441
4442 static void
4443 generate_method_descriptors (tree protocol)
4444 {
4445 tree initlist, chain, method_list_template;
4446 int size;
4447
4448 if (!objc_method_prototype_template)
4449 objc_method_prototype_template = build_method_prototype_template ();
4450
4451 chain = PROTOCOL_CLS_METHODS (protocol);
4452 if (chain)
4453 {
4454 size = list_length (chain);
4455
4456 method_list_template
4457 = build_method_prototype_list_template (objc_method_prototype_template,
4458 size);
4459
4460 initlist
4461 = build_descriptor_table_initializer (objc_method_prototype_template,
4462 chain);
4463
4464 UOBJC_CLASS_METHODS_decl
4465 = generate_descriptor_table (method_list_template,
4466 "_OBJC_PROTOCOL_CLASS_METHODS",
4467 size, initlist, protocol);
4468 }
4469 else
4470 UOBJC_CLASS_METHODS_decl = 0;
4471
4472 chain = PROTOCOL_NST_METHODS (protocol);
4473 if (chain)
4474 {
4475 size = list_length (chain);
4476
4477 method_list_template
4478 = build_method_prototype_list_template (objc_method_prototype_template,
4479 size);
4480 initlist
4481 = build_descriptor_table_initializer (objc_method_prototype_template,
4482 chain);
4483
4484 UOBJC_INSTANCE_METHODS_decl
4485 = generate_descriptor_table (method_list_template,
4486 "_OBJC_PROTOCOL_INSTANCE_METHODS",
4487 size, initlist, protocol);
4488 }
4489 else
4490 UOBJC_INSTANCE_METHODS_decl = 0;
4491 }
4492
4493 static void
4494 generate_protocol_references (tree plist)
4495 {
4496 tree lproto;
4497
4498 /* Forward declare protocols referenced. */
4499 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4500 {
4501 tree proto = TREE_VALUE (lproto);
4502
4503 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
4504 && PROTOCOL_NAME (proto))
4505 {
4506 if (! PROTOCOL_FORWARD_DECL (proto))
4507 build_protocol_reference (proto);
4508
4509 if (PROTOCOL_LIST (proto))
4510 generate_protocol_references (PROTOCOL_LIST (proto));
4511 }
4512 }
4513 }
4514
4515 /* Generate either '- .cxx_construct' or '- .cxx_destruct' for the
4516 current class. */
4517 #ifdef OBJCPLUS
4518 static void
4519 objc_generate_cxx_ctor_or_dtor (bool dtor)
4520 {
4521 tree fn, body, compound_stmt, ivar;
4522
4523 /* - (id) .cxx_construct { ... return self; } */
4524 /* - (void) .cxx_construct { ... } */
4525
4526 objc_set_method_type (MINUS_EXPR);
4527 objc_start_method_definition
4528 (objc_build_method_signature (build_tree_list (NULL_TREE,
4529 dtor
4530 ? void_type_node
4531 : objc_object_type),
4532 get_identifier (dtor
4533 ? TAG_CXX_DESTRUCT
4534 : TAG_CXX_CONSTRUCT),
4535 make_node (TREE_LIST),
4536 false));
4537 body = begin_function_body ();
4538 compound_stmt = begin_compound_stmt (0);
4539
4540 ivar = CLASS_IVARS (implementation_template);
4541 /* Destroy ivars in reverse order. */
4542 if (dtor)
4543 ivar = nreverse (copy_list (ivar));
4544
4545 for (; ivar; ivar = TREE_CHAIN (ivar))
4546 {
4547 if (TREE_CODE (ivar) == FIELD_DECL)
4548 {
4549 tree type = TREE_TYPE (ivar);
4550
4551 /* Call the ivar's default constructor or destructor. Do not
4552 call the destructor unless a corresponding constructor call
4553 has also been made (or is not needed). */
4554 if (MAYBE_CLASS_TYPE_P (type)
4555 && (dtor
4556 ? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4557 && (!TYPE_NEEDS_CONSTRUCTING (type)
4558 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4559 : (TYPE_NEEDS_CONSTRUCTING (type)
4560 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))))
4561 finish_expr_stmt
4562 (build_special_member_call
4563 (build_ivar_reference (DECL_NAME (ivar)),
4564 dtor ? complete_dtor_identifier : complete_ctor_identifier,
4565 NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
4566 }
4567 }
4568
4569 /* The constructor returns 'self'. */
4570 if (!dtor)
4571 finish_return_stmt (self_decl);
4572
4573 finish_compound_stmt (compound_stmt);
4574 finish_function_body (body);
4575 fn = current_function_decl;
4576 finish_function ();
4577 objc_finish_method_definition (fn);
4578 }
4579
4580 /* The following routine will examine the current @interface for any
4581 non-POD C++ ivars requiring non-trivial construction and/or
4582 destruction, and then synthesize special '- .cxx_construct' and/or
4583 '- .cxx_destruct' methods which will run the appropriate
4584 construction or destruction code. Note that ivars inherited from
4585 super-classes are _not_ considered. */
4586 static void
4587 objc_generate_cxx_cdtors (void)
4588 {
4589 bool need_ctor = false, need_dtor = false;
4590 tree ivar;
4591
4592 /* We do not want to do this for categories, since they do not have
4593 their own ivars. */
4594
4595 if (TREE_CODE (objc_implementation_context) != CLASS_IMPLEMENTATION_TYPE)
4596 return;
4597
4598 /* First, determine if we even need a constructor and/or destructor. */
4599
4600 for (ivar = CLASS_IVARS (implementation_template); ivar;
4601 ivar = TREE_CHAIN (ivar))
4602 {
4603 if (TREE_CODE (ivar) == FIELD_DECL)
4604 {
4605 tree type = TREE_TYPE (ivar);
4606
4607 if (MAYBE_CLASS_TYPE_P (type))
4608 {
4609 if (TYPE_NEEDS_CONSTRUCTING (type)
4610 && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
4611 /* NB: If a default constructor is not available, we will not
4612 be able to initialize this ivar; the add_instance_variable()
4613 routine will already have warned about this. */
4614 need_ctor = true;
4615
4616 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4617 && (!TYPE_NEEDS_CONSTRUCTING (type)
4618 || TYPE_HAS_DEFAULT_CONSTRUCTOR (type)))
4619 /* NB: If a default constructor is not available, we will not
4620 call the destructor either, for symmetry. */
4621 need_dtor = true;
4622 }
4623 }
4624 }
4625
4626 /* Generate '- .cxx_construct' if needed. */
4627
4628 if (need_ctor)
4629 objc_generate_cxx_ctor_or_dtor (false);
4630
4631 /* Generate '- .cxx_destruct' if needed. */
4632
4633 if (need_dtor)
4634 objc_generate_cxx_ctor_or_dtor (true);
4635
4636 /* The 'imp_list' variable points at an imp_entry record for the current
4637 @implementation. Record the existence of '- .cxx_construct' and/or
4638 '- .cxx_destruct' methods therein; it will be included in the
4639 metadata for the class. */
4640 if (flag_next_runtime)
4641 imp_list->has_cxx_cdtors = (need_ctor || need_dtor);
4642 }
4643 #endif
4644
4645 /* For each protocol which was referenced either from a @protocol()
4646 expression, or because a class/category implements it (then a
4647 pointer to the protocol is stored in the struct describing the
4648 class/category), we create a statically allocated instance of the
4649 Protocol class. The code is written in such a way as to generate
4650 as few Protocol objects as possible; we generate a unique Protocol
4651 instance for each protocol, and we don't generate a Protocol
4652 instance if the protocol is never referenced (either from a
4653 @protocol() or from a class/category implementation). These
4654 statically allocated objects can be referred to via the static
4655 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
4656
4657 The statically allocated Protocol objects that we generate here
4658 need to be fixed up at runtime in order to be used: the 'isa'
4659 pointer of the objects need to be set up to point to the 'Protocol'
4660 class, as known at runtime.
4661
4662 The NeXT runtime fixes up all protocols at program startup time,
4663 before main() is entered. It uses a low-level trick to look up all
4664 those symbols, then loops on them and fixes them up.
4665
4666 The GNU runtime as well fixes up all protocols before user code
4667 from the module is executed; it requires pointers to those symbols
4668 to be put in the objc_symtab (which is then passed as argument to
4669 the function __objc_exec_class() which the compiler sets up to be
4670 executed automatically when the module is loaded); setup of those
4671 Protocol objects happen in two ways in the GNU runtime: all
4672 Protocol objects referred to by a class or category implementation
4673 are fixed up when the class/category is loaded; all Protocol
4674 objects referred to by a @protocol() expression are added by the
4675 compiler to the list of statically allocated instances to fixup
4676 (the same list holding the statically allocated constant string
4677 objects). Because, as explained above, the compiler generates as
4678 few Protocol objects as possible, some Protocol object might end up
4679 being referenced multiple times when compiled with the GNU runtime,
4680 and end up being fixed up multiple times at runtime initialization.
4681 But that doesn't hurt, it's just a little inefficient. */
4682
4683 static void
4684 generate_protocols (void)
4685 {
4686 tree p, encoding;
4687 tree decl;
4688 tree initlist, protocol_name_expr, refs_decl, refs_expr;
4689
4690 /* If a protocol was directly referenced, pull in indirect references. */
4691 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4692 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
4693 generate_protocol_references (PROTOCOL_LIST (p));
4694
4695 for (p = protocol_chain; p; p = TREE_CHAIN (p))
4696 {
4697 tree nst_methods = PROTOCOL_NST_METHODS (p);
4698 tree cls_methods = PROTOCOL_CLS_METHODS (p);
4699
4700 /* If protocol wasn't referenced, don't generate any code. */
4701 decl = PROTOCOL_FORWARD_DECL (p);
4702
4703 if (!decl)
4704 continue;
4705
4706 /* Make sure we link in the Protocol class. */
4707 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
4708
4709 while (nst_methods)
4710 {
4711 if (! METHOD_ENCODING (nst_methods))
4712 {
4713 encoding = encode_method_prototype (nst_methods);
4714 METHOD_ENCODING (nst_methods) = encoding;
4715 }
4716 nst_methods = TREE_CHAIN (nst_methods);
4717 }
4718
4719 while (cls_methods)
4720 {
4721 if (! METHOD_ENCODING (cls_methods))
4722 {
4723 encoding = encode_method_prototype (cls_methods);
4724 METHOD_ENCODING (cls_methods) = encoding;
4725 }
4726
4727 cls_methods = TREE_CHAIN (cls_methods);
4728 }
4729 generate_method_descriptors (p);
4730
4731 if (PROTOCOL_LIST (p))
4732 refs_decl = generate_protocol_list (p);
4733 else
4734 refs_decl = 0;
4735
4736 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4737 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
4738
4739 if (refs_decl)
4740 refs_expr = convert (build_pointer_type (build_pointer_type
4741 (objc_protocol_template)),
4742 build_unary_op (input_location,
4743 ADDR_EXPR, refs_decl, 0));
4744 else
4745 refs_expr = build_int_cst (NULL_TREE, 0);
4746
4747 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
4748 by generate_method_descriptors, which is called above. */
4749 initlist = build_protocol_initializer (TREE_TYPE (decl),
4750 protocol_name_expr, refs_expr,
4751 UOBJC_INSTANCE_METHODS_decl,
4752 UOBJC_CLASS_METHODS_decl);
4753 finish_var_decl (decl, initlist);
4754 }
4755 }
4756
4757 static tree
4758 build_protocol_initializer (tree type, tree protocol_name,
4759 tree protocol_list, tree instance_methods,
4760 tree class_methods)
4761 {
4762 tree initlist = NULL_TREE, expr;
4763 tree cast_type = build_pointer_type
4764 (xref_tag (RECORD_TYPE,
4765 get_identifier (UTAG_CLASS)));
4766
4767 /* Filling the "isa" in with one allows the runtime system to
4768 detect that the version change...should remove before final release. */
4769
4770 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
4771 initlist = tree_cons (NULL_TREE, expr, initlist);
4772 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
4773 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
4774
4775 if (!instance_methods)
4776 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4777 else
4778 {
4779 expr = convert (objc_method_proto_list_ptr,
4780 build_unary_op (input_location,
4781 ADDR_EXPR, instance_methods, 0));
4782 initlist = tree_cons (NULL_TREE, expr, initlist);
4783 }
4784
4785 if (!class_methods)
4786 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4787 else
4788 {
4789 expr = convert (objc_method_proto_list_ptr,
4790 build_unary_op (input_location,
4791 ADDR_EXPR, class_methods, 0));
4792 initlist = tree_cons (NULL_TREE, expr, initlist);
4793 }
4794
4795 return objc_build_constructor (type, nreverse (initlist));
4796 }
4797 \f
4798 /* struct _objc_category {
4799 char *category_name;
4800 char *class_name;
4801 struct _objc_method_list *instance_methods;
4802 struct _objc_method_list *class_methods;
4803 struct _objc_protocol_list *protocols;
4804 }; */
4805
4806 static void
4807 build_category_template (void)
4808 {
4809 tree field_decl, field_decl_chain;
4810
4811 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
4812
4813 /* char *category_name; */
4814 field_decl = create_field_decl (string_type_node, "category_name");
4815 field_decl_chain = field_decl;
4816
4817 /* char *class_name; */
4818 field_decl = create_field_decl (string_type_node, "class_name");
4819 chainon (field_decl_chain, field_decl);
4820
4821 /* struct _objc_method_list *instance_methods; */
4822 field_decl = create_field_decl (objc_method_list_ptr,
4823 "instance_methods");
4824 chainon (field_decl_chain, field_decl);
4825
4826 /* struct _objc_method_list *class_methods; */
4827 field_decl = create_field_decl (objc_method_list_ptr,
4828 "class_methods");
4829 chainon (field_decl_chain, field_decl);
4830
4831 /* struct _objc_protocol **protocol_list; */
4832 field_decl = create_field_decl (build_pointer_type
4833 (build_pointer_type
4834 (objc_protocol_template)),
4835 "protocol_list");
4836 chainon (field_decl_chain, field_decl);
4837
4838 objc_finish_struct (objc_category_template, field_decl_chain);
4839 }
4840
4841 /* struct _objc_selector {
4842 SEL sel_id;
4843 char *sel_type;
4844 }; */
4845
4846 static void
4847 build_selector_template (void)
4848 {
4849 tree field_decl, field_decl_chain;
4850
4851 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
4852
4853 /* SEL sel_id; */
4854 field_decl = create_field_decl (objc_selector_type, "sel_id");
4855 field_decl_chain = field_decl;
4856
4857 /* char *sel_type; */
4858 field_decl = create_field_decl (string_type_node, "sel_type");
4859 chainon (field_decl_chain, field_decl);
4860
4861 objc_finish_struct (objc_selector_template, field_decl_chain);
4862 }
4863
4864 /* struct _objc_class {
4865 struct _objc_class *isa;
4866 struct _objc_class *super_class;
4867 char *name;
4868 long version;
4869 long info;
4870 long instance_size;
4871 struct _objc_ivar_list *ivars;
4872 struct _objc_method_list *methods;
4873 #ifdef __NEXT_RUNTIME__
4874 struct objc_cache *cache;
4875 #else
4876 struct sarray *dtable;
4877 struct _objc_class *subclass_list;
4878 struct _objc_class *sibling_class;
4879 #endif
4880 struct _objc_protocol_list *protocols;
4881 #ifdef __NEXT_RUNTIME__
4882 void *sel_id;
4883 #endif
4884 void *gc_object_type;
4885 }; */
4886
4887 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4888 the NeXT/Apple runtime; still, the compiler must generate them to
4889 maintain backward binary compatibility (and to allow for future
4890 expansion). */
4891
4892 static void
4893 build_class_template (void)
4894 {
4895 tree field_decl, field_decl_chain;
4896
4897 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
4898
4899 /* struct _objc_class *isa; */
4900 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4901 "isa");
4902 field_decl_chain = field_decl;
4903
4904 /* struct _objc_class *super_class; */
4905 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4906 "super_class");
4907 chainon (field_decl_chain, field_decl);
4908
4909 /* char *name; */
4910 field_decl = create_field_decl (string_type_node, "name");
4911 chainon (field_decl_chain, field_decl);
4912
4913 /* long version; */
4914 field_decl = create_field_decl (long_integer_type_node, "version");
4915 chainon (field_decl_chain, field_decl);
4916
4917 /* long info; */
4918 field_decl = create_field_decl (long_integer_type_node, "info");
4919 chainon (field_decl_chain, field_decl);
4920
4921 /* long instance_size; */
4922 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4923 chainon (field_decl_chain, field_decl);
4924
4925 /* struct _objc_ivar_list *ivars; */
4926 field_decl = create_field_decl (objc_ivar_list_ptr,
4927 "ivars");
4928 chainon (field_decl_chain, field_decl);
4929
4930 /* struct _objc_method_list *methods; */
4931 field_decl = create_field_decl (objc_method_list_ptr,
4932 "methods");
4933 chainon (field_decl_chain, field_decl);
4934
4935 if (flag_next_runtime)
4936 {
4937 /* struct objc_cache *cache; */
4938 field_decl = create_field_decl (build_pointer_type
4939 (xref_tag (RECORD_TYPE,
4940 get_identifier
4941 ("objc_cache"))),
4942 "cache");
4943 chainon (field_decl_chain, field_decl);
4944 }
4945 else
4946 {
4947 /* struct sarray *dtable; */
4948 field_decl = create_field_decl (build_pointer_type
4949 (xref_tag (RECORD_TYPE,
4950 get_identifier
4951 ("sarray"))),
4952 "dtable");
4953 chainon (field_decl_chain, field_decl);
4954
4955 /* struct objc_class *subclass_list; */
4956 field_decl = create_field_decl (build_pointer_type
4957 (objc_class_template),
4958 "subclass_list");
4959 chainon (field_decl_chain, field_decl);
4960
4961 /* struct objc_class *sibling_class; */
4962 field_decl = create_field_decl (build_pointer_type
4963 (objc_class_template),
4964 "sibling_class");
4965 chainon (field_decl_chain, field_decl);
4966 }
4967
4968 /* struct _objc_protocol **protocol_list; */
4969 field_decl = create_field_decl (build_pointer_type
4970 (build_pointer_type
4971 (xref_tag (RECORD_TYPE,
4972 get_identifier
4973 (UTAG_PROTOCOL)))),
4974 "protocol_list");
4975 chainon (field_decl_chain, field_decl);
4976
4977 if (flag_next_runtime)
4978 {
4979 /* void *sel_id; */
4980 field_decl = create_field_decl (build_pointer_type (void_type_node),
4981 "sel_id");
4982 chainon (field_decl_chain, field_decl);
4983 }
4984
4985 /* void *gc_object_type; */
4986 field_decl = create_field_decl (build_pointer_type (void_type_node),
4987 "gc_object_type");
4988 chainon (field_decl_chain, field_decl);
4989
4990 objc_finish_struct (objc_class_template, field_decl_chain);
4991 }
4992
4993 /* Generate appropriate forward declarations for an implementation. */
4994
4995 static void
4996 synth_forward_declarations (void)
4997 {
4998 tree an_id;
4999
5000 /* static struct objc_class _OBJC_CLASS_<my_name>; */
5001 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
5002 objc_class_template);
5003
5004 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
5005 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
5006 objc_class_template);
5007
5008 /* Pre-build the following entities - for speed/convenience. */
5009
5010 an_id = get_identifier ("super_class");
5011 ucls_super_ref = objc_build_component_ref (UOBJC_CLASS_decl, an_id);
5012 uucls_super_ref = objc_build_component_ref (UOBJC_METACLASS_decl, an_id);
5013 }
5014
5015 static void
5016 error_with_ivar (const char *message, tree decl)
5017 {
5018 error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
5019 message, identifier_to_locale (gen_declaration (decl)));
5020
5021 }
5022
5023 static void
5024 check_ivars (tree inter, tree imp)
5025 {
5026 tree intdecls = CLASS_RAW_IVARS (inter);
5027 tree impdecls = CLASS_RAW_IVARS (imp);
5028
5029 while (1)
5030 {
5031 tree t1, t2;
5032
5033 #ifdef OBJCPLUS
5034 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
5035 intdecls = TREE_CHAIN (intdecls);
5036 #endif
5037 if (intdecls == 0 && impdecls == 0)
5038 break;
5039 if (intdecls == 0 || impdecls == 0)
5040 {
5041 error ("inconsistent instance variable specification");
5042 break;
5043 }
5044
5045 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
5046
5047 if (!comptypes (t1, t2)
5048 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
5049 DECL_INITIAL (impdecls)))
5050 {
5051 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
5052 {
5053 error_with_ivar ("conflicting instance variable type",
5054 impdecls);
5055 error_with_ivar ("previous declaration of",
5056 intdecls);
5057 }
5058 else /* both the type and the name don't match */
5059 {
5060 error ("inconsistent instance variable specification");
5061 break;
5062 }
5063 }
5064
5065 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
5066 {
5067 error_with_ivar ("conflicting instance variable name",
5068 impdecls);
5069 error_with_ivar ("previous declaration of",
5070 intdecls);
5071 }
5072
5073 intdecls = TREE_CHAIN (intdecls);
5074 impdecls = TREE_CHAIN (impdecls);
5075 }
5076 }
5077
5078 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
5079 This needs to be done just once per compilation. */
5080
5081 /* struct _objc_super {
5082 struct _objc_object *self;
5083 struct _objc_class *super_class;
5084 }; */
5085
5086 static void
5087 build_super_template (void)
5088 {
5089 tree field_decl, field_decl_chain;
5090
5091 objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
5092
5093 /* struct _objc_object *self; */
5094 field_decl = create_field_decl (objc_object_type, "self");
5095 field_decl_chain = field_decl;
5096
5097 /* struct _objc_class *super_class; */
5098 field_decl = create_field_decl (build_pointer_type (objc_class_template),
5099 "super_class");
5100 chainon (field_decl_chain, field_decl);
5101
5102 objc_finish_struct (objc_super_template, field_decl_chain);
5103 }
5104
5105 /* struct _objc_ivar {
5106 char *ivar_name;
5107 char *ivar_type;
5108 int ivar_offset;
5109 }; */
5110
5111 static tree
5112 build_ivar_template (void)
5113 {
5114 tree objc_ivar_id, objc_ivar_record;
5115 tree field_decl, field_decl_chain;
5116
5117 objc_ivar_id = get_identifier (UTAG_IVAR);
5118 objc_ivar_record = objc_start_struct (objc_ivar_id);
5119
5120 /* char *ivar_name; */
5121 field_decl = create_field_decl (string_type_node, "ivar_name");
5122 field_decl_chain = field_decl;
5123
5124 /* char *ivar_type; */
5125 field_decl = create_field_decl (string_type_node, "ivar_type");
5126 chainon (field_decl_chain, field_decl);
5127
5128 /* int ivar_offset; */
5129 field_decl = create_field_decl (integer_type_node, "ivar_offset");
5130 chainon (field_decl_chain, field_decl);
5131
5132 objc_finish_struct (objc_ivar_record, field_decl_chain);
5133
5134 return objc_ivar_record;
5135 }
5136
5137 /* struct {
5138 int ivar_count;
5139 struct objc_ivar ivar_list[ivar_count];
5140 }; */
5141
5142 static tree
5143 build_ivar_list_template (tree list_type, int size)
5144 {
5145 tree objc_ivar_list_record;
5146 tree field_decl, field_decl_chain;
5147
5148 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5149
5150 /* int ivar_count; */
5151 field_decl = create_field_decl (integer_type_node, "ivar_count");
5152 field_decl_chain = field_decl;
5153
5154 /* struct objc_ivar ivar_list[]; */
5155 field_decl = create_field_decl (build_array_type
5156 (list_type,
5157 build_index_type
5158 (build_int_cst (NULL_TREE, size - 1))),
5159 "ivar_list");
5160 chainon (field_decl_chain, field_decl);
5161
5162 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5163
5164 return objc_ivar_list_record;
5165 }
5166
5167 /* struct {
5168 struct _objc__method_prototype_list *method_next;
5169 int method_count;
5170 struct objc_method method_list[method_count];
5171 }; */
5172
5173 static tree
5174 build_method_list_template (tree list_type, int size)
5175 {
5176 tree objc_ivar_list_record;
5177 tree field_decl, field_decl_chain;
5178
5179 objc_ivar_list_record = objc_start_struct (NULL_TREE);
5180
5181 /* struct _objc__method_prototype_list *method_next; */
5182 field_decl = create_field_decl (objc_method_proto_list_ptr,
5183 "method_next");
5184 field_decl_chain = field_decl;
5185
5186 /* int method_count; */
5187 field_decl = create_field_decl (integer_type_node, "method_count");
5188 chainon (field_decl_chain, field_decl);
5189
5190 /* struct objc_method method_list[]; */
5191 field_decl = create_field_decl (build_array_type
5192 (list_type,
5193 build_index_type
5194 (build_int_cst (NULL_TREE, size - 1))),
5195 "method_list");
5196 chainon (field_decl_chain, field_decl);
5197
5198 objc_finish_struct (objc_ivar_list_record, field_decl_chain);
5199
5200 return objc_ivar_list_record;
5201 }
5202
5203 static tree
5204 build_ivar_list_initializer (tree type, tree field_decl)
5205 {
5206 tree initlist = NULL_TREE;
5207
5208 do
5209 {
5210 tree ivar = NULL_TREE;
5211
5212 /* Set name. */
5213 if (DECL_NAME (field_decl))
5214 ivar = tree_cons (NULL_TREE,
5215 add_objc_string (DECL_NAME (field_decl),
5216 meth_var_names),
5217 ivar);
5218 else
5219 /* Unnamed bit-field ivar (yuck). */
5220 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
5221
5222 /* Set type. */
5223 encode_field_decl (field_decl,
5224 obstack_object_size (&util_obstack),
5225 OBJC_ENCODE_DONT_INLINE_DEFS);
5226
5227 /* Null terminate string. */
5228 obstack_1grow (&util_obstack, 0);
5229 ivar
5230 = tree_cons
5231 (NULL_TREE,
5232 add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
5233 meth_var_types),
5234 ivar);
5235 obstack_free (&util_obstack, util_firstobj);
5236
5237 /* Set offset. */
5238 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
5239 initlist = tree_cons (NULL_TREE,
5240 objc_build_constructor (type, nreverse (ivar)),
5241 initlist);
5242 do
5243 field_decl = TREE_CHAIN (field_decl);
5244 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
5245 }
5246 while (field_decl);
5247
5248 return objc_build_constructor (build_array_type (type, 0),
5249 nreverse (initlist));
5250 }
5251
5252 static tree
5253 generate_ivars_list (tree type, const char *name, int size, tree list)
5254 {
5255 tree decl, initlist;
5256
5257 decl = start_var_decl (type, synth_id_with_class_suffix
5258 (name, objc_implementation_context));
5259
5260 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
5261 initlist = tree_cons (NULL_TREE, list, initlist);
5262
5263 finish_var_decl (decl,
5264 objc_build_constructor (TREE_TYPE (decl),
5265 nreverse (initlist)));
5266
5267 return decl;
5268 }
5269
5270 /* Count only the fields occurring in T. */
5271
5272 static int
5273 ivar_list_length (tree t)
5274 {
5275 int count = 0;
5276
5277 for (; t; t = TREE_CHAIN (t))
5278 if (TREE_CODE (t) == FIELD_DECL)
5279 ++count;
5280
5281 return count;
5282 }
5283
5284 static void
5285 generate_ivar_lists (void)
5286 {
5287 tree initlist, ivar_list_template, chain;
5288 int size;
5289
5290 generating_instance_variables = 1;
5291
5292 if (!objc_ivar_template)
5293 objc_ivar_template = build_ivar_template ();
5294
5295 /* Only generate class variables for the root of the inheritance
5296 hierarchy since these will be the same for every class. */
5297
5298 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
5299 && (chain = TYPE_FIELDS (objc_class_template)))
5300 {
5301 size = ivar_list_length (chain);
5302
5303 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5304 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5305
5306 UOBJC_CLASS_VARIABLES_decl
5307 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
5308 size, initlist);
5309 }
5310 else
5311 UOBJC_CLASS_VARIABLES_decl = 0;
5312
5313 chain = CLASS_IVARS (implementation_template);
5314 if (chain)
5315 {
5316 size = ivar_list_length (chain);
5317 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
5318 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
5319
5320 UOBJC_INSTANCE_VARIABLES_decl
5321 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
5322 size, initlist);
5323 }
5324 else
5325 UOBJC_INSTANCE_VARIABLES_decl = 0;
5326
5327 generating_instance_variables = 0;
5328 }
5329
5330 static tree
5331 build_dispatch_table_initializer (tree type, tree entries)
5332 {
5333 tree initlist = NULL_TREE;
5334
5335 do
5336 {
5337 tree elemlist = NULL_TREE;
5338
5339 elemlist = tree_cons (NULL_TREE,
5340 build_selector (METHOD_SEL_NAME (entries)),
5341 NULL_TREE);
5342
5343 /* Generate the method encoding if we don't have one already. */
5344 if (! METHOD_ENCODING (entries))
5345 METHOD_ENCODING (entries) =
5346 encode_method_prototype (entries);
5347
5348 elemlist = tree_cons (NULL_TREE,
5349 add_objc_string (METHOD_ENCODING (entries),
5350 meth_var_types),
5351 elemlist);
5352
5353 elemlist
5354 = tree_cons (NULL_TREE,
5355 convert (ptr_type_node,
5356 build_unary_op (input_location, ADDR_EXPR,
5357 METHOD_DEFINITION (entries), 1)),
5358 elemlist);
5359
5360 initlist = tree_cons (NULL_TREE,
5361 objc_build_constructor (type, nreverse (elemlist)),
5362 initlist);
5363
5364 entries = TREE_CHAIN (entries);
5365 }
5366 while (entries);
5367
5368 return objc_build_constructor (build_array_type (type, 0),
5369 nreverse (initlist));
5370 }
5371
5372 /* To accomplish method prototyping without generating all kinds of
5373 inane warnings, the definition of the dispatch table entries were
5374 changed from:
5375
5376 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
5377 to:
5378 struct objc_method { SEL _cmd; ...; void *_imp; }; */
5379
5380 static tree
5381 build_method_template (void)
5382 {
5383 tree _SLT_record;
5384 tree field_decl, field_decl_chain;
5385
5386 _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
5387
5388 /* SEL _cmd; */
5389 field_decl = create_field_decl (objc_selector_type, "_cmd");
5390 field_decl_chain = field_decl;
5391
5392 /* char *method_types; */
5393 field_decl = create_field_decl (string_type_node, "method_types");
5394 chainon (field_decl_chain, field_decl);
5395
5396 /* void *_imp; */
5397 field_decl = create_field_decl (build_pointer_type (void_type_node),
5398 "_imp");
5399 chainon (field_decl_chain, field_decl);
5400
5401 objc_finish_struct (_SLT_record, field_decl_chain);
5402
5403 return _SLT_record;
5404 }
5405
5406
5407 static tree
5408 generate_dispatch_table (tree type, const char *name, int size, tree list)
5409 {
5410 tree decl, initlist;
5411
5412 decl = start_var_decl (type, synth_id_with_class_suffix
5413 (name, objc_implementation_context));
5414
5415 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
5416 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
5417 initlist = tree_cons (NULL_TREE, list, initlist);
5418
5419 finish_var_decl (decl,
5420 objc_build_constructor (TREE_TYPE (decl),
5421 nreverse (initlist)));
5422
5423 return decl;
5424 }
5425
5426 static void
5427 mark_referenced_methods (void)
5428 {
5429 struct imp_entry *impent;
5430 tree chain;
5431
5432 for (impent = imp_list; impent; impent = impent->next)
5433 {
5434 chain = CLASS_CLS_METHODS (impent->imp_context);
5435 while (chain)
5436 {
5437 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5438 chain = TREE_CHAIN (chain);
5439 }
5440
5441 chain = CLASS_NST_METHODS (impent->imp_context);
5442 while (chain)
5443 {
5444 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
5445 chain = TREE_CHAIN (chain);
5446 }
5447 }
5448 }
5449
5450 static void
5451 generate_dispatch_tables (void)
5452 {
5453 tree initlist, chain, method_list_template;
5454 int size;
5455
5456 if (!objc_method_template)
5457 objc_method_template = build_method_template ();
5458
5459 chain = CLASS_CLS_METHODS (objc_implementation_context);
5460 if (chain)
5461 {
5462 size = list_length (chain);
5463
5464 method_list_template
5465 = build_method_list_template (objc_method_template, size);
5466 initlist
5467 = build_dispatch_table_initializer (objc_method_template, chain);
5468
5469 UOBJC_CLASS_METHODS_decl
5470 = generate_dispatch_table (method_list_template,
5471 ((TREE_CODE (objc_implementation_context)
5472 == CLASS_IMPLEMENTATION_TYPE)
5473 ? "_OBJC_CLASS_METHODS"
5474 : "_OBJC_CATEGORY_CLASS_METHODS"),
5475 size, initlist);
5476 }
5477 else
5478 UOBJC_CLASS_METHODS_decl = 0;
5479
5480 chain = CLASS_NST_METHODS (objc_implementation_context);
5481 if (chain)
5482 {
5483 size = list_length (chain);
5484
5485 method_list_template
5486 = build_method_list_template (objc_method_template, size);
5487 initlist
5488 = build_dispatch_table_initializer (objc_method_template, chain);
5489
5490 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
5491 UOBJC_INSTANCE_METHODS_decl
5492 = generate_dispatch_table (method_list_template,
5493 "_OBJC_INSTANCE_METHODS",
5494 size, initlist);
5495 else
5496 /* We have a category. */
5497 UOBJC_INSTANCE_METHODS_decl
5498 = generate_dispatch_table (method_list_template,
5499 "_OBJC_CATEGORY_INSTANCE_METHODS",
5500 size, initlist);
5501 }
5502 else
5503 UOBJC_INSTANCE_METHODS_decl = 0;
5504 }
5505
5506 static tree
5507 generate_protocol_list (tree i_or_p)
5508 {
5509 tree initlist;
5510 tree refs_decl, lproto, e, plist;
5511 int size = 0;
5512 const char *ref_name;
5513
5514 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
5515 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5516 plist = CLASS_PROTOCOL_LIST (i_or_p);
5517 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5518 plist = PROTOCOL_LIST (i_or_p);
5519 else
5520 abort ();
5521
5522 /* Compute size. */
5523 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5524 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
5525 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
5526 size++;
5527
5528 /* Build initializer. */
5529 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
5530 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
5531 initlist = tree_cons (NULL_TREE, e, initlist);
5532
5533 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
5534 {
5535 tree pval = TREE_VALUE (lproto);
5536
5537 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
5538 && PROTOCOL_FORWARD_DECL (pval))
5539 {
5540 e = build_unary_op (input_location, ADDR_EXPR,
5541 PROTOCOL_FORWARD_DECL (pval), 0);
5542 initlist = tree_cons (NULL_TREE, e, initlist);
5543 }
5544 }
5545
5546 /* static struct objc_protocol *refs[n]; */
5547
5548 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
5549 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
5550 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
5551 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
5552 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
5553 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
5554 else
5555 abort ();
5556
5557 refs_decl = start_var_decl
5558 (build_array_type
5559 (build_pointer_type (objc_protocol_template),
5560 build_index_type (build_int_cst (NULL_TREE, size + 2))),
5561 ref_name);
5562
5563 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
5564 nreverse (initlist)));
5565
5566 return refs_decl;
5567 }
5568
5569 static tree
5570 build_category_initializer (tree type, tree cat_name, tree class_name,
5571 tree instance_methods, tree class_methods,
5572 tree protocol_list)
5573 {
5574 tree initlist = NULL_TREE, expr;
5575
5576 initlist = tree_cons (NULL_TREE, cat_name, initlist);
5577 initlist = tree_cons (NULL_TREE, class_name, initlist);
5578
5579 if (!instance_methods)
5580 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5581 else
5582 {
5583 expr = convert (objc_method_list_ptr,
5584 build_unary_op (input_location, ADDR_EXPR,
5585 instance_methods, 0));
5586 initlist = tree_cons (NULL_TREE, expr, initlist);
5587 }
5588 if (!class_methods)
5589 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5590 else
5591 {
5592 expr = convert (objc_method_list_ptr,
5593 build_unary_op (input_location, ADDR_EXPR,
5594 class_methods, 0));
5595 initlist = tree_cons (NULL_TREE, expr, initlist);
5596 }
5597
5598 /* protocol_list = */
5599 if (!protocol_list)
5600 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5601 else
5602 {
5603 expr = convert (build_pointer_type
5604 (build_pointer_type
5605 (objc_protocol_template)),
5606 build_unary_op (input_location, ADDR_EXPR,
5607 protocol_list, 0));
5608 initlist = tree_cons (NULL_TREE, expr, initlist);
5609 }
5610
5611 return objc_build_constructor (type, nreverse (initlist));
5612 }
5613
5614 /* struct _objc_class {
5615 struct objc_class *isa;
5616 struct objc_class *super_class;
5617 char *name;
5618 long version;
5619 long info;
5620 long instance_size;
5621 struct objc_ivar_list *ivars;
5622 struct objc_method_list *methods;
5623 if (flag_next_runtime)
5624 struct objc_cache *cache;
5625 else {
5626 struct sarray *dtable;
5627 struct objc_class *subclass_list;
5628 struct objc_class *sibling_class;
5629 }
5630 struct objc_protocol_list *protocols;
5631 if (flag_next_runtime)
5632 void *sel_id;
5633 void *gc_object_type;
5634 }; */
5635
5636 static tree
5637 build_shared_structure_initializer (tree type, tree isa, tree super,
5638 tree name, tree size, int status,
5639 tree dispatch_table, tree ivar_list,
5640 tree protocol_list)
5641 {
5642 tree initlist = NULL_TREE, expr;
5643
5644 /* isa = */
5645 initlist = tree_cons (NULL_TREE, isa, initlist);
5646
5647 /* super_class = */
5648 initlist = tree_cons (NULL_TREE, super, initlist);
5649
5650 /* name = */
5651 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
5652
5653 /* version = */
5654 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
5655 initlist);
5656
5657 /* info = */
5658 initlist = tree_cons (NULL_TREE,
5659 build_int_cst (long_integer_type_node, status),
5660 initlist);
5661
5662 /* instance_size = */
5663 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
5664 initlist);
5665
5666 /* objc_ivar_list = */
5667 if (!ivar_list)
5668 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5669 else
5670 {
5671 expr = convert (objc_ivar_list_ptr,
5672 build_unary_op (input_location, ADDR_EXPR,
5673 ivar_list, 0));
5674 initlist = tree_cons (NULL_TREE, expr, initlist);
5675 }
5676
5677 /* objc_method_list = */
5678 if (!dispatch_table)
5679 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5680 else
5681 {
5682 expr = convert (objc_method_list_ptr,
5683 build_unary_op (input_location, ADDR_EXPR,
5684 dispatch_table, 0));
5685 initlist = tree_cons (NULL_TREE, expr, initlist);
5686 }
5687
5688 if (flag_next_runtime)
5689 /* method_cache = */
5690 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5691 else
5692 {
5693 /* dtable = */
5694 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5695
5696 /* subclass_list = */
5697 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5698
5699 /* sibling_class = */
5700 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5701 }
5702
5703 /* protocol_list = */
5704 if (! protocol_list)
5705 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5706 else
5707 {
5708 expr = convert (build_pointer_type
5709 (build_pointer_type
5710 (objc_protocol_template)),
5711 build_unary_op (input_location, ADDR_EXPR,
5712 protocol_list, 0));
5713 initlist = tree_cons (NULL_TREE, expr, initlist);
5714 }
5715
5716 if (flag_next_runtime)
5717 /* sel_id = NULL */
5718 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5719
5720 /* gc_object_type = NULL */
5721 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
5722
5723 return objc_build_constructor (type, nreverse (initlist));
5724 }
5725
5726 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
5727
5728 static inline tree
5729 lookup_category (tree klass, tree cat_name)
5730 {
5731 tree category = CLASS_CATEGORY_LIST (klass);
5732
5733 while (category && CLASS_SUPER_NAME (category) != cat_name)
5734 category = CLASS_CATEGORY_LIST (category);
5735 return category;
5736 }
5737
5738 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
5739
5740 static void
5741 generate_category (tree cat)
5742 {
5743 tree decl;
5744 tree initlist, cat_name_expr, class_name_expr;
5745 tree protocol_decl, category;
5746
5747 add_class_reference (CLASS_NAME (cat));
5748 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
5749
5750 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
5751
5752 category = lookup_category (implementation_template,
5753 CLASS_SUPER_NAME (cat));
5754
5755 if (category && CLASS_PROTOCOL_LIST (category))
5756 {
5757 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
5758 protocol_decl = generate_protocol_list (category);
5759 }
5760 else
5761 protocol_decl = 0;
5762
5763 decl = start_var_decl (objc_category_template,
5764 synth_id_with_class_suffix
5765 ("_OBJC_CATEGORY", objc_implementation_context));
5766
5767 initlist = build_category_initializer (TREE_TYPE (decl),
5768 cat_name_expr, class_name_expr,
5769 UOBJC_INSTANCE_METHODS_decl,
5770 UOBJC_CLASS_METHODS_decl,
5771 protocol_decl);
5772
5773 finish_var_decl (decl, initlist);
5774 }
5775
5776 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
5777 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5778
5779 static void
5780 generate_shared_structures (int cls_flags)
5781 {
5782 tree sc_spec, decl_specs, decl;
5783 tree name_expr, super_expr, root_expr;
5784 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
5785 tree cast_type, initlist, protocol_decl;
5786
5787 my_super_id = CLASS_SUPER_NAME (implementation_template);
5788 if (my_super_id)
5789 {
5790 add_class_reference (my_super_id);
5791
5792 /* Compute "my_root_id" - this is required for code generation.
5793 the "isa" for all meta class structures points to the root of
5794 the inheritance hierarchy (e.g. "__Object")... */
5795 my_root_id = my_super_id;
5796 do
5797 {
5798 tree my_root_int = lookup_interface (my_root_id);
5799
5800 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5801 my_root_id = CLASS_SUPER_NAME (my_root_int);
5802 else
5803 break;
5804 }
5805 while (1);
5806 }
5807 else
5808 /* No super class. */
5809 my_root_id = CLASS_NAME (implementation_template);
5810
5811 cast_type = build_pointer_type (objc_class_template);
5812 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5813 class_names);
5814
5815 /* Install class `isa' and `super' pointers at runtime. */
5816 if (my_super_id)
5817 {
5818 super_expr = add_objc_string (my_super_id, class_names);
5819 super_expr = build_c_cast (input_location,
5820 cast_type, super_expr); /* cast! */
5821 }
5822 else
5823 super_expr = build_int_cst (NULL_TREE, 0);
5824
5825 root_expr = add_objc_string (my_root_id, class_names);
5826 root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
5827
5828 if (CLASS_PROTOCOL_LIST (implementation_template))
5829 {
5830 generate_protocol_references
5831 (CLASS_PROTOCOL_LIST (implementation_template));
5832 protocol_decl = generate_protocol_list (implementation_template);
5833 }
5834 else
5835 protocol_decl = 0;
5836
5837 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5838
5839 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5840 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5841
5842 decl = start_var_decl (objc_class_template,
5843 IDENTIFIER_POINTER
5844 (DECL_NAME (UOBJC_METACLASS_decl)));
5845
5846 initlist
5847 = build_shared_structure_initializer
5848 (TREE_TYPE (decl),
5849 root_expr, super_expr, name_expr,
5850 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5851 2 /*CLS_META*/,
5852 UOBJC_CLASS_METHODS_decl,
5853 UOBJC_CLASS_VARIABLES_decl,
5854 protocol_decl);
5855
5856 finish_var_decl (decl, initlist);
5857
5858 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5859
5860 decl = start_var_decl (objc_class_template,
5861 IDENTIFIER_POINTER
5862 (DECL_NAME (UOBJC_CLASS_decl)));
5863
5864 initlist
5865 = build_shared_structure_initializer
5866 (TREE_TYPE (decl),
5867 build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5868 super_expr, name_expr,
5869 convert (integer_type_node,
5870 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5871 (implementation_template))),
5872 1 /*CLS_FACTORY*/ | cls_flags,
5873 UOBJC_INSTANCE_METHODS_decl,
5874 UOBJC_INSTANCE_VARIABLES_decl,
5875 protocol_decl);
5876
5877 finish_var_decl (decl, initlist);
5878 }
5879
5880
5881 static const char *
5882 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5883 {
5884 static char string[BUFSIZE];
5885
5886 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5887 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5888 {
5889 sprintf (string, "%s_%s", preamble,
5890 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5891 }
5892 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5893 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5894 {
5895 /* We have a category. */
5896 const char *const class_name
5897 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5898 const char *const class_super_name
5899 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5900 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5901 }
5902 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5903 {
5904 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5905 sprintf (string, "%s_%s", preamble, protocol_name);
5906 }
5907 else
5908 abort ();
5909
5910 return string;
5911 }
5912
5913 /* If type is empty or only type qualifiers are present, add default
5914 type of id (otherwise grokdeclarator will default to int). */
5915
5916 static tree
5917 adjust_type_for_id_default (tree type)
5918 {
5919 if (!type)
5920 type = make_node (TREE_LIST);
5921
5922 if (!TREE_VALUE (type))
5923 TREE_VALUE (type) = objc_object_type;
5924 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5925 && TYPED_OBJECT (TREE_VALUE (type)))
5926 error ("can not use an object as parameter to a method");
5927
5928 return type;
5929 }
5930
5931 /* Usage:
5932 keyworddecl:
5933 selector ':' '(' typename ')' identifier
5934
5935 Purpose:
5936 Transform an Objective-C keyword argument into
5937 the C equivalent parameter declarator.
5938
5939 In: key_name, an "identifier_node" (optional).
5940 arg_type, a "tree_list" (optional).
5941 arg_name, an "identifier_node".
5942
5943 Note: It would be really nice to strongly type the preceding
5944 arguments in the function prototype; however, then I
5945 could not use the "accessor" macros defined in "tree.h".
5946
5947 Out: an instance of "keyword_decl". */
5948
5949 tree
5950 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5951 {
5952 tree keyword_decl;
5953
5954 /* If no type is specified, default to "id". */
5955 arg_type = adjust_type_for_id_default (arg_type);
5956
5957 keyword_decl = make_node (KEYWORD_DECL);
5958
5959 TREE_TYPE (keyword_decl) = arg_type;
5960 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5961 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5962
5963 return keyword_decl;
5964 }
5965
5966 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5967
5968 static tree
5969 build_keyword_selector (tree selector)
5970 {
5971 int len = 0;
5972 tree key_chain, key_name;
5973 char *buf;
5974
5975 /* Scan the selector to see how much space we'll need. */
5976 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5977 {
5978 if (TREE_CODE (selector) == KEYWORD_DECL)
5979 key_name = KEYWORD_KEY_NAME (key_chain);
5980 else if (TREE_CODE (selector) == TREE_LIST)
5981 key_name = TREE_PURPOSE (key_chain);
5982 else
5983 abort ();
5984
5985 if (key_name)
5986 len += IDENTIFIER_LENGTH (key_name) + 1;
5987 else
5988 /* Just a ':' arg. */
5989 len++;
5990 }
5991
5992 buf = (char *) alloca (len + 1);
5993 /* Start the buffer out as an empty string. */
5994 buf[0] = '\0';
5995
5996 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5997 {
5998 if (TREE_CODE (selector) == KEYWORD_DECL)
5999 key_name = KEYWORD_KEY_NAME (key_chain);
6000 else if (TREE_CODE (selector) == TREE_LIST)
6001 {
6002 key_name = TREE_PURPOSE (key_chain);
6003 /* The keyword decl chain will later be used as a function argument
6004 chain. Unhook the selector itself so as to not confuse other
6005 parts of the compiler. */
6006 TREE_PURPOSE (key_chain) = NULL_TREE;
6007 }
6008 else
6009 abort ();
6010
6011 if (key_name)
6012 strcat (buf, IDENTIFIER_POINTER (key_name));
6013 strcat (buf, ":");
6014 }
6015
6016 return get_identifier (buf);
6017 }
6018
6019 /* Used for declarations and definitions. */
6020
6021 static tree
6022 build_method_decl (enum tree_code code, tree ret_type, tree selector,
6023 tree add_args, bool ellipsis)
6024 {
6025 tree method_decl;
6026
6027 /* If no type is specified, default to "id". */
6028 ret_type = adjust_type_for_id_default (ret_type);
6029
6030 method_decl = make_node (code);
6031 TREE_TYPE (method_decl) = ret_type;
6032
6033 /* If we have a keyword selector, create an identifier_node that
6034 represents the full selector name (`:' included)... */
6035 if (TREE_CODE (selector) == KEYWORD_DECL)
6036 {
6037 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
6038 METHOD_SEL_ARGS (method_decl) = selector;
6039 METHOD_ADD_ARGS (method_decl) = add_args;
6040 METHOD_ADD_ARGS_ELLIPSIS_P (method_decl) = ellipsis;
6041 }
6042 else
6043 {
6044 METHOD_SEL_NAME (method_decl) = selector;
6045 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
6046 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
6047 }
6048
6049 return method_decl;
6050 }
6051
6052 #define METHOD_DEF 0
6053 #define METHOD_REF 1
6054
6055 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
6056 an argument list for method METH. CONTEXT is either METHOD_DEF or
6057 METHOD_REF, saying whether we are trying to define a method or call
6058 one. SUPERFLAG says this is for a send to super; this makes a
6059 difference for the NeXT calling sequence in which the lookup and
6060 the method call are done together. If METH is null, user-defined
6061 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
6062
6063 static tree
6064 get_arg_type_list (tree meth, int context, int superflag)
6065 {
6066 tree arglist, akey;
6067
6068 /* Receiver type. */
6069 if (flag_next_runtime && superflag)
6070 arglist = build_tree_list (NULL_TREE, objc_super_type);
6071 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6072 arglist = build_tree_list (NULL_TREE, objc_instance_type);
6073 else
6074 arglist = build_tree_list (NULL_TREE, objc_object_type);
6075
6076 /* Selector type - will eventually change to `int'. */
6077 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
6078
6079 /* No actual method prototype given -- assume that remaining arguments
6080 are `...'. */
6081 if (!meth)
6082 return arglist;
6083
6084 /* Build a list of argument types. */
6085 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
6086 {
6087 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
6088
6089 /* Decay arrays and functions into pointers. */
6090 if (TREE_CODE (arg_type) == ARRAY_TYPE)
6091 arg_type = build_pointer_type (TREE_TYPE (arg_type));
6092 else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
6093 arg_type = build_pointer_type (arg_type);
6094
6095 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6096 }
6097
6098 if (METHOD_ADD_ARGS (meth))
6099 {
6100 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
6101 akey; akey = TREE_CHAIN (akey))
6102 {
6103 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
6104
6105 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
6106 }
6107
6108 if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
6109 goto lack_of_ellipsis;
6110 }
6111 else
6112 {
6113 lack_of_ellipsis:
6114 chainon (arglist, OBJC_VOID_AT_END);
6115 }
6116
6117 return arglist;
6118 }
6119
6120 static tree
6121 check_duplicates (hash hsh, int methods, int is_class)
6122 {
6123 tree meth = NULL_TREE;
6124
6125 if (hsh)
6126 {
6127 meth = hsh->key;
6128
6129 if (hsh->list)
6130 {
6131 /* We have two or more methods with the same name but
6132 different types. */
6133 attr loop;
6134
6135 /* But just how different are those types? If
6136 -Wno-strict-selector-match is specified, we shall not
6137 complain if the differences are solely among types with
6138 identical size and alignment. */
6139 if (!warn_strict_selector_match)
6140 {
6141 for (loop = hsh->list; loop; loop = loop->next)
6142 if (!comp_proto_with_proto (meth, loop->value, 0))
6143 goto issue_warning;
6144
6145 return meth;
6146 }
6147
6148 issue_warning:
6149 if (methods)
6150 {
6151 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6152
6153 warning_at (input_location, 0,
6154 "multiple methods named %<%c%E%> found",
6155 (is_class ? '+' : '-'),
6156 METHOD_SEL_NAME (meth));
6157 inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
6158 (type ? '-' : '+'),
6159 identifier_to_locale (gen_method_decl (meth)));
6160 }
6161 else
6162 {
6163 bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
6164
6165 warning_at (input_location, 0,
6166 "multiple selectors named %<%c%E%> found",
6167 (is_class ? '+' : '-'),
6168 METHOD_SEL_NAME (meth));
6169 inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
6170 (type ? '-' : '+'),
6171 identifier_to_locale (gen_method_decl (meth)));
6172 }
6173
6174 for (loop = hsh->list; loop; loop = loop->next)
6175 {
6176 bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
6177
6178 inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
6179 (type ? '-' : '+'),
6180 identifier_to_locale (gen_method_decl (loop->value)));
6181 }
6182 }
6183 }
6184 return meth;
6185 }
6186
6187 /* If RECEIVER is a class reference, return the identifier node for
6188 the referenced class. RECEIVER is created by objc_get_class_reference,
6189 so we check the exact form created depending on which runtimes are
6190 used. */
6191
6192 static tree
6193 receiver_is_class_object (tree receiver, int self, int super)
6194 {
6195 tree chain, exp, arg;
6196
6197 /* The receiver is 'self' or 'super' in the context of a class method. */
6198 if (objc_method_context
6199 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
6200 && (self || super))
6201 return (super
6202 ? CLASS_SUPER_NAME (implementation_template)
6203 : CLASS_NAME (implementation_template));
6204
6205 if (flag_next_runtime)
6206 {
6207 /* The receiver is a variable created by
6208 build_class_reference_decl. */
6209 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
6210 /* Look up the identifier. */
6211 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
6212 if (TREE_PURPOSE (chain) == receiver)
6213 return TREE_VALUE (chain);
6214 }
6215
6216 /* The receiver is a function call that returns an id. Check if
6217 it is a call to objc_getClass, if so, pick up the class name. */
6218 if (TREE_CODE (receiver) == CALL_EXPR
6219 && (exp = CALL_EXPR_FN (receiver))
6220 && TREE_CODE (exp) == ADDR_EXPR
6221 && (exp = TREE_OPERAND (exp, 0))
6222 && TREE_CODE (exp) == FUNCTION_DECL
6223 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
6224 prototypes for objc_get_class(). Thankfully, they seem to share the
6225 same function type. */
6226 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
6227 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
6228 /* We have a call to objc_get_class/objc_getClass! */
6229 && (arg = CALL_EXPR_ARG (receiver, 0)))
6230 {
6231 STRIP_NOPS (arg);
6232 if (TREE_CODE (arg) == ADDR_EXPR
6233 && (arg = TREE_OPERAND (arg, 0))
6234 && TREE_CODE (arg) == STRING_CST)
6235 /* Finally, we have the class name. */
6236 return get_identifier (TREE_STRING_POINTER (arg));
6237 }
6238 return 0;
6239 }
6240 \f
6241 /* If we are currently building a message expr, this holds
6242 the identifier of the selector of the message. This is
6243 used when printing warnings about argument mismatches. */
6244
6245 static tree current_objc_message_selector = 0;
6246
6247 tree
6248 objc_message_selector (void)
6249 {
6250 return current_objc_message_selector;
6251 }
6252
6253 /* Construct an expression for sending a message.
6254 MESS has the object to send to in TREE_PURPOSE
6255 and the argument list (including selector) in TREE_VALUE.
6256
6257 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
6258 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
6259
6260 tree
6261 objc_build_message_expr (tree mess)
6262 {
6263 tree receiver = TREE_PURPOSE (mess);
6264 location_t loc;
6265 tree sel_name;
6266 #ifdef OBJCPLUS
6267 tree args = TREE_PURPOSE (TREE_VALUE (mess));
6268 #else
6269 tree args = TREE_VALUE (mess);
6270 #endif
6271 tree method_params = NULL_TREE;
6272
6273 if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
6274 return error_mark_node;
6275
6276 if (CAN_HAVE_LOCATION_P (receiver))
6277 loc = EXPR_LOCATION (receiver);
6278 else
6279 loc = input_location;
6280
6281 /* Obtain the full selector name. */
6282 if (TREE_CODE (args) == IDENTIFIER_NODE)
6283 /* A unary selector. */
6284 sel_name = args;
6285 else if (TREE_CODE (args) == TREE_LIST)
6286 sel_name = build_keyword_selector (args);
6287 else
6288 abort ();
6289
6290 /* Build the parameter list to give to the method. */
6291 if (TREE_CODE (args) == TREE_LIST)
6292 #ifdef OBJCPLUS
6293 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
6294 #else
6295 {
6296 tree chain = args, prev = NULL_TREE;
6297
6298 /* We have a keyword selector--check for comma expressions. */
6299 while (chain)
6300 {
6301 tree element = TREE_VALUE (chain);
6302
6303 /* We have a comma expression, must collapse... */
6304 if (TREE_CODE (element) == TREE_LIST)
6305 {
6306 if (prev)
6307 TREE_CHAIN (prev) = element;
6308 else
6309 args = element;
6310 }
6311 prev = chain;
6312 chain = TREE_CHAIN (chain);
6313 }
6314 method_params = args;
6315 }
6316 #endif
6317
6318 #ifdef OBJCPLUS
6319 if (processing_template_decl)
6320 /* Must wait until template instantiation time. */
6321 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
6322 method_params);
6323 #endif
6324
6325 return objc_finish_message_expr (receiver, sel_name, method_params);
6326 }
6327
6328 /* Look up method SEL_NAME that would be suitable for receiver
6329 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
6330 nonzero), and report on any duplicates. */
6331
6332 static tree
6333 lookup_method_in_hash_lists (tree sel_name, int is_class)
6334 {
6335 hash method_prototype = NULL;
6336
6337 if (!is_class)
6338 method_prototype = hash_lookup (nst_method_hash_list,
6339 sel_name);
6340
6341 if (!method_prototype)
6342 {
6343 method_prototype = hash_lookup (cls_method_hash_list,
6344 sel_name);
6345 is_class = 1;
6346 }
6347
6348 return check_duplicates (method_prototype, 1, is_class);
6349 }
6350
6351 /* The 'objc_finish_message_expr' routine is called from within
6352 'objc_build_message_expr' for non-template functions. In the case of
6353 C++ template functions, it is called from 'build_expr_from_tree'
6354 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
6355
6356 tree
6357 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
6358 {
6359 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
6360 tree selector, retval, class_tree;
6361 int self, super, have_cast;
6362
6363 /* Extract the receiver of the message, as well as its type
6364 (where the latter may take the form of a cast or be inferred
6365 from the implementation context). */
6366 rtype = receiver;
6367 while (TREE_CODE (rtype) == COMPOUND_EXPR
6368 || TREE_CODE (rtype) == MODIFY_EXPR
6369 || CONVERT_EXPR_P (rtype)
6370 || TREE_CODE (rtype) == COMPONENT_REF)
6371 rtype = TREE_OPERAND (rtype, 0);
6372 self = (rtype == self_decl);
6373 super = (rtype == UOBJC_SUPER_decl);
6374 rtype = TREE_TYPE (receiver);
6375 have_cast = (TREE_CODE (receiver) == NOP_EXPR
6376 || (TREE_CODE (receiver) == COMPOUND_EXPR
6377 && !IS_SUPER (rtype)));
6378
6379 /* If we are calling [super dealloc], reset our warning flag. */
6380 if (super && !strcmp ("dealloc", IDENTIFIER_POINTER (sel_name)))
6381 should_call_super_dealloc = 0;
6382
6383 /* If the receiver is a class object, retrieve the corresponding
6384 @interface, if one exists. */
6385 class_tree = receiver_is_class_object (receiver, self, super);
6386
6387 /* Now determine the receiver type (if an explicit cast has not been
6388 provided). */
6389 if (!have_cast)
6390 {
6391 if (class_tree)
6392 rtype = lookup_interface (class_tree);
6393 /* Handle `self' and `super'. */
6394 else if (super)
6395 {
6396 if (!CLASS_SUPER_NAME (implementation_template))
6397 {
6398 error ("no super class declared in @interface for %qE",
6399 CLASS_NAME (implementation_template));
6400 return error_mark_node;
6401 }
6402 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
6403 }
6404 else if (self)
6405 rtype = lookup_interface (CLASS_NAME (implementation_template));
6406 }
6407
6408 /* If receiver is of type `id' or `Class' (or if the @interface for a
6409 class is not visible), we shall be satisfied with the existence of
6410 any instance or class method. */
6411 if (objc_is_id (rtype))
6412 {
6413 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
6414 rprotos = (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype))
6415 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype))
6416 : NULL_TREE);
6417 rtype = NULL_TREE;
6418
6419 if (rprotos)
6420 {
6421 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
6422 in protocols themselves for the method prototype. */
6423 method_prototype
6424 = lookup_method_in_protocol_list (rprotos, sel_name,
6425 class_tree != NULL_TREE);
6426
6427 /* If messaging 'Class <Proto>' but did not find a class method
6428 prototype, search for an instance method instead, and warn
6429 about having done so. */
6430 if (!method_prototype && !rtype && class_tree != NULL_TREE)
6431 {
6432 method_prototype
6433 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
6434
6435 if (method_prototype)
6436 warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
6437 sel_name, sel_name);
6438 }
6439 }
6440 }
6441 else if (rtype)
6442 {
6443 tree orig_rtype = rtype, saved_rtype;
6444
6445 if (TREE_CODE (rtype) == POINTER_TYPE)
6446 rtype = TREE_TYPE (rtype);
6447 /* Traverse typedef aliases */
6448 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
6449 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
6450 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
6451 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
6452 saved_rtype = rtype;
6453 if (TYPED_OBJECT (rtype))
6454 {
6455 rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
6456 rtype = TYPE_OBJC_INTERFACE (rtype);
6457 }
6458 /* If we could not find an @interface declaration, we must have
6459 only seen a @class declaration; so, we cannot say anything
6460 more intelligent about which methods the receiver will
6461 understand. */
6462 if (!rtype || TREE_CODE (rtype) == IDENTIFIER_NODE)
6463 rtype = NULL_TREE;
6464 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
6465 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
6466 {
6467 /* We have a valid ObjC class name. Look up the method name
6468 in the published @interface for the class (and its
6469 superclasses). */
6470 method_prototype
6471 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
6472
6473 /* If the method was not found in the @interface, it may still
6474 exist locally as part of the @implementation. */
6475 if (!method_prototype && objc_implementation_context
6476 && CLASS_NAME (objc_implementation_context)
6477 == OBJC_TYPE_NAME (rtype))
6478 method_prototype
6479 = lookup_method
6480 ((class_tree
6481 ? CLASS_CLS_METHODS (objc_implementation_context)
6482 : CLASS_NST_METHODS (objc_implementation_context)),
6483 sel_name);
6484
6485 /* If we haven't found a candidate method by now, try looking for
6486 it in the protocol list. */
6487 if (!method_prototype && rprotos)
6488 method_prototype
6489 = lookup_method_in_protocol_list (rprotos, sel_name,
6490 class_tree != NULL_TREE);
6491 }
6492 else
6493 {
6494 warning (0, "invalid receiver type %qs",
6495 identifier_to_locale (gen_type_name (orig_rtype)));
6496 /* After issuing the "invalid receiver" warning, perform method
6497 lookup as if we were messaging 'id'. */
6498 rtype = rprotos = NULL_TREE;
6499 }
6500 }
6501
6502
6503 /* For 'id' or 'Class' receivers, search in the global hash table
6504 as a last resort. For all receivers, warn if protocol searches
6505 have failed. */
6506 if (!method_prototype)
6507 {
6508 if (rprotos)
6509 warning (0, "%<%c%E%> not found in protocol(s)",
6510 (class_tree ? '+' : '-'),
6511 sel_name);
6512
6513 if (!rtype)
6514 method_prototype
6515 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
6516 }
6517
6518 if (!method_prototype)
6519 {
6520 static bool warn_missing_methods = false;
6521
6522 if (rtype)
6523 warning (0, "%qE may not respond to %<%c%E%>",
6524 OBJC_TYPE_NAME (rtype),
6525 (class_tree ? '+' : '-'),
6526 sel_name);
6527 /* If we are messaging an 'id' or 'Class' object and made it here,
6528 then we have failed to find _any_ instance or class method,
6529 respectively. */
6530 else
6531 warning (0, "no %<%c%E%> method found",
6532 (class_tree ? '+' : '-'),
6533 sel_name);
6534
6535 if (!warn_missing_methods)
6536 {
6537 warning_at (input_location,
6538 0, "(Messages without a matching method signature");
6539 warning_at (input_location,
6540 0, "will be assumed to return %<id%> and accept");
6541 warning_at (input_location,
6542 0, "%<...%> as arguments.)");
6543 warn_missing_methods = true;
6544 }
6545 }
6546
6547 /* Save the selector name for printing error messages. */
6548 current_objc_message_selector = sel_name;
6549
6550 /* Build the parameters list for looking up the method.
6551 These are the object itself and the selector. */
6552
6553 if (flag_typed_selectors)
6554 selector = build_typed_selector_reference (input_location,
6555 sel_name, method_prototype);
6556 else
6557 selector = build_selector_reference (input_location, sel_name);
6558
6559 retval = build_objc_method_call (input_location, super, method_prototype,
6560 receiver,
6561 selector, method_params);
6562
6563 current_objc_message_selector = 0;
6564
6565 return retval;
6566 }
6567 \f
6568 /* Build a tree expression to send OBJECT the operation SELECTOR,
6569 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
6570 assuming the method has prototype METHOD_PROTOTYPE.
6571 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
6572 LOC is the location of the expression to build.
6573 Use METHOD_PARAMS as list of args to pass to the method.
6574 If SUPER_FLAG is nonzero, we look up the superclass's method. */
6575
6576 static tree
6577 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
6578 tree lookup_object, tree selector,
6579 tree method_params)
6580 {
6581 tree sender = (super_flag ? umsg_super_decl :
6582 (!flag_next_runtime || flag_nil_receivers
6583 ? (flag_objc_direct_dispatch
6584 ? umsg_fast_decl
6585 : umsg_decl)
6586 : umsg_nonnil_decl));
6587 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
6588
6589 /* If a prototype for the method to be called exists, then cast
6590 the sender's return type and arguments to match that of the method.
6591 Otherwise, leave sender as is. */
6592 tree ret_type
6593 = (method_prototype
6594 ? TREE_VALUE (TREE_TYPE (method_prototype))
6595 : objc_object_type);
6596 tree sender_cast
6597 = build_pointer_type
6598 (build_function_type
6599 (ret_type,
6600 get_arg_type_list
6601 (method_prototype, METHOD_REF, super_flag)));
6602 tree method, t;
6603
6604 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
6605
6606 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
6607 lookup_object = save_expr (lookup_object);
6608
6609 if (flag_next_runtime)
6610 {
6611 /* If we are returning a struct in memory, and the address
6612 of that memory location is passed as a hidden first
6613 argument, then change which messenger entry point this
6614 expr will call. NB: Note that sender_cast remains
6615 unchanged (it already has a struct return type). */
6616 if (!targetm.calls.struct_value_rtx (0, 0)
6617 && (TREE_CODE (ret_type) == RECORD_TYPE
6618 || TREE_CODE (ret_type) == UNION_TYPE)
6619 && targetm.calls.return_in_memory (ret_type, 0))
6620 sender = (super_flag ? umsg_super_stret_decl :
6621 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
6622
6623 method_params = tree_cons (NULL_TREE, lookup_object,
6624 tree_cons (NULL_TREE, selector,
6625 method_params));
6626 method = build_fold_addr_expr (sender);
6627 }
6628 else
6629 {
6630 /* This is the portable (GNU) way. */
6631 tree object;
6632
6633 /* First, call the lookup function to get a pointer to the method,
6634 then cast the pointer, then call it with the method arguments. */
6635
6636 object = (super_flag ? self_decl : lookup_object);
6637
6638 t = tree_cons (NULL_TREE, selector, NULL_TREE);
6639 t = tree_cons (NULL_TREE, lookup_object, t);
6640 method = build_function_call (loc,
6641 sender, t);
6642
6643 /* Pass the object to the method. */
6644 method_params = tree_cons (NULL_TREE, object,
6645 tree_cons (NULL_TREE, selector,
6646 method_params));
6647 }
6648
6649 /* ??? Selector is not at this point something we can use inside
6650 the compiler itself. Set it to garbage for the nonce. */
6651 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
6652 return build_function_call (loc,
6653 t, method_params);
6654 }
6655 \f
6656 static void
6657 build_protocol_reference (tree p)
6658 {
6659 tree decl;
6660 const char *proto_name;
6661
6662 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
6663
6664 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
6665 decl = start_var_decl (objc_protocol_template, proto_name);
6666
6667 PROTOCOL_FORWARD_DECL (p) = decl;
6668 }
6669
6670 /* This function is called by the parser when (and only when) a
6671 @protocol() expression is found, in order to compile it. */
6672 tree
6673 objc_build_protocol_expr (tree protoname)
6674 {
6675 tree expr;
6676 tree p = lookup_protocol (protoname);
6677
6678 if (!p)
6679 {
6680 error ("cannot find protocol declaration for %qE",
6681 protoname);
6682 return error_mark_node;
6683 }
6684
6685 if (!PROTOCOL_FORWARD_DECL (p))
6686 build_protocol_reference (p);
6687
6688 expr = build_unary_op (input_location,
6689 ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
6690
6691 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
6692 if we have it, rather than converting it here. */
6693 expr = convert (objc_protocol_type, expr);
6694
6695 /* The @protocol() expression is being compiled into a pointer to a
6696 statically allocated instance of the Protocol class. To become
6697 usable at runtime, the 'isa' pointer of the instance need to be
6698 fixed up at runtime by the runtime library, to point to the
6699 actual 'Protocol' class. */
6700
6701 /* For the GNU runtime, put the static Protocol instance in the list
6702 of statically allocated instances, so that we make sure that its
6703 'isa' pointer is fixed up at runtime by the GNU runtime library
6704 to point to the Protocol class (at runtime, when loading the
6705 module, the GNU runtime library loops on the statically allocated
6706 instances (as found in the defs field in objc_symtab) and fixups
6707 all the 'isa' pointers of those objects). */
6708 if (! flag_next_runtime)
6709 {
6710 /* This type is a struct containing the fields of a Protocol
6711 object. (Cfr. objc_protocol_type instead is the type of a pointer
6712 to such a struct). */
6713 tree protocol_struct_type = xref_tag
6714 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
6715 tree *chain;
6716
6717 /* Look for the list of Protocol statically allocated instances
6718 to fixup at runtime. Create a new list to hold Protocol
6719 statically allocated instances, if the list is not found. At
6720 present there is only another list, holding NSConstantString
6721 static instances to be fixed up at runtime. */
6722 for (chain = &objc_static_instances;
6723 *chain && TREE_VALUE (*chain) != protocol_struct_type;
6724 chain = &TREE_CHAIN (*chain));
6725 if (!*chain)
6726 {
6727 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
6728 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
6729 class_names);
6730 }
6731
6732 /* Add this statically allocated instance to the Protocol list. */
6733 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
6734 PROTOCOL_FORWARD_DECL (p),
6735 TREE_PURPOSE (*chain));
6736 }
6737
6738
6739 return expr;
6740 }
6741
6742 /* This function is called by the parser when a @selector() expression
6743 is found, in order to compile it. It is only called by the parser
6744 and only to compile a @selector(). LOC is the location of the
6745 @selector. */
6746 tree
6747 objc_build_selector_expr (location_t loc, tree selnamelist)
6748 {
6749 tree selname;
6750
6751 /* Obtain the full selector name. */
6752 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
6753 /* A unary selector. */
6754 selname = selnamelist;
6755 else if (TREE_CODE (selnamelist) == TREE_LIST)
6756 selname = build_keyword_selector (selnamelist);
6757 else
6758 abort ();
6759
6760 /* If we are required to check @selector() expressions as they
6761 are found, check that the selector has been declared. */
6762 if (warn_undeclared_selector)
6763 {
6764 /* Look the selector up in the list of all known class and
6765 instance methods (up to this line) to check that the selector
6766 exists. */
6767 hash hsh;
6768
6769 /* First try with instance methods. */
6770 hsh = hash_lookup (nst_method_hash_list, selname);
6771
6772 /* If not found, try with class methods. */
6773 if (!hsh)
6774 {
6775 hsh = hash_lookup (cls_method_hash_list, selname);
6776 }
6777
6778 /* If still not found, print out a warning. */
6779 if (!hsh)
6780 {
6781 warning (0, "undeclared selector %qE", selname);
6782 }
6783 }
6784
6785
6786 if (flag_typed_selectors)
6787 return build_typed_selector_reference (loc, selname, 0);
6788 else
6789 return build_selector_reference (loc, selname);
6790 }
6791
6792 tree
6793 objc_build_encode_expr (tree type)
6794 {
6795 tree result;
6796 const char *string;
6797
6798 encode_type (type, obstack_object_size (&util_obstack),
6799 OBJC_ENCODE_INLINE_DEFS);
6800 obstack_1grow (&util_obstack, 0); /* null terminate string */
6801 string = XOBFINISH (&util_obstack, const char *);
6802
6803 /* Synthesize a string that represents the encoded struct/union. */
6804 result = my_build_string (strlen (string) + 1, string);
6805 obstack_free (&util_obstack, util_firstobj);
6806 return result;
6807 }
6808
6809 static tree
6810 build_ivar_reference (tree id)
6811 {
6812 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
6813 {
6814 /* Historically, a class method that produced objects (factory
6815 method) would assign `self' to the instance that it
6816 allocated. This would effectively turn the class method into
6817 an instance method. Following this assignment, the instance
6818 variables could be accessed. That practice, while safe,
6819 violates the simple rule that a class method should not refer
6820 to an instance variable. It's better to catch the cases
6821 where this is done unknowingly than to support the above
6822 paradigm. */
6823 warning (0, "instance variable %qE accessed in class method",
6824 id);
6825 self_decl = convert (objc_instance_type, self_decl); /* cast */
6826 }
6827
6828 return objc_build_component_ref (build_indirect_ref (input_location,
6829 self_decl, "->"), id);
6830 }
6831 \f
6832 /* Compute a hash value for a given method SEL_NAME. */
6833
6834 static size_t
6835 hash_func (tree sel_name)
6836 {
6837 const unsigned char *s
6838 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
6839 size_t h = 0;
6840
6841 while (*s)
6842 h = h * 67 + *s++ - 113;
6843 return h;
6844 }
6845
6846 static void
6847 hash_init (void)
6848 {
6849 nst_method_hash_list
6850 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6851 cls_method_hash_list
6852 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6853
6854 /* Initialize the hash table used to hold the constant string objects. */
6855 string_htab = htab_create_ggc (31, string_hash,
6856 string_eq, NULL);
6857
6858 /* Initialize the hash table used to hold EH-volatilized types. */
6859 volatilized_htab = htab_create_ggc (31, volatilized_hash,
6860 volatilized_eq, NULL);
6861 }
6862
6863 /* WARNING!!!! hash_enter is called with a method, and will peek
6864 inside to find its selector! But hash_lookup is given a selector
6865 directly, and looks for the selector that's inside the found
6866 entry's key (method) for comparison. */
6867
6868 static void
6869 hash_enter (hash *hashlist, tree method)
6870 {
6871 hash obj;
6872 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6873
6874 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6875 obj->list = 0;
6876 obj->next = hashlist[slot];
6877 obj->key = method;
6878
6879 hashlist[slot] = obj; /* append to front */
6880 }
6881
6882 static hash
6883 hash_lookup (hash *hashlist, tree sel_name)
6884 {
6885 hash target;
6886
6887 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6888
6889 while (target)
6890 {
6891 if (sel_name == METHOD_SEL_NAME (target->key))
6892 return target;
6893
6894 target = target->next;
6895 }
6896 return 0;
6897 }
6898
6899 static void
6900 hash_add_attr (hash entry, tree value)
6901 {
6902 attr obj;
6903
6904 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6905 obj->next = entry->list;
6906 obj->value = value;
6907
6908 entry->list = obj; /* append to front */
6909 }
6910 \f
6911 static tree
6912 lookup_method (tree mchain, tree method)
6913 {
6914 tree key;
6915
6916 if (TREE_CODE (method) == IDENTIFIER_NODE)
6917 key = method;
6918 else
6919 key = METHOD_SEL_NAME (method);
6920
6921 while (mchain)
6922 {
6923 if (METHOD_SEL_NAME (mchain) == key)
6924 return mchain;
6925
6926 mchain = TREE_CHAIN (mchain);
6927 }
6928 return NULL_TREE;
6929 }
6930
6931 /* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
6932 in INTERFACE, along with any categories and protocols attached thereto.
6933 If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
6934 recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
6935 set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
6936 be found in INTERFACE or any of its superclasses, look for an _instance_
6937 method of the same name in the root class as a last resort.
6938
6939 If a suitable method cannot be found, return NULL_TREE. */
6940
6941 static tree
6942 lookup_method_static (tree interface, tree ident, int flags)
6943 {
6944 tree meth = NULL_TREE, root_inter = NULL_TREE;
6945 tree inter = interface;
6946 int is_class = (flags & OBJC_LOOKUP_CLASS);
6947 int no_superclasses = (flags & OBJC_LOOKUP_NO_SUPER);
6948
6949 while (inter)
6950 {
6951 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6952 tree category = inter;
6953
6954 /* First, look up the method in the class itself. */
6955 if ((meth = lookup_method (chain, ident)))
6956 return meth;
6957
6958 /* Failing that, look for the method in each category of the class. */
6959 while ((category = CLASS_CATEGORY_LIST (category)))
6960 {
6961 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6962
6963 /* Check directly in each category. */
6964 if ((meth = lookup_method (chain, ident)))
6965 return meth;
6966
6967 /* Failing that, check in each category's protocols. */
6968 if (CLASS_PROTOCOL_LIST (category))
6969 {
6970 if ((meth = (lookup_method_in_protocol_list
6971 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6972 return meth;
6973 }
6974 }
6975
6976 /* If not found in categories, check in protocols of the main class. */
6977 if (CLASS_PROTOCOL_LIST (inter))
6978 {
6979 if ((meth = (lookup_method_in_protocol_list
6980 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6981 return meth;
6982 }
6983
6984 /* If we were instructed not to look in superclasses, don't. */
6985 if (no_superclasses)
6986 return NULL_TREE;
6987
6988 /* Failing that, climb up the inheritance hierarchy. */
6989 root_inter = inter;
6990 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6991 }
6992 while (inter);
6993
6994 /* If no class (factory) method was found, check if an _instance_
6995 method of the same name exists in the root class. This is what
6996 the Objective-C runtime will do. If an instance method was not
6997 found, return 0. */
6998 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6999 }
7000
7001 /* Add the method to the hash list if it doesn't contain an identical
7002 method already. */
7003
7004 static void
7005 add_method_to_hash_list (hash *hash_list, tree method)
7006 {
7007 hash hsh;
7008
7009 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
7010 {
7011 /* Install on a global chain. */
7012 hash_enter (hash_list, method);
7013 }
7014 else
7015 {
7016 /* Check types against those; if different, add to a list. */
7017 attr loop;
7018 int already_there = comp_proto_with_proto (method, hsh->key, 1);
7019 for (loop = hsh->list; !already_there && loop; loop = loop->next)
7020 already_there |= comp_proto_with_proto (method, loop->value, 1);
7021 if (!already_there)
7022 hash_add_attr (hsh, method);
7023 }
7024 }
7025
7026 static tree
7027 objc_add_method (tree klass, tree method, int is_class)
7028 {
7029 tree mth;
7030
7031 if (!(mth = lookup_method (is_class
7032 ? CLASS_CLS_METHODS (klass)
7033 : CLASS_NST_METHODS (klass), method)))
7034 {
7035 /* put method on list in reverse order */
7036 if (is_class)
7037 {
7038 TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
7039 CLASS_CLS_METHODS (klass) = method;
7040 }
7041 else
7042 {
7043 TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
7044 CLASS_NST_METHODS (klass) = method;
7045 }
7046 }
7047 else
7048 {
7049 /* When processing an @interface for a class or category, give hard
7050 errors on methods with identical selectors but differing argument
7051 and/or return types. We do not do this for @implementations, because
7052 C/C++ will do it for us (i.e., there will be duplicate function
7053 definition errors). */
7054 if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
7055 || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
7056 && !comp_proto_with_proto (method, mth, 1))
7057 error ("duplicate declaration of method %<%c%E%>",
7058 is_class ? '+' : '-',
7059 METHOD_SEL_NAME (mth));
7060 }
7061
7062 if (is_class)
7063 add_method_to_hash_list (cls_method_hash_list, method);
7064 else
7065 {
7066 add_method_to_hash_list (nst_method_hash_list, method);
7067
7068 /* Instance methods in root classes (and categories thereof)
7069 may act as class methods as a last resort. We also add
7070 instance methods listed in @protocol declarations to
7071 the class hash table, on the assumption that @protocols
7072 may be adopted by root classes or categories. */
7073 if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
7074 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7075 klass = lookup_interface (CLASS_NAME (klass));
7076
7077 if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
7078 || !CLASS_SUPER_NAME (klass))
7079 add_method_to_hash_list (cls_method_hash_list, method);
7080 }
7081
7082 return method;
7083 }
7084
7085 static tree
7086 add_class (tree class_name, tree name)
7087 {
7088 struct interface_tuple **slot;
7089
7090 /* Put interfaces on list in reverse order. */
7091 TREE_CHAIN (class_name) = interface_chain;
7092 interface_chain = class_name;
7093
7094 if (interface_htab == NULL)
7095 interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
7096 slot = (struct interface_tuple **)
7097 htab_find_slot_with_hash (interface_htab, name,
7098 IDENTIFIER_HASH_VALUE (name),
7099 INSERT);
7100 if (!*slot)
7101 {
7102 *slot = (struct interface_tuple *) ggc_alloc_cleared (sizeof (struct interface_tuple));
7103 (*slot)->id = name;
7104 }
7105 (*slot)->class_name = class_name;
7106
7107 return interface_chain;
7108 }
7109
7110 static void
7111 add_category (tree klass, tree category)
7112 {
7113 /* Put categories on list in reverse order. */
7114 tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
7115
7116 if (cat)
7117 {
7118 warning (0, "duplicate interface declaration for category %<%E(%E)%>",
7119 CLASS_NAME (klass),
7120 CLASS_SUPER_NAME (category));
7121 }
7122 else
7123 {
7124 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
7125 CLASS_CATEGORY_LIST (klass) = category;
7126 }
7127 }
7128
7129 /* Called after parsing each instance variable declaration. Necessary to
7130 preserve typedefs and implement public/private...
7131
7132 VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
7133
7134 static tree
7135 add_instance_variable (tree klass, int visibility, tree field_decl)
7136 {
7137 tree field_type = TREE_TYPE (field_decl);
7138 const char *ivar_name = DECL_NAME (field_decl)
7139 ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
7140 : _("<unnamed>");
7141
7142 #ifdef OBJCPLUS
7143 if (TREE_CODE (field_type) == REFERENCE_TYPE)
7144 {
7145 error ("illegal reference type specified for instance variable %qs",
7146 ivar_name);
7147 /* Return class as is without adding this ivar. */
7148 return klass;
7149 }
7150 #endif
7151
7152 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
7153 || TYPE_SIZE (field_type) == error_mark_node)
7154 /* 'type[0]' is allowed, but 'type[]' is not! */
7155 {
7156 error ("instance variable %qs has unknown size", ivar_name);
7157 /* Return class as is without adding this ivar. */
7158 return klass;
7159 }
7160
7161 #ifdef OBJCPLUS
7162 /* Check if the ivar being added has a non-POD C++ type. If so, we will
7163 need to either (1) warn the user about it or (2) generate suitable
7164 constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
7165 methods (if '-fobjc-call-cxx-cdtors' was specified). */
7166 if (MAYBE_CLASS_TYPE_P (field_type)
7167 && (TYPE_NEEDS_CONSTRUCTING (field_type)
7168 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
7169 || TYPE_POLYMORPHIC_P (field_type)))
7170 {
7171 tree type_name = OBJC_TYPE_NAME (field_type);
7172
7173 if (flag_objc_call_cxx_cdtors)
7174 {
7175 /* Since the ObjC runtime will be calling the constructors and
7176 destructors for us, the only thing we can't handle is the lack
7177 of a default constructor. */
7178 if (TYPE_NEEDS_CONSTRUCTING (field_type)
7179 && !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
7180 {
7181 warning (0, "type %qE has no default constructor to call",
7182 type_name);
7183
7184 /* If we cannot call a constructor, we should also avoid
7185 calling the destructor, for symmetry. */
7186 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7187 warning (0, "destructor for %qE shall not be run either",
7188 type_name);
7189 }
7190 }
7191 else
7192 {
7193 static bool warn_cxx_ivars = false;
7194
7195 if (TYPE_POLYMORPHIC_P (field_type))
7196 {
7197 /* Vtable pointers are Real Bad(tm), since Obj-C cannot
7198 initialize them. */
7199 error ("type %qE has virtual member functions", type_name);
7200 error ("illegal aggregate type %qE specified "
7201 "for instance variable %qs",
7202 type_name, ivar_name);
7203 /* Return class as is without adding this ivar. */
7204 return klass;
7205 }
7206
7207 /* User-defined constructors and destructors are not known to Obj-C
7208 and hence will not be called. This may or may not be a problem. */
7209 if (TYPE_NEEDS_CONSTRUCTING (field_type))
7210 warning (0, "type %qE has a user-defined constructor", type_name);
7211 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
7212 warning (0, "type %qE has a user-defined destructor", type_name);
7213
7214 if (!warn_cxx_ivars)
7215 {
7216 warning (0, "C++ constructors and destructors will not "
7217 "be invoked for Objective-C fields");
7218 warn_cxx_ivars = true;
7219 }
7220 }
7221 }
7222 #endif
7223
7224 /* Overload the public attribute, it is not used for FIELD_DECLs. */
7225 switch (visibility)
7226 {
7227 case 0:
7228 TREE_PUBLIC (field_decl) = 0;
7229 TREE_PRIVATE (field_decl) = 0;
7230 TREE_PROTECTED (field_decl) = 1;
7231 break;
7232
7233 case 1:
7234 TREE_PUBLIC (field_decl) = 1;
7235 TREE_PRIVATE (field_decl) = 0;
7236 TREE_PROTECTED (field_decl) = 0;
7237 break;
7238
7239 case 2:
7240 TREE_PUBLIC (field_decl) = 0;
7241 TREE_PRIVATE (field_decl) = 1;
7242 TREE_PROTECTED (field_decl) = 0;
7243 break;
7244
7245 }
7246
7247 CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
7248
7249 return klass;
7250 }
7251 \f
7252 static tree
7253 is_ivar (tree decl_chain, tree ident)
7254 {
7255 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
7256 if (DECL_NAME (decl_chain) == ident)
7257 return decl_chain;
7258 return NULL_TREE;
7259 }
7260
7261 /* True if the ivar is private and we are not in its implementation. */
7262
7263 static int
7264 is_private (tree decl)
7265 {
7266 return (TREE_PRIVATE (decl)
7267 && ! is_ivar (CLASS_IVARS (implementation_template),
7268 DECL_NAME (decl)));
7269 }
7270
7271 /* We have an instance variable reference;, check to see if it is public. */
7272
7273 int
7274 objc_is_public (tree expr, tree identifier)
7275 {
7276 tree basetype, decl;
7277
7278 #ifdef OBJCPLUS
7279 if (processing_template_decl)
7280 return 1;
7281 #endif
7282
7283 if (TREE_TYPE (expr) == error_mark_node)
7284 return 1;
7285
7286 basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
7287
7288 if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
7289 {
7290 if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
7291 {
7292 tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
7293
7294 if (!klass)
7295 {
7296 error ("cannot find interface declaration for %qE",
7297 OBJC_TYPE_NAME (basetype));
7298 return 0;
7299 }
7300
7301 if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
7302 {
7303 if (TREE_PUBLIC (decl))
7304 return 1;
7305
7306 /* Important difference between the Stepstone translator:
7307 all instance variables should be public within the context
7308 of the implementation. */
7309 if (objc_implementation_context
7310 && ((TREE_CODE (objc_implementation_context)
7311 == CLASS_IMPLEMENTATION_TYPE)
7312 || (TREE_CODE (objc_implementation_context)
7313 == CATEGORY_IMPLEMENTATION_TYPE)))
7314 {
7315 tree curtype = TYPE_MAIN_VARIANT
7316 (CLASS_STATIC_TEMPLATE
7317 (implementation_template));
7318
7319 if (basetype == curtype
7320 || DERIVED_FROM_P (basetype, curtype))
7321 {
7322 int priv = is_private (decl);
7323
7324 if (priv)
7325 error ("instance variable %qE is declared private",
7326 DECL_NAME (decl));
7327
7328 return !priv;
7329 }
7330 }
7331
7332 /* The 2.95.2 compiler sometimes allowed C functions to access
7333 non-@public ivars. We will let this slide for now... */
7334 if (!objc_method_context)
7335 {
7336 warning (0, "instance variable %qE is %s; "
7337 "this will be a hard error in the future",
7338 identifier,
7339 TREE_PRIVATE (decl) ? "@private" : "@protected");
7340 return 1;
7341 }
7342
7343 error ("instance variable %qE is declared %s",
7344 identifier,
7345 TREE_PRIVATE (decl) ? "private" : "protected");
7346 return 0;
7347 }
7348 }
7349 }
7350
7351 return 1;
7352 }
7353 \f
7354 /* Make sure all entries in CHAIN are also in LIST. */
7355
7356 static int
7357 check_methods (tree chain, tree list, int mtype)
7358 {
7359 int first = 1;
7360
7361 while (chain)
7362 {
7363 if (!lookup_method (list, chain))
7364 {
7365 if (first)
7366 {
7367 if (TREE_CODE (objc_implementation_context)
7368 == CLASS_IMPLEMENTATION_TYPE)
7369 warning (0, "incomplete implementation of class %qE",
7370 CLASS_NAME (objc_implementation_context));
7371 else if (TREE_CODE (objc_implementation_context)
7372 == CATEGORY_IMPLEMENTATION_TYPE)
7373 warning (0, "incomplete implementation of category %qE",
7374 CLASS_SUPER_NAME (objc_implementation_context));
7375 first = 0;
7376 }
7377
7378 warning (0, "method definition for %<%c%E%> not found",
7379 mtype, METHOD_SEL_NAME (chain));
7380 }
7381
7382 chain = TREE_CHAIN (chain);
7383 }
7384
7385 return first;
7386 }
7387
7388 /* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
7389
7390 static int
7391 conforms_to_protocol (tree klass, tree protocol)
7392 {
7393 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
7394 {
7395 tree p = CLASS_PROTOCOL_LIST (klass);
7396 while (p && TREE_VALUE (p) != protocol)
7397 p = TREE_CHAIN (p);
7398
7399 if (!p)
7400 {
7401 tree super = (CLASS_SUPER_NAME (klass)
7402 ? lookup_interface (CLASS_SUPER_NAME (klass))
7403 : NULL_TREE);
7404 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
7405 if (!tmp)
7406 return 0;
7407 }
7408 }
7409
7410 return 1;
7411 }
7412
7413 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
7414 CONTEXT. This is one of two mechanisms to check protocol integrity. */
7415
7416 static int
7417 check_methods_accessible (tree chain, tree context, int mtype)
7418 {
7419 int first = 1;
7420 tree list;
7421 tree base_context = context;
7422
7423 while (chain)
7424 {
7425 context = base_context;
7426 while (context)
7427 {
7428 if (mtype == '+')
7429 list = CLASS_CLS_METHODS (context);
7430 else
7431 list = CLASS_NST_METHODS (context);
7432
7433 if (lookup_method (list, chain))
7434 break;
7435
7436 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
7437 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
7438 context = (CLASS_SUPER_NAME (context)
7439 ? lookup_interface (CLASS_SUPER_NAME (context))
7440 : NULL_TREE);
7441
7442 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
7443 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
7444 context = (CLASS_NAME (context)
7445 ? lookup_interface (CLASS_NAME (context))
7446 : NULL_TREE);
7447 else
7448 abort ();
7449 }
7450
7451 if (context == NULL_TREE)
7452 {
7453 if (first)
7454 {
7455 if (TREE_CODE (objc_implementation_context)
7456 == CLASS_IMPLEMENTATION_TYPE)
7457 warning (0, "incomplete implementation of class %qE",
7458 CLASS_NAME (objc_implementation_context));
7459 else if (TREE_CODE (objc_implementation_context)
7460 == CATEGORY_IMPLEMENTATION_TYPE)
7461 warning (0, "incomplete implementation of category %qE",
7462 CLASS_SUPER_NAME (objc_implementation_context));
7463 first = 0;
7464 }
7465 warning (0, "method definition for %<%c%E%> not found",
7466 mtype, METHOD_SEL_NAME (chain));
7467 }
7468
7469 chain = TREE_CHAIN (chain); /* next method... */
7470 }
7471 return first;
7472 }
7473
7474 /* Check whether the current interface (accessible via
7475 'objc_implementation_context') actually implements protocol P, along
7476 with any protocols that P inherits. */
7477
7478 static void
7479 check_protocol (tree p, const char *type, tree name)
7480 {
7481 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
7482 {
7483 int f1, f2;
7484
7485 /* Ensure that all protocols have bodies! */
7486 if (warn_protocol)
7487 {
7488 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
7489 CLASS_CLS_METHODS (objc_implementation_context),
7490 '+');
7491 f2 = check_methods (PROTOCOL_NST_METHODS (p),
7492 CLASS_NST_METHODS (objc_implementation_context),
7493 '-');
7494 }
7495 else
7496 {
7497 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
7498 objc_implementation_context,
7499 '+');
7500 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
7501 objc_implementation_context,
7502 '-');
7503 }
7504
7505 if (!f1 || !f2)
7506 warning (0, "%s %qE does not fully implement the %qE protocol",
7507 type, name, PROTOCOL_NAME (p));
7508 }
7509
7510 /* Check protocols recursively. */
7511 if (PROTOCOL_LIST (p))
7512 {
7513 tree subs = PROTOCOL_LIST (p);
7514 tree super_class =
7515 lookup_interface (CLASS_SUPER_NAME (implementation_template));
7516
7517 while (subs)
7518 {
7519 tree sub = TREE_VALUE (subs);
7520
7521 /* If the superclass does not conform to the protocols
7522 inherited by P, then we must! */
7523 if (!super_class || !conforms_to_protocol (super_class, sub))
7524 check_protocol (sub, type, name);
7525 subs = TREE_CHAIN (subs);
7526 }
7527 }
7528 }
7529
7530 /* Check whether the current interface (accessible via
7531 'objc_implementation_context') actually implements the protocols listed
7532 in PROTO_LIST. */
7533
7534 static void
7535 check_protocols (tree proto_list, const char *type, tree name)
7536 {
7537 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
7538 {
7539 tree p = TREE_VALUE (proto_list);
7540
7541 check_protocol (p, type, name);
7542 }
7543 }
7544 \f
7545 /* Make sure that the class CLASS_NAME is defined
7546 CODE says which kind of thing CLASS_NAME ought to be.
7547 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
7548 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
7549
7550 static tree
7551 start_class (enum tree_code code, tree class_name, tree super_name,
7552 tree protocol_list)
7553 {
7554 tree klass, decl;
7555
7556 #ifdef OBJCPLUS
7557 if (current_namespace != global_namespace) {
7558 error ("Objective-C declarations may only appear in global scope");
7559 }
7560 #endif /* OBJCPLUS */
7561
7562 if (objc_implementation_context)
7563 {
7564 warning (0, "%<@end%> missing in implementation context");
7565 finish_class (objc_implementation_context);
7566 objc_ivar_chain = NULL_TREE;
7567 objc_implementation_context = NULL_TREE;
7568 }
7569
7570 klass = make_node (code);
7571 TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
7572
7573 /* Check for existence of the super class, if one was specified. Note
7574 that we must have seen an @interface, not just a @class. If we
7575 are looking at a @compatibility_alias, traverse it first. */
7576 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
7577 && super_name)
7578 {
7579 tree super = objc_is_class_name (super_name);
7580
7581 if (!super || !lookup_interface (super))
7582 {
7583 error ("cannot find interface declaration for %qE, superclass of %qE",
7584 super ? super : super_name,
7585 class_name);
7586 super_name = NULL_TREE;
7587 }
7588 else
7589 super_name = super;
7590 }
7591
7592 CLASS_NAME (klass) = class_name;
7593 CLASS_SUPER_NAME (klass) = super_name;
7594 CLASS_CLS_METHODS (klass) = NULL_TREE;
7595
7596 if (! objc_is_class_name (class_name)
7597 && (decl = lookup_name (class_name)))
7598 {
7599 error ("%qE redeclared as different kind of symbol",
7600 class_name);
7601 error ("previous declaration of %q+D",
7602 decl);
7603 }
7604
7605 if (code == CLASS_IMPLEMENTATION_TYPE)
7606 {
7607 {
7608 tree chain;
7609
7610 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
7611 if (TREE_VALUE (chain) == class_name)
7612 {
7613 error ("reimplementation of class %qE",
7614 class_name);
7615 return error_mark_node;
7616 }
7617 implemented_classes = tree_cons (NULL_TREE, class_name,
7618 implemented_classes);
7619 }
7620
7621 /* Reset for multiple classes per file. */
7622 method_slot = 0;
7623
7624 objc_implementation_context = klass;
7625
7626 /* Lookup the interface for this implementation. */
7627
7628 if (!(implementation_template = lookup_interface (class_name)))
7629 {
7630 warning (0, "cannot find interface declaration for %qE",
7631 class_name);
7632 add_class (implementation_template = objc_implementation_context,
7633 class_name);
7634 }
7635
7636 /* If a super class has been specified in the implementation,
7637 insure it conforms to the one specified in the interface. */
7638
7639 if (super_name
7640 && (super_name != CLASS_SUPER_NAME (implementation_template)))
7641 {
7642 tree previous_name = CLASS_SUPER_NAME (implementation_template);
7643 error ("conflicting super class name %qE",
7644 super_name);
7645 if (previous_name)
7646 error ("previous declaration of %qE", previous_name);
7647 else
7648 error ("previous declaration");
7649 }
7650
7651 else if (! super_name)
7652 {
7653 CLASS_SUPER_NAME (objc_implementation_context)
7654 = CLASS_SUPER_NAME (implementation_template);
7655 }
7656 }
7657
7658 else if (code == CLASS_INTERFACE_TYPE)
7659 {
7660 if (lookup_interface (class_name))
7661 #ifdef OBJCPLUS
7662 error ("duplicate interface declaration for class %qE",
7663 #else
7664 warning (0, "duplicate interface declaration for class %qE",
7665 #endif
7666 class_name);
7667 else
7668 add_class (klass, class_name);
7669
7670 if (protocol_list)
7671 CLASS_PROTOCOL_LIST (klass)
7672 = lookup_and_install_protocols (protocol_list);
7673 }
7674
7675 else if (code == CATEGORY_INTERFACE_TYPE)
7676 {
7677 tree class_category_is_assoc_with;
7678
7679 /* For a category, class_name is really the name of the class that
7680 the following set of methods will be associated with. We must
7681 find the interface so that can derive the objects template. */
7682
7683 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
7684 {
7685 error ("cannot find interface declaration for %qE",
7686 class_name);
7687 exit (FATAL_EXIT_CODE);
7688 }
7689 else
7690 add_category (class_category_is_assoc_with, klass);
7691
7692 if (protocol_list)
7693 CLASS_PROTOCOL_LIST (klass)
7694 = lookup_and_install_protocols (protocol_list);
7695 }
7696
7697 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
7698 {
7699 /* Reset for multiple classes per file. */
7700 method_slot = 0;
7701
7702 objc_implementation_context = klass;
7703
7704 /* For a category, class_name is really the name of the class that
7705 the following set of methods will be associated with. We must
7706 find the interface so that can derive the objects template. */
7707
7708 if (!(implementation_template = lookup_interface (class_name)))
7709 {
7710 error ("cannot find interface declaration for %qE",
7711 class_name);
7712 exit (FATAL_EXIT_CODE);
7713 }
7714 }
7715 return klass;
7716 }
7717
7718 static tree
7719 continue_class (tree klass)
7720 {
7721 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
7722 || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7723 {
7724 struct imp_entry *imp_entry;
7725
7726 /* Check consistency of the instance variables. */
7727
7728 if (CLASS_RAW_IVARS (klass))
7729 check_ivars (implementation_template, klass);
7730
7731 /* code generation */
7732
7733 #ifdef OBJCPLUS
7734 push_lang_context (lang_name_c);
7735 #endif
7736
7737 build_private_template (implementation_template);
7738 uprivate_record = CLASS_STATIC_TEMPLATE (implementation_template);
7739 objc_instance_type = build_pointer_type (uprivate_record);
7740
7741 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
7742
7743 imp_entry->next = imp_list;
7744 imp_entry->imp_context = klass;
7745 imp_entry->imp_template = implementation_template;
7746
7747 synth_forward_declarations ();
7748 imp_entry->class_decl = UOBJC_CLASS_decl;
7749 imp_entry->meta_decl = UOBJC_METACLASS_decl;
7750 imp_entry->has_cxx_cdtors = 0;
7751
7752 /* Append to front and increment count. */
7753 imp_list = imp_entry;
7754 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7755 imp_count++;
7756 else
7757 cat_count++;
7758
7759 #ifdef OBJCPLUS
7760 pop_lang_context ();
7761 #endif /* OBJCPLUS */
7762
7763 return get_class_ivars (implementation_template, true);
7764 }
7765
7766 else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
7767 {
7768 #ifdef OBJCPLUS
7769 push_lang_context (lang_name_c);
7770 #endif /* OBJCPLUS */
7771
7772 build_private_template (klass);
7773
7774 #ifdef OBJCPLUS
7775 pop_lang_context ();
7776 #endif /* OBJCPLUS */
7777
7778 return NULL_TREE;
7779 }
7780
7781 else
7782 return error_mark_node;
7783 }
7784
7785 /* This is called once we see the "@end" in an interface/implementation. */
7786
7787 static void
7788 finish_class (tree klass)
7789 {
7790 if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
7791 {
7792 /* All code generation is done in finish_objc. */
7793
7794 if (implementation_template != objc_implementation_context)
7795 {
7796 /* Ensure that all method listed in the interface contain bodies. */
7797 check_methods (CLASS_CLS_METHODS (implementation_template),
7798 CLASS_CLS_METHODS (objc_implementation_context), '+');
7799 check_methods (CLASS_NST_METHODS (implementation_template),
7800 CLASS_NST_METHODS (objc_implementation_context), '-');
7801
7802 if (CLASS_PROTOCOL_LIST (implementation_template))
7803 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
7804 "class",
7805 CLASS_NAME (objc_implementation_context));
7806 }
7807 }
7808
7809 else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
7810 {
7811 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
7812
7813 if (category)
7814 {
7815 /* Ensure all method listed in the interface contain bodies. */
7816 check_methods (CLASS_CLS_METHODS (category),
7817 CLASS_CLS_METHODS (objc_implementation_context), '+');
7818 check_methods (CLASS_NST_METHODS (category),
7819 CLASS_NST_METHODS (objc_implementation_context), '-');
7820
7821 if (CLASS_PROTOCOL_LIST (category))
7822 check_protocols (CLASS_PROTOCOL_LIST (category),
7823 "category",
7824 CLASS_SUPER_NAME (objc_implementation_context));
7825 }
7826 }
7827 }
7828
7829 static tree
7830 add_protocol (tree protocol)
7831 {
7832 /* Put protocol on list in reverse order. */
7833 TREE_CHAIN (protocol) = protocol_chain;
7834 protocol_chain = protocol;
7835 return protocol_chain;
7836 }
7837
7838 static tree
7839 lookup_protocol (tree ident)
7840 {
7841 tree chain;
7842
7843 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
7844 if (ident == PROTOCOL_NAME (chain))
7845 return chain;
7846
7847 return NULL_TREE;
7848 }
7849
7850 /* This function forward declares the protocols named by NAMES. If
7851 they are already declared or defined, the function has no effect. */
7852
7853 void
7854 objc_declare_protocols (tree names)
7855 {
7856 tree list;
7857
7858 #ifdef OBJCPLUS
7859 if (current_namespace != global_namespace) {
7860 error ("Objective-C declarations may only appear in global scope");
7861 }
7862 #endif /* OBJCPLUS */
7863
7864 for (list = names; list; list = TREE_CHAIN (list))
7865 {
7866 tree name = TREE_VALUE (list);
7867
7868 if (lookup_protocol (name) == NULL_TREE)
7869 {
7870 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
7871
7872 TYPE_LANG_SLOT_1 (protocol)
7873 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7874 PROTOCOL_NAME (protocol) = name;
7875 PROTOCOL_LIST (protocol) = NULL_TREE;
7876 add_protocol (protocol);
7877 PROTOCOL_DEFINED (protocol) = 0;
7878 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7879 }
7880 }
7881 }
7882
7883 static tree
7884 start_protocol (enum tree_code code, tree name, tree list)
7885 {
7886 tree protocol;
7887
7888 #ifdef OBJCPLUS
7889 if (current_namespace != global_namespace) {
7890 error ("Objective-C declarations may only appear in global scope");
7891 }
7892 #endif /* OBJCPLUS */
7893
7894 protocol = lookup_protocol (name);
7895
7896 if (!protocol)
7897 {
7898 protocol = make_node (code);
7899 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
7900
7901 PROTOCOL_NAME (protocol) = name;
7902 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7903 add_protocol (protocol);
7904 PROTOCOL_DEFINED (protocol) = 1;
7905 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
7906
7907 check_protocol_recursively (protocol, list);
7908 }
7909 else if (! PROTOCOL_DEFINED (protocol))
7910 {
7911 PROTOCOL_DEFINED (protocol) = 1;
7912 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
7913
7914 check_protocol_recursively (protocol, list);
7915 }
7916 else
7917 {
7918 warning (0, "duplicate declaration for protocol %qE",
7919 name);
7920 }
7921 return protocol;
7922 }
7923
7924 \f
7925 /* "Encode" a data type into a string, which grows in util_obstack.
7926 ??? What is the FORMAT? Someone please document this! */
7927
7928 static void
7929 encode_type_qualifiers (tree declspecs)
7930 {
7931 tree spec;
7932
7933 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
7934 {
7935 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
7936 obstack_1grow (&util_obstack, 'n');
7937 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
7938 obstack_1grow (&util_obstack, 'N');
7939 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
7940 obstack_1grow (&util_obstack, 'o');
7941 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7942 obstack_1grow (&util_obstack, 'O');
7943 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7944 obstack_1grow (&util_obstack, 'R');
7945 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7946 obstack_1grow (&util_obstack, 'V');
7947 }
7948 }
7949
7950 /* Encode a pointer type. */
7951
7952 static void
7953 encode_pointer (tree type, int curtype, int format)
7954 {
7955 tree pointer_to = TREE_TYPE (type);
7956
7957 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7958 {
7959 if (OBJC_TYPE_NAME (pointer_to)
7960 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7961 {
7962 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7963
7964 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7965 {
7966 obstack_1grow (&util_obstack, '@');
7967 return;
7968 }
7969 else if (TYPE_HAS_OBJC_INFO (pointer_to)
7970 && TYPE_OBJC_INTERFACE (pointer_to))
7971 {
7972 if (generating_instance_variables)
7973 {
7974 obstack_1grow (&util_obstack, '@');
7975 obstack_1grow (&util_obstack, '"');
7976 obstack_grow (&util_obstack, name, strlen (name));
7977 obstack_1grow (&util_obstack, '"');
7978 return;
7979 }
7980 else
7981 {
7982 obstack_1grow (&util_obstack, '@');
7983 return;
7984 }
7985 }
7986 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7987 {
7988 obstack_1grow (&util_obstack, '#');
7989 return;
7990 }
7991 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7992 {
7993 obstack_1grow (&util_obstack, ':');
7994 return;
7995 }
7996 }
7997 }
7998 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7999 && TYPE_MODE (pointer_to) == QImode)
8000 {
8001 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
8002 ? OBJC_TYPE_NAME (pointer_to)
8003 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
8004
8005 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
8006 {
8007 /* It appears that "r*" means "const char *" rather than
8008 "char *const". */
8009 if (TYPE_READONLY (pointer_to))
8010 obstack_1grow (&util_obstack, 'r');
8011
8012 obstack_1grow (&util_obstack, '*');
8013 return;
8014 }
8015 }
8016
8017 /* We have a type that does not get special treatment. */
8018
8019 /* NeXT extension */
8020 obstack_1grow (&util_obstack, '^');
8021 encode_type (pointer_to, curtype, format);
8022 }
8023
8024 static void
8025 encode_array (tree type, int curtype, int format)
8026 {
8027 tree an_int_cst = TYPE_SIZE (type);
8028 tree array_of = TREE_TYPE (type);
8029 char buffer[40];
8030
8031 /* An incomplete array is treated like a pointer. */
8032 if (an_int_cst == NULL)
8033 {
8034 encode_pointer (type, curtype, format);
8035 return;
8036 }
8037
8038 if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
8039 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
8040 else
8041 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
8042 TREE_INT_CST_LOW (an_int_cst)
8043 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
8044
8045 obstack_grow (&util_obstack, buffer, strlen (buffer));
8046 encode_type (array_of, curtype, format);
8047 obstack_1grow (&util_obstack, ']');
8048 return;
8049 }
8050 \f
8051 static void
8052 encode_aggregate_fields (tree type, int pointed_to, int curtype, int format)
8053 {
8054 tree field = TYPE_FIELDS (type);
8055
8056 for (; field; field = TREE_CHAIN (field))
8057 {
8058 #ifdef OBJCPLUS
8059 /* C++ static members, and things that are not field at all,
8060 should not appear in the encoding. */
8061 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
8062 continue;
8063 #endif
8064
8065 /* Recursively encode fields of embedded base classes. */
8066 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
8067 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
8068 {
8069 encode_aggregate_fields (TREE_TYPE (field),
8070 pointed_to, curtype, format);
8071 continue;
8072 }
8073
8074 if (generating_instance_variables && !pointed_to)
8075 {
8076 tree fname = DECL_NAME (field);
8077
8078 obstack_1grow (&util_obstack, '"');
8079
8080 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
8081 obstack_grow (&util_obstack,
8082 IDENTIFIER_POINTER (fname),
8083 strlen (IDENTIFIER_POINTER (fname)));
8084
8085 obstack_1grow (&util_obstack, '"');
8086 }
8087
8088 encode_field_decl (field, curtype, format);
8089 }
8090 }
8091
8092 static void
8093 encode_aggregate_within (tree type, int curtype, int format, int left,
8094 int right)
8095 {
8096 tree name;
8097 /* NB: aggregates that are pointed to have slightly different encoding
8098 rules in that you never encode the names of instance variables. */
8099 int ob_size = obstack_object_size (&util_obstack);
8100 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
8101 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
8102 int pointed_to = (c0 == '^' || (c1 == '^' && c0 == 'r'));
8103 int inline_contents
8104 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
8105 && (!pointed_to || ob_size - curtype == (c1 == 'r' ? 2 : 1)));
8106
8107 /* Traverse struct aliases; it is important to get the
8108 original struct and its tag name (if any). */
8109 type = TYPE_MAIN_VARIANT (type);
8110 name = OBJC_TYPE_NAME (type);
8111 /* Open parenth/bracket. */
8112 obstack_1grow (&util_obstack, left);
8113
8114 /* Encode the struct/union tag name, or '?' if a tag was
8115 not provided. Typedef aliases do not qualify. */
8116 if (name && TREE_CODE (name) == IDENTIFIER_NODE
8117 #ifdef OBJCPLUS
8118 /* Did this struct have a tag? */
8119 && !TYPE_WAS_ANONYMOUS (type)
8120 #endif
8121 )
8122 obstack_grow (&util_obstack,
8123 IDENTIFIER_POINTER (name),
8124 strlen (IDENTIFIER_POINTER (name)));
8125 else
8126 obstack_1grow (&util_obstack, '?');
8127
8128 /* Encode the types (and possibly names) of the inner fields,
8129 if required. */
8130 if (inline_contents)
8131 {
8132 obstack_1grow (&util_obstack, '=');
8133 encode_aggregate_fields (type, pointed_to, curtype, format);
8134 }
8135 /* Close parenth/bracket. */
8136 obstack_1grow (&util_obstack, right);
8137 }
8138
8139 static void
8140 encode_aggregate (tree type, int curtype, int format)
8141 {
8142 enum tree_code code = TREE_CODE (type);
8143
8144 switch (code)
8145 {
8146 case RECORD_TYPE:
8147 {
8148 encode_aggregate_within (type, curtype, format, '{', '}');
8149 break;
8150 }
8151 case UNION_TYPE:
8152 {
8153 encode_aggregate_within (type, curtype, format, '(', ')');
8154 break;
8155 }
8156
8157 case ENUMERAL_TYPE:
8158 obstack_1grow (&util_obstack, 'i');
8159 break;
8160
8161 default:
8162 break;
8163 }
8164 }
8165
8166 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
8167 field type. */
8168
8169 static void
8170 encode_next_bitfield (int width)
8171 {
8172 char buffer[40];
8173 sprintf (buffer, "b%d", width);
8174 obstack_grow (&util_obstack, buffer, strlen (buffer));
8175 }
8176 \f
8177 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
8178 static void
8179 encode_type (tree type, int curtype, int format)
8180 {
8181 enum tree_code code = TREE_CODE (type);
8182 char c;
8183
8184 if (type == error_mark_node)
8185 return;
8186
8187 if (TYPE_READONLY (type))
8188 obstack_1grow (&util_obstack, 'r');
8189
8190 if (code == INTEGER_TYPE)
8191 {
8192 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8193 {
8194 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
8195 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
8196 case 32:
8197 if (type == long_unsigned_type_node
8198 || type == long_integer_type_node)
8199 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
8200 else
8201 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
8202 break;
8203 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
8204 default: abort ();
8205 }
8206 obstack_1grow (&util_obstack, c);
8207 }
8208
8209 else if (code == REAL_TYPE)
8210 {
8211 /* Floating point types. */
8212 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
8213 {
8214 case 32: c = 'f'; break;
8215 case 64:
8216 case 96:
8217 case 128: c = 'd'; break;
8218 default: abort ();
8219 }
8220 obstack_1grow (&util_obstack, c);
8221 }
8222
8223 else if (code == VOID_TYPE)
8224 obstack_1grow (&util_obstack, 'v');
8225
8226 else if (code == BOOLEAN_TYPE)
8227 obstack_1grow (&util_obstack, 'B');
8228
8229 else if (code == ARRAY_TYPE)
8230 encode_array (type, curtype, format);
8231
8232 else if (code == POINTER_TYPE)
8233 encode_pointer (type, curtype, format);
8234
8235 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
8236 encode_aggregate (type, curtype, format);
8237
8238 else if (code == FUNCTION_TYPE) /* '?' */
8239 obstack_1grow (&util_obstack, '?');
8240
8241 else if (code == COMPLEX_TYPE)
8242 {
8243 obstack_1grow (&util_obstack, 'j');
8244 encode_type (TREE_TYPE (type), curtype, format);
8245 }
8246 }
8247
8248 static void
8249 encode_gnu_bitfield (int position, tree type, int size)
8250 {
8251 enum tree_code code = TREE_CODE (type);
8252 char buffer[40];
8253 char charType = '?';
8254
8255 if (code == INTEGER_TYPE)
8256 {
8257 if (integer_zerop (TYPE_MIN_VALUE (type)))
8258 {
8259 /* Unsigned integer types. */
8260
8261 if (TYPE_MODE (type) == QImode)
8262 charType = 'C';
8263 else if (TYPE_MODE (type) == HImode)
8264 charType = 'S';
8265 else if (TYPE_MODE (type) == SImode)
8266 {
8267 if (type == long_unsigned_type_node)
8268 charType = 'L';
8269 else
8270 charType = 'I';
8271 }
8272 else if (TYPE_MODE (type) == DImode)
8273 charType = 'Q';
8274 }
8275
8276 else
8277 /* Signed integer types. */
8278 {
8279 if (TYPE_MODE (type) == QImode)
8280 charType = 'c';
8281 else if (TYPE_MODE (type) == HImode)
8282 charType = 's';
8283 else if (TYPE_MODE (type) == SImode)
8284 {
8285 if (type == long_integer_type_node)
8286 charType = 'l';
8287 else
8288 charType = 'i';
8289 }
8290
8291 else if (TYPE_MODE (type) == DImode)
8292 charType = 'q';
8293 }
8294 }
8295 else if (code == ENUMERAL_TYPE)
8296 charType = 'i';
8297 else
8298 abort ();
8299
8300 sprintf (buffer, "b%d%c%d", position, charType, size);
8301 obstack_grow (&util_obstack, buffer, strlen (buffer));
8302 }
8303
8304 static void
8305 encode_field_decl (tree field_decl, int curtype, int format)
8306 {
8307 tree type;
8308
8309 #ifdef OBJCPLUS
8310 /* C++ static members, and things that are not fields at all,
8311 should not appear in the encoding. */
8312 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
8313 return;
8314 #endif
8315
8316 type = TREE_TYPE (field_decl);
8317
8318 /* Generate the bitfield typing information, if needed. Note the difference
8319 between GNU and NeXT runtimes. */
8320 if (DECL_BIT_FIELD_TYPE (field_decl))
8321 {
8322 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
8323
8324 if (flag_next_runtime)
8325 encode_next_bitfield (size);
8326 else
8327 encode_gnu_bitfield (int_bit_position (field_decl),
8328 DECL_BIT_FIELD_TYPE (field_decl), size);
8329 }
8330 else
8331 encode_type (TREE_TYPE (field_decl), curtype, format);
8332 }
8333
8334 static GTY(()) tree objc_parmlist = NULL_TREE;
8335
8336 /* Append PARM to a list of formal parameters of a method, making a necessary
8337 array-to-pointer adjustment along the way. */
8338
8339 static void
8340 objc_push_parm (tree parm)
8341 {
8342 bool relayout_needed = false;
8343
8344 if (TREE_TYPE (parm) == error_mark_node)
8345 {
8346 objc_parmlist = chainon (objc_parmlist, parm);
8347 return;
8348 }
8349
8350 /* Decay arrays and functions into pointers. */
8351 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
8352 {
8353 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
8354 relayout_needed = true;
8355 }
8356 else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
8357 {
8358 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
8359 relayout_needed = true;
8360 }
8361
8362 if (relayout_needed)
8363 relayout_decl (parm);
8364
8365
8366 DECL_ARG_TYPE (parm)
8367 = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
8368
8369 /* Record constancy and volatility. */
8370 c_apply_type_quals_to_decl
8371 ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
8372 | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
8373 | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
8374
8375 objc_parmlist = chainon (objc_parmlist, parm);
8376 }
8377
8378 /* Retrieve the formal parameter list constructed via preceding calls to
8379 objc_push_parm(). */
8380
8381 #ifdef OBJCPLUS
8382 static tree
8383 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
8384 #else
8385 static struct c_arg_info *
8386 objc_get_parm_info (int have_ellipsis)
8387 #endif
8388 {
8389 #ifdef OBJCPLUS
8390 tree parm_info = objc_parmlist;
8391 objc_parmlist = NULL_TREE;
8392
8393 return parm_info;
8394 #else
8395 tree parm_info = objc_parmlist;
8396 struct c_arg_info *arg_info;
8397 /* The C front-end requires an elaborate song and dance at
8398 this point. */
8399 push_scope ();
8400 declare_parm_level ();
8401 while (parm_info)
8402 {
8403 tree next = TREE_CHAIN (parm_info);
8404
8405 TREE_CHAIN (parm_info) = NULL_TREE;
8406 parm_info = pushdecl (parm_info);
8407 finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
8408 parm_info = next;
8409 }
8410 arg_info = get_parm_info (have_ellipsis);
8411 pop_scope ();
8412 objc_parmlist = NULL_TREE;
8413 return arg_info;
8414 #endif
8415 }
8416
8417 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
8418 method definitions. In the case of instance methods, we can be more
8419 specific as to the type of 'self'. */
8420
8421 static void
8422 synth_self_and_ucmd_args (void)
8423 {
8424 tree self_type;
8425
8426 if (objc_method_context
8427 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
8428 self_type = objc_instance_type;
8429 else
8430 /* Really a `struct objc_class *'. However, we allow people to
8431 assign to self, which changes its type midstream. */
8432 self_type = objc_object_type;
8433
8434 /* id self; */
8435 objc_push_parm (build_decl (input_location,
8436 PARM_DECL, self_id, self_type));
8437
8438 /* SEL _cmd; */
8439 objc_push_parm (build_decl (input_location,
8440 PARM_DECL, ucmd_id, objc_selector_type));
8441 }
8442
8443 /* Transform an Objective-C method definition into a static C function
8444 definition, synthesizing the first two arguments, "self" and "_cmd",
8445 in the process. */
8446
8447 static void
8448 start_method_def (tree method)
8449 {
8450 tree parmlist;
8451 #ifdef OBJCPLUS
8452 tree parm_info;
8453 #else
8454 struct c_arg_info *parm_info;
8455 #endif
8456 int have_ellipsis = 0;
8457
8458 /* If we are defining a "dealloc" method in a non-root class, we
8459 will need to check if a [super dealloc] is missing, and warn if
8460 it is. */
8461 if(CLASS_SUPER_NAME (objc_implementation_context)
8462 && !strcmp ("dealloc", IDENTIFIER_POINTER (METHOD_SEL_NAME (method))))
8463 should_call_super_dealloc = 1;
8464 else
8465 should_call_super_dealloc = 0;
8466
8467 /* Required to implement _msgSuper. */
8468 objc_method_context = method;
8469 UOBJC_SUPER_decl = NULL_TREE;
8470
8471 /* Generate prototype declarations for arguments..."new-style". */
8472 synth_self_and_ucmd_args ();
8473
8474 /* Generate argument declarations if a keyword_decl. */
8475 parmlist = METHOD_SEL_ARGS (method);
8476 while (parmlist)
8477 {
8478 tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
8479
8480 parm = build_decl (input_location,
8481 PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
8482 objc_push_parm (parm);
8483 parmlist = TREE_CHAIN (parmlist);
8484 }
8485
8486 if (METHOD_ADD_ARGS (method))
8487 {
8488 tree akey;
8489
8490 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
8491 akey; akey = TREE_CHAIN (akey))
8492 {
8493 objc_push_parm (TREE_VALUE (akey));
8494 }
8495
8496 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
8497 have_ellipsis = 1;
8498 }
8499
8500 parm_info = objc_get_parm_info (have_ellipsis);
8501
8502 really_start_method (objc_method_context, parm_info);
8503 }
8504
8505 /* Return 1 if TYPE1 is equivalent to TYPE2
8506 for purposes of method overloading. */
8507
8508 static int
8509 objc_types_are_equivalent (tree type1, tree type2)
8510 {
8511 if (type1 == type2)
8512 return 1;
8513
8514 /* Strip away indirections. */
8515 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
8516 && (TREE_CODE (type1) == TREE_CODE (type2)))
8517 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
8518 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
8519 return 0;
8520
8521 type1 = (TYPE_HAS_OBJC_INFO (type1)
8522 ? TYPE_OBJC_PROTOCOL_LIST (type1)
8523 : NULL_TREE);
8524 type2 = (TYPE_HAS_OBJC_INFO (type2)
8525 ? TYPE_OBJC_PROTOCOL_LIST (type2)
8526 : NULL_TREE);
8527
8528 if (list_length (type1) == list_length (type2))
8529 {
8530 for (; type2; type2 = TREE_CHAIN (type2))
8531 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
8532 return 0;
8533 return 1;
8534 }
8535 return 0;
8536 }
8537
8538 /* Return 1 if TYPE1 has the same size and alignment as TYPE2. */
8539
8540 static int
8541 objc_types_share_size_and_alignment (tree type1, tree type2)
8542 {
8543 return (simple_cst_equal (TYPE_SIZE (type1), TYPE_SIZE (type2))
8544 && TYPE_ALIGN (type1) == TYPE_ALIGN (type2));
8545 }
8546
8547 /* Return 1 if PROTO1 is equivalent to PROTO2
8548 for purposes of method overloading. Ordinarily, the type signatures
8549 should match up exactly, unless STRICT is zero, in which case we
8550 shall allow differences in which the size and alignment of a type
8551 is the same. */
8552
8553 static int
8554 comp_proto_with_proto (tree proto1, tree proto2, int strict)
8555 {
8556 tree type1, type2;
8557
8558 /* The following test is needed in case there are hashing
8559 collisions. */
8560 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
8561 return 0;
8562
8563 /* Compare return types. */
8564 type1 = TREE_VALUE (TREE_TYPE (proto1));
8565 type2 = TREE_VALUE (TREE_TYPE (proto2));
8566
8567 if (!objc_types_are_equivalent (type1, type2)
8568 && (strict || !objc_types_share_size_and_alignment (type1, type2)))
8569 return 0;
8570
8571 /* Compare argument types. */
8572 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
8573 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
8574 type1 && type2;
8575 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
8576 {
8577 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2))
8578 && (strict
8579 || !objc_types_share_size_and_alignment (TREE_VALUE (type1),
8580 TREE_VALUE (type2))))
8581 return 0;
8582 }
8583
8584 return (!type1 && !type2);
8585 }
8586
8587 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
8588 this occurs. ObjC method dispatches are _not_ like C++ virtual
8589 member function dispatches, and we account for the difference here. */
8590 tree
8591 #ifdef OBJCPLUS
8592 objc_fold_obj_type_ref (tree ref, tree known_type)
8593 #else
8594 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
8595 tree known_type ATTRIBUTE_UNUSED)
8596 #endif
8597 {
8598 #ifdef OBJCPLUS
8599 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
8600
8601 /* If the receiver does not have virtual member functions, there
8602 is nothing we can (or need to) do here. */
8603 if (!v)
8604 return NULL_TREE;
8605
8606 /* Let C++ handle C++ virtual functions. */
8607 return cp_fold_obj_type_ref (ref, known_type);
8608 #else
8609 /* For plain ObjC, we currently do not need to do anything. */
8610 return NULL_TREE;
8611 #endif
8612 }
8613
8614 static void
8615 objc_start_function (tree name, tree type, tree attrs,
8616 #ifdef OBJCPLUS
8617 tree params
8618 #else
8619 struct c_arg_info *params
8620 #endif
8621 )
8622 {
8623 tree fndecl = build_decl (input_location,
8624 FUNCTION_DECL, name, type);
8625
8626 #ifdef OBJCPLUS
8627 DECL_ARGUMENTS (fndecl) = params;
8628 DECL_INITIAL (fndecl) = error_mark_node;
8629 DECL_EXTERNAL (fndecl) = 0;
8630 TREE_STATIC (fndecl) = 1;
8631 retrofit_lang_decl (fndecl);
8632 cplus_decl_attributes (&fndecl, attrs, 0);
8633 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
8634 #else
8635 current_function_returns_value = 0; /* Assume, until we see it does. */
8636 current_function_returns_null = 0;
8637
8638 decl_attributes (&fndecl, attrs, 0);
8639 announce_function (fndecl);
8640 DECL_INITIAL (fndecl) = error_mark_node;
8641 DECL_EXTERNAL (fndecl) = 0;
8642 TREE_STATIC (fndecl) = 1;
8643 current_function_decl = pushdecl (fndecl);
8644 push_scope ();
8645 declare_parm_level ();
8646 DECL_RESULT (current_function_decl)
8647 = build_decl (input_location,
8648 RESULT_DECL, NULL_TREE,
8649 TREE_TYPE (TREE_TYPE (current_function_decl)));
8650 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
8651 DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
8652 start_fname_decls ();
8653 store_parm_decls_from (params);
8654 #endif
8655
8656 TREE_USED (current_function_decl) = 1;
8657 }
8658
8659 /* - Generate an identifier for the function. the format is "_n_cls",
8660 where 1 <= n <= nMethods, and cls is the name the implementation we
8661 are processing.
8662 - Install the return type from the method declaration.
8663 - If we have a prototype, check for type consistency. */
8664
8665 static void
8666 really_start_method (tree method,
8667 #ifdef OBJCPLUS
8668 tree parmlist
8669 #else
8670 struct c_arg_info *parmlist
8671 #endif
8672 )
8673 {
8674 tree ret_type, meth_type;
8675 tree method_id;
8676 const char *sel_name, *class_name, *cat_name;
8677 char *buf;
8678
8679 /* Synth the storage class & assemble the return type. */
8680 ret_type = TREE_VALUE (TREE_TYPE (method));
8681
8682 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
8683 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
8684 cat_name = ((TREE_CODE (objc_implementation_context)
8685 == CLASS_IMPLEMENTATION_TYPE)
8686 ? NULL
8687 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
8688 method_slot++;
8689
8690 /* Make sure this is big enough for any plausible method label. */
8691 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
8692 + (cat_name ? strlen (cat_name) : 0));
8693
8694 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
8695 class_name, cat_name, sel_name, method_slot);
8696
8697 method_id = get_identifier (buf);
8698
8699 #ifdef OBJCPLUS
8700 /* Objective-C methods cannot be overloaded, so we don't need
8701 the type encoding appended. It looks bad anyway... */
8702 push_lang_context (lang_name_c);
8703 #endif
8704
8705 meth_type
8706 = build_function_type (ret_type,
8707 get_arg_type_list (method, METHOD_DEF, 0));
8708 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
8709
8710 /* Set self_decl from the first argument. */
8711 self_decl = DECL_ARGUMENTS (current_function_decl);
8712
8713 /* Suppress unused warnings. */
8714 TREE_USED (self_decl) = 1;
8715 TREE_USED (TREE_CHAIN (self_decl)) = 1;
8716 #ifdef OBJCPLUS
8717 pop_lang_context ();
8718 #endif
8719
8720 METHOD_DEFINITION (method) = current_function_decl;
8721
8722 /* Check consistency...start_function, pushdecl, duplicate_decls. */
8723
8724 if (implementation_template != objc_implementation_context)
8725 {
8726 tree proto
8727 = lookup_method_static (implementation_template,
8728 METHOD_SEL_NAME (method),
8729 ((TREE_CODE (method) == CLASS_METHOD_DECL)
8730 | OBJC_LOOKUP_NO_SUPER));
8731
8732 if (proto)
8733 {
8734 if (!comp_proto_with_proto (method, proto, 1))
8735 {
8736 bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
8737
8738 warning_at (DECL_SOURCE_LOCATION (method), 0,
8739 "conflicting types for %<%c%s%>",
8740 (type ? '-' : '+'),
8741 identifier_to_locale (gen_method_decl (method)));
8742 inform (DECL_SOURCE_LOCATION (proto),
8743 "previous declaration of %<%c%s%>",
8744 (type ? '-' : '+'),
8745 identifier_to_locale (gen_method_decl (proto)));
8746 }
8747 }
8748 else
8749 {
8750 /* We have a method @implementation even though we did not
8751 see a corresponding @interface declaration (which is allowed
8752 by Objective-C rules). Go ahead and place the method in
8753 the @interface anyway, so that message dispatch lookups
8754 will see it. */
8755 tree interface = implementation_template;
8756
8757 if (TREE_CODE (objc_implementation_context)
8758 == CATEGORY_IMPLEMENTATION_TYPE)
8759 interface = lookup_category
8760 (interface,
8761 CLASS_SUPER_NAME (objc_implementation_context));
8762
8763 if (interface)
8764 objc_add_method (interface, copy_node (method),
8765 TREE_CODE (method) == CLASS_METHOD_DECL);
8766 }
8767 }
8768 }
8769
8770 static void *UOBJC_SUPER_scope = 0;
8771
8772 /* _n_Method (id self, SEL sel, ...)
8773 {
8774 struct objc_super _S;
8775 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
8776 } */
8777
8778 static tree
8779 get_super_receiver (void)
8780 {
8781 if (objc_method_context)
8782 {
8783 tree super_expr, super_expr_list;
8784
8785 if (!UOBJC_SUPER_decl)
8786 {
8787 UOBJC_SUPER_decl = build_decl (input_location,
8788 VAR_DECL, get_identifier (TAG_SUPER),
8789 objc_super_template);
8790 /* This prevents `unused variable' warnings when compiling with -Wall. */
8791 TREE_USED (UOBJC_SUPER_decl) = 1;
8792 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
8793 finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
8794 NULL_TREE);
8795 UOBJC_SUPER_scope = objc_get_current_scope ();
8796 }
8797
8798 /* Set receiver to self. */
8799 super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
8800 super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
8801 NOP_EXPR, input_location, self_decl,
8802 NULL_TREE);
8803 super_expr_list = super_expr;
8804
8805 /* Set class to begin searching. */
8806 super_expr = objc_build_component_ref (UOBJC_SUPER_decl,
8807 get_identifier ("super_class"));
8808
8809 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8810 {
8811 /* [_cls, __cls]Super are "pre-built" in
8812 synth_forward_declarations. */
8813
8814 super_expr = build_modify_expr (input_location, super_expr,
8815 NULL_TREE, NOP_EXPR,
8816 input_location,
8817 ((TREE_CODE (objc_method_context)
8818 == INSTANCE_METHOD_DECL)
8819 ? ucls_super_ref
8820 : uucls_super_ref),
8821 NULL_TREE);
8822 }
8823
8824 else
8825 /* We have a category. */
8826 {
8827 tree super_name = CLASS_SUPER_NAME (implementation_template);
8828 tree super_class;
8829
8830 /* Barf if super used in a category of Object. */
8831 if (!super_name)
8832 {
8833 error ("no super class declared in interface for %qE",
8834 CLASS_NAME (implementation_template));
8835 return error_mark_node;
8836 }
8837
8838 if (flag_next_runtime && !flag_zero_link)
8839 {
8840 super_class = objc_get_class_reference (super_name);
8841 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
8842 /* If we are in a class method, we must retrieve the
8843 _metaclass_ for the current class, pointed at by
8844 the class's "isa" pointer. The following assumes that
8845 "isa" is the first ivar in a class (which it must be). */
8846 super_class
8847 = build_indirect_ref
8848 (input_location,
8849 build_c_cast (input_location,
8850 build_pointer_type (objc_class_type),
8851 super_class), "unary *");
8852 }
8853 else
8854 {
8855 add_class_reference (super_name);
8856 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8857 ? objc_get_class_decl : objc_get_meta_class_decl);
8858 assemble_external (super_class);
8859 super_class
8860 = build_function_call
8861 (input_location,
8862 super_class,
8863 build_tree_list
8864 (NULL_TREE,
8865 my_build_string_pointer
8866 (IDENTIFIER_LENGTH (super_name) + 1,
8867 IDENTIFIER_POINTER (super_name))));
8868 }
8869
8870 super_expr
8871 = build_modify_expr (input_location, super_expr, NULL_TREE,
8872 NOP_EXPR,
8873 input_location,
8874 build_c_cast (input_location,
8875 TREE_TYPE (super_expr),
8876 super_class),
8877 NULL_TREE);
8878 }
8879
8880 super_expr_list = build_compound_expr (input_location,
8881 super_expr_list, super_expr);
8882
8883 super_expr = build_unary_op (input_location,
8884 ADDR_EXPR, UOBJC_SUPER_decl, 0);
8885 super_expr_list = build_compound_expr (input_location,
8886 super_expr_list, super_expr);
8887
8888 return super_expr_list;
8889 }
8890 else
8891 {
8892 error ("[super ...] must appear in a method context");
8893 return error_mark_node;
8894 }
8895 }
8896
8897 /* When exiting a scope, sever links to a 'super' declaration (if any)
8898 therein contained. */
8899
8900 void
8901 objc_clear_super_receiver (void)
8902 {
8903 if (objc_method_context
8904 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
8905 UOBJC_SUPER_decl = 0;
8906 UOBJC_SUPER_scope = 0;
8907 }
8908 }
8909
8910 void
8911 objc_finish_method_definition (tree fndecl)
8912 {
8913 /* We cannot validly inline ObjC methods, at least not without a language
8914 extension to declare that a method need not be dynamically
8915 dispatched, so suppress all thoughts of doing so. */
8916 DECL_UNINLINABLE (fndecl) = 1;
8917
8918 #ifndef OBJCPLUS
8919 /* The C++ front-end will have called finish_function() for us. */
8920 finish_function ();
8921 #endif
8922
8923 METHOD_ENCODING (objc_method_context)
8924 = encode_method_prototype (objc_method_context);
8925
8926 /* Required to implement _msgSuper. This must be done AFTER finish_function,
8927 since the optimizer may find "may be used before set" errors. */
8928 objc_method_context = NULL_TREE;
8929
8930 if (should_call_super_dealloc)
8931 warning (0, "method possibly missing a [super dealloc] call");
8932 }
8933
8934 /* Given a tree DECL node, produce a printable description of it in the given
8935 buffer, overwriting the buffer. */
8936
8937 static char *
8938 gen_declaration (tree decl)
8939 {
8940 errbuf[0] = '\0';
8941
8942 if (DECL_P (decl))
8943 {
8944 gen_type_name_0 (TREE_TYPE (decl));
8945
8946 if (DECL_NAME (decl))
8947 {
8948 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
8949 strcat (errbuf, " ");
8950
8951 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
8952 }
8953
8954 if (DECL_INITIAL (decl)
8955 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
8956 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
8957 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
8958 }
8959
8960 return errbuf;
8961 }
8962
8963 /* Given a tree TYPE node, produce a printable description of it in the given
8964 buffer, overwriting the buffer. */
8965
8966 static char *
8967 gen_type_name_0 (tree type)
8968 {
8969 tree orig = type, proto;
8970
8971 if (TYPE_P (type) && TYPE_NAME (type))
8972 type = TYPE_NAME (type);
8973 else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
8974 {
8975 tree inner = TREE_TYPE (type);
8976
8977 while (TREE_CODE (inner) == ARRAY_TYPE)
8978 inner = TREE_TYPE (inner);
8979
8980 gen_type_name_0 (inner);
8981
8982 if (!POINTER_TYPE_P (inner))
8983 strcat (errbuf, " ");
8984
8985 if (POINTER_TYPE_P (type))
8986 strcat (errbuf, "*");
8987 else
8988 while (type != inner)
8989 {
8990 strcat (errbuf, "[");
8991
8992 if (TYPE_DOMAIN (type))
8993 {
8994 char sz[20];
8995
8996 sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
8997 (TREE_INT_CST_LOW
8998 (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
8999 strcat (errbuf, sz);
9000 }
9001
9002 strcat (errbuf, "]");
9003 type = TREE_TYPE (type);
9004 }
9005
9006 goto exit_function;
9007 }
9008
9009 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
9010 type = DECL_NAME (type);
9011
9012 strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
9013 ? IDENTIFIER_POINTER (type)
9014 : "");
9015
9016 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
9017 if (objc_is_id (orig))
9018 orig = TREE_TYPE (orig);
9019
9020 proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
9021
9022 if (proto)
9023 {
9024 strcat (errbuf, " <");
9025
9026 while (proto) {
9027 strcat (errbuf,
9028 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
9029 proto = TREE_CHAIN (proto);
9030 strcat (errbuf, proto ? ", " : ">");
9031 }
9032 }
9033
9034 exit_function:
9035 return errbuf;
9036 }
9037
9038 static char *
9039 gen_type_name (tree type)
9040 {
9041 errbuf[0] = '\0';
9042
9043 return gen_type_name_0 (type);
9044 }
9045
9046 /* Given a method tree, put a printable description into the given
9047 buffer (overwriting) and return a pointer to the buffer. */
9048
9049 static char *
9050 gen_method_decl (tree method)
9051 {
9052 tree chain;
9053
9054 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
9055 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
9056 strcat (errbuf, ")");
9057 chain = METHOD_SEL_ARGS (method);
9058
9059 if (chain)
9060 {
9061 /* We have a chain of keyword_decls. */
9062 do
9063 {
9064 if (KEYWORD_KEY_NAME (chain))
9065 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
9066
9067 strcat (errbuf, ":(");
9068 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
9069 strcat (errbuf, ")");
9070
9071 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
9072 if ((chain = TREE_CHAIN (chain)))
9073 strcat (errbuf, " ");
9074 }
9075 while (chain);
9076
9077 if (METHOD_ADD_ARGS (method))
9078 {
9079 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
9080
9081 /* Know we have a chain of parm_decls. */
9082 while (chain)
9083 {
9084 strcat (errbuf, ", ");
9085 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
9086 chain = TREE_CHAIN (chain);
9087 }
9088
9089 if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
9090 strcat (errbuf, ", ...");
9091 }
9092 }
9093
9094 else
9095 /* We have a unary selector. */
9096 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
9097
9098 return errbuf;
9099 }
9100 \f
9101 /* Debug info. */
9102
9103
9104 /* Dump an @interface declaration of the supplied class CHAIN to the
9105 supplied file FP. Used to implement the -gen-decls option (which
9106 prints out an @interface declaration of all classes compiled in
9107 this run); potentially useful for debugging the compiler too. */
9108 static void
9109 dump_interface (FILE *fp, tree chain)
9110 {
9111 /* FIXME: A heap overflow here whenever a method (or ivar)
9112 declaration is so long that it doesn't fit in the buffer. The
9113 code and all the related functions should be rewritten to avoid
9114 using fixed size buffers. */
9115 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
9116 tree ivar_decls = CLASS_RAW_IVARS (chain);
9117 tree nst_methods = CLASS_NST_METHODS (chain);
9118 tree cls_methods = CLASS_CLS_METHODS (chain);
9119
9120 fprintf (fp, "\n@interface %s", my_name);
9121
9122 /* CLASS_SUPER_NAME is used to store the superclass name for
9123 classes, and the category name for categories. */
9124 if (CLASS_SUPER_NAME (chain))
9125 {
9126 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
9127
9128 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
9129 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
9130 {
9131 fprintf (fp, " (%s)\n", name);
9132 }
9133 else
9134 {
9135 fprintf (fp, " : %s\n", name);
9136 }
9137 }
9138 else
9139 fprintf (fp, "\n");
9140
9141 /* FIXME - the following doesn't seem to work at the moment. */
9142 if (ivar_decls)
9143 {
9144 fprintf (fp, "{\n");
9145 do
9146 {
9147 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
9148 ivar_decls = TREE_CHAIN (ivar_decls);
9149 }
9150 while (ivar_decls);
9151 fprintf (fp, "}\n");
9152 }
9153
9154 while (nst_methods)
9155 {
9156 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
9157 nst_methods = TREE_CHAIN (nst_methods);
9158 }
9159
9160 while (cls_methods)
9161 {
9162 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
9163 cls_methods = TREE_CHAIN (cls_methods);
9164 }
9165
9166 fprintf (fp, "@end\n");
9167 }
9168
9169 /* Demangle function for Objective-C */
9170 static const char *
9171 objc_demangle (const char *mangled)
9172 {
9173 char *demangled, *cp;
9174
9175 if (mangled[0] == '_' &&
9176 (mangled[1] == 'i' || mangled[1] == 'c') &&
9177 mangled[2] == '_')
9178 {
9179 cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
9180 if (mangled[1] == 'i')
9181 *cp++ = '-'; /* for instance method */
9182 else
9183 *cp++ = '+'; /* for class method */
9184 *cp++ = '['; /* opening left brace */
9185 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
9186 while (*cp && *cp == '_')
9187 cp++; /* skip any initial underbars in class name */
9188 cp = strchr(cp, '_'); /* find first non-initial underbar */
9189 if (cp == NULL)
9190 {
9191 free(demangled); /* not mangled name */
9192 return mangled;
9193 }
9194 if (cp[1] == '_') /* easy case: no category name */
9195 {
9196 *cp++ = ' '; /* replace two '_' with one ' ' */
9197 strcpy(cp, mangled + (cp - demangled) + 2);
9198 }
9199 else
9200 {
9201 *cp++ = '('; /* less easy case: category name */
9202 cp = strchr(cp, '_');
9203 if (cp == 0)
9204 {
9205 free(demangled); /* not mangled name */
9206 return mangled;
9207 }
9208 *cp++ = ')';
9209 *cp++ = ' '; /* overwriting 1st char of method name... */
9210 strcpy(cp, mangled + (cp - demangled)); /* get it back */
9211 }
9212 while (*cp && *cp == '_')
9213 cp++; /* skip any initial underbars in method name */
9214 for (; *cp; cp++)
9215 if (*cp == '_')
9216 *cp = ':'; /* replace remaining '_' with ':' */
9217 *cp++ = ']'; /* closing right brace */
9218 *cp++ = 0; /* string terminator */
9219 return demangled;
9220 }
9221 else
9222 return mangled; /* not an objc mangled name */
9223 }
9224
9225 const char *
9226 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
9227 {
9228 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
9229 }
9230
9231 static void
9232 init_objc (void)
9233 {
9234 gcc_obstack_init (&util_obstack);
9235 util_firstobj = (char *) obstack_finish (&util_obstack);
9236
9237 errbuf = XNEWVEC (char, 1024 * 10);
9238 hash_init ();
9239 synth_module_prologue ();
9240 }
9241 \f
9242 static void
9243 finish_objc (void)
9244 {
9245 struct imp_entry *impent;
9246 tree chain;
9247 /* The internally generated initializers appear to have missing braces.
9248 Don't warn about this. */
9249 int save_warn_missing_braces = warn_missing_braces;
9250 warn_missing_braces = 0;
9251
9252 /* A missing @end may not be detected by the parser. */
9253 if (objc_implementation_context)
9254 {
9255 warning (0, "%<@end%> missing in implementation context");
9256 finish_class (objc_implementation_context);
9257 objc_ivar_chain = NULL_TREE;
9258 objc_implementation_context = NULL_TREE;
9259 }
9260
9261 /* Process the static instances here because initialization of objc_symtab
9262 depends on them. */
9263 if (objc_static_instances)
9264 generate_static_references ();
9265
9266 if (imp_list || class_names_chain
9267 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9268 generate_objc_symtab_decl ();
9269
9270 for (impent = imp_list; impent; impent = impent->next)
9271 {
9272 objc_implementation_context = impent->imp_context;
9273 implementation_template = impent->imp_template;
9274
9275 UOBJC_CLASS_decl = impent->class_decl;
9276 UOBJC_METACLASS_decl = impent->meta_decl;
9277
9278 /* Dump the @interface of each class as we compile it, if the
9279 -gen-decls option is in use. TODO: Dump the classes in the
9280 order they were found, rather than in reverse order as we
9281 are doing now. */
9282 if (flag_gen_declaration)
9283 {
9284 dump_interface (gen_declaration_file, objc_implementation_context);
9285 }
9286
9287 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
9288 {
9289 /* all of the following reference the string pool... */
9290 generate_ivar_lists ();
9291 generate_dispatch_tables ();
9292 generate_shared_structures (impent->has_cxx_cdtors
9293 ? CLS_HAS_CXX_STRUCTORS
9294 : 0);
9295 }
9296 else
9297 {
9298 generate_dispatch_tables ();
9299 generate_category (objc_implementation_context);
9300 }
9301 }
9302
9303 /* If we are using an array of selectors, we must always
9304 finish up the array decl even if no selectors were used. */
9305 if (! flag_next_runtime || sel_ref_chain)
9306 build_selector_translation_table ();
9307
9308 if (protocol_chain)
9309 generate_protocols ();
9310
9311 if ((flag_replace_objc_classes && imp_list) || flag_objc_gc)
9312 generate_objc_image_info ();
9313
9314 /* Arrange for ObjC data structures to be initialized at run time. */
9315 if (objc_implementation_context || class_names_chain || objc_static_instances
9316 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
9317 {
9318 build_module_descriptor ();
9319
9320 if (!flag_next_runtime)
9321 build_module_initializer_routine ();
9322 }
9323
9324 /* Dump the class references. This forces the appropriate classes
9325 to be linked into the executable image, preserving unix archive
9326 semantics. This can be removed when we move to a more dynamically
9327 linked environment. */
9328
9329 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
9330 {
9331 handle_class_ref (chain);
9332 if (TREE_PURPOSE (chain))
9333 generate_classref_translation_entry (chain);
9334 }
9335
9336 for (impent = imp_list; impent; impent = impent->next)
9337 handle_impent (impent);
9338
9339 if (warn_selector)
9340 {
9341 int slot;
9342 hash hsh;
9343
9344 /* Run through the selector hash tables and print a warning for any
9345 selector which has multiple methods. */
9346
9347 for (slot = 0; slot < SIZEHASHTABLE; slot++)
9348 {
9349 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
9350 check_duplicates (hsh, 0, 1);
9351 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
9352 check_duplicates (hsh, 0, 1);
9353 }
9354 }
9355
9356 warn_missing_braces = save_warn_missing_braces;
9357 }
9358 \f
9359 /* Subroutines of finish_objc. */
9360
9361 static void
9362 generate_classref_translation_entry (tree chain)
9363 {
9364 tree expr, decl, type;
9365
9366 decl = TREE_PURPOSE (chain);
9367 type = TREE_TYPE (decl);
9368
9369 expr = add_objc_string (TREE_VALUE (chain), class_names);
9370 expr = convert (type, expr); /* cast! */
9371
9372 /* The decl that is the one that we
9373 forward declared in build_class_reference. */
9374 finish_var_decl (decl, expr);
9375 return;
9376 }
9377
9378 static void
9379 handle_class_ref (tree chain)
9380 {
9381 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
9382 char *string = (char *) alloca (strlen (name) + 30);
9383 tree decl;
9384 tree exp;
9385
9386 sprintf (string, "%sobjc_class_name_%s",
9387 (flag_next_runtime ? "." : "__"), name);
9388
9389 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
9390 if (flag_next_runtime)
9391 {
9392 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
9393 return;
9394 }
9395 #endif
9396
9397 /* Make a decl for this name, so we can use its address in a tree. */
9398 decl = build_decl (input_location,
9399 VAR_DECL, get_identifier (string), char_type_node);
9400 DECL_EXTERNAL (decl) = 1;
9401 TREE_PUBLIC (decl) = 1;
9402
9403 pushdecl (decl);
9404 rest_of_decl_compilation (decl, 0, 0);
9405
9406 /* Make a decl for the address. */
9407 sprintf (string, "%sobjc_class_ref_%s",
9408 (flag_next_runtime ? "." : "__"), name);
9409 exp = build1 (ADDR_EXPR, string_type_node, decl);
9410 decl = build_decl (input_location,
9411 VAR_DECL, get_identifier (string), string_type_node);
9412 DECL_INITIAL (decl) = exp;
9413 TREE_STATIC (decl) = 1;
9414 TREE_USED (decl) = 1;
9415 /* Force the output of the decl as this forces the reference of the class. */
9416 mark_decl_referenced (decl);
9417
9418 pushdecl (decl);
9419 rest_of_decl_compilation (decl, 0, 0);
9420 }
9421
9422 static void
9423 handle_impent (struct imp_entry *impent)
9424 {
9425 char *string;
9426
9427 objc_implementation_context = impent->imp_context;
9428 implementation_template = impent->imp_template;
9429
9430 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
9431 {
9432 const char *const class_name =
9433 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9434
9435 string = (char *) alloca (strlen (class_name) + 30);
9436
9437 sprintf (string, "%sobjc_class_name_%s",
9438 (flag_next_runtime ? "." : "__"), class_name);
9439 }
9440 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
9441 {
9442 const char *const class_name =
9443 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
9444 const char *const class_super_name =
9445 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
9446
9447 string = (char *) alloca (strlen (class_name)
9448 + strlen (class_super_name) + 30);
9449
9450 /* Do the same for categories. Even though no references to
9451 these symbols are generated automatically by the compiler, it
9452 gives you a handle to pull them into an archive by hand. */
9453 sprintf (string, "*%sobjc_category_name_%s_%s",
9454 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
9455 }
9456 else
9457 return;
9458
9459 #ifdef ASM_DECLARE_CLASS_REFERENCE
9460 if (flag_next_runtime)
9461 {
9462 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
9463 return;
9464 }
9465 else
9466 #endif
9467 {
9468 tree decl, init;
9469
9470 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
9471 decl = build_decl (input_location,
9472 VAR_DECL, get_identifier (string), TREE_TYPE (init));
9473 TREE_PUBLIC (decl) = 1;
9474 TREE_READONLY (decl) = 1;
9475 TREE_USED (decl) = 1;
9476 TREE_CONSTANT (decl) = 1;
9477 DECL_CONTEXT (decl) = 0;
9478 DECL_ARTIFICIAL (decl) = 1;
9479 DECL_INITIAL (decl) = init;
9480 assemble_variable (decl, 1, 0, 0);
9481 }
9482 }
9483 \f
9484 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
9485 later requires that ObjC translation units participating in F&C be
9486 specially marked. The following routine accomplishes this. */
9487
9488 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
9489
9490 static void
9491 generate_objc_image_info (void)
9492 {
9493 tree decl, initlist;
9494 int flags
9495 = ((flag_replace_objc_classes && imp_list ? 1 : 0)
9496 | (flag_objc_gc ? 2 : 0));
9497
9498 decl = start_var_decl (build_array_type
9499 (integer_type_node,
9500 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
9501 "_OBJC_IMAGE_INFO");
9502
9503 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
9504 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), initlist);
9505 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
9506
9507 finish_var_decl (decl, initlist);
9508 }
9509
9510 /* Look up ID as an instance variable. OTHER contains the result of
9511 the C or C++ lookup, which we may want to use instead. */
9512
9513 tree
9514 objc_lookup_ivar (tree other, tree id)
9515 {
9516 tree ivar;
9517
9518 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
9519 if (!objc_method_context)
9520 return other;
9521
9522 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
9523 /* We have a message to super. */
9524 return get_super_receiver ();
9525
9526 /* In a class method, look up an instance variable only as a last
9527 resort. */
9528 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
9529 && other && other != error_mark_node)
9530 return other;
9531
9532 /* Look up the ivar, but do not use it if it is not accessible. */
9533 ivar = is_ivar (objc_ivar_chain, id);
9534
9535 if (!ivar || is_private (ivar))
9536 return other;
9537
9538 /* In an instance method, a local variable (or parameter) may hide the
9539 instance variable. */
9540 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
9541 && other && other != error_mark_node
9542 #ifdef OBJCPLUS
9543 && CP_DECL_CONTEXT (other) != global_namespace)
9544 #else
9545 && !DECL_FILE_SCOPE_P (other))
9546 #endif
9547 {
9548 warning (0, "local declaration of %qE hides instance variable",
9549 id);
9550
9551 return other;
9552 }
9553
9554 /* At this point, we are either in an instance method with no obscuring
9555 local definitions, or in a class method with no alternate definitions
9556 at all. */
9557 return build_ivar_reference (id);
9558 }
9559
9560 /* Possibly rewrite a function CALL into an OBJ_TYPE_REF expression. This
9561 needs to be done if we are calling a function through a cast. */
9562
9563 tree
9564 objc_rewrite_function_call (tree function, tree first_param)
9565 {
9566 if (TREE_CODE (function) == NOP_EXPR
9567 && TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
9568 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
9569 == FUNCTION_DECL)
9570 {
9571 function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
9572 TREE_OPERAND (function, 0),
9573 first_param, size_zero_node);
9574 }
9575
9576 return function;
9577 }
9578
9579 /* Look for the special case of OBJC_TYPE_REF with the address of
9580 a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
9581 of its cousins). */
9582
9583 int
9584 objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
9585 {
9586 enum gimplify_status r0, r1;
9587 if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
9588 && TREE_CODE (OBJ_TYPE_REF_EXPR (*expr_p)) == ADDR_EXPR
9589 && TREE_CODE (TREE_OPERAND (OBJ_TYPE_REF_EXPR (*expr_p), 0))
9590 == FUNCTION_DECL)
9591 {
9592 /* Postincrements in OBJ_TYPE_REF_OBJECT don't affect the
9593 value of the OBJ_TYPE_REF, so force them to be emitted
9594 during subexpression evaluation rather than after the
9595 OBJ_TYPE_REF. This permits objc_msgSend calls in Objective
9596 C to use direct rather than indirect calls when the
9597 object expression has a postincrement. */
9598 r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, NULL,
9599 is_gimple_val, fb_rvalue);
9600 r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
9601 is_gimple_val, fb_rvalue);
9602
9603 return MIN (r0, r1);
9604 }
9605
9606 #ifdef OBJCPLUS
9607 return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
9608 #else
9609 return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
9610 #endif
9611 }
9612
9613 #include "gt-objc-objc-act.h"