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