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