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

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