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