2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / objc / objc-encoding.c
blob39431dc9f3c38e18fe84a91439ffaee9fd09e31a
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"
25 #ifdef OBJCPLUS
26 #include "cp/cp-tree.h"
27 #else
28 #include "c/c-tree.h"
29 #include "c/c-lang.h"
30 #endif
32 #include "c-family/c-common.h"
33 #include "c-family/c-objc.h"
35 #include "objc-encoding.h"
36 #include "objc-act.h"
38 /* For my_build_string(). */
39 #include "objc-runtime-shared-support.h"
41 /* For BITS_PER_UNIT. */
42 #include "tm.h"
44 /* When building Objective-C++, we are not linking against the C front-end
45 and so need to replicate the C tree-construction functions in some way. */
46 #ifdef OBJCPLUS
47 #define OBJCP_REMAP_FUNCTIONS
48 #include "objcp-decl.h"
49 #endif /* OBJCPLUS */
51 /* Set up for use of obstacks. */
52 #include "obstack.h"
54 /* This obstack is used to accumulate the encoding of a data type. */
55 static struct obstack util_obstack;
57 /* This points to the beginning of obstack contents, so we can free
58 the whole contents. */
59 static char *util_firstobj;
61 void objc_encoding_init (void)
63 gcc_obstack_init (&util_obstack);
64 util_firstobj = (char *) obstack_finish (&util_obstack);
67 int generating_instance_variables = 0;
69 static void encode_type_qualifiers (tree);
70 static void encode_type (tree, int, int);
71 static void encode_field (tree field_decl, int curtype, int format);
73 static tree
74 objc_method_parm_type (tree type)
76 type = TREE_VALUE (TREE_TYPE (type));
77 if (TREE_CODE (type) == TYPE_DECL)
78 type = TREE_TYPE (type);
79 return type;
82 static int
83 objc_encoded_type_size (tree type)
85 int sz = int_size_in_bytes (type);
87 /* Make all integer and enum types at least as large
88 as an int. */
89 if (sz > 0 && INTEGRAL_TYPE_P (type))
90 sz = MAX (sz, int_size_in_bytes (integer_type_node));
91 /* Treat arrays as pointers, since that's how they're
92 passed in. */
93 else if (TREE_CODE (type) == ARRAY_TYPE)
94 sz = int_size_in_bytes (ptr_type_node);
95 return sz;
98 /* Encode a method prototype. */
99 tree
100 encode_method_prototype (tree method_decl)
102 tree parms;
103 int parm_offset, i;
104 char buf[40];
105 tree result;
107 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
108 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
110 /* Encode return type. */
111 encode_type (objc_method_parm_type (method_decl),
112 obstack_object_size (&util_obstack),
113 OBJC_ENCODE_INLINE_DEFS);
115 /* Stack size. */
116 /* The first two arguments (self and _cmd) are pointers; account for
117 their size. */
118 i = int_size_in_bytes (ptr_type_node);
119 parm_offset = 2 * i;
120 for (parms = METHOD_SEL_ARGS (method_decl); parms;
121 parms = DECL_CHAIN (parms))
123 tree type = objc_method_parm_type (parms);
124 int sz = objc_encoded_type_size (type);
126 /* If a type size is not known, bail out. */
127 if (sz < 0)
129 error_at (DECL_SOURCE_LOCATION (method_decl),
130 "type %qT does not have a known size",
131 type);
132 /* Pretend that the encoding succeeded; the compilation will
133 fail nevertheless. */
134 goto finish_encoding;
136 parm_offset += sz;
139 sprintf (buf, "%d@0:%d", parm_offset, i);
140 obstack_grow (&util_obstack, buf, strlen (buf));
142 /* Argument types. */
143 parm_offset = 2 * i;
144 for (parms = METHOD_SEL_ARGS (method_decl); parms;
145 parms = DECL_CHAIN (parms))
147 tree type = objc_method_parm_type (parms);
149 /* Process argument qualifiers for user supplied arguments. */
150 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
152 /* Type. */
153 encode_type (type, obstack_object_size (&util_obstack),
154 OBJC_ENCODE_INLINE_DEFS);
156 /* Compute offset. */
157 sprintf (buf, "%d", parm_offset);
158 parm_offset += objc_encoded_type_size (type);
160 obstack_grow (&util_obstack, buf, strlen (buf));
163 finish_encoding:
164 obstack_1grow (&util_obstack, '\0');
165 result = get_identifier (XOBFINISH (&util_obstack, char *));
166 obstack_free (&util_obstack, util_firstobj);
167 return result;
170 /* This is used to implement @encode(). */
171 tree
172 objc_build_encode_expr (tree type)
174 tree result;
175 const char *string;
177 encode_type (type, obstack_object_size (&util_obstack),
178 OBJC_ENCODE_INLINE_DEFS);
179 obstack_1grow (&util_obstack, 0); /* null terminate string */
180 string = XOBFINISH (&util_obstack, const char *);
182 /* Synthesize a string that represents the encoded struct/union. */
183 result = my_build_string (strlen (string) + 1, string);
184 obstack_free (&util_obstack, util_firstobj);
185 return result;
188 /* "Encode" a data type into a string, which grows in util_obstack.
190 The format is described in gcc/doc/objc.texi, section 'Type
191 encoding'.
193 Most of the encode_xxx functions have a 'type' argument, which is
194 the type to encode, and an integer 'curtype' argument, which is the
195 index in the encoding string of the beginning of the encoding of
196 the current type, and allows you to find what characters have
197 already been written for the current type (they are the ones in the
198 current encoding string starting from 'curtype').
200 For example, if we are encoding a method which returns 'int' and
201 takes a 'char **' argument, then when we get to the point of
202 encoding the 'char **' argument, the encoded string already
203 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
204 'curtype' will be set to 7 when starting to encode 'char **'.
205 During the whole of the encoding of 'char **', 'curtype' will be
206 fixed at 7, so the routine encoding the second pointer can find out
207 that it's actually encoding a pointer to a pointer by looking
208 backwards at what has already been encoded for the current type,
209 and seeing there is a "^" (meaning a pointer) in there. */
212 /* Encode type qualifiers encodes one of the "PQ" Objective-C
213 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
214 'const', instead, is encoded directly as part of the type. */
215 static void
216 encode_type_qualifiers (tree declspecs)
218 tree spec;
220 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
222 /* FIXME: Shouldn't we use token->keyword here ? */
223 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
224 obstack_1grow (&util_obstack, 'n');
225 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
226 obstack_1grow (&util_obstack, 'N');
227 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
228 obstack_1grow (&util_obstack, 'o');
229 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
230 obstack_1grow (&util_obstack, 'O');
231 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
232 obstack_1grow (&util_obstack, 'R');
233 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
234 obstack_1grow (&util_obstack, 'V');
235 else
236 gcc_unreachable ();
240 /* Determine if a pointee is marked read-only. Only used by the NeXT
241 runtime to be compatible with gcc-3.3. */
242 static bool
243 pointee_is_readonly (tree pointee)
245 while (POINTER_TYPE_P (pointee))
246 pointee = TREE_TYPE (pointee);
248 return TYPE_READONLY (pointee);
251 /* Encode a pointer type. */
252 static void
253 encode_pointer (tree type, int curtype, int format)
255 tree pointer_to = TREE_TYPE (type);
257 if (flag_next_runtime)
259 /* This code is used to be compatible with gcc-3.3. */
260 /* For historical/compatibility reasons, the read-only qualifier
261 of the pointee gets emitted _before_ the '^'. The read-only
262 qualifier of the pointer itself gets ignored, _unless_ we are
263 looking at a typedef! Also, do not emit the 'r' for anything
264 but the outermost type! */
265 if (!generating_instance_variables
266 && (obstack_object_size (&util_obstack) - curtype <= 1)
267 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
268 ? TYPE_READONLY (type)
269 : pointee_is_readonly (pointer_to)))
270 obstack_1grow (&util_obstack, 'r');
273 if (TREE_CODE (pointer_to) == RECORD_TYPE)
275 if (OBJC_TYPE_NAME (pointer_to)
276 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
278 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
280 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
282 obstack_1grow (&util_obstack, '@');
283 return;
285 else if (TYPE_HAS_OBJC_INFO (pointer_to)
286 && TYPE_OBJC_INTERFACE (pointer_to))
288 if (generating_instance_variables)
290 obstack_1grow (&util_obstack, '@');
291 obstack_1grow (&util_obstack, '"');
292 obstack_grow (&util_obstack, name, strlen (name));
293 obstack_1grow (&util_obstack, '"');
294 return;
296 else
298 obstack_1grow (&util_obstack, '@');
299 return;
302 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
304 obstack_1grow (&util_obstack, '#');
305 return;
307 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
309 obstack_1grow (&util_obstack, ':');
310 return;
314 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
315 && TYPE_MODE (pointer_to) == QImode)
317 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
318 ? OBJC_TYPE_NAME (pointer_to)
319 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
321 /* (BOOL *) are an exception and are encoded as ^c, while all
322 other pointers to char are encoded as *. */
323 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
325 if (!flag_next_runtime)
327 /* The NeXT runtime adds the 'r' before getting here. */
329 /* It appears that "r*" means "const char *" rather than
330 "char *const". "char *const" is encoded as "*",
331 which is identical to "char *", so the "const" is
332 unfortunately lost. */
333 if (TYPE_READONLY (pointer_to))
334 obstack_1grow (&util_obstack, 'r');
337 obstack_1grow (&util_obstack, '*');
338 return;
342 /* We have a normal pointer type that does not get special treatment. */
343 obstack_1grow (&util_obstack, '^');
344 encode_type (pointer_to, curtype, format);
347 static void
348 encode_array (tree type, int curtype, int format)
350 tree an_int_cst = TYPE_SIZE (type);
351 tree array_of = TREE_TYPE (type);
352 char buffer[40];
354 if (an_int_cst == NULL)
356 /* We are trying to encode an incomplete array. An incomplete
357 array is forbidden as part of an instance variable; but it
358 may occur if the instance variable is a pointer to such an
359 array. */
361 /* So the only case in which an incomplete array could occur
362 (without being pointed to) is if we are encoding the
363 arguments or return value of a method. In that case, an
364 incomplete array argument or return value (eg,
365 -(void)display: (char[])string) is treated like a pointer
366 because that is how the compiler does the function call. A
367 special, more complicated case, is when the incomplete array
368 is the last member of a struct (eg, if we are encoding
369 "struct { unsigned long int a;double b[];}"), which is again
370 part of a method argument/return value. In that case, we
371 really need to communicate to the runtime that there is an
372 incomplete array (not a pointer!) there. So, we detect that
373 special case and encode it as a zero-length array.
375 Try to detect that we are part of a struct. We do this by
376 searching for '=' in the type encoding for the current type.
377 NB: This hack assumes that you can't use '=' as part of a C
378 identifier.
381 char *enc = obstack_base (&util_obstack) + curtype;
382 if (memchr (enc, '=',
383 obstack_object_size (&util_obstack) - curtype) == NULL)
385 /* We are not inside a struct. Encode the array as a
386 pointer. */
387 encode_pointer (type, curtype, format);
388 return;
392 /* Else, we are in a struct, and we encode it as a zero-length
393 array. */
394 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
396 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
397 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
398 else
399 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
400 TREE_INT_CST_LOW (an_int_cst)
401 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
403 obstack_grow (&util_obstack, buffer, strlen (buffer));
404 encode_type (array_of, curtype, format);
405 obstack_1grow (&util_obstack, ']');
406 return;
409 /* Encode a vector. The vector type is a GCC extension to C. */
410 static void
411 encode_vector (tree type, int curtype, int format)
413 tree vector_of = TREE_TYPE (type);
414 char buffer[40];
416 /* Vectors are like simple fixed-size arrays. */
418 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
419 alignment of the vector, and <code> is the base type. Eg, int
420 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
421 assuming that the alignment is 32 bytes. We include size and
422 alignment in bytes so that the runtime does not have to have any
423 knowledge of the actual types.
425 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
426 /* We want to compute the equivalent of sizeof (<vector>).
427 Code inspired by c_sizeof_or_alignof_type. */
428 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
429 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
430 /* We want to compute the equivalent of __alignof__
431 (<vector>). Code inspired by
432 c_sizeof_or_alignof_type. */
433 TYPE_ALIGN_UNIT (type));
434 obstack_grow (&util_obstack, buffer, strlen (buffer));
435 encode_type (vector_of, curtype, format);
436 obstack_1grow (&util_obstack, ']');
437 return;
440 static void
441 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
443 tree field = TYPE_FIELDS (type);
445 for (; field; field = DECL_CHAIN (field))
447 #ifdef OBJCPLUS
448 /* C++ static members, and things that are not field at all,
449 should not appear in the encoding. */
450 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
451 continue;
452 #endif
454 /* Recursively encode fields of embedded base classes. */
455 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
456 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
458 encode_aggregate_fields (TREE_TYPE (field),
459 pointed_to, curtype, format);
460 continue;
463 if (generating_instance_variables && !pointed_to)
465 tree fname = DECL_NAME (field);
467 obstack_1grow (&util_obstack, '"');
469 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
470 obstack_grow (&util_obstack,
471 IDENTIFIER_POINTER (fname),
472 strlen (IDENTIFIER_POINTER (fname)));
474 obstack_1grow (&util_obstack, '"');
477 encode_field (field, curtype, format);
481 static void
482 encode_aggregate_within (tree type, int curtype, int format, int left,
483 int right)
485 tree name;
486 /* NB: aggregates that are pointed to have slightly different encoding
487 rules in that you never encode the names of instance variables. */
488 int ob_size = obstack_object_size (&util_obstack);
489 bool inline_contents = false;
490 bool pointed_to = false;
492 if (flag_next_runtime)
494 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
495 pointed_to = true;
497 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
498 && (!pointed_to || ob_size - curtype == 1
499 || (ob_size - curtype == 2
500 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
501 inline_contents = true;
503 else
505 /* c0 and c1 are the last two characters in the encoding of the
506 current type; if the last two characters were '^' or '^r',
507 then we are encoding an aggregate that is "pointed to". The
508 comment above applies: in that case we should avoid encoding
509 the names of instance variables.
511 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
512 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
514 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
515 pointed_to = true;
517 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
519 if (!pointed_to)
520 inline_contents = true;
521 else
523 /* Note that the check (ob_size - curtype < 2) prevents
524 infinite recursion when encoding a structure which is
525 a linked list (eg, struct node { struct node *next;
526 }). Each time we follow a pointer, we add one
527 character to ob_size, and curtype is fixed, so after
528 at most two pointers we stop inlining contents and
529 break the loop.
531 The other case where we don't inline is "^r", which
532 is a pointer to a constant struct.
534 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
535 inline_contents = true;
540 /* Traverse struct aliases; it is important to get the
541 original struct and its tag name (if any). */
542 type = TYPE_MAIN_VARIANT (type);
543 name = OBJC_TYPE_NAME (type);
544 /* Open parenth/bracket. */
545 obstack_1grow (&util_obstack, left);
547 /* Encode the struct/union tag name, or '?' if a tag was
548 not provided. Typedef aliases do not qualify. */
549 #ifdef OBJCPLUS
550 /* For compatibility with the NeXT runtime, ObjC++ encodes template
551 args as a composite struct tag name. */
552 if (name && TREE_CODE (name) == IDENTIFIER_NODE
553 /* Did this struct have a tag? */
554 && !TYPE_WAS_ANONYMOUS (type))
555 obstack_grow (&util_obstack,
556 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
557 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
558 #else
559 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
560 obstack_grow (&util_obstack,
561 IDENTIFIER_POINTER (name),
562 strlen (IDENTIFIER_POINTER (name)));
563 #endif
564 else
565 obstack_1grow (&util_obstack, '?');
567 /* Encode the types (and possibly names) of the inner fields,
568 if required. */
569 if (inline_contents)
571 obstack_1grow (&util_obstack, '=');
572 encode_aggregate_fields (type, pointed_to, curtype, format);
574 /* Close parenth/bracket. */
575 obstack_1grow (&util_obstack, right);
578 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
579 field type. */
580 static void
581 encode_next_bitfield (int width)
583 char buffer[40];
584 sprintf (buffer, "b%d", width);
585 obstack_grow (&util_obstack, buffer, strlen (buffer));
588 /* Encodes 'type', ignoring type qualifiers (which you should encode
589 beforehand if needed) with the exception of 'const', which is
590 encoded by encode_type. See above for the explanation of
591 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
592 OBJC_ENCODE_DONT_INLINE_DEFS. */
593 static void
594 encode_type (tree type, int curtype, int format)
596 enum tree_code code = TREE_CODE (type);
598 /* Ignore type qualifiers other than 'const' when encoding a
599 type. */
601 if (type == error_mark_node)
602 return;
604 if (!flag_next_runtime)
606 if (TYPE_READONLY (type))
607 obstack_1grow (&util_obstack, 'r');
610 switch (code)
612 case ENUMERAL_TYPE:
613 if (flag_next_runtime)
615 /* Kludge for backwards-compatibility with gcc-3.3: enums
616 are always encoded as 'i' no matter what type they
617 actually are (!). */
618 obstack_1grow (&util_obstack, 'i');
619 break;
621 /* Else, they are encoded exactly like the integer type that is
622 used by the compiler to store them. */
623 case INTEGER_TYPE:
625 char c;
626 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
628 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
629 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
630 case 32:
632 tree int_type = type;
633 if (flag_next_runtime)
635 /* Another legacy kludge for compatiblity with
636 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
637 but not always. For typedefs, we need to use 'i'
638 or 'I' instead if encoding a struct field, or a
639 pointer! */
640 int_type = ((!generating_instance_variables
641 && (obstack_object_size (&util_obstack)
642 == (unsigned) curtype))
643 ? TYPE_MAIN_VARIANT (type)
644 : type);
646 if (int_type == long_unsigned_type_node
647 || int_type == long_integer_type_node)
648 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
649 else
650 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
652 break;
653 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
654 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
655 default: gcc_unreachable ();
657 obstack_1grow (&util_obstack, c);
658 break;
660 case REAL_TYPE:
662 char c;
663 /* Floating point types. */
664 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
666 case 32: c = 'f'; break;
667 case 64: c = 'd'; break;
668 case 96:
669 case 128: c = 'D'; break;
670 default: gcc_unreachable ();
672 obstack_1grow (&util_obstack, c);
673 break;
675 case VOID_TYPE:
676 obstack_1grow (&util_obstack, 'v');
677 break;
679 case BOOLEAN_TYPE:
680 obstack_1grow (&util_obstack, 'B');
681 break;
683 case ARRAY_TYPE:
684 encode_array (type, curtype, format);
685 break;
687 case POINTER_TYPE:
688 #ifdef OBJCPLUS
689 case REFERENCE_TYPE:
690 #endif
691 encode_pointer (type, curtype, format);
692 break;
694 case RECORD_TYPE:
695 encode_aggregate_within (type, curtype, format, '{', '}');
696 break;
698 case UNION_TYPE:
699 encode_aggregate_within (type, curtype, format, '(', ')');
700 break;
702 case FUNCTION_TYPE: /* '?' means an unknown type. */
703 obstack_1grow (&util_obstack, '?');
704 break;
706 case COMPLEX_TYPE:
707 /* A complex is encoded as 'j' followed by the inner type (eg,
708 "_Complex int" is encoded as 'ji'). */
709 obstack_1grow (&util_obstack, 'j');
710 encode_type (TREE_TYPE (type), curtype, format);
711 break;
713 case VECTOR_TYPE:
714 encode_vector (type, curtype, format);
715 break;
717 default:
718 warning (0, "unknown type %<%T%> found during Objective-C encoding",
719 TREE_TYPE (type));
720 obstack_1grow (&util_obstack, '?');
721 break;
724 if (flag_next_runtime)
726 /* Super-kludge. Some ObjC qualifier and type combinations need
727 to be rearranged for compatibility with gcc-3.3. */
728 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
730 char *enc = obstack_base (&util_obstack) + curtype;
732 /* Rewrite "in const" from "nr" to "rn". */
733 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
734 strncpy (enc - 1, "rn", 2);
739 static void
740 encode_gnu_bitfield (int position, tree type, int size)
742 enum tree_code code = TREE_CODE (type);
743 char buffer[40];
744 char charType = '?';
746 /* This code is only executed for the GNU runtime, so we can ignore
747 the NeXT runtime kludge of always encoding enums as 'i' no matter
748 what integers they actually are. */
749 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
751 if (integer_zerop (TYPE_MIN_VALUE (type)))
752 /* Unsigned integer types. */
754 switch (TYPE_MODE (type))
756 case QImode:
757 charType = 'C'; break;
758 case HImode:
759 charType = 'S'; break;
760 case SImode:
762 if (type == long_unsigned_type_node)
763 charType = 'L';
764 else
765 charType = 'I';
766 break;
768 case DImode:
769 charType = 'Q'; break;
770 default:
771 gcc_unreachable ();
774 else
775 /* Signed integer types. */
777 switch (TYPE_MODE (type))
779 case QImode:
780 charType = 'c'; break;
781 case HImode:
782 charType = 's'; break;
783 case SImode:
785 if (type == long_integer_type_node)
786 charType = 'l';
787 else
788 charType = 'i';
789 break;
791 case DImode:
792 charType = 'q'; break;
793 default:
794 gcc_unreachable ();
798 else
800 /* Do not do any encoding, produce an error and keep going. */
801 error ("trying to encode non-integer type as a bitfield");
802 return;
805 sprintf (buffer, "b%d%c%d", position, charType, size);
806 obstack_grow (&util_obstack, buffer, strlen (buffer));
809 static void
810 encode_field (tree field_decl, int curtype, int format)
812 #ifdef OBJCPLUS
813 /* C++ static members, and things that are not fields at all,
814 should not appear in the encoding. */
815 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
816 return;
817 #endif
819 /* Generate the bitfield typing information, if needed. Note the difference
820 between GNU and NeXT runtimes. */
821 if (DECL_BIT_FIELD_TYPE (field_decl))
823 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
825 if (flag_next_runtime)
826 encode_next_bitfield (size);
827 else
828 encode_gnu_bitfield (int_bit_position (field_decl),
829 DECL_BIT_FIELD_TYPE (field_decl), size);
831 else
832 encode_type (TREE_TYPE (field_decl), curtype, format);
835 tree
836 encode_field_decl (tree field_decl)
838 tree result;
840 encode_field (field_decl,
841 obstack_object_size (&util_obstack),
842 OBJC_ENCODE_DONT_INLINE_DEFS);
844 /* Null terminate string. */
845 obstack_1grow (&util_obstack, 0);
847 /* Get identifier for the string. */
848 result = get_identifier (XOBFINISH (&util_obstack, char *));
849 obstack_free (&util_obstack, util_firstobj);
851 return result;
854 /* This routine encodes the attribute of the input PROPERTY according
855 to following formula:
857 Property attributes are stored as a comma-delimited C string.
858 Simple attributes such as readonly are encoded as single
859 character. The parametrized attributes, getter=name and
860 setter=name, are encoded as a single character followed by an
861 identifier. Property types are also encoded as a parametrized
862 attribute. The characters used to encode these attributes are
863 defined by the following enumeration:
865 enum PropertyAttributes {
866 kPropertyReadOnly = 'R',
867 kPropertyBycopy = 'C',
868 kPropertyByref = '&',
869 kPropertyDynamic = 'D',
870 kPropertyGetter = 'G',
871 kPropertySetter = 'S',
872 kPropertyInstanceVariable = 'V',
873 kPropertyType = 'T',
874 kPropertyWeak = 'W',
875 kPropertyStrong = 'P',
876 kPropertyNonAtomic = 'N'
877 }; */
878 tree
879 objc_v2_encode_prop_attr (tree property)
881 const char *string;
882 tree type = TREE_TYPE (property);
884 obstack_1grow (&util_obstack, 'T');
885 encode_type (type, obstack_object_size (&util_obstack),
886 OBJC_ENCODE_INLINE_DEFS);
888 if (PROPERTY_READONLY (property))
889 obstack_grow (&util_obstack, ",R", 2);
891 switch (PROPERTY_ASSIGN_SEMANTICS (property))
893 case OBJC_PROPERTY_COPY:
894 obstack_grow (&util_obstack, ",C", 2);
895 break;
896 case OBJC_PROPERTY_RETAIN:
897 obstack_grow (&util_obstack, ",&", 2);
898 break;
899 case OBJC_PROPERTY_ASSIGN:
900 default:
901 break;
904 if (PROPERTY_DYNAMIC (property))
905 obstack_grow (&util_obstack, ",D", 2);
907 if (PROPERTY_NONATOMIC (property))
908 obstack_grow (&util_obstack, ",N", 2);
910 /* Here we want to encode the getter name, but only if it's not the
911 standard one. */
912 if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property))
914 obstack_grow (&util_obstack, ",G", 2);
915 string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property));
916 obstack_grow (&util_obstack, string, strlen (string));
919 if (!PROPERTY_READONLY (property))
921 /* Here we want to encode the setter name, but only if it's not
922 the standard one. */
923 tree standard_setter = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property)));
924 if (PROPERTY_SETTER_NAME (property) != standard_setter)
926 obstack_grow (&util_obstack, ",S", 2);
927 string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
928 obstack_grow (&util_obstack, string, strlen (string));
932 /* TODO: Encode strong ('P'), weak ('W') for garbage collection. */
934 if (!PROPERTY_DYNAMIC (property))
936 obstack_grow (&util_obstack, ",V", 2);
937 if (PROPERTY_IVAR_NAME (property))
938 string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
939 else
940 string = IDENTIFIER_POINTER (PROPERTY_NAME (property));
941 obstack_grow (&util_obstack, string, strlen (string));
944 /* NULL-terminate string. */
945 obstack_1grow (&util_obstack, 0);
946 string = XOBFINISH (&util_obstack, char *);
947 obstack_free (&util_obstack, util_firstobj);
948 return get_identifier (string);