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