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