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