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