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