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