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