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