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