Import pre-release gcc-5.0 to new vendor branch
[dragonfly.git] / contrib / gcc-5.0 / gcc / objc / objc-encoding.c
1 /* Routines dealing with ObjC encoding of types
2    Copyright (C) 1992-2015 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "hash-set.h"
24 #include "machmode.h"
25 #include "vec.h"
26 #include "double-int.h"
27 #include "input.h"
28 #include "alias.h"
29 #include "symtab.h"
30 #include "options.h"
31 #include "wide-int.h"
32 #include "inchash.h"
33 #include "tree.h"
34 #include "stringpool.h"
35 #include "stor-layout.h"
36
37 #ifdef OBJCPLUS
38 #include "cp/cp-tree.h"
39 #else
40 #include "c/c-tree.h"
41 #include "c/c-lang.h"
42 #endif
43
44 #include "c-family/c-common.h"
45 #include "c-family/c-objc.h"
46
47 #include "objc-encoding.h"
48 #include "objc-act.h"
49
50 /* For my_build_string().  */
51 #include "objc-runtime-shared-support.h"
52
53 /* For BITS_PER_UNIT.  */
54 #include "tm.h"
55
56 /* When building Objective-C++, we are not linking against the C front-end
57    and so need to replicate the C tree-construction functions in some way.  */
58 #ifdef OBJCPLUS
59 #define OBJCP_REMAP_FUNCTIONS
60 #include "objcp-decl.h"
61 #endif  /* OBJCPLUS */
62
63 /* Set up for use of obstacks.  */
64 #include "obstack.h"
65
66 /* This obstack is used to accumulate the encoding of a data type.  */
67 static struct obstack util_obstack;
68
69 /* This points to the beginning of obstack contents, so we can free
70    the whole contents.  */
71 static char *util_firstobj;
72
73 void objc_encoding_init (void)
74 {
75   gcc_obstack_init (&util_obstack);
76   util_firstobj = (char *) obstack_finish (&util_obstack);
77 }
78
79 int generating_instance_variables = 0;
80
81 static void encode_type_qualifiers (tree);
82 static void encode_type (tree, int, int);
83 static void encode_field (tree field_decl, int curtype, int format);
84
85 static tree
86 objc_method_parm_type (tree type)
87 {
88   type = TREE_VALUE (TREE_TYPE (type));
89   if (TREE_CODE (type) == TYPE_DECL)
90     type = TREE_TYPE (type);
91   return type;
92 }
93
94 static int
95 objc_encoded_type_size (tree type)
96 {
97   int sz = int_size_in_bytes (type);
98
99   /* Make all integer and enum types at least as large
100      as an int.  */
101   if (sz > 0 && INTEGRAL_TYPE_P (type))
102     sz = MAX (sz, int_size_in_bytes (integer_type_node));
103   /* Treat arrays as pointers, since that's how they're
104      passed in.  */
105   else if (TREE_CODE (type) == ARRAY_TYPE)
106     sz = int_size_in_bytes (ptr_type_node);
107   return sz;
108 }
109
110 /* Encode a method prototype.  */
111 tree
112 encode_method_prototype (tree method_decl)
113 {
114   tree parms;
115   int parm_offset, i;
116   char buf[40];
117   tree result;
118
119   /* ONEWAY and BYCOPY, for remote object are the only method qualifiers.  */
120   encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
121
122   /* Encode return type.  */
123   encode_type (objc_method_parm_type (method_decl),
124                obstack_object_size (&util_obstack),
125                OBJC_ENCODE_INLINE_DEFS);
126
127   /* Stack size.  */
128   /* The first two arguments (self and _cmd) are pointers; account for
129      their size.  */
130   i = int_size_in_bytes (ptr_type_node);
131   parm_offset = 2 * i;
132   for (parms = METHOD_SEL_ARGS (method_decl); parms;
133        parms = DECL_CHAIN (parms))
134     {
135       tree type = objc_method_parm_type (parms);
136       int sz = objc_encoded_type_size (type);
137
138       /* If a type size is not known, bail out.  */
139       if (sz < 0)
140         {
141           error_at (DECL_SOURCE_LOCATION (method_decl),
142                     "type %qT does not have a known size",
143                     type);
144           /* Pretend that the encoding succeeded; the compilation will
145              fail nevertheless.  */
146           goto finish_encoding;
147         }
148       parm_offset += sz;
149     }
150
151   sprintf (buf, "%d@0:%d", parm_offset, i);
152   obstack_grow (&util_obstack, buf, strlen (buf));
153
154   /* Argument types.  */
155   parm_offset = 2 * i;
156   for (parms = METHOD_SEL_ARGS (method_decl); parms;
157        parms = DECL_CHAIN (parms))
158     {
159       tree type = objc_method_parm_type (parms);
160
161       /* Process argument qualifiers for user supplied arguments.  */
162       encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
163
164       /* Type.  */
165       encode_type (type, obstack_object_size (&util_obstack),
166                    OBJC_ENCODE_INLINE_DEFS);
167
168       /* Compute offset.  */
169       sprintf (buf, "%d", parm_offset);
170       parm_offset += objc_encoded_type_size (type);
171
172       obstack_grow (&util_obstack, buf, strlen (buf));
173     }
174
175   finish_encoding:
176   obstack_1grow (&util_obstack, '\0');
177   result = get_identifier (XOBFINISH (&util_obstack, char *));
178   obstack_free (&util_obstack, util_firstobj);
179   return result;
180 }
181
182 /* This is used to implement @encode().  */
183 tree
184 objc_build_encode_expr (tree type)
185 {
186   tree result;
187   const char *string;
188
189   encode_type (type, obstack_object_size (&util_obstack),
190                OBJC_ENCODE_INLINE_DEFS);
191   obstack_1grow (&util_obstack, 0);    /* null terminate string */
192   string = XOBFINISH (&util_obstack, const char *);
193
194   /* Synthesize a string that represents the encoded struct/union.  */
195   result = my_build_string (strlen (string) + 1, string);
196   obstack_free (&util_obstack, util_firstobj);
197   return result;
198 }
199
200 /* "Encode" a data type into a string, which grows in util_obstack.
201
202    The format is described in gcc/doc/objc.texi, section 'Type
203    encoding'.
204
205    Most of the encode_xxx functions have a 'type' argument, which is
206    the type to encode, and an integer 'curtype' argument, which is the
207    index in the encoding string of the beginning of the encoding of
208    the current type, and allows you to find what characters have
209    already been written for the current type (they are the ones in the
210    current encoding string starting from 'curtype').
211
212    For example, if we are encoding a method which returns 'int' and
213    takes a 'char **' argument, then when we get to the point of
214    encoding the 'char **' argument, the encoded string already
215    contains 'i12@0:4' (assuming a pointer size of 4 bytes).  So,
216    'curtype' will be set to 7 when starting to encode 'char **'.
217    During the whole of the encoding of 'char **', 'curtype' will be
218    fixed at 7, so the routine encoding the second pointer can find out
219    that it's actually encoding a pointer to a pointer by looking
220    backwards at what has already been encoded for the current type,
221    and seeing there is a "^" (meaning a pointer) in there.  */
222
223
224 /* Encode type qualifiers encodes one of the "PQ" Objective-C
225    keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
226    'const', instead, is encoded directly as part of the type.  */
227 static void
228 encode_type_qualifiers (tree declspecs)
229 {
230   tree spec;
231
232   for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
233     {
234       /* FIXME: Shouldn't we use token->keyword here ? */
235       if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
236         obstack_1grow (&util_obstack, 'n');
237       else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
238         obstack_1grow (&util_obstack, 'N');
239       else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
240         obstack_1grow (&util_obstack, 'o');
241       else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
242         obstack_1grow (&util_obstack, 'O');
243       else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
244         obstack_1grow (&util_obstack, 'R');
245       else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
246         obstack_1grow (&util_obstack, 'V');
247       else
248         gcc_unreachable ();
249     }
250 }
251
252 /* Determine if a pointee is marked read-only.  Only used by the NeXT
253    runtime to be compatible with gcc-3.3.  */
254 static bool
255 pointee_is_readonly (tree pointee)
256 {
257   while (POINTER_TYPE_P (pointee))
258     pointee = TREE_TYPE (pointee);
259
260   return TYPE_READONLY (pointee);
261 }
262
263 /* Encode a pointer type.  */
264 static void
265 encode_pointer (tree type, int curtype, int format)
266 {
267   tree pointer_to = TREE_TYPE (type);
268
269   if (flag_next_runtime)
270     {
271       /* This code is used to be compatible with gcc-3.3.  */
272       /* For historical/compatibility reasons, the read-only qualifier
273          of the pointee gets emitted _before_ the '^'.  The read-only
274          qualifier of the pointer itself gets ignored, _unless_ we are
275          looking at a typedef!  Also, do not emit the 'r' for anything
276          but the outermost type!  */
277       if (!generating_instance_variables
278           && (obstack_object_size (&util_obstack) - curtype <= 1)
279           && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
280               ? TYPE_READONLY (type)
281               : pointee_is_readonly (pointer_to)))
282         obstack_1grow (&util_obstack, 'r');
283     }
284
285   if (TREE_CODE (pointer_to) == RECORD_TYPE)
286     {
287       if (OBJC_TYPE_NAME (pointer_to)
288           && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
289         {
290           const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
291
292           if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
293             {
294               obstack_1grow (&util_obstack, '@');
295               return;
296             }
297           else if (TYPE_HAS_OBJC_INFO (pointer_to)
298                    && TYPE_OBJC_INTERFACE (pointer_to))
299             {
300               if (generating_instance_variables)
301                 {
302                   obstack_1grow (&util_obstack, '@');
303                   obstack_1grow (&util_obstack, '"');
304                   obstack_grow (&util_obstack, name, strlen (name));
305                   obstack_1grow (&util_obstack, '"');
306                   return;
307                 }
308               else
309                 {
310                   obstack_1grow (&util_obstack, '@');
311                   return;
312                 }
313             }
314           else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
315             {
316               obstack_1grow (&util_obstack, '#');
317               return;
318             }
319           else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
320             {
321               obstack_1grow (&util_obstack, ':');
322               return;
323             }
324         }
325     }
326   else if (TREE_CODE (pointer_to) == INTEGER_TYPE
327            && TYPE_MODE (pointer_to) == QImode)
328     {
329       tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
330                   ? OBJC_TYPE_NAME (pointer_to)
331                   : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
332
333       /* (BOOL *) are an exception and are encoded as ^c, while all
334          other pointers to char are encoded as *.   */
335       if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
336         {
337           if (!flag_next_runtime)
338             {
339               /* The NeXT runtime adds the 'r' before getting here.  */
340
341               /* It appears that "r*" means "const char *" rather than
342                  "char *const".  "char *const" is encoded as "*",
343                  which is identical to "char *", so the "const" is
344                  unfortunately lost.  */
345               if (TYPE_READONLY (pointer_to))
346                 obstack_1grow (&util_obstack, 'r');
347             }
348
349           obstack_1grow (&util_obstack, '*');
350           return;
351         }
352     }
353
354   /* We have a normal pointer type that does not get special treatment.  */
355   obstack_1grow (&util_obstack, '^');
356   encode_type (pointer_to, curtype, format);
357 }
358
359 static void
360 encode_array (tree type, int curtype, int format)
361 {
362   tree an_int_cst = TYPE_SIZE (type);
363   tree array_of = TREE_TYPE (type);
364   char buffer[40];
365
366   if (an_int_cst == NULL)
367     {
368       /* We are trying to encode an incomplete array.  An incomplete
369          array is forbidden as part of an instance variable; but it
370          may occur if the instance variable is a pointer to such an
371          array.  */
372
373       /* So the only case in which an incomplete array could occur
374          (without being pointed to) is if we are encoding the
375          arguments or return value of a method.  In that case, an
376          incomplete array argument or return value (eg,
377          -(void)display: (char[])string) is treated like a pointer
378          because that is how the compiler does the function call.  A
379          special, more complicated case, is when the incomplete array
380          is the last member of a struct (eg, if we are encoding
381          "struct { unsigned long int a;double b[];}"), which is again
382          part of a method argument/return value.  In that case, we
383          really need to communicate to the runtime that there is an
384          incomplete array (not a pointer!) there.  So, we detect that
385          special case and encode it as a zero-length array.
386
387          Try to detect that we are part of a struct.  We do this by
388          searching for '=' in the type encoding for the current type.
389          NB: This hack assumes that you can't use '=' as part of a C
390          identifier.
391       */
392       {
393         char *enc = (char *) obstack_base (&util_obstack) + curtype;
394         if (memchr (enc, '=',
395                     obstack_object_size (&util_obstack) - curtype) == NULL)
396           {
397             /* We are not inside a struct.  Encode the array as a
398                pointer.  */
399             encode_pointer (type, curtype, format);
400             return;
401           }
402       }
403
404       /* Else, we are in a struct, and we encode it as a zero-length
405          array.  */
406       sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
407     }
408   else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
409    sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
410   else
411     sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
412              TREE_INT_CST_LOW (an_int_cst)
413               / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
414
415   obstack_grow (&util_obstack, buffer, strlen (buffer));
416   encode_type (array_of, curtype, format);
417   obstack_1grow (&util_obstack, ']');
418   return;
419 }
420
421 /* Encode a vector.  The vector type is a GCC extension to C.  */
422 static void
423 encode_vector (tree type, int curtype, int format)
424 {
425   tree vector_of = TREE_TYPE (type);
426   char buffer[40];
427
428   /* Vectors are like simple fixed-size arrays.  */
429
430   /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
431      alignment of the vector, and <code> is the base type.  Eg, int
432      __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
433      assuming that the alignment is 32 bytes.  We include size and
434      alignment in bytes so that the runtime does not have to have any
435      knowledge of the actual types.
436   */
437   sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
438            /* We want to compute the equivalent of sizeof (<vector>).
439               Code inspired by c_sizeof_or_alignof_type.  */
440            ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
441              / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
442            /* We want to compute the equivalent of __alignof__
443               (<vector>).  Code inspired by
444               c_sizeof_or_alignof_type.  */
445            TYPE_ALIGN_UNIT (type));
446   obstack_grow (&util_obstack, buffer, strlen (buffer));
447   encode_type (vector_of, curtype, format);
448   obstack_1grow (&util_obstack, ']');
449   return;
450 }
451
452 static void
453 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
454 {
455   tree field = TYPE_FIELDS (type);
456
457   for (; field; field = DECL_CHAIN (field))
458     {
459 #ifdef OBJCPLUS
460       /* C++ static members, and things that are not field at all,
461          should not appear in the encoding.  */
462       if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
463         continue;
464 #endif
465
466       /* Recursively encode fields of embedded base classes.  */
467       if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
468           && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
469         {
470           encode_aggregate_fields (TREE_TYPE (field),
471                                    pointed_to, curtype, format);
472           continue;
473         }
474
475       if (generating_instance_variables && !pointed_to)
476         {
477           tree fname = DECL_NAME (field);
478
479           obstack_1grow (&util_obstack, '"');
480
481           if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
482             obstack_grow (&util_obstack,
483                           IDENTIFIER_POINTER (fname),
484                           strlen (IDENTIFIER_POINTER (fname)));
485
486           obstack_1grow (&util_obstack, '"');
487         }
488
489       encode_field (field, curtype, format);
490     }
491 }
492
493 static void
494 encode_aggregate_within (tree type, int curtype, int format, int left,
495                          int right)
496 {
497   tree name;
498   /* NB: aggregates that are pointed to have slightly different encoding
499      rules in that you never encode the names of instance variables.  */
500   int ob_size = obstack_object_size (&util_obstack);
501   bool inline_contents = false;
502   bool pointed_to = false;
503
504   if (flag_next_runtime)
505     {
506       if (ob_size > 0  &&  *(obstack_next_free (&util_obstack) - 1) == '^')
507         pointed_to = true;
508
509       if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
510           && (!pointed_to || ob_size - curtype == 1
511               || (ob_size - curtype == 2
512                   && *(obstack_next_free (&util_obstack) - 2) == 'r')))
513         inline_contents = true;
514     }
515   else
516     {
517       /* c0 and c1 are the last two characters in the encoding of the
518          current type; if the last two characters were '^' or '^r',
519          then we are encoding an aggregate that is "pointed to".  The
520          comment above applies: in that case we should avoid encoding
521          the names of instance variables.
522       */
523       char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
524       char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
525
526       if (c0 == '^' || (c1 == '^' && c0 == 'r'))
527         pointed_to = true;
528
529       if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
530         {
531           if (!pointed_to)
532             inline_contents = true;
533           else
534             {
535               /* Note that the check (ob_size - curtype < 2) prevents
536                  infinite recursion when encoding a structure which is
537                  a linked list (eg, struct node { struct node *next;
538                  }).  Each time we follow a pointer, we add one
539                  character to ob_size, and curtype is fixed, so after
540                  at most two pointers we stop inlining contents and
541                  break the loop.
542
543                  The other case where we don't inline is "^r", which
544                  is a pointer to a constant struct.
545               */
546               if ((ob_size - curtype <= 2) && !(c0 == 'r'))
547                 inline_contents = true;
548             }
549         }
550     }
551
552   /* Traverse struct aliases; it is important to get the
553      original struct and its tag name (if any).  */
554   type = TYPE_MAIN_VARIANT (type);
555   name = OBJC_TYPE_NAME (type);
556   /* Open parenth/bracket.  */
557   obstack_1grow (&util_obstack, left);
558
559   /* Encode the struct/union tag name, or '?' if a tag was
560      not provided.  Typedef aliases do not qualify.  */
561 #ifdef OBJCPLUS
562   /* For compatibility with the NeXT runtime, ObjC++ encodes template
563      args as a composite struct tag name. */
564   if (name && TREE_CODE (name) == IDENTIFIER_NODE
565       /* Did this struct have a tag?  */
566       && !TYPE_WAS_ANONYMOUS (type))
567     obstack_grow (&util_obstack,
568                   decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
569                   strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
570 #else
571   if (name && TREE_CODE (name) == IDENTIFIER_NODE)
572     obstack_grow (&util_obstack,
573                   IDENTIFIER_POINTER (name),
574                   strlen (IDENTIFIER_POINTER (name)));
575 #endif
576   else
577     obstack_1grow (&util_obstack, '?');
578
579   /* Encode the types (and possibly names) of the inner fields,
580      if required.  */
581   if (inline_contents)
582     {
583       obstack_1grow (&util_obstack, '=');
584       encode_aggregate_fields (type, pointed_to, curtype, format);
585     }
586   /* Close parenth/bracket.  */
587   obstack_1grow (&util_obstack, right);
588 }
589
590 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
591    field type.  */
592 static void
593 encode_next_bitfield (int width)
594 {
595   char buffer[40];
596   sprintf (buffer, "b%d", width);
597   obstack_grow (&util_obstack, buffer, strlen (buffer));
598 }
599
600 /* Encodes 'type', ignoring type qualifiers (which you should encode
601    beforehand if needed) with the exception of 'const', which is
602    encoded by encode_type.  See above for the explanation of
603    'curtype'.  'format' can be OBJC_ENCODE_INLINE_DEFS or
604    OBJC_ENCODE_DONT_INLINE_DEFS.  */
605 static void
606 encode_type (tree type, int curtype, int format)
607 {
608   enum tree_code code = TREE_CODE (type);
609
610   /* Ignore type qualifiers other than 'const' when encoding a
611      type.  */
612
613   if (type == error_mark_node)
614     return;
615
616   if (!flag_next_runtime)
617     {
618       if (TYPE_READONLY (type))
619         obstack_1grow (&util_obstack, 'r');
620     }
621
622   switch (code)
623     {
624     case ENUMERAL_TYPE:
625       if (flag_next_runtime)
626         {
627           /* Kludge for backwards-compatibility with gcc-3.3: enums
628              are always encoded as 'i' no matter what type they
629              actually are (!).  */
630           obstack_1grow (&util_obstack, 'i');
631           break;
632         }
633       /* Else, they are encoded exactly like the integer type that is
634          used by the compiler to store them.  */
635     case INTEGER_TYPE:
636       {
637         char c;
638         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
639           {
640           case 8:  c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
641           case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
642           case 32:
643             {
644               tree int_type = type;
645               if (flag_next_runtime)
646                 {
647                   /* Another legacy kludge for compatibility with
648                      gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
649                      but not always.  For typedefs, we need to use 'i'
650                      or 'I' instead if encoding a struct field, or a
651                      pointer!  */
652                   int_type =  ((!generating_instance_variables
653                                 && (obstack_object_size (&util_obstack)
654                                     == (unsigned) curtype))
655                                ? TYPE_MAIN_VARIANT (type)
656                                : type);
657                 }
658               if (int_type == long_unsigned_type_node
659                   || int_type == long_integer_type_node)
660                 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
661               else
662                 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
663             }
664             break;
665           case 64:  c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
666           case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
667           default: gcc_unreachable ();
668           }
669         obstack_1grow (&util_obstack, c);
670         break;
671       }
672     case REAL_TYPE:
673       {
674         char c;
675         /* Floating point types.  */
676         switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
677           {
678           case 32:  c = 'f'; break;
679           case 64:  c = 'd'; break;
680           case 96:
681           case 128: c = 'D'; break;
682           default: gcc_unreachable ();
683           }
684         obstack_1grow (&util_obstack, c);
685         break;
686       }
687     case VOID_TYPE:
688       obstack_1grow (&util_obstack, 'v');
689       break;
690
691     case BOOLEAN_TYPE:
692       obstack_1grow (&util_obstack, 'B');
693       break;
694
695     case ARRAY_TYPE:
696       encode_array (type, curtype, format);
697       break;
698
699     case POINTER_TYPE:
700 #ifdef OBJCPLUS
701     case REFERENCE_TYPE:
702 #endif
703       encode_pointer (type, curtype, format);
704       break;
705
706     case RECORD_TYPE:
707       encode_aggregate_within (type, curtype, format, '{', '}');
708       break;
709
710     case UNION_TYPE:
711       encode_aggregate_within (type, curtype, format, '(', ')');
712       break;
713
714     case FUNCTION_TYPE: /* '?' means an unknown type.  */
715       obstack_1grow (&util_obstack, '?');
716       break;
717
718     case COMPLEX_TYPE:
719       /* A complex is encoded as 'j' followed by the inner type (eg,
720          "_Complex int" is encoded as 'ji').  */
721       obstack_1grow (&util_obstack, 'j');
722       encode_type (TREE_TYPE (type), curtype, format);
723       break;
724
725     case VECTOR_TYPE:
726       encode_vector (type, curtype, format);
727       break;
728
729     default:
730       warning (0, "unknown type %<%T%> found during Objective-C encoding",
731                TREE_TYPE (type));
732       obstack_1grow (&util_obstack, '?');
733       break;
734     }
735
736   if (flag_next_runtime)
737     {
738       /* Super-kludge.  Some ObjC qualifier and type combinations need
739          to be rearranged for compatibility with gcc-3.3.  */
740       if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
741         {
742           char *enc = (char *) obstack_base (&util_obstack) + curtype;
743
744           /* Rewrite "in const" from "nr" to "rn".  */
745           if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
746             strncpy (enc - 1, "rn", 2);
747         }
748     }
749 }
750
751 static void
752 encode_gnu_bitfield (int position, tree type, int size)
753 {
754   enum tree_code code = TREE_CODE (type);
755   char buffer[40];
756   char charType = '?';
757
758   /* This code is only executed for the GNU runtime, so we can ignore
759      the NeXT runtime kludge of always encoding enums as 'i' no matter
760      what integers they actually are.  */
761   if (code == INTEGER_TYPE  ||  code == ENUMERAL_TYPE)
762     {
763       if (integer_zerop (TYPE_MIN_VALUE (type)))
764         /* Unsigned integer types.  */
765         {
766           switch (TYPE_MODE (type))
767             {
768             case QImode:
769               charType = 'C'; break;
770             case HImode:
771               charType = 'S'; break;
772             case SImode:
773               {
774                 if (type == long_unsigned_type_node)
775                   charType = 'L';
776                 else
777                   charType = 'I';
778                 break;
779               }
780             case DImode:
781               charType = 'Q'; break;
782             default:
783               gcc_unreachable ();
784             }
785         }
786       else
787         /* Signed integer types.  */
788         {
789           switch (TYPE_MODE (type))
790             {
791             case QImode:
792               charType = 'c'; break;
793             case HImode:
794               charType = 's'; break;
795             case SImode:
796               {
797                 if (type == long_integer_type_node)
798                   charType = 'l';
799                 else
800                   charType = 'i';
801                 break;
802               }
803             case DImode:
804               charType = 'q'; break;
805             default:
806               gcc_unreachable ();
807             }
808         }
809     }
810   else
811     {
812       /* Do not do any encoding, produce an error and keep going.  */
813       error ("trying to encode non-integer type as a bitfield");
814       return;
815     }
816
817   sprintf (buffer, "b%d%c%d", position, charType, size);
818   obstack_grow (&util_obstack, buffer, strlen (buffer));
819 }
820
821 static void
822 encode_field (tree field_decl, int curtype, int format)
823 {
824 #ifdef OBJCPLUS
825   /* C++ static members, and things that are not fields at all,
826      should not appear in the encoding.  */
827   if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
828     return;
829 #endif
830
831   /* Generate the bitfield typing information, if needed.  Note the difference
832      between GNU and NeXT runtimes.  */
833   if (DECL_BIT_FIELD_TYPE (field_decl))
834     {
835       int size = tree_to_uhwi (DECL_SIZE (field_decl));
836
837       if (flag_next_runtime)
838         encode_next_bitfield (size);
839       else
840         encode_gnu_bitfield (int_bit_position (field_decl),
841                              DECL_BIT_FIELD_TYPE (field_decl), size);
842     }
843   else
844     encode_type (TREE_TYPE (field_decl), curtype, format);
845 }
846
847 tree
848 encode_field_decl (tree field_decl)
849 {
850   tree result;
851
852   encode_field (field_decl,
853                 obstack_object_size (&util_obstack),
854                 OBJC_ENCODE_DONT_INLINE_DEFS);
855   
856   /* Null terminate string.  */
857   obstack_1grow (&util_obstack, 0);
858
859   /* Get identifier for the string.  */
860   result = get_identifier (XOBFINISH (&util_obstack, char *));
861   obstack_free (&util_obstack, util_firstobj);
862
863   return result;
864 }
865
866 /* This routine encodes the attribute of the input PROPERTY according
867    to following formula:
868
869    Property attributes are stored as a comma-delimited C string.
870    Simple attributes such as readonly are encoded as single
871    character. The parametrized attributes, getter=name and
872    setter=name, are encoded as a single character followed by an
873    identifier.  Property types are also encoded as a parametrized
874    attribute.  The characters used to encode these attributes are
875    defined by the following enumeration:
876
877    enum PropertyAttributes {
878      kPropertyReadOnly = 'R',
879      kPropertyBycopy = 'C',
880      kPropertyByref = '&',
881      kPropertyDynamic = 'D',
882      kPropertyGetter = 'G',
883      kPropertySetter = 'S',
884      kPropertyInstanceVariable = 'V',
885      kPropertyType = 'T',
886      kPropertyWeak = 'W',
887      kPropertyStrong = 'P',
888      kPropertyNonAtomic = 'N'
889    };  */
890 tree
891 objc_v2_encode_prop_attr (tree property)
892 {
893   const char *string;
894   tree type = TREE_TYPE (property);
895
896   obstack_1grow (&util_obstack, 'T');
897   encode_type (type, obstack_object_size (&util_obstack),
898                OBJC_ENCODE_INLINE_DEFS);
899
900   if (PROPERTY_READONLY (property))
901     obstack_grow (&util_obstack, ",R", 2);
902
903   switch (PROPERTY_ASSIGN_SEMANTICS (property))
904     {
905     case OBJC_PROPERTY_COPY:
906       obstack_grow (&util_obstack, ",C", 2);
907       break;
908     case OBJC_PROPERTY_RETAIN:
909       obstack_grow (&util_obstack, ",&", 2);
910       break;
911     case OBJC_PROPERTY_ASSIGN:
912     default:
913       break;
914     }
915
916   if (PROPERTY_DYNAMIC (property))
917     obstack_grow (&util_obstack, ",D", 2);
918
919   if (PROPERTY_NONATOMIC (property))
920     obstack_grow (&util_obstack, ",N", 2);
921
922   /* Here we want to encode the getter name, but only if it's not the
923      standard one.  */
924   if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property))
925     {
926       obstack_grow (&util_obstack, ",G", 2);
927       string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property));
928       obstack_grow (&util_obstack, string, strlen (string));
929     }
930
931   if (!PROPERTY_READONLY (property))
932     {
933       /* Here we want to encode the setter name, but only if it's not
934          the standard one.  */
935       tree standard_setter = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property)));
936       if (PROPERTY_SETTER_NAME (property) != standard_setter)
937         {
938           obstack_grow (&util_obstack, ",S", 2);
939           string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
940           obstack_grow (&util_obstack, string, strlen (string));
941         }
942     }
943
944   /* TODO: Encode strong ('P'), weak ('W') for garbage collection.  */
945
946   if (!PROPERTY_DYNAMIC (property))
947     {
948       obstack_grow (&util_obstack, ",V", 2);
949       if (PROPERTY_IVAR_NAME (property))
950         string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
951       else
952         string = IDENTIFIER_POINTER (PROPERTY_NAME (property));
953       obstack_grow (&util_obstack, string, strlen (string));
954     }
955
956   /* NULL-terminate string.  */
957   obstack_1grow (&util_obstack, 0);
958   string = XOBFINISH (&util_obstack, char *);
959   obstack_free (&util_obstack, util_firstobj);
960   return get_identifier (string);
961 }