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