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