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