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