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