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