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