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