OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [objc/] [objc-act.c] - Blame information for rev 826

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.