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