OSDN Git Service

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