OSDN Git Service

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