gcc/
[official-gcc.git] / gcc / objc / objc-encoding.c
blob17c0b21771010985e2f6a28e4b027da32f4d692c
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 "symtab.h"
25 #include "options.h"
26 #include "tree.h"
27 #include "stringpool.h"
28 #include "stor-layout.h"
30 #ifdef OBJCPLUS
31 #include "cp/cp-tree.h"
32 #else
33 #include "c/c-tree.h"
34 #include "c/c-lang.h"
35 #endif
37 #include "c-family/c-common.h"
38 #include "c-family/c-objc.h"
40 #include "objc-encoding.h"
41 #include "objc-act.h"
43 /* For my_build_string(). */
44 #include "objc-runtime-shared-support.h"
46 /* For BITS_PER_UNIT. */
47 #include "tm.h"
49 /* When building Objective-C++, we are not linking against the C front-end
50 and so need to replicate the C tree-construction functions in some way. */
51 #ifdef OBJCPLUS
52 #define OBJCP_REMAP_FUNCTIONS
53 #include "objcp-decl.h"
54 #endif /* OBJCPLUS */
56 /* Set up for use of obstacks. */
57 #include "obstack.h"
59 /* This obstack is used to accumulate the encoding of a data type. */
60 static struct obstack util_obstack;
62 /* This points to the beginning of obstack contents, so we can free
63 the whole contents. */
64 static char *util_firstobj;
66 void objc_encoding_init (void)
68 gcc_obstack_init (&util_obstack);
69 util_firstobj = (char *) obstack_finish (&util_obstack);
72 int generating_instance_variables = 0;
74 static void encode_type_qualifiers (tree);
75 static void encode_type (tree, int, int);
76 static void encode_field (tree field_decl, int curtype, int format);
78 static tree
79 objc_method_parm_type (tree type)
81 type = TREE_VALUE (TREE_TYPE (type));
82 if (TREE_CODE (type) == TYPE_DECL)
83 type = TREE_TYPE (type);
84 return type;
87 static int
88 objc_encoded_type_size (tree type)
90 int sz = int_size_in_bytes (type);
92 /* Make all integer and enum types at least as large
93 as an int. */
94 if (sz > 0 && INTEGRAL_TYPE_P (type))
95 sz = MAX (sz, int_size_in_bytes (integer_type_node));
96 /* Treat arrays as pointers, since that's how they're
97 passed in. */
98 else if (TREE_CODE (type) == ARRAY_TYPE)
99 sz = int_size_in_bytes (ptr_type_node);
100 return sz;
103 /* Encode a method prototype. */
104 tree
105 encode_method_prototype (tree method_decl)
107 tree parms;
108 int parm_offset, i;
109 char buf[40];
110 tree result;
112 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
113 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
115 /* Encode return type. */
116 encode_type (objc_method_parm_type (method_decl),
117 obstack_object_size (&util_obstack),
118 OBJC_ENCODE_INLINE_DEFS);
120 /* Stack size. */
121 /* The first two arguments (self and _cmd) are pointers; account for
122 their size. */
123 i = int_size_in_bytes (ptr_type_node);
124 parm_offset = 2 * i;
125 for (parms = METHOD_SEL_ARGS (method_decl); parms;
126 parms = DECL_CHAIN (parms))
128 tree type = objc_method_parm_type (parms);
129 int sz = objc_encoded_type_size (type);
131 /* If a type size is not known, bail out. */
132 if (sz < 0)
134 error_at (DECL_SOURCE_LOCATION (method_decl),
135 "type %qT does not have a known size",
136 type);
137 /* Pretend that the encoding succeeded; the compilation will
138 fail nevertheless. */
139 goto finish_encoding;
141 parm_offset += sz;
144 sprintf (buf, "%d@0:%d", parm_offset, i);
145 obstack_grow (&util_obstack, buf, strlen (buf));
147 /* Argument types. */
148 parm_offset = 2 * i;
149 for (parms = METHOD_SEL_ARGS (method_decl); parms;
150 parms = DECL_CHAIN (parms))
152 tree type = objc_method_parm_type (parms);
154 /* Process argument qualifiers for user supplied arguments. */
155 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
157 /* Type. */
158 encode_type (type, obstack_object_size (&util_obstack),
159 OBJC_ENCODE_INLINE_DEFS);
161 /* Compute offset. */
162 sprintf (buf, "%d", parm_offset);
163 parm_offset += objc_encoded_type_size (type);
165 obstack_grow (&util_obstack, buf, strlen (buf));
168 finish_encoding:
169 obstack_1grow (&util_obstack, '\0');
170 result = get_identifier (XOBFINISH (&util_obstack, char *));
171 obstack_free (&util_obstack, util_firstobj);
172 return result;
175 /* This is used to implement @encode(). */
176 tree
177 objc_build_encode_expr (tree type)
179 tree result;
180 const char *string;
182 encode_type (type, obstack_object_size (&util_obstack),
183 OBJC_ENCODE_INLINE_DEFS);
184 obstack_1grow (&util_obstack, 0); /* null terminate string */
185 string = XOBFINISH (&util_obstack, const char *);
187 /* Synthesize a string that represents the encoded struct/union. */
188 result = my_build_string (strlen (string) + 1, string);
189 obstack_free (&util_obstack, util_firstobj);
190 return result;
193 /* "Encode" a data type into a string, which grows in util_obstack.
195 The format is described in gcc/doc/objc.texi, section 'Type
196 encoding'.
198 Most of the encode_xxx functions have a 'type' argument, which is
199 the type to encode, and an integer 'curtype' argument, which is the
200 index in the encoding string of the beginning of the encoding of
201 the current type, and allows you to find what characters have
202 already been written for the current type (they are the ones in the
203 current encoding string starting from 'curtype').
205 For example, if we are encoding a method which returns 'int' and
206 takes a 'char **' argument, then when we get to the point of
207 encoding the 'char **' argument, the encoded string already
208 contains 'i12@0:4' (assuming a pointer size of 4 bytes). So,
209 'curtype' will be set to 7 when starting to encode 'char **'.
210 During the whole of the encoding of 'char **', 'curtype' will be
211 fixed at 7, so the routine encoding the second pointer can find out
212 that it's actually encoding a pointer to a pointer by looking
213 backwards at what has already been encoded for the current type,
214 and seeing there is a "^" (meaning a pointer) in there. */
217 /* Encode type qualifiers encodes one of the "PQ" Objective-C
218 keywords, ie 'in', 'out', 'inout', 'bycopy', 'byref', 'oneway'.
219 'const', instead, is encoded directly as part of the type. */
220 static void
221 encode_type_qualifiers (tree declspecs)
223 tree spec;
225 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
227 /* FIXME: Shouldn't we use token->keyword here ? */
228 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
229 obstack_1grow (&util_obstack, 'n');
230 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
231 obstack_1grow (&util_obstack, 'N');
232 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
233 obstack_1grow (&util_obstack, 'o');
234 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
235 obstack_1grow (&util_obstack, 'O');
236 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
237 obstack_1grow (&util_obstack, 'R');
238 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
239 obstack_1grow (&util_obstack, 'V');
240 else
241 gcc_unreachable ();
245 /* Determine if a pointee is marked read-only. Only used by the NeXT
246 runtime to be compatible with gcc-3.3. */
247 static bool
248 pointee_is_readonly (tree pointee)
250 while (POINTER_TYPE_P (pointee))
251 pointee = TREE_TYPE (pointee);
253 return TYPE_READONLY (pointee);
256 /* Encode a pointer type. */
257 static void
258 encode_pointer (tree type, int curtype, int format)
260 tree pointer_to = TREE_TYPE (type);
262 if (flag_next_runtime)
264 /* This code is used to be compatible with gcc-3.3. */
265 /* For historical/compatibility reasons, the read-only qualifier
266 of the pointee gets emitted _before_ the '^'. The read-only
267 qualifier of the pointer itself gets ignored, _unless_ we are
268 looking at a typedef! Also, do not emit the 'r' for anything
269 but the outermost type! */
270 if (!generating_instance_variables
271 && (obstack_object_size (&util_obstack) - curtype <= 1)
272 && (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
273 ? TYPE_READONLY (type)
274 : pointee_is_readonly (pointer_to)))
275 obstack_1grow (&util_obstack, 'r');
278 if (TREE_CODE (pointer_to) == RECORD_TYPE)
280 if (OBJC_TYPE_NAME (pointer_to)
281 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
283 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
285 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
287 obstack_1grow (&util_obstack, '@');
288 return;
290 else if (TYPE_HAS_OBJC_INFO (pointer_to)
291 && TYPE_OBJC_INTERFACE (pointer_to))
293 if (generating_instance_variables)
295 obstack_1grow (&util_obstack, '@');
296 obstack_1grow (&util_obstack, '"');
297 obstack_grow (&util_obstack, name, strlen (name));
298 obstack_1grow (&util_obstack, '"');
299 return;
301 else
303 obstack_1grow (&util_obstack, '@');
304 return;
307 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
309 obstack_1grow (&util_obstack, '#');
310 return;
312 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
314 obstack_1grow (&util_obstack, ':');
315 return;
319 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
320 && TYPE_MODE (pointer_to) == QImode)
322 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
323 ? OBJC_TYPE_NAME (pointer_to)
324 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
326 /* (BOOL *) are an exception and are encoded as ^c, while all
327 other pointers to char are encoded as *. */
328 if (strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
330 if (!flag_next_runtime)
332 /* The NeXT runtime adds the 'r' before getting here. */
334 /* It appears that "r*" means "const char *" rather than
335 "char *const". "char *const" is encoded as "*",
336 which is identical to "char *", so the "const" is
337 unfortunately lost. */
338 if (TYPE_READONLY (pointer_to))
339 obstack_1grow (&util_obstack, 'r');
342 obstack_1grow (&util_obstack, '*');
343 return;
347 /* We have a normal pointer type that does not get special treatment. */
348 obstack_1grow (&util_obstack, '^');
349 encode_type (pointer_to, curtype, format);
352 static void
353 encode_array (tree type, int curtype, int format)
355 tree an_int_cst = TYPE_SIZE (type);
356 tree array_of = TREE_TYPE (type);
357 char buffer[40];
359 if (an_int_cst == NULL)
361 /* We are trying to encode an incomplete array. An incomplete
362 array is forbidden as part of an instance variable; but it
363 may occur if the instance variable is a pointer to such an
364 array. */
366 /* So the only case in which an incomplete array could occur
367 (without being pointed to) is if we are encoding the
368 arguments or return value of a method. In that case, an
369 incomplete array argument or return value (eg,
370 -(void)display: (char[])string) is treated like a pointer
371 because that is how the compiler does the function call. A
372 special, more complicated case, is when the incomplete array
373 is the last member of a struct (eg, if we are encoding
374 "struct { unsigned long int a;double b[];}"), which is again
375 part of a method argument/return value. In that case, we
376 really need to communicate to the runtime that there is an
377 incomplete array (not a pointer!) there. So, we detect that
378 special case and encode it as a zero-length array.
380 Try to detect that we are part of a struct. We do this by
381 searching for '=' in the type encoding for the current type.
382 NB: This hack assumes that you can't use '=' as part of a C
383 identifier.
386 char *enc = (char *) obstack_base (&util_obstack) + curtype;
387 if (memchr (enc, '=',
388 obstack_object_size (&util_obstack) - curtype) == NULL)
390 /* We are not inside a struct. Encode the array as a
391 pointer. */
392 encode_pointer (type, curtype, format);
393 return;
397 /* Else, we are in a struct, and we encode it as a zero-length
398 array. */
399 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
401 else if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
402 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
403 else
404 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
405 TREE_INT_CST_LOW (an_int_cst)
406 / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
408 obstack_grow (&util_obstack, buffer, strlen (buffer));
409 encode_type (array_of, curtype, format);
410 obstack_1grow (&util_obstack, ']');
411 return;
414 /* Encode a vector. The vector type is a GCC extension to C. */
415 static void
416 encode_vector (tree type, int curtype, int format)
418 tree vector_of = TREE_TYPE (type);
419 char buffer[40];
421 /* Vectors are like simple fixed-size arrays. */
423 /* Output ![xx,yy,<code>] where xx is the vector_size, yy is the
424 alignment of the vector, and <code> is the base type. Eg, int
425 __attribute__ ((vector_size (16))) gets encoded as ![16,32,i]
426 assuming that the alignment is 32 bytes. We include size and
427 alignment in bytes so that the runtime does not have to have any
428 knowledge of the actual types.
430 sprintf (buffer, "![" HOST_WIDE_INT_PRINT_DEC ",%d",
431 /* We want to compute the equivalent of sizeof (<vector>).
432 Code inspired by c_sizeof_or_alignof_type. */
433 ((TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type))
434 / (TYPE_PRECISION (char_type_node) / BITS_PER_UNIT))),
435 /* We want to compute the equivalent of __alignof__
436 (<vector>). Code inspired by
437 c_sizeof_or_alignof_type. */
438 TYPE_ALIGN_UNIT (type));
439 obstack_grow (&util_obstack, buffer, strlen (buffer));
440 encode_type (vector_of, curtype, format);
441 obstack_1grow (&util_obstack, ']');
442 return;
445 static void
446 encode_aggregate_fields (tree type, bool pointed_to, int curtype, int format)
448 tree field = TYPE_FIELDS (type);
450 for (; field; field = DECL_CHAIN (field))
452 #ifdef OBJCPLUS
453 /* C++ static members, and things that are not field at all,
454 should not appear in the encoding. */
455 if (TREE_CODE (field) != FIELD_DECL || TREE_STATIC (field))
456 continue;
457 #endif
459 /* Recursively encode fields of embedded base classes. */
460 if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
461 && TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
463 encode_aggregate_fields (TREE_TYPE (field),
464 pointed_to, curtype, format);
465 continue;
468 if (generating_instance_variables && !pointed_to)
470 tree fname = DECL_NAME (field);
472 obstack_1grow (&util_obstack, '"');
474 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
475 obstack_grow (&util_obstack,
476 IDENTIFIER_POINTER (fname),
477 strlen (IDENTIFIER_POINTER (fname)));
479 obstack_1grow (&util_obstack, '"');
482 encode_field (field, curtype, format);
486 static void
487 encode_aggregate_within (tree type, int curtype, int format, int left,
488 int right)
490 tree name;
491 /* NB: aggregates that are pointed to have slightly different encoding
492 rules in that you never encode the names of instance variables. */
493 int ob_size = obstack_object_size (&util_obstack);
494 bool inline_contents = false;
495 bool pointed_to = false;
497 if (flag_next_runtime)
499 if (ob_size > 0 && *(obstack_next_free (&util_obstack) - 1) == '^')
500 pointed_to = true;
502 if ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
503 && (!pointed_to || ob_size - curtype == 1
504 || (ob_size - curtype == 2
505 && *(obstack_next_free (&util_obstack) - 2) == 'r')))
506 inline_contents = true;
508 else
510 /* c0 and c1 are the last two characters in the encoding of the
511 current type; if the last two characters were '^' or '^r',
512 then we are encoding an aggregate that is "pointed to". The
513 comment above applies: in that case we should avoid encoding
514 the names of instance variables.
516 char c1 = ob_size > 1 ? *(obstack_next_free (&util_obstack) - 2) : 0;
517 char c0 = ob_size > 0 ? *(obstack_next_free (&util_obstack) - 1) : 0;
519 if (c0 == '^' || (c1 == '^' && c0 == 'r'))
520 pointed_to = true;
522 if (format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
524 if (!pointed_to)
525 inline_contents = true;
526 else
528 /* Note that the check (ob_size - curtype < 2) prevents
529 infinite recursion when encoding a structure which is
530 a linked list (eg, struct node { struct node *next;
531 }). Each time we follow a pointer, we add one
532 character to ob_size, and curtype is fixed, so after
533 at most two pointers we stop inlining contents and
534 break the loop.
536 The other case where we don't inline is "^r", which
537 is a pointer to a constant struct.
539 if ((ob_size - curtype <= 2) && !(c0 == 'r'))
540 inline_contents = true;
545 /* Traverse struct aliases; it is important to get the
546 original struct and its tag name (if any). */
547 type = TYPE_MAIN_VARIANT (type);
548 name = OBJC_TYPE_NAME (type);
549 /* Open parenth/bracket. */
550 obstack_1grow (&util_obstack, left);
552 /* Encode the struct/union tag name, or '?' if a tag was
553 not provided. Typedef aliases do not qualify. */
554 #ifdef OBJCPLUS
555 /* For compatibility with the NeXT runtime, ObjC++ encodes template
556 args as a composite struct tag name. */
557 if (name && TREE_CODE (name) == IDENTIFIER_NODE
558 /* Did this struct have a tag? */
559 && !TYPE_WAS_ANONYMOUS (type))
560 obstack_grow (&util_obstack,
561 decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME),
562 strlen (decl_as_string (type, TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME)));
563 #else
564 if (name && TREE_CODE (name) == IDENTIFIER_NODE)
565 obstack_grow (&util_obstack,
566 IDENTIFIER_POINTER (name),
567 strlen (IDENTIFIER_POINTER (name)));
568 #endif
569 else
570 obstack_1grow (&util_obstack, '?');
572 /* Encode the types (and possibly names) of the inner fields,
573 if required. */
574 if (inline_contents)
576 obstack_1grow (&util_obstack, '=');
577 encode_aggregate_fields (type, pointed_to, curtype, format);
579 /* Close parenth/bracket. */
580 obstack_1grow (&util_obstack, right);
583 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
584 field type. */
585 static void
586 encode_next_bitfield (int width)
588 char buffer[40];
589 sprintf (buffer, "b%d", width);
590 obstack_grow (&util_obstack, buffer, strlen (buffer));
593 /* Encodes 'type', ignoring type qualifiers (which you should encode
594 beforehand if needed) with the exception of 'const', which is
595 encoded by encode_type. See above for the explanation of
596 'curtype'. 'format' can be OBJC_ENCODE_INLINE_DEFS or
597 OBJC_ENCODE_DONT_INLINE_DEFS. */
598 static void
599 encode_type (tree type, int curtype, int format)
601 enum tree_code code = TREE_CODE (type);
603 /* Ignore type qualifiers other than 'const' when encoding a
604 type. */
606 if (type == error_mark_node)
607 return;
609 if (!flag_next_runtime)
611 if (TYPE_READONLY (type))
612 obstack_1grow (&util_obstack, 'r');
615 switch (code)
617 case ENUMERAL_TYPE:
618 if (flag_next_runtime)
620 /* Kludge for backwards-compatibility with gcc-3.3: enums
621 are always encoded as 'i' no matter what type they
622 actually are (!). */
623 obstack_1grow (&util_obstack, 'i');
624 break;
626 /* Else, they are encoded exactly like the integer type that is
627 used by the compiler to store them. */
628 case INTEGER_TYPE:
630 char c;
631 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
633 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
634 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
635 case 32:
637 tree int_type = type;
638 if (flag_next_runtime)
640 /* Another legacy kludge for compatibility with
641 gcc-3.3: 32-bit longs are encoded as 'l' or 'L',
642 but not always. For typedefs, we need to use 'i'
643 or 'I' instead if encoding a struct field, or a
644 pointer! */
645 int_type = ((!generating_instance_variables
646 && (obstack_object_size (&util_obstack)
647 == (unsigned) curtype))
648 ? TYPE_MAIN_VARIANT (type)
649 : type);
651 if (int_type == long_unsigned_type_node
652 || int_type == long_integer_type_node)
653 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
654 else
655 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
657 break;
658 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
659 case 128: c = TYPE_UNSIGNED (type) ? 'T' : 't'; break;
660 default: gcc_unreachable ();
662 obstack_1grow (&util_obstack, c);
663 break;
665 case REAL_TYPE:
667 char c;
668 /* Floating point types. */
669 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
671 case 32: c = 'f'; break;
672 case 64: c = 'd'; break;
673 case 96:
674 case 128: c = 'D'; break;
675 default: gcc_unreachable ();
677 obstack_1grow (&util_obstack, c);
678 break;
680 case VOID_TYPE:
681 obstack_1grow (&util_obstack, 'v');
682 break;
684 case BOOLEAN_TYPE:
685 obstack_1grow (&util_obstack, 'B');
686 break;
688 case ARRAY_TYPE:
689 encode_array (type, curtype, format);
690 break;
692 case POINTER_TYPE:
693 #ifdef OBJCPLUS
694 case REFERENCE_TYPE:
695 #endif
696 encode_pointer (type, curtype, format);
697 break;
699 case RECORD_TYPE:
700 encode_aggregate_within (type, curtype, format, '{', '}');
701 break;
703 case UNION_TYPE:
704 encode_aggregate_within (type, curtype, format, '(', ')');
705 break;
707 case FUNCTION_TYPE: /* '?' means an unknown type. */
708 obstack_1grow (&util_obstack, '?');
709 break;
711 case COMPLEX_TYPE:
712 /* A complex is encoded as 'j' followed by the inner type (eg,
713 "_Complex int" is encoded as 'ji'). */
714 obstack_1grow (&util_obstack, 'j');
715 encode_type (TREE_TYPE (type), curtype, format);
716 break;
718 case VECTOR_TYPE:
719 encode_vector (type, curtype, format);
720 break;
722 default:
723 warning (0, "unknown type %<%T%> found during Objective-C encoding",
724 TREE_TYPE (type));
725 obstack_1grow (&util_obstack, '?');
726 break;
729 if (flag_next_runtime)
731 /* Super-kludge. Some ObjC qualifier and type combinations need
732 to be rearranged for compatibility with gcc-3.3. */
733 if (code == POINTER_TYPE && obstack_object_size (&util_obstack) >= 3)
735 char *enc = (char *) obstack_base (&util_obstack) + curtype;
737 /* Rewrite "in const" from "nr" to "rn". */
738 if (curtype >= 1 && !strncmp (enc - 1, "nr", 2))
739 strncpy (enc - 1, "rn", 2);
744 static void
745 encode_gnu_bitfield (int position, tree type, int size)
747 enum tree_code code = TREE_CODE (type);
748 char buffer[40];
749 char charType = '?';
751 /* This code is only executed for the GNU runtime, so we can ignore
752 the NeXT runtime kludge of always encoding enums as 'i' no matter
753 what integers they actually are. */
754 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
756 if (integer_zerop (TYPE_MIN_VALUE (type)))
757 /* Unsigned integer types. */
759 switch (TYPE_MODE (type))
761 case QImode:
762 charType = 'C'; break;
763 case HImode:
764 charType = 'S'; break;
765 case SImode:
767 if (type == long_unsigned_type_node)
768 charType = 'L';
769 else
770 charType = 'I';
771 break;
773 case DImode:
774 charType = 'Q'; break;
775 default:
776 gcc_unreachable ();
779 else
780 /* Signed integer types. */
782 switch (TYPE_MODE (type))
784 case QImode:
785 charType = 'c'; break;
786 case HImode:
787 charType = 's'; break;
788 case SImode:
790 if (type == long_integer_type_node)
791 charType = 'l';
792 else
793 charType = 'i';
794 break;
796 case DImode:
797 charType = 'q'; break;
798 default:
799 gcc_unreachable ();
803 else
805 /* Do not do any encoding, produce an error and keep going. */
806 error ("trying to encode non-integer type as a bitfield");
807 return;
810 sprintf (buffer, "b%d%c%d", position, charType, size);
811 obstack_grow (&util_obstack, buffer, strlen (buffer));
814 static void
815 encode_field (tree field_decl, int curtype, int format)
817 #ifdef OBJCPLUS
818 /* C++ static members, and things that are not fields at all,
819 should not appear in the encoding. */
820 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
821 return;
822 #endif
824 /* Generate the bitfield typing information, if needed. Note the difference
825 between GNU and NeXT runtimes. */
826 if (DECL_BIT_FIELD_TYPE (field_decl))
828 int size = tree_to_uhwi (DECL_SIZE (field_decl));
830 if (flag_next_runtime)
831 encode_next_bitfield (size);
832 else
833 encode_gnu_bitfield (int_bit_position (field_decl),
834 DECL_BIT_FIELD_TYPE (field_decl), size);
836 else
837 encode_type (TREE_TYPE (field_decl), curtype, format);
840 tree
841 encode_field_decl (tree field_decl)
843 tree result;
845 encode_field (field_decl,
846 obstack_object_size (&util_obstack),
847 OBJC_ENCODE_DONT_INLINE_DEFS);
849 /* Null terminate string. */
850 obstack_1grow (&util_obstack, 0);
852 /* Get identifier for the string. */
853 result = get_identifier (XOBFINISH (&util_obstack, char *));
854 obstack_free (&util_obstack, util_firstobj);
856 return result;
859 /* This routine encodes the attribute of the input PROPERTY according
860 to following formula:
862 Property attributes are stored as a comma-delimited C string.
863 Simple attributes such as readonly are encoded as single
864 character. The parametrized attributes, getter=name and
865 setter=name, are encoded as a single character followed by an
866 identifier. Property types are also encoded as a parametrized
867 attribute. The characters used to encode these attributes are
868 defined by the following enumeration:
870 enum PropertyAttributes {
871 kPropertyReadOnly = 'R',
872 kPropertyBycopy = 'C',
873 kPropertyByref = '&',
874 kPropertyDynamic = 'D',
875 kPropertyGetter = 'G',
876 kPropertySetter = 'S',
877 kPropertyInstanceVariable = 'V',
878 kPropertyType = 'T',
879 kPropertyWeak = 'W',
880 kPropertyStrong = 'P',
881 kPropertyNonAtomic = 'N'
882 }; */
883 tree
884 objc_v2_encode_prop_attr (tree property)
886 const char *string;
887 tree type = TREE_TYPE (property);
889 obstack_1grow (&util_obstack, 'T');
890 encode_type (type, obstack_object_size (&util_obstack),
891 OBJC_ENCODE_INLINE_DEFS);
893 if (PROPERTY_READONLY (property))
894 obstack_grow (&util_obstack, ",R", 2);
896 switch (PROPERTY_ASSIGN_SEMANTICS (property))
898 case OBJC_PROPERTY_COPY:
899 obstack_grow (&util_obstack, ",C", 2);
900 break;
901 case OBJC_PROPERTY_RETAIN:
902 obstack_grow (&util_obstack, ",&", 2);
903 break;
904 case OBJC_PROPERTY_ASSIGN:
905 default:
906 break;
909 if (PROPERTY_DYNAMIC (property))
910 obstack_grow (&util_obstack, ",D", 2);
912 if (PROPERTY_NONATOMIC (property))
913 obstack_grow (&util_obstack, ",N", 2);
915 /* Here we want to encode the getter name, but only if it's not the
916 standard one. */
917 if (PROPERTY_GETTER_NAME (property) != PROPERTY_NAME (property))
919 obstack_grow (&util_obstack, ",G", 2);
920 string = IDENTIFIER_POINTER (PROPERTY_GETTER_NAME (property));
921 obstack_grow (&util_obstack, string, strlen (string));
924 if (!PROPERTY_READONLY (property))
926 /* Here we want to encode the setter name, but only if it's not
927 the standard one. */
928 tree standard_setter = get_identifier (objc_build_property_setter_name (PROPERTY_NAME (property)));
929 if (PROPERTY_SETTER_NAME (property) != standard_setter)
931 obstack_grow (&util_obstack, ",S", 2);
932 string = IDENTIFIER_POINTER (PROPERTY_SETTER_NAME (property));
933 obstack_grow (&util_obstack, string, strlen (string));
937 /* TODO: Encode strong ('P'), weak ('W') for garbage collection. */
939 if (!PROPERTY_DYNAMIC (property))
941 obstack_grow (&util_obstack, ",V", 2);
942 if (PROPERTY_IVAR_NAME (property))
943 string = IDENTIFIER_POINTER (PROPERTY_IVAR_NAME (property));
944 else
945 string = IDENTIFIER_POINTER (PROPERTY_NAME (property));
946 obstack_grow (&util_obstack, string, strlen (string));
949 /* NULL-terminate string. */
950 obstack_1grow (&util_obstack, 0);
951 string = XOBFINISH (&util_obstack, char *);
952 obstack_free (&util_obstack, util_firstobj);
953 return get_identifier (string);