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