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

source code of gcc/objc/objc-act.cc