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