OSDN Git Service

* objc-act.c (finish_var_decl): Set the generated symbols as "used".
[pf3gnuchains/gcc-fork.git] / gcc / objc / objc-act.c
1 /* Implement classes and message passing for Objective C.
2    Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3    2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
4    Contributed by Steve Naroff.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22
23 /* Purpose: This module implements the Objective-C 4.0 language.
24
25    compatibility issues (with the Stepstone translator):
26
27    - does not recognize the following 3.3 constructs.
28      @requires, @classes, @messages, = (...)
29    - methods with variable arguments must conform to ANSI standard.
30    - tagged structure definitions that appear in BOTH the interface
31      and implementation are not allowed.
32    - public/private: all instance variables are public within the
33      context of the implementation...I consider this to be a bug in
34      the translator.
35    - statically allocated objects are not supported. the user will
36      receive an error if this service is requested.
37
38    code generation `options':
39
40    */
41
42 #include "config.h"
43 #include "system.h"
44 #include "coretypes.h"
45 #include "tm.h"
46 #include "tree.h"
47 #include "rtl.h"
48 #include "tm_p.h"
49 #include "expr.h"
50
51 #ifdef OBJCPLUS
52 #include "cp-tree.h"
53 #else
54 #include "c-tree.h"
55 #include "c-lang.h"
56 #endif
57
58 #include "c-common.h"
59 #include "c-pragma.h"
60 #include "flags.h"
61 #include "langhooks.h"
62 #include "objc-act.h"
63 #include "input.h"
64 #include "except.h"
65 #include "function.h"
66 #include "output.h"
67 #include "toplev.h"
68 #include "ggc.h"
69 #include "varray.h"
70 #include "debug.h"
71 #include "target.h"
72 #include "diagnostic.h"
73 #include "intl.h"
74 #include "cgraph.h"
75 #include "tree-iterator.h"
76 #include "libfuncs.h"
77 #include "hashtab.h"
78 #include "langhooks-def.h"
79
80 #define OBJC_VOID_AT_END        void_list_node
81
82 static unsigned int should_call_super_dealloc = 0;
83
84 /* When building Objective-C++, we need in_late_binary_op.  */
85 #ifdef OBJCPLUS
86 bool in_late_binary_op = false;
87 #endif  /* OBJCPLUS */
88
89 /* When building Objective-C++, we are not linking against the C front-end
90    and so need to replicate the C tree-construction functions in some way.  */
91 #ifdef OBJCPLUS
92 #define OBJCP_REMAP_FUNCTIONS
93 #include "objcp-decl.h"
94 #endif  /* OBJCPLUS */
95
96 /* This is the default way of generating a method name.  */
97 /* I am not sure it is really correct.
98    Perhaps there's a danger that it will make name conflicts
99    if method names contain underscores. -- rms.  */
100 #ifndef OBJC_GEN_METHOD_LABEL
101 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
102   do {                                      \
103     char *temp;                             \
104     sprintf ((BUF), "_%s_%s_%s_%s",         \
105              ((IS_INST) ? "i" : "c"),       \
106              (CLASS_NAME),                  \
107              ((CAT_NAME)? (CAT_NAME) : ""), \
108              (SEL_NAME));                   \
109     for (temp = (BUF); *temp; temp++)       \
110       if (*temp == ':') *temp = '_';        \
111   } while (0)
112 #endif
113
114 /* These need specifying.  */
115 #ifndef OBJC_FORWARDING_STACK_OFFSET
116 #define OBJC_FORWARDING_STACK_OFFSET 0
117 #endif
118
119 #ifndef OBJC_FORWARDING_MIN_OFFSET
120 #define OBJC_FORWARDING_MIN_OFFSET 0
121 #endif
122 \f
123 /* Set up for use of obstacks.  */
124
125 #include "obstack.h"
126
127 /* This obstack is used to accumulate the encoding of a data type.  */
128 static struct obstack util_obstack;
129
130 /* This points to the beginning of obstack contents, so we can free
131    the whole contents.  */
132 char *util_firstobj;
133
134 /* The version identifies which language generation and runtime
135    the module (file) was compiled for, and is recorded in the
136    module descriptor.  */
137
138 #define OBJC_VERSION    (flag_next_runtime ? 6 : 8)
139 #define PROTOCOL_VERSION 2
140
141 /* (Decide if these can ever be validly changed.) */
142 #define OBJC_ENCODE_INLINE_DEFS         0
143 #define OBJC_ENCODE_DONT_INLINE_DEFS    1
144
145 /*** Private Interface (procedures) ***/
146
147 /* Used by compile_file.  */
148
149 static void init_objc (void);
150 static void finish_objc (void);
151
152 /* Code generation.  */
153
154 static tree objc_build_constructor (tree, tree);
155 static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
156 static tree get_proto_encoding (tree);
157 static tree lookup_interface (tree);
158 static tree objc_add_static_instance (tree, tree);
159
160 static tree start_class (enum tree_code, tree, tree, tree);
161 static tree continue_class (tree);
162 static void finish_class (tree);
163 static void start_method_def (tree);
164 #ifdef OBJCPLUS
165 static void objc_start_function (tree, tree, tree, tree);
166 #else
167 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
168 #endif
169 static tree start_protocol (enum tree_code, tree, tree);
170 static tree build_method_decl (enum tree_code, tree, tree, tree, bool);
171 static tree objc_add_method (tree, tree, int);
172 static tree add_instance_variable (tree, int, tree);
173 static tree build_ivar_reference (tree);
174 static tree is_ivar (tree, tree);
175
176 static void build_objc_exception_stuff (void);
177 static void build_next_objc_exception_stuff (void);
178
179 /* We only need the following for ObjC; ObjC++ will use C++'s definition
180    of DERIVED_FROM_P.  */
181 #ifndef OBJCPLUS
182 static bool objc_derived_from_p (tree, tree);
183 #define DERIVED_FROM_P(PARENT, CHILD) objc_derived_from_p (PARENT, CHILD)
184 #endif
185 static void objc_xref_basetypes (tree, tree);
186
187 static void build_class_template (void);
188 static void build_selector_template (void);
189 static void build_category_template (void);
190 static void build_super_template (void);
191 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
192 static tree get_class_ivars (tree, bool);
193 static tree generate_protocol_list (tree);
194 static void build_protocol_reference (tree);
195
196 #ifdef OBJCPLUS
197 static void objc_generate_cxx_cdtors (void);
198 #endif
199
200 static const char *synth_id_with_class_suffix (const char *, tree);
201
202 /* Hash tables to manage the global pool of method prototypes.  */
203
204 hash *nst_method_hash_list = 0;
205 hash *cls_method_hash_list = 0;
206
207 static hash hash_lookup (hash *, tree);
208 static tree lookup_method (tree, tree);
209 static tree lookup_method_static (tree, tree, int);
210
211 enum string_section
212 {
213   class_names,          /* class, category, protocol, module names */
214   meth_var_names,       /* method and variable names */
215   meth_var_types        /* method and variable type descriptors */
216 };
217
218 static tree add_objc_string (tree, enum string_section);
219 static tree build_objc_string_decl (enum string_section);
220 static void build_selector_table_decl (void);
221
222 /* Protocol additions.  */
223
224 static tree lookup_protocol (tree);
225 static tree lookup_and_install_protocols (tree);
226
227 /* Type encoding.  */
228
229 static void encode_type_qualifiers (tree);
230 static void encode_type (tree, int, int);
231 static void encode_field_decl (tree, int, int);
232
233 #ifdef OBJCPLUS
234 static void really_start_method (tree, tree);
235 #else
236 static void really_start_method (tree, struct c_arg_info *);
237 #endif
238 static int comp_proto_with_proto (tree, tree, int);
239 static void objc_push_parm (tree);
240 #ifdef OBJCPLUS
241 static tree objc_get_parm_info (int);
242 #else
243 static struct c_arg_info *objc_get_parm_info (int);
244 #endif
245
246 /* Utilities for debugging and error diagnostics.  */
247
248 static char *gen_type_name (tree);
249 static char *gen_type_name_0 (tree);
250 static char *gen_method_decl (tree);
251 static char *gen_declaration (tree);
252
253 /* Everything else.  */
254
255 static tree create_field_decl (tree, const char *);
256 static void add_class_reference (tree);
257 static void build_protocol_template (void);
258 static tree encode_method_prototype (tree);
259 static void generate_classref_translation_entry (tree);
260 static void handle_class_ref (tree);
261 static void generate_struct_by_value_array (void)
262      ATTRIBUTE_NORETURN;
263 static void mark_referenced_methods (void);
264 static void generate_objc_image_info (void);
265
266 /*** Private Interface (data) ***/
267
268 /* Reserved tag definitions.  */
269
270 #define OBJECT_TYPEDEF_NAME             "id"
271 #define CLASS_TYPEDEF_NAME              "Class"
272
273 #define TAG_OBJECT                      "objc_object"
274 #define TAG_CLASS                       "objc_class"
275 #define TAG_SUPER                       "objc_super"
276 #define TAG_SELECTOR                    "objc_selector"
277
278 #define UTAG_CLASS                      "_objc_class"
279 #define UTAG_IVAR                       "_objc_ivar"
280 #define UTAG_IVAR_LIST                  "_objc_ivar_list"
281 #define UTAG_METHOD                     "_objc_method"
282 #define UTAG_METHOD_LIST                "_objc_method_list"
283 #define UTAG_CATEGORY                   "_objc_category"
284 #define UTAG_MODULE                     "_objc_module"
285 #define UTAG_SYMTAB                     "_objc_symtab"
286 #define UTAG_SUPER                      "_objc_super"
287 #define UTAG_SELECTOR                   "_objc_selector"
288
289 #define UTAG_PROTOCOL                   "_objc_protocol"
290 #define UTAG_METHOD_PROTOTYPE           "_objc_method_prototype"
291 #define UTAG_METHOD_PROTOTYPE_LIST      "_objc__method_prototype_list"
292
293 /* Note that the string object global name is only needed for the
294    NeXT runtime.  */
295 #define STRING_OBJECT_GLOBAL_FORMAT     "_%sClassReference"
296
297 #define PROTOCOL_OBJECT_CLASS_NAME      "Protocol"
298
299 static const char *TAG_GETCLASS;
300 static const char *TAG_GETMETACLASS;
301 static const char *TAG_MSGSEND;
302 static const char *TAG_MSGSENDSUPER;
303 /* The NeXT Objective-C messenger may have two extra entry points, for use
304    when returning a structure. */
305 static const char *TAG_MSGSEND_STRET;
306 static const char *TAG_MSGSENDSUPER_STRET;
307 static const char *default_constant_string_class_name;
308
309 /* Runtime metadata flags.  */
310 #define CLS_FACTORY                     0x0001L
311 #define CLS_META                        0x0002L
312 #define CLS_HAS_CXX_STRUCTORS           0x2000L
313
314 #define OBJC_MODIFIER_STATIC            0x00000001
315 #define OBJC_MODIFIER_FINAL             0x00000002
316 #define OBJC_MODIFIER_PUBLIC            0x00000004
317 #define OBJC_MODIFIER_PRIVATE           0x00000008
318 #define OBJC_MODIFIER_PROTECTED         0x00000010
319 #define OBJC_MODIFIER_NATIVE            0x00000020
320 #define OBJC_MODIFIER_SYNCHRONIZED      0x00000040
321 #define OBJC_MODIFIER_ABSTRACT          0x00000080
322 #define OBJC_MODIFIER_VOLATILE          0x00000100
323 #define OBJC_MODIFIER_TRANSIENT         0x00000200
324 #define OBJC_MODIFIER_NONE_SPECIFIED    0x80000000
325
326 /* NeXT-specific tags.  */
327
328 #define TAG_MSGSEND_NONNIL              "objc_msgSendNonNil"
329 #define TAG_MSGSEND_NONNIL_STRET        "objc_msgSendNonNil_stret"
330 #define TAG_EXCEPTIONEXTRACT            "objc_exception_extract"
331 #define TAG_EXCEPTIONTRYENTER           "objc_exception_try_enter"
332 #define TAG_EXCEPTIONTRYEXIT            "objc_exception_try_exit"
333 #define TAG_EXCEPTIONMATCH              "objc_exception_match"
334 #define TAG_EXCEPTIONTHROW              "objc_exception_throw"
335 #define TAG_SYNCENTER                   "objc_sync_enter"
336 #define TAG_SYNCEXIT                    "objc_sync_exit"
337 #define TAG_SETJMP                      "_setjmp"
338 #define UTAG_EXCDATA                    "_objc_exception_data"
339
340 #define TAG_ASSIGNIVAR                  "objc_assign_ivar"
341 #define TAG_ASSIGNGLOBAL                "objc_assign_global"
342 #define TAG_ASSIGNSTRONGCAST            "objc_assign_strongCast"
343
344 /* Branch entry points.  All that matters here are the addresses;
345    functions with these names do not really exist in libobjc.  */
346
347 #define TAG_MSGSEND_FAST                "objc_msgSend_Fast"
348 #define TAG_ASSIGNIVAR_FAST             "objc_assign_ivar_Fast"
349
350 #define TAG_CXX_CONSTRUCT               ".cxx_construct"
351 #define TAG_CXX_DESTRUCT                ".cxx_destruct"
352
353 /* GNU-specific tags.  */
354
355 #define TAG_EXECCLASS                   "__objc_exec_class"
356 #define TAG_GNUINIT                     "__objc_gnu_init"
357
358 /* Flags for lookup_method_static().  */
359 #define OBJC_LOOKUP_CLASS       1       /* Look for class methods.  */
360 #define OBJC_LOOKUP_NO_SUPER    2       /* Do not examine superclasses.  */
361
362 /* The OCTI_... enumeration itself is in objc/objc-act.h.  */
363 tree objc_global_trees[OCTI_MAX];
364
365 static void handle_impent (struct imp_entry *);
366
367 struct imp_entry *imp_list = 0;
368 int imp_count = 0;      /* `@implementation' */
369 int cat_count = 0;      /* `@category' */
370
371 enum tree_code objc_inherit_code;
372 int objc_public_flag;
373
374 /* Use to generate method labels.  */
375 static int method_slot = 0;
376
377 #define BUFSIZE         1024
378
379 static char *errbuf;    /* Buffer for error diagnostics */
380
381 /* Data imported from tree.c.  */
382
383 extern enum debug_info_type write_symbols;
384
385 /* Data imported from toplev.c.  */
386
387 extern const char *dump_base_name;
388 \f
389 static int flag_typed_selectors;
390
391 /* Store all constructed constant strings in a hash table so that
392    they get uniqued properly.  */
393
394 struct GTY(()) string_descriptor {
395   /* The literal argument .  */
396   tree literal;
397
398   /* The resulting constant string.  */
399   tree constructor;
400 };
401
402 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
403
404 /* Store the EH-volatilized types in a hash table, for easy retrieval.  */
405 struct GTY(()) volatilized_type {
406   tree type;
407 };
408
409 static GTY((param_is (struct volatilized_type))) htab_t volatilized_htab;
410
411 FILE *gen_declaration_file;
412
413 /* Tells "encode_pointer/encode_aggregate" whether we are generating
414    type descriptors for instance variables (as opposed to methods).
415    Type descriptors for instance variables contain more information
416    than methods (for static typing and embedded structures).  */
417
418 static int generating_instance_variables = 0;
419
420 /* For building an objc struct.  These may not be used when this file
421    is compiled as part of obj-c++.  */
422
423 static bool objc_building_struct;
424 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
425
426 /* Start building a struct for objc.  */
427
428 static tree
429 objc_start_struct (tree name)
430 {
431   gcc_assert (!objc_building_struct);
432   objc_building_struct = true;
433   return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
434 }
435
436 /* Finish building a struct for objc.  */
437
438 static tree
439 objc_finish_struct (tree type, tree fieldlist)
440 {
441   gcc_assert (objc_building_struct);
442   objc_building_struct = false;
443   return finish_struct (input_location, type, fieldlist, NULL_TREE,
444                         objc_struct_info);
445 }
446
447 /* Some platforms pass small structures through registers versus
448    through an invisible pointer.  Determine at what size structure is
449    the transition point between the two possibilities.  */
450
451 static void
452 generate_struct_by_value_array (void)
453 {
454   tree type;
455   tree field_decl, field_decl_chain;
456   int i, j;
457   int aggregate_in_mem[32];
458   int found = 0;
459
460   /* Presumably no platform passes 32 byte structures in a register.  */
461   for (i = 1; i < 32; i++)
462     {
463       char buffer[5];
464
465       /* Create an unnamed struct that has `i' character components */
466       type = objc_start_struct (NULL_TREE);
467
468       strcpy (buffer, "c1");
469       field_decl = create_field_decl (char_type_node,
470                                       buffer);
471       field_decl_chain = field_decl;
472
473       for (j = 1; j < i; j++)
474         {
475           sprintf (buffer, "c%d", j + 1);
476           field_decl = create_field_decl (char_type_node,
477                                           buffer);
478           chainon (field_decl_chain, field_decl);
479         }
480       objc_finish_struct (type, field_decl_chain);
481
482       aggregate_in_mem[i] = aggregate_value_p (type, 0);
483       if (!aggregate_in_mem[i])
484         found = 1;
485     }
486
487   /* We found some structures that are returned in registers instead of memory
488      so output the necessary data.  */
489   if (found)
490     {
491       for (i = 31; i >= 0;  i--)
492         if (!aggregate_in_mem[i])
493           break;
494       printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
495
496       /* The first member of the structure is always 0 because we don't handle
497          structures with 0 members */
498       printf ("static int struct_forward_array[] = {\n  0");
499
500       for (j = 1; j <= i; j++)
501         printf (", %d", aggregate_in_mem[j]);
502       printf ("\n};\n");
503     }
504
505   exit (0);
506 }
507
508 bool
509 objc_init (void)
510 {
511 #ifdef OBJCPLUS
512   if (cxx_init () == false)
513 #else
514   if (c_objc_common_init () == false)
515 #endif
516     return false;
517
518   /* If gen_declaration desired, open the output file.  */
519   if (flag_gen_declaration)
520     {
521       register char * const dumpname = concat (dump_base_name, ".decl", NULL);
522       gen_declaration_file = fopen (dumpname, "w");
523       if (gen_declaration_file == 0)
524         fatal_error ("can't open %s: %m", dumpname);
525       free (dumpname);
526     }
527
528   if (flag_next_runtime)
529     {
530       TAG_GETCLASS = "objc_getClass";
531       TAG_GETMETACLASS = "objc_getMetaClass";
532       TAG_MSGSEND = "objc_msgSend";
533       TAG_MSGSENDSUPER = "objc_msgSendSuper";
534       TAG_MSGSEND_STRET = "objc_msgSend_stret";
535       TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
536       default_constant_string_class_name = "NSConstantString";
537     }
538   else
539     {
540       TAG_GETCLASS = "objc_get_class";
541       TAG_GETMETACLASS = "objc_get_meta_class";
542       TAG_MSGSEND = "objc_msg_lookup";
543       TAG_MSGSENDSUPER = "objc_msg_lookup_super";
544       /* GNU runtime does not provide special functions to support
545          structure-returning methods.  */
546       default_constant_string_class_name = "NXConstantString";
547       flag_typed_selectors = 1;
548     }
549
550   init_objc ();
551
552   if (print_struct_values && !flag_compare_debug)
553     generate_struct_by_value_array ();
554
555   return true;
556 }
557
558 void
559 objc_finish_file (void)
560 {
561   mark_referenced_methods ();
562
563 #ifdef OBJCPLUS
564   /* We need to instantiate templates _before_ we emit ObjC metadata;
565      if we do not, some metadata (such as selectors) may go missing.  */
566   at_eof = 1;
567   instantiate_pending_templates (0);
568 #endif
569
570   /* Finalize Objective-C runtime data.  No need to generate tables
571      and code if only checking syntax, or if generating a PCH file.  */
572   if (!flag_syntax_only && !pch_file)
573     finish_objc ();
574
575   if (gen_declaration_file)
576     fclose (gen_declaration_file);
577 }
578 \f
579 /* Return the first occurrence of a method declaration corresponding
580    to sel_name in rproto_list.  Search rproto_list recursively.
581    If is_class is 0, search for instance methods, otherwise for class
582    methods.  */
583 static tree
584 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
585                                 int is_class)
586 {
587    tree rproto, p;
588    tree fnd = 0;
589
590    for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
591      {
592         p = TREE_VALUE (rproto);
593
594         if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
595           {
596             if ((fnd = lookup_method (is_class
597                                       ? PROTOCOL_CLS_METHODS (p)
598                                       : PROTOCOL_NST_METHODS (p), sel_name)))
599               ;
600             else if (PROTOCOL_LIST (p))
601               fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
602                                                     sel_name, is_class);
603           }
604         else
605           {
606             ; /* An identifier...if we could not find a protocol.  */
607           }
608
609         if (fnd)
610           return fnd;
611      }
612
613    return 0;
614 }
615
616 static tree
617 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
618 {
619   tree rproto, p;
620
621   /* Make sure the protocol is supported by the object on the rhs.  */
622   if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
623     {
624       tree fnd = 0;
625       for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
626         {
627           p = TREE_VALUE (rproto);
628
629           if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
630             {
631               if (lproto == p)
632                 fnd = lproto;
633
634               else if (PROTOCOL_LIST (p))
635                 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
636             }
637
638           if (fnd)
639             return fnd;
640         }
641     }
642   else
643     {
644       ; /* An identifier...if we could not find a protocol.  */
645     }
646
647   return 0;
648 }
649
650 void
651 objc_start_class_interface (tree klass, tree super_class, tree protos)
652 {
653   objc_interface_context
654     = objc_ivar_context
655     = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
656   objc_public_flag = 0;
657 }
658
659 void
660 objc_start_category_interface (tree klass, tree categ, tree protos)
661 {
662   objc_interface_context
663     = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
664   objc_ivar_chain
665     = continue_class (objc_interface_context);
666 }
667
668 void
669 objc_start_protocol (tree name, tree protos)
670 {
671   objc_interface_context
672     = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
673 }
674
675 void
676 objc_continue_interface (void)
677 {
678   objc_ivar_chain
679     = continue_class (objc_interface_context);
680 }
681
682 void
683 objc_finish_interface (void)
684 {
685   finish_class (objc_interface_context);
686   objc_interface_context = NULL_TREE;
687 }
688
689 void
690 objc_start_class_implementation (tree klass, tree super_class)
691 {
692   objc_implementation_context
693     = objc_ivar_context
694     = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
695   objc_public_flag = 0;
696 }
697
698 void
699 objc_start_category_implementation (tree klass, tree categ)
700 {
701   objc_implementation_context
702     = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
703   objc_ivar_chain
704     = continue_class (objc_implementation_context);
705 }
706
707 void
708 objc_continue_implementation (void)
709 {
710   objc_ivar_chain
711     = continue_class (objc_implementation_context);
712 }
713
714 void
715 objc_finish_implementation (void)
716 {
717 #ifdef OBJCPLUS
718   if (flag_objc_call_cxx_cdtors)
719     objc_generate_cxx_cdtors ();
720 #endif
721
722   if (objc_implementation_context)
723     {
724       finish_class (objc_implementation_context);
725       objc_ivar_chain = NULL_TREE;
726       objc_implementation_context = NULL_TREE;
727     }
728   else
729     warning (0, "%<@end%> must appear in an @implementation context");
730 }
731
732 void
733 objc_set_visibility (int visibility)
734 {
735   objc_public_flag = visibility;
736 }
737
738 void
739 objc_set_method_type (enum tree_code type)
740 {
741   objc_inherit_code = (type == PLUS_EXPR
742                        ? CLASS_METHOD_DECL
743                        : INSTANCE_METHOD_DECL);
744 }
745
746 tree
747 objc_build_method_signature (tree rettype, tree selector,
748                              tree optparms, bool ellipsis)
749 {
750   return build_method_decl (objc_inherit_code, rettype, selector,
751                             optparms, ellipsis);
752 }
753
754 void
755 objc_add_method_declaration (tree decl)
756 {
757   if (!objc_interface_context)
758     fatal_error ("method declaration not in @interface context");
759
760   objc_add_method (objc_interface_context,
761                    decl,
762                    objc_inherit_code == CLASS_METHOD_DECL);
763 }
764
765 void
766 objc_start_method_definition (tree decl)
767 {
768   if (!objc_implementation_context)
769     fatal_error ("method definition not in @implementation context");
770
771   objc_add_method (objc_implementation_context,
772                    decl,
773                    objc_inherit_code == CLASS_METHOD_DECL);
774   start_method_def (decl);
775 }
776
777 void
778 objc_add_instance_variable (tree decl)
779 {
780   (void) add_instance_variable (objc_ivar_context,
781                                 objc_public_flag,
782                                 decl);
783 }
784
785 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
786    an '@'.  */
787
788 int
789 objc_is_reserved_word (tree ident)
790 {
791   unsigned char code = C_RID_CODE (ident);
792
793   return (OBJC_IS_AT_KEYWORD (code)
794           || code == RID_CLASS || code == RID_PUBLIC
795           || code == RID_PROTECTED || code == RID_PRIVATE
796           || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
797 }
798
799 /* Return true if TYPE is 'id'.  */
800
801 static bool
802 objc_is_object_id (tree type)
803 {
804   return OBJC_TYPE_NAME (type) == objc_object_id;
805 }
806
807 static bool
808 objc_is_class_id (tree type)
809 {
810   return OBJC_TYPE_NAME (type) == objc_class_id;
811 }
812
813 /* Construct a C struct with same name as KLASS, a base struct with tag
814    SUPER_NAME (if any), and FIELDS indicated.  */
815
816 static tree
817 objc_build_struct (tree klass, tree fields, tree super_name)
818 {
819   tree name = CLASS_NAME (klass);
820   tree s = objc_start_struct (name);
821   tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
822   tree t, objc_info = NULL_TREE;
823
824   if (super)
825     {
826       /* Prepend a packed variant of the base class into the layout.  This
827          is necessary to preserve ObjC ABI compatibility.  */
828       tree base = build_decl (input_location,
829                               FIELD_DECL, NULL_TREE, super);
830       tree field = TYPE_FIELDS (super);
831
832       while (field && TREE_CHAIN (field)
833              && TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
834         field = TREE_CHAIN (field);
835
836       /* For ObjC ABI purposes, the "packed" size of a base class is
837          the sum of the offset and the size (in bits) of the last field
838          in the class.  */
839       DECL_SIZE (base)
840         = (field && TREE_CODE (field) == FIELD_DECL
841            ? size_binop (PLUS_EXPR,
842                          size_binop (PLUS_EXPR,
843                                      size_binop
844                                      (MULT_EXPR,
845                                       convert (bitsizetype,
846                                                DECL_FIELD_OFFSET (field)),
847                                       bitsize_int (BITS_PER_UNIT)),
848                                      DECL_FIELD_BIT_OFFSET (field)),
849                          DECL_SIZE (field))
850            : bitsize_zero_node);
851       DECL_SIZE_UNIT (base)
852         = size_binop (FLOOR_DIV_EXPR, convert (sizetype, DECL_SIZE (base)),
853                       size_int (BITS_PER_UNIT));
854       DECL_ARTIFICIAL (base) = 1;
855       DECL_ALIGN (base) = 1;
856       DECL_FIELD_CONTEXT (base) = s;
857 #ifdef OBJCPLUS
858       DECL_FIELD_IS_BASE (base) = 1;
859
860       if (fields)
861         TREE_NO_WARNING (fields) = 1;   /* Suppress C++ ABI warnings -- we   */
862 #endif                                  /* are following the ObjC ABI here.  */
863       TREE_CHAIN (base) = fields;
864       fields = base;
865     }
866
867   /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
868      in all variants of this RECORD_TYPE to be clobbered, but it is therein
869      that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
870      Hence, we must squirrel away the ObjC-specific information before calling
871      finish_struct(), and then reinstate it afterwards.  */
872
873   for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
874     {
875       if (!TYPE_HAS_OBJC_INFO (t))
876         {
877           INIT_TYPE_OBJC_INFO (t);
878           TYPE_OBJC_INTERFACE (t) = klass;
879         }
880       objc_info
881         = chainon (objc_info,
882                    build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
883     }
884
885   /* Point the struct at its related Objective-C class.  */
886   INIT_TYPE_OBJC_INFO (s);
887   TYPE_OBJC_INTERFACE (s) = klass;
888
889   s = objc_finish_struct (s, fields);
890
891   for (t = TYPE_NEXT_VARIANT (s); t;
892        t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
893     {
894       TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
895       /* Replace the IDENTIFIER_NODE with an actual @interface.  */
896       TYPE_OBJC_INTERFACE (t) = klass;
897     }
898
899   /* Use TYPE_BINFO structures to point at the super class, if any.  */
900   objc_xref_basetypes (s, super);
901
902   /* Mark this struct as a class template.  */
903   CLASS_STATIC_TEMPLATE (klass) = s;
904
905   return s;
906 }
907
908 /* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
909    Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
910    process.  */
911 static tree
912 objc_build_volatilized_type (tree type)
913 {
914   tree t;
915
916   /* Check if we have not constructed the desired variant already.  */
917   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
918     {
919       /* The type qualifiers must (obviously) match up.  */
920       if (!TYPE_VOLATILE (t)
921           || (TYPE_READONLY (t) != TYPE_READONLY (type))
922           || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
923         continue;
924
925       /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
926          info, if any) must match up.  */
927       if (POINTER_TYPE_P (t)
928           && (TREE_TYPE (t) != TREE_TYPE (type)))
929         continue;
930
931       /* Everything matches up!  */
932       return t;
933     }
934
935   /* Ok, we could not re-use any of the pre-existing variants.  Create
936      a new one.  */
937   t = build_variant_type_copy (type);
938   TYPE_VOLATILE (t) = 1;
939
940   /* Set up the canonical type information. */
941   if (TYPE_STRUCTURAL_EQUALITY_P (type))
942     SET_TYPE_STRUCTURAL_EQUALITY (t);
943   else if (TYPE_CANONICAL (type) != type)
944     TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
945   else
946     TYPE_CANONICAL (t) = t;
947
948   return t;
949 }
950
951 /* Mark DECL as being 'volatile' for purposes of Darwin
952    _setjmp()/_longjmp() exception handling.  Called from
953    objc_mark_locals_volatile().  */
954 void
955 objc_volatilize_decl (tree decl)
956 {
957   /* Do not mess with variables that are 'static' or (already)
958      'volatile'.  */
959   if (!TREE_THIS_VOLATILE (decl) && !TREE_STATIC (decl)
960       && (TREE_CODE (decl) == VAR_DECL
961           || TREE_CODE (decl) == PARM_DECL))
962     {
963       tree t = TREE_TYPE (decl);
964       struct volatilized_type key;
965       void **loc;
966
967       t = objc_build_volatilized_type (t);
968       key.type = t;
969       loc = htab_find_slot (volatilized_htab, &key, INSERT);
970
971       if (!*loc)
972         {
973           *loc = ggc_alloc (sizeof (key));
974           ((struct volatilized_type *) *loc)->type = t;
975         }
976
977       TREE_TYPE (decl) = t;
978       TREE_THIS_VOLATILE (decl) = 1;
979       TREE_SIDE_EFFECTS (decl) = 1;
980       DECL_REGISTER (decl) = 0;
981 #ifndef OBJCPLUS
982       C_DECL_REGISTER (decl) = 0;
983 #endif
984     }
985 }
986
987 /* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
988    (including its categories and superclasses) or by object type TYP.
989    Issue a warning if PROTO is not adopted anywhere and WARN is set.  */
990
991 static bool
992 objc_lookup_protocol (tree proto, tree cls, tree typ, bool warn)
993 {
994   bool class_type = (cls != NULL_TREE);
995
996   while (cls)
997     {
998       tree c;
999
1000       /* Check protocols adopted by the class and its categories.  */
1001       for (c = cls; c; c = CLASS_CATEGORY_LIST (c))
1002         {
1003           if (lookup_protocol_in_reflist (CLASS_PROTOCOL_LIST (c), proto))
1004             return true;
1005         }
1006
1007       /* Repeat for superclasses.  */
1008       cls = lookup_interface (CLASS_SUPER_NAME (cls));
1009     }
1010
1011   /* Check for any protocols attached directly to the object type.  */
1012   if (TYPE_HAS_OBJC_INFO (typ))
1013     {
1014       if (lookup_protocol_in_reflist (TYPE_OBJC_PROTOCOL_LIST (typ), proto))
1015         return true;
1016     }
1017
1018   if (warn)
1019     {
1020       *errbuf = 0;
1021       gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
1022       /* NB: Types 'id' and 'Class' cannot reasonably be described as
1023          "implementing" a given protocol, since they do not have an
1024          implementation.  */
1025       if (class_type)
1026         warning (0, "class %qs does not implement the %qE protocol",
1027                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1028       else
1029         warning (0, "type %qs does not conform to the %qE protocol",
1030                  identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
1031     }
1032
1033   return false;
1034 }
1035
1036 /* Check if class RCLS and instance struct type RTYP conform to at least the
1037    same protocols that LCLS and LTYP conform to.  */
1038
1039 static bool
1040 objc_compare_protocols (tree lcls, tree ltyp, tree rcls, tree rtyp, bool warn)
1041 {
1042   tree p;
1043   bool have_lproto = false;
1044
1045   while (lcls)
1046     {
1047       /* NB: We do _not_ look at categories defined for LCLS; these may or
1048          may not get loaded in, and therefore it is unreasonable to require
1049          that RCLS/RTYP must implement any of their protocols.  */
1050       for (p = CLASS_PROTOCOL_LIST (lcls); p; p = TREE_CHAIN (p))
1051         {
1052           have_lproto = true;
1053
1054           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1055             return warn;
1056         }
1057
1058       /* Repeat for superclasses.  */
1059       lcls = lookup_interface (CLASS_SUPER_NAME (lcls));
1060     }
1061
1062   /* Check for any protocols attached directly to the object type.  */
1063   if (TYPE_HAS_OBJC_INFO (ltyp))
1064     {
1065       for (p = TYPE_OBJC_PROTOCOL_LIST (ltyp); p; p = TREE_CHAIN (p))
1066         {
1067           have_lproto = true;
1068
1069           if (!objc_lookup_protocol (TREE_VALUE (p), rcls, rtyp, warn))
1070             return warn;
1071         }
1072     }
1073
1074   /* NB: If LTYP and LCLS have no protocols to search for, return 'true'
1075      vacuously, _unless_ RTYP is a protocol-qualified 'id'.  We can get
1076      away with simply checking for 'id' or 'Class' (!RCLS), since this
1077      routine will not get called in other cases.  */
1078   return have_lproto || (rcls != NULL_TREE);
1079 }
1080
1081 /* Determine if it is permissible to assign (if ARGNO is greater than -3)
1082    an instance of RTYP to an instance of LTYP or to compare the two
1083    (if ARGNO is equal to -3), per ObjC type system rules.  Before
1084    returning 'true', this routine may issue warnings related to, e.g.,
1085    protocol conformance.  When returning 'false', the routine must
1086    produce absolutely no warnings; the C or C++ front-end will do so
1087    instead, if needed.  If either LTYP or RTYP is not an Objective-C type,
1088    the routine must return 'false'.
1089
1090    The ARGNO parameter is encoded as follows:
1091      >= 1       Parameter number (CALLEE contains function being called);
1092      0          Return value;
1093      -1         Assignment;
1094      -2         Initialization;
1095      -3         Comparison (LTYP and RTYP may match in either direction).  */
1096
1097 bool
1098 objc_compare_types (tree ltyp, tree rtyp, int argno, tree callee)
1099 {
1100   tree lcls, rcls, lproto, rproto;
1101   bool pointers_compatible;
1102
1103   /* We must be dealing with pointer types */
1104   if (!POINTER_TYPE_P (ltyp) || !POINTER_TYPE_P (rtyp))
1105     return false;
1106
1107   do
1108     {
1109       ltyp = TREE_TYPE (ltyp);  /* Remove indirections.  */
1110       rtyp = TREE_TYPE (rtyp);
1111     }
1112   while (POINTER_TYPE_P (ltyp) && POINTER_TYPE_P (rtyp));
1113
1114   /* Past this point, we are only interested in ObjC class instances,
1115      or 'id' or 'Class'.  */
1116   if (TREE_CODE (ltyp) != RECORD_TYPE || TREE_CODE (rtyp) != RECORD_TYPE)
1117     return false;
1118
1119   if (!objc_is_object_id (ltyp) && !objc_is_class_id (ltyp)
1120       && !TYPE_HAS_OBJC_INFO (ltyp))
1121     return false;
1122
1123   if (!objc_is_object_id (rtyp) && !objc_is_class_id (rtyp)
1124       && !TYPE_HAS_OBJC_INFO (rtyp))
1125     return false;
1126
1127   /* Past this point, we are committed to returning 'true' to the caller.
1128      However, we can still warn about type and/or protocol mismatches.  */
1129
1130   if (TYPE_HAS_OBJC_INFO (ltyp))
1131     {
1132       lcls = TYPE_OBJC_INTERFACE (ltyp);
1133       lproto = TYPE_OBJC_PROTOCOL_LIST (ltyp);
1134     }
1135   else
1136     lcls = lproto = NULL_TREE;
1137
1138   if (TYPE_HAS_OBJC_INFO (rtyp))
1139     {
1140       rcls = TYPE_OBJC_INTERFACE (rtyp);
1141       rproto = TYPE_OBJC_PROTOCOL_LIST (rtyp);
1142     }
1143   else
1144     rcls = rproto = NULL_TREE;
1145
1146   /* If we could not find an @interface declaration, we must have
1147      only seen a @class declaration; for purposes of type comparison,
1148      treat it as a stand-alone (root) class.  */
1149
1150   if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
1151     lcls = NULL_TREE;
1152
1153   if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
1154     rcls = NULL_TREE;
1155
1156   /* If either type is an unqualified 'id', we're done.  */
1157   if ((!lproto && objc_is_object_id (ltyp))
1158       || (!rproto && objc_is_object_id (rtyp)))
1159     return true;
1160
1161   pointers_compatible = (TYPE_MAIN_VARIANT (ltyp) == TYPE_MAIN_VARIANT (rtyp));
1162
1163   /* If the underlying types are the same, and at most one of them has
1164      a protocol list, we do not need to issue any diagnostics.  */
1165   if (pointers_compatible && (!lproto || !rproto))
1166     return true;
1167
1168   /* If exactly one of the types is 'Class', issue a diagnostic; any
1169      exceptions of this rule have already been handled.  */
1170   if (objc_is_class_id (ltyp) ^ objc_is_class_id (rtyp))
1171     pointers_compatible = false;
1172   /* Otherwise, check for inheritance relations.  */
1173   else
1174     {
1175       if (!pointers_compatible)
1176         pointers_compatible
1177           = (objc_is_object_id (ltyp) || objc_is_object_id (rtyp));
1178
1179       if (!pointers_compatible)
1180         pointers_compatible = DERIVED_FROM_P (ltyp, rtyp);
1181
1182       if (!pointers_compatible && argno == -3)
1183         pointers_compatible = DERIVED_FROM_P (rtyp, ltyp);
1184     }
1185
1186   /* If the pointers match modulo protocols, check for protocol conformance
1187      mismatches.  */
1188   if (pointers_compatible)
1189     {
1190       pointers_compatible = objc_compare_protocols (lcls, ltyp, rcls, rtyp,
1191                                                     argno != -3);
1192
1193       if (!pointers_compatible && argno == -3)
1194         pointers_compatible = objc_compare_protocols (rcls, rtyp, lcls, ltyp,
1195                                                       argno != -3);
1196     }
1197
1198   if (!pointers_compatible)
1199     {
1200       /* NB: For the time being, we shall make our warnings look like their
1201          C counterparts.  In the future, we may wish to make them more
1202          ObjC-specific.  */
1203       switch (argno)
1204         {
1205         case -3:
1206           warning (0, "comparison of distinct Objective-C types lacks a cast");
1207           break;
1208
1209         case -2:
1210           warning (0, "initialization from distinct Objective-C type");
1211           break;
1212
1213         case -1:
1214           warning (0, "assignment from distinct Objective-C type");
1215           break;
1216
1217         case 0:
1218           warning (0, "distinct Objective-C type in return");
1219           break;
1220
1221         default:
1222           warning (0, "passing argument %d of %qE from distinct "
1223                    "Objective-C type", argno, callee);
1224           break;
1225         }
1226     }
1227
1228   return true;
1229 }
1230
1231 /* Check if LTYP and RTYP have the same type qualifiers.  If either type
1232    lives in the volatilized hash table, ignore the 'volatile' bit when
1233    making the comparison.  */
1234
1235 bool
1236 objc_type_quals_match (tree ltyp, tree rtyp)
1237 {
1238   int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp);
1239   struct volatilized_type key;
1240
1241   key.type = ltyp;
1242
1243   if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1244     lquals &= ~TYPE_QUAL_VOLATILE;
1245
1246   key.type = rtyp;
1247
1248   if (htab_find_slot (volatilized_htab, &key, NO_INSERT))
1249     rquals &= ~TYPE_QUAL_VOLATILE;
1250
1251   return (lquals == rquals);
1252 }
1253
1254 #ifndef OBJCPLUS
1255 /* Determine if CHILD is derived from PARENT.  The routine assumes that
1256    both parameters are RECORD_TYPEs, and is non-reflexive.  */
1257
1258 static bool
1259 objc_derived_from_p (tree parent, tree child)
1260 {
1261   parent = TYPE_MAIN_VARIANT (parent);
1262
1263   for (child = TYPE_MAIN_VARIANT (child);
1264        TYPE_BINFO (child) && BINFO_N_BASE_BINFOS (TYPE_BINFO (child));)
1265     {
1266       child = TYPE_MAIN_VARIANT (BINFO_TYPE (BINFO_BASE_BINFO
1267                                              (TYPE_BINFO (child),
1268                                               0)));
1269
1270       if (child == parent)
1271         return true;
1272     }
1273
1274   return false;
1275 }
1276 #endif
1277
1278 static tree
1279 objc_build_component_ref (tree datum, tree component)
1280 {
1281   /* If COMPONENT is NULL, the caller is referring to the anonymous
1282      base class field.  */
1283   if (!component)
1284     {
1285       tree base = TYPE_FIELDS (TREE_TYPE (datum));
1286
1287       return build3 (COMPONENT_REF, TREE_TYPE (base), datum, base, NULL_TREE);
1288     }
1289
1290   /* The 'build_component_ref' routine has been removed from the C++
1291      front-end, but 'finish_class_member_access_expr' seems to be
1292      a worthy substitute.  */
1293 #ifdef OBJCPLUS
1294   return finish_class_member_access_expr (datum, component, false,
1295                                           tf_warning_or_error);
1296 #else
1297   return build_component_ref (input_location, datum, component);
1298 #endif
1299 }
1300
1301 /* Recursively copy inheritance information rooted at BINFO.  To do this,
1302    we emulate the song and dance performed by cp/tree.c:copy_binfo().  */
1303
1304 static tree
1305 objc_copy_binfo (tree binfo)
1306 {
1307   tree btype = BINFO_TYPE (binfo);
1308   tree binfo2 = make_tree_binfo (BINFO_N_BASE_BINFOS (binfo));
1309   tree base_binfo;
1310   int ix;
1311
1312   BINFO_TYPE (binfo2) = btype;
1313   BINFO_OFFSET (binfo2) = BINFO_OFFSET (binfo);
1314   BINFO_BASE_ACCESSES (binfo2) = BINFO_BASE_ACCESSES (binfo);
1315
1316   /* Recursively copy base binfos of BINFO.  */
1317   for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
1318     {
1319       tree base_binfo2 = objc_copy_binfo (base_binfo);
1320
1321       BINFO_INHERITANCE_CHAIN (base_binfo2) = binfo2;
1322       BINFO_BASE_APPEND (binfo2, base_binfo2);
1323     }
1324
1325   return binfo2;
1326 }
1327
1328 /* Record superclass information provided in BASETYPE for ObjC class REF.
1329    This is loosely based on cp/decl.c:xref_basetypes().  */
1330
1331 static void
1332 objc_xref_basetypes (tree ref, tree basetype)
1333 {
1334   tree binfo = make_tree_binfo (basetype ? 1 : 0);
1335
1336   TYPE_BINFO (ref) = binfo;
1337   BINFO_OFFSET (binfo) = size_zero_node;
1338   BINFO_TYPE (binfo) = ref;
1339
1340   if (basetype)
1341     {
1342       tree base_binfo = objc_copy_binfo (TYPE_BINFO (basetype));
1343
1344       BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
1345       BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, 1);
1346       BINFO_BASE_APPEND (binfo, base_binfo);
1347       BINFO_BASE_ACCESS_APPEND (binfo, access_public_node);
1348     }
1349 }
1350
1351 static hashval_t
1352 volatilized_hash (const void *ptr)
1353 {
1354   const_tree const typ = ((const struct volatilized_type *)ptr)->type;
1355
1356   return htab_hash_pointer(typ);
1357 }
1358
1359 static int
1360 volatilized_eq (const void *ptr1, const void *ptr2)
1361 {
1362   const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
1363   const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
1364
1365   return typ1 == typ2;
1366 }
1367
1368 /* Called from finish_decl.  */
1369
1370 void
1371 objc_check_decl (tree decl)
1372 {
1373   tree type = TREE_TYPE (decl);
1374
1375   if (TREE_CODE (type) != RECORD_TYPE)
1376     return;
1377   if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1378     error ("statically allocated instance of Objective-C class %qE",
1379            type);
1380 }
1381
1382 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1383    either name an Objective-C class, or refer to the special 'id' or 'Class'
1384    types.  If INTERFACE is not a valid ObjC type, just return it unchanged.  */
1385
1386 tree
1387 objc_get_protocol_qualified_type (tree interface, tree protocols)
1388 {
1389   /* If INTERFACE is not provided, default to 'id'.  */
1390   tree type = (interface ? objc_is_id (interface) : objc_object_type);
1391   bool is_ptr = (type != NULL_TREE);
1392
1393   if (!is_ptr)
1394     {
1395       type = objc_is_class_name (interface);
1396
1397       if (type)
1398         type = xref_tag (RECORD_TYPE, type);
1399       else
1400         return interface;
1401     }
1402
1403   if (protocols)
1404     {
1405       type = build_variant_type_copy (type);
1406
1407       /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1408          to the pointee.  */
1409       if (is_ptr)
1410         {
1411           tree orig_pointee_type = TREE_TYPE (type);
1412           TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
1413
1414           /* Set up the canonical type information. */
1415           TYPE_CANONICAL (type) 
1416             = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
1417
1418           TYPE_POINTER_TO (TREE_TYPE (type)) = type;
1419           type = TREE_TYPE (type);
1420         }
1421
1422       /* Look up protocols and install in lang specific list.  */
1423       DUP_TYPE_OBJC_INFO (type, TYPE_MAIN_VARIANT (type));
1424       TYPE_OBJC_PROTOCOL_LIST (type) = lookup_and_install_protocols (protocols);
1425
1426       /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1427          return the pointer to the new pointee variant.  */
1428       if (is_ptr)
1429         type = TYPE_POINTER_TO (type);
1430       else
1431         TYPE_OBJC_INTERFACE (type)
1432           = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type));
1433     }
1434
1435   return type;
1436 }
1437
1438 /* Check for circular dependencies in protocols.  The arguments are
1439    PROTO, the protocol to check, and LIST, a list of protocol it
1440    conforms to.  */
1441
1442 static void
1443 check_protocol_recursively (tree proto, tree list)
1444 {
1445   tree p;
1446
1447   for (p = list; p; p = TREE_CHAIN (p))
1448     {
1449       tree pp = TREE_VALUE (p);
1450
1451       if (TREE_CODE (pp) == IDENTIFIER_NODE)
1452         pp = lookup_protocol (pp);
1453
1454       if (pp == proto)
1455         fatal_error ("protocol %qE has circular dependency",
1456                      PROTOCOL_NAME (pp));
1457       if (pp)
1458         check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1459     }
1460 }
1461
1462 /* Look up PROTOCOLS, and return a list of those that are found.
1463    If none are found, return NULL.  */
1464
1465 static tree
1466 lookup_and_install_protocols (tree protocols)
1467 {
1468   tree proto;
1469   tree return_value = NULL_TREE;
1470
1471   for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1472     {
1473       tree ident = TREE_VALUE (proto);
1474       tree p = lookup_protocol (ident);
1475
1476       if (p)
1477         return_value = chainon (return_value,
1478                                 build_tree_list (NULL_TREE, p));
1479       else if (ident != error_mark_node)
1480         error ("cannot find protocol declaration for %qE",
1481                ident);
1482     }
1483
1484   return return_value;
1485 }
1486
1487 /* Create a declaration for field NAME of a given TYPE.  */
1488
1489 static tree
1490 create_field_decl (tree type, const char *name)
1491 {
1492   return build_decl (input_location,
1493                      FIELD_DECL, get_identifier (name), type);
1494 }
1495
1496 /* Create a global, static declaration for variable NAME of a given TYPE.  The
1497    finish_var_decl() routine will need to be called on it afterwards.  */
1498
1499 static tree
1500 start_var_decl (tree type, const char *name)
1501 {
1502   tree var = build_decl (input_location,
1503                          VAR_DECL, get_identifier (name), type);
1504
1505   TREE_STATIC (var) = 1;
1506   DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
1507   DECL_IGNORED_P (var) = 1;
1508   DECL_ARTIFICIAL (var) = 1;
1509   DECL_CONTEXT (var) = NULL_TREE;
1510 #ifdef OBJCPLUS
1511   DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1512 #endif
1513
1514   return var;
1515 }
1516
1517 /* Finish off the variable declaration created by start_var_decl().  */
1518
1519 static void
1520 finish_var_decl (tree var, tree initializer)
1521 {
1522   finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
1523   /* Ensure that the variable actually gets output.  */
1524   mark_decl_referenced (var);
1525   /* Mark the decl to avoid "defined but not used" warning.  */
1526   TREE_USED (var) = 1;
1527   /* We reserve the right for the runtime to use/modify these variables
1528      in ways that are opaque to us.  */
1529   DECL_PRESERVE_P (var) = 1;
1530   /* ipa*.c/cgraphunit.c use lookup attribute rather than testing
1531      DECL_PRESERVE_P.  Once they switch to testing DECL_PRESERVE_P,
1532      this can be removed. */
1533   DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("used"), NULL, 
1534                                      DECL_ATTRIBUTES (var)) ;
1535 }
1536
1537 /* Find the decl for the constant string class reference.  This is only
1538    used for the NeXT runtime.  */
1539
1540 static tree
1541 setup_string_decl (void)
1542 {
1543   char *name;
1544   size_t length;
1545
1546   /* %s in format will provide room for terminating null */
1547   length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1548            + strlen (constant_string_class_name);
1549   name = XNEWVEC (char, length);
1550   sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1551            constant_string_class_name);
1552   constant_string_global_id = get_identifier (name);
1553   string_class_decl = lookup_name (constant_string_global_id);
1554
1555   return string_class_decl;
1556 }
1557
1558 /* Purpose: "play" parser, creating/installing representations
1559    of the declarations that are required by Objective-C.
1560
1561    Model:
1562
1563         type_spec--------->sc_spec
1564         (tree_list)        (tree_list)
1565             |                  |
1566             |                  |
1567         identifier_node    identifier_node  */
1568
1569 static void
1570 synth_module_prologue (void)
1571 {
1572   tree type;
1573   enum debug_info_type save_write_symbols = write_symbols;
1574   const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1575
1576   /* Suppress outputting debug symbols, because
1577      dbxout_init hasn't been called yet.  */
1578   write_symbols = NO_DEBUG;
1579   debug_hooks = &do_nothing_debug_hooks;
1580
1581 #ifdef OBJCPLUS
1582   push_lang_context (lang_name_c); /* extern "C" */
1583 #endif
1584
1585   /* The following are also defined in <objc/objc.h> and friends.  */
1586
1587   objc_object_id = get_identifier (TAG_OBJECT);
1588   objc_class_id = get_identifier (TAG_CLASS);
1589
1590   objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1591   objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1592
1593   objc_object_type = build_pointer_type (objc_object_reference);
1594   objc_class_type = build_pointer_type (objc_class_reference);
1595
1596   objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1597   objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1598
1599   /* Declare the 'id' and 'Class' typedefs.  */
1600
1601   type = lang_hooks.decls.pushdecl (build_decl (input_location,
1602                                                 TYPE_DECL,
1603                                                 objc_object_name,
1604                                                 objc_object_type));
1605   TREE_NO_WARNING (type) = 1;
1606   type = lang_hooks.decls.pushdecl (build_decl (input_location,
1607                                                 TYPE_DECL,
1608                                                 objc_class_name,
1609                                                 objc_class_type));
1610   TREE_NO_WARNING (type) = 1;
1611
1612   /* Forward-declare '@interface Protocol'.  */
1613
1614   type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1615   objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1616   objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1617                                 type));
1618
1619   /* Declare type of selector-objects that represent an operation name.  */
1620
1621   if (flag_next_runtime)
1622     /* `struct objc_selector *' */
1623     objc_selector_type
1624       = build_pointer_type (xref_tag (RECORD_TYPE,
1625                                       get_identifier (TAG_SELECTOR)));
1626   else
1627     /* `const struct objc_selector *' */
1628     objc_selector_type
1629       = build_pointer_type
1630         (build_qualified_type (xref_tag (RECORD_TYPE,
1631                                          get_identifier (TAG_SELECTOR)),
1632                                TYPE_QUAL_CONST));
1633
1634   /* Declare receiver type used for dispatching messages to 'super'.  */
1635
1636   /* `struct objc_super *' */
1637   objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1638                                                   get_identifier (TAG_SUPER)));
1639
1640   /* Declare pointers to method and ivar lists.  */
1641   objc_method_list_ptr = build_pointer_type
1642                          (xref_tag (RECORD_TYPE,
1643                                     get_identifier (UTAG_METHOD_LIST)));
1644   objc_method_proto_list_ptr
1645     = build_pointer_type (xref_tag (RECORD_TYPE,
1646                                     get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
1647   objc_ivar_list_ptr = build_pointer_type
1648                        (xref_tag (RECORD_TYPE,
1649                                   get_identifier (UTAG_IVAR_LIST)));
1650
1651   /* TREE_NOTHROW is cleared for the message-sending functions,
1652      because the function that gets called can throw in Obj-C++, or
1653      could itself call something that can throw even in Obj-C.  */
1654
1655   if (flag_next_runtime)
1656     {
1657       /* NB: In order to call one of the ..._stret (struct-returning)
1658       functions, the function *MUST* first be cast to a signature that
1659       corresponds to the actual ObjC method being invoked.  This is
1660       what is done by the build_objc_method_call() routine below.  */
1661
1662       /* id objc_msgSend (id, SEL, ...); */
1663       /* id objc_msgSendNonNil (id, SEL, ...); */
1664       /* id objc_msgSend_stret (id, SEL, ...); */
1665       /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1666       type
1667         = build_function_type (objc_object_type,
1668                                tree_cons (NULL_TREE, objc_object_type,
1669                                           tree_cons (NULL_TREE, objc_selector_type,
1670                                                      NULL_TREE)));
1671       umsg_decl = add_builtin_function (TAG_MSGSEND,
1672                                         type, 0, NOT_BUILT_IN,
1673                                         NULL, NULL_TREE);
1674       umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
1675                                                type, 0, NOT_BUILT_IN,
1676                                                NULL, NULL_TREE);
1677       umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
1678                                               type, 0, NOT_BUILT_IN,
1679                                               NULL, NULL_TREE);
1680       umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
1681                                                      type, 0, NOT_BUILT_IN,
1682                                                      NULL, NULL_TREE);
1683
1684       /* These can throw, because the function that gets called can throw
1685          in Obj-C++, or could itself call something that can throw even
1686          in Obj-C.  */
1687       TREE_NOTHROW (umsg_decl) = 0;
1688       TREE_NOTHROW (umsg_nonnil_decl) = 0;
1689       TREE_NOTHROW (umsg_stret_decl) = 0;
1690       TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
1691
1692       /* id objc_msgSend_Fast (id, SEL, ...)
1693            __attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
1694 #ifdef OFFS_MSGSEND_FAST
1695       umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
1696                                              type, 0, NOT_BUILT_IN,
1697                                              NULL, NULL_TREE);
1698       TREE_NOTHROW (umsg_fast_decl) = 0;
1699       DECL_ATTRIBUTES (umsg_fast_decl)
1700         = tree_cons (get_identifier ("hard_coded_address"),
1701                      build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
1702                      NULL_TREE);
1703 #else
1704       /* No direct dispatch available.  */
1705       umsg_fast_decl = umsg_decl;
1706 #endif
1707
1708       /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1709       /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1710       type
1711         = build_function_type (objc_object_type,
1712                                tree_cons (NULL_TREE, objc_super_type,
1713                                           tree_cons (NULL_TREE, objc_selector_type,
1714                                                      NULL_TREE)));
1715       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1716                                               type, 0, NOT_BUILT_IN,
1717                                               NULL, NULL_TREE);
1718       umsg_super_stret_decl = add_builtin_function (TAG_MSGSENDSUPER_STRET,
1719                                                     type, 0, NOT_BUILT_IN, 0,
1720                                                     NULL_TREE);
1721       TREE_NOTHROW (umsg_super_decl) = 0;
1722       TREE_NOTHROW (umsg_super_stret_decl) = 0;
1723     }
1724   else
1725     {
1726       /* GNU runtime messenger entry points.  */
1727
1728       /* typedef id (*IMP)(id, SEL, ...); */
1729       tree IMP_type
1730         = build_pointer_type
1731           (build_function_type (objc_object_type,
1732                                 tree_cons (NULL_TREE, objc_object_type,
1733                                            tree_cons (NULL_TREE, objc_selector_type,
1734                                                       NULL_TREE))));
1735
1736       /* IMP objc_msg_lookup (id, SEL); */
1737       type
1738         = build_function_type (IMP_type,
1739                                tree_cons (NULL_TREE, objc_object_type,
1740                                           tree_cons (NULL_TREE, objc_selector_type,
1741                                                      OBJC_VOID_AT_END)));
1742       umsg_decl = add_builtin_function (TAG_MSGSEND,
1743                                         type, 0, NOT_BUILT_IN,
1744                                         NULL, NULL_TREE);
1745       TREE_NOTHROW (umsg_decl) = 0;
1746
1747       /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1748       type
1749         = build_function_type (IMP_type,
1750                                tree_cons (NULL_TREE, objc_super_type,
1751                                           tree_cons (NULL_TREE, objc_selector_type,
1752                                                      OBJC_VOID_AT_END)));
1753       umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
1754                                               type, 0, NOT_BUILT_IN,
1755                                               NULL, NULL_TREE);
1756       TREE_NOTHROW (umsg_super_decl) = 0;
1757
1758       /* The following GNU runtime entry point is called to initialize
1759          each module:
1760
1761          __objc_exec_class (void *); */
1762       type
1763         = build_function_type (void_type_node,
1764                                tree_cons (NULL_TREE, ptr_type_node,
1765                                           OBJC_VOID_AT_END));
1766       execclass_decl = add_builtin_function (TAG_EXECCLASS,
1767                                              type, 0, NOT_BUILT_IN,
1768                                              NULL, NULL_TREE);
1769     }
1770
1771   /* id objc_getClass (const char *); */
1772
1773   type = build_function_type (objc_object_type,
1774                                    tree_cons (NULL_TREE,
1775                                               const_string_type_node,
1776                                               OBJC_VOID_AT_END));
1777
1778   objc_get_class_decl
1779     = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1780                             NULL, NULL_TREE);
1781
1782   /* id objc_getMetaClass (const char *); */
1783
1784   objc_get_meta_class_decl
1785     = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1786
1787   build_class_template ();
1788   build_super_template ();
1789   build_protocol_template ();
1790   build_category_template ();
1791   build_objc_exception_stuff ();
1792
1793   if (flag_next_runtime)
1794     build_next_objc_exception_stuff ();
1795
1796   /* static SEL _OBJC_SELECTOR_TABLE[]; */
1797
1798   if (! flag_next_runtime)
1799     build_selector_table_decl ();
1800
1801   /* Forward declare constant_string_id and constant_string_type.  */
1802   if (!constant_string_class_name)
1803     constant_string_class_name = default_constant_string_class_name;
1804
1805   constant_string_id = get_identifier (constant_string_class_name);
1806   objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1807
1808   /* Pre-build the following entities - for speed/convenience.  */
1809   self_id = get_identifier ("self");
1810   ucmd_id = get_identifier ("_cmd");
1811
1812 #ifdef OBJCPLUS
1813   pop_lang_context ();
1814 #endif
1815
1816   write_symbols = save_write_symbols;
1817   debug_hooks = save_hooks;
1818 }
1819
1820 /* Ensure that the ivar list for NSConstantString/NXConstantString
1821    (or whatever was specified via `-fconstant-string-class')
1822    contains fields at least as large as the following three, so that
1823    the runtime can stomp on them with confidence:
1824
1825    struct STRING_OBJECT_CLASS_NAME
1826    {
1827      Object isa;
1828      char *cString;
1829      unsigned int length;
1830    }; */
1831
1832 static int
1833 check_string_class_template (void)
1834 {
1835   tree field_decl = objc_get_class_ivars (constant_string_id);
1836
1837 #define AT_LEAST_AS_LARGE_AS(F, T) \
1838   (F && TREE_CODE (F) == FIELD_DECL \
1839      && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
1840          >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1841
1842   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1843     return 0;
1844
1845   field_decl = TREE_CHAIN (field_decl);
1846   if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1847     return 0;
1848
1849   field_decl = TREE_CHAIN (field_decl);
1850   return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1851
1852 #undef AT_LEAST_AS_LARGE_AS
1853 }
1854
1855 /* Avoid calling `check_string_class_template ()' more than once.  */
1856 static GTY(()) int string_layout_checked;
1857
1858 /* Construct an internal string layout to be used as a template for
1859    creating NSConstantString/NXConstantString instances.  */
1860
1861 static tree
1862 objc_build_internal_const_str_type (void)
1863 {
1864   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
1865   tree fields = build_decl (input_location,
1866                             FIELD_DECL, NULL_TREE, ptr_type_node);
1867   tree field = build_decl (input_location,
1868                            FIELD_DECL, NULL_TREE, ptr_type_node);
1869
1870   TREE_CHAIN (field) = fields; fields = field;
1871   field = build_decl (input_location,
1872                       FIELD_DECL, NULL_TREE, unsigned_type_node);
1873   TREE_CHAIN (field) = fields; fields = field;
1874   /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
1875      reverse order!  */
1876   finish_builtin_struct (type, "__builtin_ObjCString",
1877                          fields, NULL_TREE);
1878
1879   return type;
1880 }
1881
1882 /* Custom build_string which sets TREE_TYPE!  */
1883
1884 static tree
1885 my_build_string (int len, const char *str)
1886 {
1887   return fix_string_type (build_string (len, str));
1888 }
1889
1890 /* Build a string with contents STR and length LEN and convert it to a
1891    pointer.  */
1892
1893 static tree
1894 my_build_string_pointer (int len, const char *str)
1895 {
1896   tree string = my_build_string (len, str);
1897   tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
1898   return build1 (ADDR_EXPR, ptrtype, string);
1899 }
1900
1901 static hashval_t
1902 string_hash (const void *ptr)
1903 {
1904   const_tree const str = ((const struct string_descriptor *)ptr)->literal;
1905   const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1906   int i, len = TREE_STRING_LENGTH (str);
1907   hashval_t h = len;
1908
1909   for (i = 0; i < len; i++)
1910     h = ((h * 613) + p[i]);
1911
1912   return h;
1913 }
1914
1915 static int
1916 string_eq (const void *ptr1, const void *ptr2)
1917 {
1918   const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
1919   const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
1920   int len1 = TREE_STRING_LENGTH (str1);
1921
1922   return (len1 == TREE_STRING_LENGTH (str2)
1923           && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1924                       len1));
1925 }
1926
1927 /* Given a chain of STRING_CST's, build a static instance of
1928    NXConstantString which points at the concatenation of those
1929    strings.  We place the string object in the __string_objects
1930    section of the __OBJC segment.  The Objective-C runtime will
1931    initialize the isa pointers of the string objects to point at the
1932    NXConstantString class object.  */
1933
1934 tree
1935 objc_build_string_object (tree string)
1936 {
1937   tree initlist, constructor, constant_string_class;
1938   int length;
1939   tree fields, addr;
1940   struct string_descriptor *desc, key;
1941   void **loc;
1942
1943   /* Prep the string argument.  */
1944   string = fix_string_type (string);
1945   TREE_SET_CODE (string, STRING_CST);
1946   length = TREE_STRING_LENGTH (string) - 1;
1947
1948   /* Check whether the string class being used actually exists and has the
1949      correct ivar layout.  */
1950   if (!string_layout_checked)
1951     {
1952       string_layout_checked = -1;
1953       constant_string_class = lookup_interface (constant_string_id);
1954       internal_const_str_type = objc_build_internal_const_str_type ();
1955
1956       if (!constant_string_class
1957           || !(constant_string_type
1958                = CLASS_STATIC_TEMPLATE (constant_string_class)))
1959         error ("cannot find interface declaration for %qE",
1960                constant_string_id);
1961       /* The NSConstantString/NXConstantString ivar layout is now known.  */
1962       else if (!check_string_class_template ())
1963         error ("interface %qE does not have valid constant string layout",
1964                constant_string_id);
1965       /* For the NeXT runtime, we can generate a literal reference
1966          to the string class, don't need to run a constructor.  */
1967       else if (flag_next_runtime && !setup_string_decl ())
1968         error ("cannot find reference tag for class %qE",
1969                constant_string_id);
1970       else
1971         {
1972           string_layout_checked = 1;  /* Success!  */
1973           add_class_reference (constant_string_id);
1974         }
1975     }
1976
1977   if (string_layout_checked == -1)
1978     return error_mark_node;
1979
1980   /* Perhaps we already constructed a constant string just like this one? */
1981   key.literal = string;
1982   loc = htab_find_slot (string_htab, &key, INSERT);
1983   desc = (struct string_descriptor *) *loc;
1984
1985   if (!desc)
1986     {
1987       tree var;
1988       *loc = desc = GGC_NEW (struct string_descriptor);
1989       desc->literal = string;
1990
1991       /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
1992       /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */
1993       fields = TYPE_FIELDS (internal_const_str_type);
1994       initlist
1995         = build_tree_list (fields,
1996                            flag_next_runtime
1997                            ? build_unary_op (input_location,
1998                                              ADDR_EXPR, string_class_decl, 0)
1999                            : build_int_cst (NULL_TREE, 0));
2000       fields = TREE_CHAIN (fields);
2001       initlist = tree_cons (fields, build_unary_op (input_location,
2002                                                     ADDR_EXPR, string, 1),
2003                             initlist);
2004       fields = TREE_CHAIN (fields);
2005       initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
2006                             initlist);
2007       constructor = objc_build_constructor (internal_const_str_type,
2008                                             nreverse (initlist));
2009
2010       if (!flag_next_runtime)
2011         constructor
2012           = objc_add_static_instance (constructor, constant_string_type);
2013       else
2014         {
2015           var = build_decl (input_location,
2016                             CONST_DECL, NULL, TREE_TYPE (constructor));
2017           DECL_INITIAL (var) = constructor;
2018           TREE_STATIC (var) = 1;
2019           pushdecl_top_level (var);
2020           constructor = var;
2021         }
2022       desc->constructor = constructor;
2023     }
2024
2025   addr = convert (build_pointer_type (constant_string_type),
2026                   build_unary_op (input_location,
2027                                   ADDR_EXPR, desc->constructor, 1));
2028
2029   return addr;
2030 }
2031
2032 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
2033
2034 static GTY(()) int num_static_inst;
2035
2036 static tree
2037 objc_add_static_instance (tree constructor, tree class_decl)
2038 {
2039   tree *chain, decl;
2040   char buf[256];
2041
2042   /* Find the list of static instances for the CLASS_DECL.  Create one if
2043      not found.  */
2044   for (chain = &objc_static_instances;
2045        *chain && TREE_VALUE (*chain) != class_decl;
2046        chain = &TREE_CHAIN (*chain));
2047   if (!*chain)
2048     {
2049       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
2050       add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
2051     }
2052
2053   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
2054   decl = build_decl (input_location,
2055                      VAR_DECL, get_identifier (buf), class_decl);
2056   TREE_STATIC (decl) = 1;
2057   DECL_ARTIFICIAL (decl) = 1;
2058   TREE_USED (decl) = 1;
2059   DECL_INITIAL (decl) = constructor;
2060
2061   /* We may be writing something else just now.
2062      Postpone till end of input.  */
2063   DECL_DEFER_OUTPUT (decl) = 1;
2064   pushdecl_top_level (decl);
2065   rest_of_decl_compilation (decl, 1, 0);
2066
2067   /* Add the DECL to the head of this CLASS' list.  */
2068   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
2069
2070   return decl;
2071 }
2072
2073 /* Build a static constant CONSTRUCTOR
2074    with type TYPE and elements ELTS.  */
2075
2076 static tree
2077 objc_build_constructor (tree type, tree elts)
2078 {
2079   tree constructor = build_constructor_from_list (type, elts);
2080
2081   TREE_CONSTANT (constructor) = 1;
2082   TREE_STATIC (constructor) = 1;
2083   TREE_READONLY (constructor) = 1;
2084
2085 #ifdef OBJCPLUS
2086   /* Adjust for impedance mismatch.  We should figure out how to build
2087      CONSTRUCTORs that consistently please both the C and C++ gods.  */
2088   if (!TREE_PURPOSE (elts))
2089     TREE_TYPE (constructor) = init_list_type_node;
2090 #endif
2091
2092   return constructor;
2093 }
2094 \f
2095 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
2096
2097 /* Predefine the following data type:
2098
2099    struct _objc_symtab
2100    {
2101      long sel_ref_cnt;
2102      SEL *refs;
2103      short cls_def_cnt;
2104      short cat_def_cnt;
2105      void *defs[cls_def_cnt + cat_def_cnt];
2106    }; */
2107
2108 static void
2109 build_objc_symtab_template (void)
2110 {
2111   tree field_decl, field_decl_chain;
2112
2113   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
2114
2115   /* long sel_ref_cnt; */
2116   field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
2117   field_decl_chain = field_decl;
2118
2119   /* SEL *refs; */
2120   field_decl = create_field_decl (build_pointer_type (objc_selector_type),
2121                                   "refs");
2122   chainon (field_decl_chain, field_decl);
2123
2124   /* short cls_def_cnt; */
2125   field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
2126   chainon (field_decl_chain, field_decl);
2127
2128   /* short cat_def_cnt; */
2129   field_decl = create_field_decl (short_integer_type_node,
2130                                   "cat_def_cnt");
2131   chainon (field_decl_chain, field_decl);
2132
2133   if (imp_count || cat_count || !flag_next_runtime)
2134     {
2135       /* void *defs[imp_count + cat_count (+ 1)]; */
2136       /* NB: The index is one less than the size of the array.  */
2137       int index = imp_count + cat_count
2138                 + (flag_next_runtime? -1: 0);
2139       field_decl = create_field_decl
2140                    (build_array_type
2141                     (ptr_type_node,
2142                      build_index_type (build_int_cst (NULL_TREE, index))),
2143                     "defs");
2144       chainon (field_decl_chain, field_decl);
2145     }
2146
2147   objc_finish_struct (objc_symtab_template, field_decl_chain);
2148 }
2149
2150 /* Create the initial value for the `defs' field of _objc_symtab.
2151    This is a CONSTRUCTOR.  */
2152
2153 static tree
2154 init_def_list (tree type)
2155 {
2156   tree expr, initlist = NULL_TREE;
2157   struct imp_entry *impent;
2158
2159   if (imp_count)
2160     for (impent = imp_list; impent; impent = impent->next)
2161       {
2162         if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2163           {
2164             expr = build_unary_op (input_location,
2165                                    ADDR_EXPR, impent->class_decl, 0);
2166             initlist = tree_cons (NULL_TREE, expr, initlist);
2167           }
2168       }
2169
2170   if (cat_count)
2171     for (impent = imp_list; impent; impent = impent->next)
2172       {
2173         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2174           {
2175             expr = build_unary_op (input_location,
2176                                    ADDR_EXPR, impent->class_decl, 0);
2177             initlist = tree_cons (NULL_TREE, expr, initlist);
2178           }
2179       }
2180
2181   if (!flag_next_runtime)
2182     {
2183       /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
2184       tree expr;
2185
2186       if (static_instances_decl)
2187         expr = build_unary_op (input_location,
2188                                ADDR_EXPR, static_instances_decl, 0);
2189       else
2190         expr = build_int_cst (NULL_TREE, 0);
2191
2192       initlist = tree_cons (NULL_TREE, expr, initlist);
2193     }
2194
2195   return objc_build_constructor (type, nreverse (initlist));
2196 }
2197
2198 /* Construct the initial value for all of _objc_symtab.  */
2199
2200 static tree
2201 init_objc_symtab (tree type)
2202 {
2203   tree initlist;
2204
2205   /* sel_ref_cnt = { ..., 5, ... } */
2206
2207   initlist = build_tree_list (NULL_TREE,
2208                               build_int_cst (long_integer_type_node, 0));
2209
2210   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2211
2212   if (flag_next_runtime || ! sel_ref_chain)
2213     initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2214   else
2215     initlist
2216       = tree_cons (NULL_TREE,
2217                    convert (build_pointer_type (objc_selector_type),
2218                             build_unary_op (input_location, ADDR_EXPR,
2219                                             UOBJC_SELECTOR_TABLE_decl, 1)),
2220                    initlist);
2221
2222   /* cls_def_cnt = { ..., 5, ... } */
2223
2224   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
2225
2226   /* cat_def_cnt = { ..., 5, ... } */
2227
2228   initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
2229
2230   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2231
2232   if (imp_count || cat_count || !flag_next_runtime)
2233     {
2234
2235       tree field = TYPE_FIELDS (type);
2236       field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
2237
2238       initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
2239                             initlist);
2240     }
2241
2242   return objc_build_constructor (type, nreverse (initlist));
2243 }
2244
2245 /* Generate forward declarations for metadata such as
2246   'OBJC_CLASS_...'.  */
2247
2248 static tree
2249 build_metadata_decl (const char *name, tree type)
2250 {
2251   tree decl;
2252
2253   /* struct TYPE NAME_<name>; */
2254   decl = start_var_decl (type, synth_id_with_class_suffix
2255                                (name,
2256                                 objc_implementation_context));
2257
2258   return decl;
2259 }
2260
2261 /* Push forward-declarations of all the categories so that
2262    init_def_list can use them in a CONSTRUCTOR.  */
2263
2264 static void
2265 forward_declare_categories (void)
2266 {
2267   struct imp_entry *impent;
2268   tree sav = objc_implementation_context;
2269
2270   for (impent = imp_list; impent; impent = impent->next)
2271     {
2272       if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
2273         {
2274           /* Set an invisible arg to synth_id_with_class_suffix.  */
2275           objc_implementation_context = impent->imp_context;
2276           /* extern struct objc_category _OBJC_CATEGORY_<name>; */
2277           impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
2278                                                     objc_category_template);
2279         }
2280     }
2281   objc_implementation_context = sav;
2282 }
2283
2284 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2285    and initialized appropriately.  */
2286
2287 static void
2288 generate_objc_symtab_decl (void)
2289 {
2290   /* forward declare categories */
2291   if (cat_count)
2292     forward_declare_categories ();
2293
2294   build_objc_symtab_template ();
2295   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2296   finish_var_decl (UOBJC_SYMBOLS_decl,
2297                    init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2298 }
2299 \f
2300 static tree
2301 init_module_descriptor (tree type)
2302 {
2303   tree initlist, expr;
2304
2305   /* version = { 1, ... } */
2306
2307   expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
2308   initlist = build_tree_list (NULL_TREE, expr);
2309
2310   /* size = { ..., sizeof (struct _objc_module), ... } */
2311
2312   expr = convert (long_integer_type_node,
2313                   size_in_bytes (objc_module_template));
2314   initlist = tree_cons (NULL_TREE, expr, initlist);
2315
2316   /* Don't provide any file name for security reasons. */
2317   /* name = { ..., "", ... } */
2318
2319   expr = add_objc_string (get_identifier (""), class_names);
2320   initlist = tree_cons (NULL_TREE, expr, initlist);
2321
2322   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2323
2324   if (UOBJC_SYMBOLS_decl)
2325     expr = build_unary_op (input_location,
2326                            ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2327   else
2328     expr = build_int_cst (NULL_TREE, 0);
2329   initlist = tree_cons (NULL_TREE, expr, initlist);
2330
2331   return objc_build_constructor (type, nreverse (initlist));
2332 }
2333
2334 /* Write out the data structures to describe Objective C classes defined.
2335
2336    struct _objc_module { ... } _OBJC_MODULE = { ... };   */
2337
2338 static void
2339 build_module_descriptor (void)
2340 {
2341   tree field_decl, field_decl_chain;
2342
2343 #ifdef OBJCPLUS
2344   push_lang_context (lang_name_c); /* extern "C" */
2345 #endif
2346
2347   objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
2348
2349   /* long version; */
2350   field_decl = create_field_decl (long_integer_type_node, "version");
2351   field_decl_chain = field_decl;
2352
2353   /* long size; */
2354   field_decl = create_field_decl (long_integer_type_node, "size");
2355   chainon (field_decl_chain, field_decl);
2356
2357   /* char *name; */
2358   field_decl = create_field_decl (string_type_node, "name");
2359   chainon (field_decl_chain, field_decl);
2360
2361   /* struct _objc_symtab *symtab; */
2362   field_decl
2363     = create_field_decl (build_pointer_type
2364                          (xref_tag (RECORD_TYPE,
2365                                     get_identifier (UTAG_SYMTAB))),
2366                          "symtab");
2367   chainon (field_decl_chain, field_decl);
2368
2369   objc_finish_struct (objc_module_template, field_decl_chain);
2370
2371   /* Create an instance of "_objc_module".  */
2372   UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2373   finish_var_decl (UOBJC_MODULES_decl,
2374                    init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2375
2376 #ifdef OBJCPLUS
2377   pop_lang_context ();
2378 #endif
2379 }
2380
2381 /* The GNU runtime requires us to provide a static initializer function
2382    for each module:
2383
2384    static void __objc_gnu_init (void) {
2385      __objc_exec_class (&L_OBJC_MODULES);
2386    }  */
2387
2388 static void
2389 build_module_initializer_routine (void)
2390 {
2391   tree body;
2392
2393 #ifdef OBJCPLUS
2394   push_lang_context (lang_name_c); /* extern "C" */
2395 #endif
2396
2397   objc_push_parm (build_decl (input_location,
2398                               PARM_DECL, NULL_TREE, void_type_node));
2399   objc_start_function (get_identifier (TAG_GNUINIT),
2400                        build_function_type (void_type_node,
2401                                             OBJC_VOID_AT_END),
2402                        NULL_TREE, objc_get_parm_info (0));
2403
2404   body = c_begin_compound_stmt (true);
2405   add_stmt (build_function_call
2406             (input_location,
2407              execclass_decl,
2408              build_tree_list
2409              (NULL_TREE,
2410               build_unary_op (input_location, ADDR_EXPR,
2411                               UOBJC_MODULES_decl, 0))));
2412   add_stmt (c_end_compound_stmt (input_location, body, true));
2413
2414   TREE_PUBLIC (current_function_decl) = 0;
2415
2416 #ifndef OBJCPLUS
2417   /* For Objective-C++, we will need to call __objc_gnu_init
2418      from objc_generate_static_init_call() below.  */
2419   DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2420 #endif
2421
2422   GNU_INIT_decl = current_function_decl;
2423   finish_function ();
2424
2425 #ifdef OBJCPLUS
2426     pop_lang_context ();
2427 #endif
2428 }
2429
2430 #ifdef OBJCPLUS
2431 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2432    to be called by the module initializer routine.  */
2433
2434 int
2435 objc_static_init_needed_p (void)
2436 {
2437   return (GNU_INIT_decl != NULL_TREE);
2438 }
2439
2440 /* Generate a call to the __objc_gnu_init initializer function.  */
2441
2442 tree
2443 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2444 {
2445   add_stmt (build_stmt (input_location, EXPR_STMT,
2446                         build_function_call (input_location,
2447                                              GNU_INIT_decl, NULL_TREE)));
2448
2449   return ctors;
2450 }
2451 #endif /* OBJCPLUS */
2452
2453 /* Return the DECL of the string IDENT in the SECTION.  */
2454
2455 static tree
2456 get_objc_string_decl (tree ident, enum string_section section)
2457 {
2458   tree chain;
2459
2460   if (section == class_names)
2461     chain = class_names_chain;
2462   else if (section == meth_var_names)
2463     chain = meth_var_names_chain;
2464   else if (section == meth_var_types)
2465     chain = meth_var_types_chain;
2466   else
2467     abort ();
2468
2469   for (; chain != 0; chain = TREE_CHAIN (chain))
2470     if (TREE_VALUE (chain) == ident)
2471       return (TREE_PURPOSE (chain));
2472
2473   abort ();
2474   return NULL_TREE;
2475 }
2476
2477 /* Output references to all statically allocated objects.  Return the DECL
2478    for the array built.  */
2479
2480 static void
2481 generate_static_references (void)
2482 {
2483   tree decls = NULL_TREE, expr = NULL_TREE;
2484   tree class_name, klass, decl, initlist;
2485   tree cl_chain, in_chain, type
2486     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2487   int num_inst, num_class;
2488   char buf[256];
2489
2490   if (flag_next_runtime)
2491     abort ();
2492
2493   for (cl_chain = objc_static_instances, num_class = 0;
2494        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2495     {
2496       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2497            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2498
2499       sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2500       decl = start_var_decl (type, buf);
2501
2502       /* Output {class_name, ...}.  */
2503       klass = TREE_VALUE (cl_chain);
2504       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
2505       initlist = build_tree_list (NULL_TREE,
2506                                   build_unary_op (input_location, 
2507                                                   ADDR_EXPR, class_name, 1));
2508
2509       /* Output {..., instance, ...}.  */
2510       for (in_chain = TREE_PURPOSE (cl_chain);
2511            in_chain; in_chain = TREE_CHAIN (in_chain))
2512         {
2513           expr = build_unary_op (input_location,
2514                                  ADDR_EXPR, TREE_VALUE (in_chain), 1);
2515           initlist = tree_cons (NULL_TREE, expr, initlist);
2516         }
2517
2518       /* Output {..., NULL}.  */
2519       initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2520
2521       expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2522       finish_var_decl (decl, expr);
2523       decls
2524         = tree_cons (NULL_TREE, build_unary_op (input_location,
2525                                                 ADDR_EXPR, decl, 1), decls);
2526     }
2527
2528   decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2529   expr = objc_build_constructor (type, nreverse (decls));
2530   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2531   finish_var_decl (static_instances_decl, expr);
2532 }
2533
2534 static GTY(()) int selector_reference_idx;
2535
2536 static tree
2537 build_selector_reference_decl (void)
2538 {
2539   tree decl;
2540   char buf[256];
2541
2542   sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2543   decl = start_var_decl (objc_selector_type, buf);
2544
2545   return decl;
2546 }
2547
2548 static void
2549 build_selector_table_decl (void)
2550 {
2551   tree temp;
2552
2553   if (flag_typed_selectors)
2554     {
2555       build_selector_template ();
2556       temp = build_array_type (objc_selector_template, NULL_TREE);
2557     }
2558   else
2559     temp = build_array_type (objc_selector_type, NULL_TREE);
2560
2561   UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2562 }
2563
2564 /* Just a handy wrapper for add_objc_string.  */
2565
2566 static tree
2567 build_selector (tree ident)
2568 {
2569   return convert (objc_selector_type,
2570                   add_objc_string (ident, meth_var_names));
2571 }
2572
2573 static void
2574 build_selector_translation_table (void)
2575 {
2576   tree chain, initlist = NULL_TREE;
2577   int offset = 0;
2578   tree decl = NULL_TREE;
2579
2580   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2581     {
2582       tree expr;
2583
2584       if (warn_selector && objc_implementation_context)
2585       {
2586         tree method_chain;
2587         bool found = false;
2588         for (method_chain = meth_var_names_chain;
2589              method_chain;
2590              method_chain = TREE_CHAIN (method_chain))
2591           {
2592             if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2593               {
2594                 found = true;
2595                 break;
2596               }
2597           }
2598         if (!found)
2599           {
2600             location_t loc;
2601             if (flag_next_runtime && TREE_PURPOSE (chain))
2602               loc = DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
2603             else
2604               loc = input_location;
2605             warning_at (loc, 0, "creating selector for nonexistent method %qE",
2606                         TREE_VALUE (chain));
2607           }
2608       }
2609
2610       expr = build_selector (TREE_VALUE (chain));
2611       /* add one for the '\0' character */
2612       offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2613
2614       if (flag_next_runtime)
2615         {
2616           decl = TREE_PURPOSE (chain);
2617           finish_var_decl (decl, expr);
2618         }
2619       else
2620         {
2621           if (flag_typed_selectors)
2622             {
2623               tree eltlist = NULL_TREE;
2624               tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2625               eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2626               eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2627               expr = objc_build_constructor (objc_selector_template,
2628                                              nreverse (eltlist));
2629             }
2630
2631           initlist = tree_cons (NULL_TREE, expr, initlist);
2632         }
2633     }
2634
2635   if (! flag_next_runtime)
2636     {
2637       /* Cause the selector table (previously forward-declared)
2638          to be actually output.  */
2639       initlist = tree_cons (NULL_TREE,
2640                             flag_typed_selectors
2641                             ? objc_build_constructor
2642                               (objc_selector_template,
2643                                tree_cons (NULL_TREE,
2644                                           build_int_cst (NULL_TREE, 0),
2645                                           tree_cons (NULL_TREE,
2646                                                      build_int_cst (NULL_TREE, 0),
2647                                                      NULL_TREE)))
2648                             : build_int_cst (NULL_TREE, 0), initlist);
2649       initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2650                                          nreverse (initlist));
2651       finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2652     }
2653 }
2654
2655 static tree
2656 get_proto_encoding (tree proto)
2657 {
2658   tree encoding;
2659   if (proto)
2660     {
2661       if (! METHOD_ENCODING (proto))
2662         {
2663           encoding = encode_method_prototype (proto);
2664           METHOD_ENCODING (proto) = encoding;
2665         }
2666       else
2667         encoding = METHOD_ENCODING (proto);
2668
2669       return add_objc_string (encoding, meth_var_types);
2670     }
2671   else
2672     return build_int_cst (NULL_TREE, 0);
2673 }
2674
2675 /* sel_ref_chain is a list whose "value" fields will be instances of
2676    identifier_node that represent the selector.  LOC is the location of
2677    the @selector.  */
2678
2679 static tree
2680 build_typed_selector_reference (location_t loc, tree ident, tree prototype)
2681 {
2682   tree *chain = &sel_ref_chain;
2683   tree expr;
2684   int index = 0;
2685
2686   while (*chain)
2687     {
2688       if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2689         goto return_at_index;
2690
2691       index++;
2692       chain = &TREE_CHAIN (*chain);
2693     }
2694
2695   *chain = tree_cons (prototype, ident, NULL_TREE);
2696
2697  return_at_index:
2698   expr = build_unary_op (loc, ADDR_EXPR,
2699                          build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2700                                           build_int_cst (NULL_TREE, index)),
2701                          1);
2702   return convert (objc_selector_type, expr);
2703 }
2704
2705 static tree
2706 build_selector_reference (location_t loc, tree ident)
2707 {
2708   tree *chain = &sel_ref_chain;
2709   tree expr;
2710   int index = 0;
2711
2712   while (*chain)
2713     {
2714       if (TREE_VALUE (*chain) == ident)
2715         return (flag_next_runtime
2716                 ? TREE_PURPOSE (*chain)
2717                 : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2718                                    build_int_cst (NULL_TREE, index)));
2719
2720       index++;
2721       chain = &TREE_CHAIN (*chain);
2722     }
2723
2724   expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2725
2726   *chain = tree_cons (expr, ident, NULL_TREE);
2727
2728   return (flag_next_runtime
2729           ? expr
2730           : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
2731                              build_int_cst (NULL_TREE, index)));
2732 }
2733
2734 static GTY(()) int class_reference_idx;
2735
2736 static tree
2737 build_class_reference_decl (void)
2738 {
2739   tree decl;
2740   char buf[256];
2741
2742   sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2743   decl = start_var_decl (objc_class_type, buf);
2744
2745   return decl;
2746 }
2747
2748 /* Create a class reference, but don't create a variable to reference
2749    it.  */
2750
2751 static void
2752 add_class_reference (tree ident)
2753 {
2754   tree chain;
2755
2756   if ((chain = cls_ref_chain))
2757     {
2758       tree tail;
2759       do
2760         {
2761           if (ident == TREE_VALUE (chain))
2762             return;
2763
2764           tail = chain;
2765           chain = TREE_CHAIN (chain);
2766         }
2767       while (chain);
2768
2769       /* Append to the end of the list */
2770       TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2771     }
2772   else
2773     cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2774 }
2775
2776 /* Get a class reference, creating it if necessary.  Also create the
2777    reference variable.  */
2778
2779 tree
2780 objc_get_class_reference (tree ident)
2781 {
2782   tree orig_ident = (DECL_P (ident)
2783                      ? DECL_NAME (ident)
2784                      : TYPE_P (ident)
2785                      ? OBJC_TYPE_NAME (ident)
2786                      : ident);
2787   bool local_scope = false;
2788
2789 #ifdef OBJCPLUS
2790   if (processing_template_decl)
2791     /* Must wait until template instantiation time.  */
2792     return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2793 #endif
2794
2795   if (TREE_CODE (ident) == TYPE_DECL)
2796     ident = (DECL_ORIGINAL_TYPE (ident)
2797              ? DECL_ORIGINAL_TYPE (ident)
2798              : TREE_TYPE (ident));
2799
2800 #ifdef OBJCPLUS
2801   if (TYPE_P (ident) && TYPE_CONTEXT (ident)
2802       && TYPE_CONTEXT (ident) != global_namespace)
2803     local_scope = true;
2804 #endif
2805
2806   if (local_scope || !(ident = objc_is_class_name (ident)))
2807     {
2808       error ("%qE is not an Objective-C class name or alias",
2809              orig_ident);
2810       return error_mark_node;
2811     }
2812
2813   if (flag_next_runtime && !flag_zero_link)
2814     {
2815       tree *chain;
2816       tree decl;
2817
2818       for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2819         if (TREE_VALUE (*chain) == ident)
2820           {
2821             if (! TREE_PURPOSE (*chain))
2822               TREE_PURPOSE (*chain) = build_class_reference_decl ();
2823
2824             return TREE_PURPOSE (*chain);
2825           }
2826
2827       decl = build_class_reference_decl ();
2828       *chain = tree_cons (decl, ident, NULL_TREE);
2829       return decl;
2830     }
2831   else
2832     {
2833       tree params;
2834
2835       add_class_reference (ident);
2836
2837       params = build_tree_list (NULL_TREE,
2838                                 my_build_string_pointer
2839                                 (IDENTIFIER_LENGTH (ident) + 1,
2840                                  IDENTIFIER_POINTER (ident)));
2841
2842       assemble_external (objc_get_class_decl);
2843       return build_function_call (input_location, objc_get_class_decl, params);
2844     }
2845 }
2846
2847 /* For each string section we have a chain which maps identifier nodes
2848    to decls for the strings.  */
2849
2850 static tree
2851 add_objc_string (tree ident, enum string_section section)
2852 {
2853   tree *chain, decl, type, string_expr;
2854
2855   if (section == class_names)
2856     chain = &class_names_chain;
2857   else if (section == meth_var_names)
2858     chain = &meth_var_names_chain;
2859   else if (section == meth_var_types)
2860     chain = &meth_var_types_chain;
2861   else
2862     abort ();
2863
2864   while (*chain)
2865     {
2866       if (TREE_VALUE (*chain) == ident)
2867         return convert (string_type_node,
2868                         build_unary_op (input_location,
2869                                         ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2870
2871       chain = &TREE_CHAIN (*chain);
2872     }
2873
2874   decl = build_objc_string_decl (section);
2875
2876   type = build_array_type
2877          (char_type_node,
2878           build_index_type
2879           (build_int_cst (NULL_TREE,
2880                           IDENTIFIER_LENGTH (ident))));
2881   decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2882   string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2883                                  IDENTIFIER_POINTER (ident));
2884   finish_var_decl (decl, string_expr);
2885
2886   *chain = tree_cons (decl, ident, NULL_TREE);
2887
2888   return convert (string_type_node, build_unary_op (input_location,
2889                                                     ADDR_EXPR, decl, 1));
2890 }
2891
2892 static GTY(()) int class_names_idx;
2893 static GTY(()) int meth_var_names_idx;
2894 static GTY(()) int meth_var_types_idx;
2895
2896 static tree
2897 build_objc_string_decl (enum string_section section)
2898 {
2899   tree decl, ident;
2900   char buf[256];
2901
2902   if (section == class_names)
2903     sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2904   else if (section == meth_var_names)
2905     sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2906   else if (section == meth_var_types)
2907     sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2908
2909   ident = get_identifier (buf);
2910
2911   decl = build_decl (input_location,
2912                      VAR_DECL, ident, build_array_type (char_type_node, 0));
2913   DECL_EXTERNAL (decl) = 1;
2914   TREE_PUBLIC (decl) = 0;
2915   TREE_USED (decl) = 1;
2916   TREE_CONSTANT (decl) = 1;
2917   DECL_CONTEXT (decl) = 0;
2918   DECL_ARTIFICIAL (decl) = 1;
2919 #ifdef OBJCPLUS
2920   DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2921 #endif
2922
2923   make_decl_rtl (decl);
2924   pushdecl_top_level (decl);
2925
2926   return decl;
2927 }
2928
2929
2930 void
2931 objc_declare_alias (tree alias_ident, tree class_ident)
2932 {
2933   tree underlying_class;
2934
2935 #ifdef OBJCPLUS
2936   if (current_namespace != global_namespace) {
2937     error ("Objective-C declarations may only appear in global scope");
2938   }
2939 #endif /* OBJCPLUS */
2940
2941   if (!(underlying_class = objc_is_class_name (class_ident)))
2942     warning (0, "cannot find class %qE", class_ident);
2943   else if (objc_is_class_name (alias_ident))
2944     warning (0, "class %qE already exists", alias_ident);
2945   else
2946     {
2947       /* Implement @compatibility_alias as a typedef.  */
2948 #ifdef OBJCPLUS
2949       push_lang_context (lang_name_c); /* extern "C" */
2950 #endif
2951       lang_hooks.decls.pushdecl (build_decl
2952                                  (input_location,
2953                                   TYPE_DECL,
2954                                   alias_ident,
2955                                   xref_tag (RECORD_TYPE, underlying_class)));
2956 #ifdef OBJCPLUS
2957       pop_lang_context ();
2958 #endif
2959       alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2960     }
2961 }
2962
2963 void
2964 objc_declare_class (tree ident_list)
2965 {
2966   tree list;
2967 #ifdef OBJCPLUS
2968   if (current_namespace != global_namespace) {
2969     error ("Objective-C declarations may only appear in global scope");
2970   }
2971 #endif /* OBJCPLUS */
2972
2973   for (list = ident_list; list; list = TREE_CHAIN (list))
2974     {
2975       tree ident = TREE_VALUE (list);
2976
2977       if (! objc_is_class_name (ident))
2978         {
2979           tree record = lookup_name (ident), type = record;
2980
2981           if (record)
2982             {
2983               if (TREE_CODE (record) == TYPE_DECL)
2984                 type = DECL_ORIGINAL_TYPE (record);
2985
2986               if (!TYPE_HAS_OBJC_INFO (type)
2987                   || !TYPE_OBJC_INTERFACE (type))
2988                 {
2989                   error ("%qE redeclared as different kind of symbol",
2990                          ident);
2991                   error ("previous declaration of %q+D",
2992                          record);
2993                 }
2994             }
2995
2996           record = xref_tag (RECORD_TYPE, ident);
2997           INIT_TYPE_OBJC_INFO (record);
2998           TYPE_OBJC_INTERFACE (record) = ident;
2999           class_chain = tree_cons (NULL_TREE, ident, class_chain);
3000         }
3001     }
3002 }
3003
3004 tree
3005 objc_is_class_name (tree ident)
3006 {
3007   tree chain;
3008
3009   if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
3010       && identifier_global_value (ident))
3011     ident = identifier_global_value (ident);
3012   while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
3013     ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
3014
3015   if (ident && TREE_CODE (ident) == RECORD_TYPE)
3016     ident = OBJC_TYPE_NAME (ident);
3017 #ifdef OBJCPLUS
3018   if (ident && TREE_CODE (ident) == TYPE_DECL)
3019     ident = DECL_NAME (ident);
3020 #endif
3021   if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
3022     return NULL_TREE;
3023
3024   if (lookup_interface (ident))
3025     return ident;
3026
3027   for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
3028     {
3029       if (ident == TREE_VALUE (chain))
3030         return ident;
3031     }
3032
3033   for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
3034     {
3035       if (ident == TREE_VALUE (chain))
3036         return TREE_PURPOSE (chain);
3037     }
3038
3039   return 0;
3040 }
3041
3042 /* Check whether TYPE is either 'id' or 'Class'.  */
3043
3044 tree
3045 objc_is_id (tree type)
3046 {
3047   if (type && TREE_CODE (type) == IDENTIFIER_NODE
3048       && identifier_global_value (type))
3049     type = identifier_global_value (type);
3050
3051   if (type && TREE_CODE (type) == TYPE_DECL)
3052     type = TREE_TYPE (type);
3053
3054   /* NB: This function may be called before the ObjC front-end has
3055      been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL.  */
3056   return (objc_object_type && type
3057           && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
3058           ? type
3059           : NULL_TREE);
3060 }
3061
3062 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
3063    class instance.  This is needed by other parts of the compiler to
3064    handle ObjC types gracefully.  */
3065
3066 tree
3067 objc_is_object_ptr (tree type)
3068 {
3069   tree ret;
3070
3071   type = TYPE_MAIN_VARIANT (type);
3072   if (!POINTER_TYPE_P (type))
3073     return 0;
3074
3075   ret = objc_is_id (type);
3076   if (!ret)
3077     ret = objc_is_class_name (TREE_TYPE (type));
3078
3079   return ret;
3080 }
3081
3082 static int
3083 objc_is_gcable_type (tree type, int or_strong_p)
3084 {
3085   tree name;
3086
3087   if (!TYPE_P (type))
3088     return 0;
3089   if (objc_is_id (TYPE_MAIN_VARIANT (type)))
3090     return 1;
3091   if (or_strong_p && lookup_attribute ("objc_gc", TYPE_ATTRIBUTES (type)))
3092     return 1;
3093   if (TREE_CODE (type) != POINTER_TYPE && TREE_CODE (type) != INDIRECT_REF)
3094     return 0;
3095   type = TREE_TYPE (type);
3096   if (TREE_CODE (type) != RECORD_TYPE)
3097     return 0;
3098   name = TYPE_NAME (type);
3099   return (objc_is_class_name (name) != NULL_TREE);
3100 }
3101
3102 static tree
3103 objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
3104 {
3105   if (expr == oldexpr)
3106     return newexpr;
3107
3108   switch (TREE_CODE (expr))
3109     {
3110     case COMPONENT_REF:
3111       return objc_build_component_ref
3112              (objc_substitute_decl (TREE_OPERAND (expr, 0),
3113                                     oldexpr,
3114                                     newexpr),
3115               DECL_NAME (TREE_OPERAND (expr, 1)));
3116     case ARRAY_REF:
3117       return build_array_ref (input_location,
3118                               objc_substitute_decl (TREE_OPERAND (expr, 0),
3119                                                     oldexpr,
3120                                                     newexpr),
3121                               TREE_OPERAND (expr, 1));
3122     case INDIRECT_REF:
3123       return build_indirect_ref (input_location,
3124                                  objc_substitute_decl (TREE_OPERAND (expr, 0),
3125                                                        oldexpr,
3126                                                        newexpr), RO_ARROW);
3127     default:
3128       return expr;
3129     }
3130 }
3131
3132 static tree
3133 objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
3134 {
3135   tree func_params;
3136   /* The LHS parameter contains the expression 'outervar->memberspec';
3137      we need to transform it into '&((typeof(outervar) *) 0)->memberspec',
3138      where memberspec may be arbitrarily complex (e.g., 'g->f.d[2].g[3]').
3139   */
3140   tree offs
3141     = objc_substitute_decl
3142       (lhs, outervar, convert (TREE_TYPE (outervar), integer_zero_node));
3143   tree func
3144     = (flag_objc_direct_dispatch
3145        ? objc_assign_ivar_fast_decl
3146        : objc_assign_ivar_decl);
3147
3148   offs = convert (integer_type_node, build_unary_op (input_location,
3149                                                      ADDR_EXPR, offs, 0));
3150   offs = fold (offs);
3151   func_params = tree_cons (NULL_TREE,
3152         convert (objc_object_type, rhs),
3153             tree_cons (NULL_TREE, convert (objc_object_type, outervar),
3154                 tree_cons (NULL_TREE, offs,
3155                     NULL_TREE)));
3156
3157   assemble_external (func);
3158   return build_function_call (input_location, func, func_params);
3159 }
3160
3161 static tree
3162 objc_build_global_assignment (tree lhs, tree rhs)
3163 {
3164   tree func_params = tree_cons (NULL_TREE,
3165         convert (objc_object_type, rhs),
3166             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3167                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3168                     NULL_TREE));
3169
3170   assemble_external (objc_assign_global_decl);
3171   return build_function_call (input_location, 
3172                               objc_assign_global_decl, func_params);
3173 }
3174
3175 static tree
3176 objc_build_strong_cast_assignment (tree lhs, tree rhs)
3177 {
3178   tree func_params = tree_cons (NULL_TREE,
3179         convert (objc_object_type, rhs),
3180             tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
3181                       build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
3182                     NULL_TREE));
3183
3184   assemble_external (objc_assign_strong_cast_decl);
3185   return build_function_call (input_location,
3186                               objc_assign_strong_cast_decl, func_params);
3187 }
3188
3189 static int
3190 objc_is_gcable_p (tree expr)
3191 {
3192   return (TREE_CODE (expr) == COMPONENT_REF
3193           ? objc_is_gcable_p (TREE_OPERAND (expr, 1))
3194           : TREE_CODE (expr) == ARRAY_REF
3195           ? (objc_is_gcable_p (TREE_TYPE (expr))
3196              || objc_is_gcable_p (TREE_OPERAND (expr, 0)))
3197           : TREE_CODE (expr) == ARRAY_TYPE
3198           ? objc_is_gcable_p (TREE_TYPE (expr))
3199           : TYPE_P (expr)
3200           ? objc_is_gcable_type (expr, 1)
3201           : (objc_is_gcable_p (TREE_TYPE (expr))
3202              || (DECL_P (expr)
3203                  && lookup_attribute ("objc_gc", DECL_ATTRIBUTES (expr)))));
3204 }
3205
3206 static int
3207 objc_is_ivar_reference_p (tree expr)
3208 {
3209   return (TREE_CODE (expr) == ARRAY_REF
3210           ? objc_is_ivar_reference_p (TREE_OPERAND (expr, 0))
3211           : TREE_CODE (expr) == COMPONENT_REF
3212           ? TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL
3213           : 0);
3214 }
3215
3216 static int
3217 objc_is_global_reference_p (tree expr)
3218 {
3219   return (TREE_CODE (expr) == INDIRECT_REF || TREE_CODE (expr) == PLUS_EXPR
3220           ? objc_is_global_reference_p (TREE_OPERAND (expr, 0))
3221           : DECL_P (expr)
3222           ? (!DECL_CONTEXT (expr) || TREE_STATIC (expr))
3223           : 0);
3224 }
3225
3226 tree
3227 objc_generate_write_barrier (tree lhs, enum tree_code modifycode, tree rhs)
3228 {
3229   tree result = NULL_TREE, outer;
3230   int strong_cast_p = 0, outer_gc_p = 0, indirect_p = 0;
3231
3232   /* See if we have any lhs casts, and strip them out.  NB: The lvalue casts
3233      will have been transformed to the form '*(type *)&expr'.  */
3234   if (TREE_CODE (lhs) == INDIRECT_REF)
3235     {
3236       outer = TREE_OPERAND (lhs, 0);
3237
3238       while (!strong_cast_p
3239              && (CONVERT_EXPR_P (outer)
3240                  || TREE_CODE (outer) == NON_LVALUE_EXPR))
3241         {
3242           tree lhstype = TREE_TYPE (outer);
3243
3244           /* Descend down the cast chain, and record the first objc_gc
3245              attribute found.  */
3246           if (POINTER_TYPE_P (lhstype))
3247             {
3248               tree attr
3249                 = lookup_attribute ("objc_gc",
3250                                     TYPE_ATTRIBUTES (TREE_TYPE (lhstype)));
3251
3252               if (attr)
3253                 strong_cast_p = 1;
3254             }
3255
3256           outer = TREE_OPERAND (outer, 0);
3257         }
3258     }
3259
3260   /* If we have a __strong cast, it trumps all else.  */
3261   if (strong_cast_p)
3262     {
3263       if (modifycode != NOP_EXPR)
3264         goto invalid_pointer_arithmetic;
3265
3266       if (warn_assign_intercept)
3267         warning (0, "strong-cast assignment has been intercepted");
3268
3269       result = objc_build_strong_cast_assignment (lhs, rhs);
3270
3271       goto exit_point;
3272     }
3273
3274   /* the lhs must be of a suitable type, regardless of its underlying
3275      structure.  */
3276   if (!objc_is_gcable_p (lhs))
3277     goto exit_point;
3278
3279   outer = lhs;
3280
3281   while (outer
3282          && (TREE_CODE (outer) == COMPONENT_REF
3283              || TREE_CODE (outer) == ARRAY_REF))
3284     outer = TREE_OPERAND (outer, 0);
3285
3286   if (TREE_CODE (outer) == INDIRECT_REF)
3287     {
3288       outer = TREE_OPERAND (outer, 0);
3289       indirect_p = 1;
3290     }
3291
3292   outer_gc_p = objc_is_gcable_p (outer);
3293
3294   /* Handle ivar assignments. */
3295   if (objc_is_ivar_reference_p (lhs))
3296     {
3297       /* if the struct to the left of the ivar is not an Objective-C object (__strong
3298          doesn't cut it here), the best we can do here is suggest a cast.  */
3299       if (!objc_is_gcable_type (TREE_TYPE (outer), 0))
3300         {
3301           /* We may still be able to use the global write barrier... */
3302           if (!indirect_p && objc_is_global_reference_p (outer))
3303             goto global_reference;
3304
3305          suggest_cast:
3306           if (modifycode == NOP_EXPR)
3307             {
3308               if (warn_assign_intercept)
3309                 warning (0, "strong-cast may possibly be needed");
3310             }
3311
3312           goto exit_point;
3313         }
3314
3315       if (modifycode != NOP_EXPR)
3316         goto invalid_pointer_arithmetic;
3317
3318       if (warn_assign_intercept)
3319         warning (0, "instance variable assignment has been intercepted");
3320
3321       result = objc_build_ivar_assignment (outer, lhs, rhs);
3322
3323       goto exit_point;
3324     }
3325
3326   /* Likewise, intercept assignment to global/static variables if their type is
3327      GC-marked.  */
3328   if (objc_is_global_reference_p (outer))
3329     {
3330       if (indirect_p)
3331         goto suggest_cast;
3332
3333      global_reference:
3334       if (modifycode != NOP_EXPR)
3335         {
3336          invalid_pointer_arithmetic:
3337           if (outer_gc_p)
3338             warning (0, "pointer arithmetic for garbage-collected objects not allowed");
3339
3340           goto exit_point;
3341         }
3342
3343       if (warn_assign_intercept)
3344         warning (0, "global/static variable assignment has been intercepted");
3345
3346       result = objc_build_global_assignment (lhs, rhs);
3347     }
3348
3349   /* In all other cases, fall back to the normal mechanism.  */
3350  exit_point:
3351   return result;
3352 }
3353
3354 struct GTY(()) interface_tuple {
3355   tree id;
3356   tree class_name;
3357 };
3358
3359 static GTY ((param_is (struct interface_tuple))) htab_t interface_htab;
3360
3361 static hashval_t
3362 hash_interface (const void *p)
3363 {
3364   const struct interface_tuple *d = (const struct interface_tuple *) p;
3365   return IDENTIFIER_HASH_VALUE (d->id);
3366 }
3367
3368 static int
3369 eq_interface (const void *p1, const void *p2)
3370 {
3371   const struct interface_tuple *d = (const struct interface_tuple *) p1;
3372   return d->id == p2;
3373 }
3374
3375 static tree
3376 lookup_interface (tree ident)
3377 {
3378 #ifdef OBJCPLUS
3379   if (ident && TREE_CODE (ident) == TYPE_DECL)
3380     ident = DECL_NAME (ident);
3381 #endif
3382
3383   if (ident == NULL_TREE || TREE_CODE (ident) != IDENTIFIER_NODE)
3384     return NULL_TREE;
3385
3386   {
3387     struct interface_tuple **slot;
3388     tree i = NULL_TREE;
3389
3390     if (interface_htab)
3391       {
3392         slot = (struct interface_tuple **)
3393           htab_find_slot_with_hash (interface_htab, ident,
3394                                     IDENTIFIER_HASH_VALUE (ident),
3395                                     NO_INSERT);
3396         if (slot && *slot)
3397           i = (*slot)->class_name;
3398       }
3399     return i;
3400   }
3401 }
3402
3403 /* Implement @defs (<classname>) within struct bodies.  */
3404
3405 tree
3406 objc_get_class_ivars (tree class_name)
3407 {
3408   tree interface = lookup_interface (class_name);
3409
3410   if (interface)
3411     return get_class_ivars (interface, true);
3412
3413   error ("cannot find interface declaration for %qE",
3414          class_name);
3415
3416   return error_mark_node;
3417 }
3418
3419 /* Used by: build_private_template, continue_class,
3420    and for @defs constructs.  */
3421
3422 static tree
3423 get_class_ivars (tree interface, bool inherited)
3424 {
3425   tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
3426
3427   /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
3428      by the current class (i.e., they do not include super-class ivars).
3429      However, the CLASS_IVARS list will be side-effected by a call to
3430      finish_struct(), which will fill in field offsets.  */
3431   if (!CLASS_IVARS (interface))
3432     CLASS_IVARS (interface) = ivar_chain;
3433
3434   if (!inherited)
3435     return ivar_chain;
3436
3437   while (CLASS_SUPER_NAME (interface))
3438     {
3439       /* Prepend super-class ivars.  */
3440       interface = lookup_interface (CLASS_SUPER_NAME (interface));
3441       ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
3442                             ivar_chain);
3443     }
3444
3445   return ivar_chain;
3446 }
3447
3448 static tree
3449 objc_create_temporary_var (tree type)
3450 {
3451   tree decl;
3452
3453   decl = build_decl (input_location,
3454                      VAR_DECL, NULL_TREE, type);
3455   TREE_USED (decl) = 1;
3456   DECL_ARTIFICIAL (decl) = 1;
3457   DECL_IGNORED_P (decl) = 1;
3458   DECL_CONTEXT (decl) = current_function_decl;
3459
3460   return decl;
3461 }
3462 \f
3463 /* Exception handling constructs.  We begin by having the parser do most
3464    of the work and passing us blocks.  What we do next depends on whether
3465    we're doing "native" exception handling or legacy Darwin setjmp exceptions.
3466    We abstract all of this in a handful of appropriately named routines.  */
3467
3468 /* Stack of open try blocks.  */
3469
3470 struct objc_try_context
3471 {
3472   struct objc_try_context *outer;
3473
3474   /* Statements (or statement lists) as processed by the parser.  */
3475   tree try_body;
3476   tree finally_body;
3477
3478   /* Some file position locations.  */
3479   location_t try_locus;
3480   location_t end_try_locus;
3481   location_t end_catch_locus;
3482   location_t finally_locus;
3483   location_t end_finally_locus;
3484
3485   /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
3486      of a TRY_CATCH_EXPR.  Even when doing Darwin setjmp.  */
3487   tree catch_list;
3488
3489   /* The CATCH_EXPR of an open @catch clause.  */
3490   tree current_catch;
3491
3492   /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer.  */
3493   tree caught_decl;
3494   tree stack_decl;
3495   tree rethrow_decl;
3496 };
3497
3498 static struct objc_try_context *cur_try_context;
3499
3500 static GTY(()) tree objc_eh_personality_decl;
3501
3502 /* This hook, called via lang_eh_runtime_type, generates a runtime object
3503    that represents TYPE.  For Objective-C, this is just the class name.  */
3504 /* ??? Isn't there a class object or some such?  Is it easy to get?  */
3505
3506 #ifndef OBJCPLUS
3507 tree
3508 objc_eh_runtime_type (tree type)
3509 {
3510   return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
3511 }
3512
3513 tree
3514 objc_eh_personality (void)
3515 {
3516   if (!flag_objc_sjlj_exceptions
3517       && !objc_eh_personality_decl)
3518     objc_eh_personality_decl
3519       = build_personality_function (USING_SJLJ_EXCEPTIONS
3520                                     ? "__gnu_objc_personality_sj0"
3521                                     : "__gnu_objc_personality_v0");
3522
3523   return objc_eh_personality_decl;
3524 }
3525 #endif
3526
3527 /* Build __builtin_eh_pointer, or the moral equivalent.  In the case
3528    of Darwin, we'll arrange for it to be initialized (and associated
3529    with a binding) later.  */
3530
3531 static tree
3532 objc_build_exc_ptr (void)
3533 {
3534   if (flag_objc_sjlj_exceptions)
3535     {
3536       tree var = cur_try_context->caught_decl;
3537       if (!var)
3538         {
3539           var = objc_create_temporary_var (objc_object_type);
3540           cur_try_context->caught_decl = var;
3541         }
3542       return var;
3543     }
3544   else
3545     {
3546       tree t;
3547       t = built_in_decls[BUILT_IN_EH_POINTER];
3548       t = build_call_expr (t, 1, integer_zero_node);
3549       return fold_convert (objc_object_type, t);
3550     }
3551 }
3552
3553 /* Build "objc_exception_try_exit(&_stack)".  */
3554
3555 static tree
3556 next_sjlj_build_try_exit (void)
3557 {
3558   tree t;
3559   t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
3560   t = tree_cons (NULL, t, NULL);
3561   t = build_function_call (input_location,
3562                            objc_exception_try_exit_decl, t);
3563   return t;
3564 }
3565
3566 /* Build
3567         objc_exception_try_enter (&_stack);
3568         if (_setjmp(&_stack.buf))
3569           ;
3570         else
3571           ;
3572    Return the COND_EXPR.  Note that the THEN and ELSE fields are left
3573    empty, ready for the caller to fill them in.  */
3574
3575 static tree
3576 next_sjlj_build_enter_and_setjmp (void)
3577 {
3578   tree t, enter, sj, cond;
3579