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