Fix unused warnings.
[official-gcc/graphite-test-results.git] / gcc / testsuite / objc / execute / next_mapping.h
blob41d40fdf0dcce35b12b886cbfcf8de0552f0ae55
1 /* This file "renames" various ObjC GNU runtime entry points
2 (and fakes the existence of several others)
3 if the NeXT runtime is being used. */
4 /* Authors: Ziemowit Laski <zlaski@apple.com> */
5 /* David Ayers <d.ayers@inode.at> */
7 #ifdef __NEXT_RUNTIME__
8 #include <objc/objc-class.h>
9 #include <objc/Object.h>
10 #include <ctype.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #define objc_get_class(C) objc_getClass(C)
15 #define objc_get_meta_class(C) objc_getMetaClass(C)
16 #define class_get_class_method(C, S) class_getClassMethod(C, S)
17 #define class_get_instance_method(C, S) class_getInstanceMethod(C, S)
18 #define method_get_imp(M) (((Method)M)->method_imp)
19 #define sel_get_name(S) sel_getName(S)
20 #define class_create_instance(C) class_createInstance(C, 0)
21 #define class_get_class_name(C) object_getClassName(C)
22 #define class_get_super_class(C) (((struct objc_class *)C)->super_class)
23 #define object_get_super_class(O) class_get_super_class(*(struct objc_class **)O)
24 #define objc_lookup_class(N) objc_lookUpClass(N)
25 #define object_get_class(O) (*(struct objc_class **)O)
26 #define class_is_class(C) (CLS_GETINFO((struct objc_class *)C, CLS_CLASS)? YES: NO)
27 #define class_is_meta_class(C) (CLS_GETINFO((struct objc_class *)C, CLS_META)? YES: NO)
28 #define object_is_class(O) class_is_meta_class(*(struct objc_class **)O)
29 #define object_is_meta_class(O) (class_is_meta_class(O) && class_is_meta_class(*(struct objc_class **)O))
31 /* You need either an empty +initialize method or an empty -forward:: method.
32 The NeXT runtime unconditionally sends +initialize to classes when they are
33 first used, and unconditionally tries to forward methods that the class
34 doesn't understand (including +initialize). If you have neither +initialize
35 nor -forward::, the runtime complains.
37 The simplest workaround is to add
39 + initialize { return self; }
41 to every root class @implementation. */
43 #ifndef NULL
44 #define NULL 0
45 #endif
47 /* The following is necessary to "cover" the bf*.m test cases on NeXT. */
49 #undef MAX
50 #undef MIN
51 #undef ROUND
53 #ifdef __cplusplus
54 #define MAX(X, Y) ((X > Y) ? X : Y)
55 #define MIN(X, Y) ((X < Y) ? X : Y)
56 #define ROUND(V, A) (A * ((V + A - 1) / A))
57 #else
58 #define MAX(X, Y) \
59 ({ typeof (X) __x = (X), __y = (Y); \
60 (__x > __y ? __x : __y); })
61 #define MIN(X, Y) \
62 ({ typeof (X) __x = (X), __y = (Y); \
63 (__x < __y ? __x : __y); })
64 #define ROUND(V, A) \
65 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
66 __a * ((__v+__a - 1)/__a); })
67 #endif
69 #define BITS_PER_UNIT __CHAR_BIT__
70 typedef struct{ char a; } __small_struct;
71 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (__small_struct))
73 /* Not sure why the following are missing from NeXT objc headers... */
75 #ifndef _C_LNG_LNG
76 #define _C_LNG_LNG 'q'
77 #endif
78 #ifndef _C_ULNG_LNG
79 #define _C_ULNG_LNG 'Q'
80 #endif
81 #ifndef _C_ATOM
82 #define _C_ATOM '%'
83 #endif
84 #ifndef _C_BOOL
85 #define _C_BOOL 'B'
86 #endif
88 #define _C_CONST 'r'
89 #define _C_IN 'n'
90 #define _C_INOUT 'N'
91 #define _C_OUT 'o'
92 #define _C_BYCOPY 'O'
93 #define _C_BYREF 'R'
94 #define _C_ONEWAY 'V'
95 #define _C_GCINVISIBLE '!'
97 #define _F_CONST 0x01
98 #define _F_IN 0x01
99 #define _F_OUT 0x02
100 #define _F_INOUT 0x03
101 #define _F_BYCOPY 0x04
102 #define _F_BYREF 0x08
103 #define _F_ONEWAY 0x10
104 #define _F_GCINVISIBLE 0x20
106 struct objc_struct_layout
108 const char *original_type;
109 const char *type;
110 const char *prev_type;
111 unsigned int record_size;
112 unsigned int record_align;
115 typedef union arglist {
116 char *arg_ptr;
117 char arg_regs[sizeof (char*)];
118 } *arglist_t; /* argument frame */
120 const char *objc_skip_typespec (const char *type);
121 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
122 unsigned int *offset, unsigned int *align, const char **type);
123 void objc_layout_structure (const char *type,
124 struct objc_struct_layout *layout);
125 BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
126 void objc_layout_finish_structure (struct objc_struct_layout *layout,
127 unsigned int *size, unsigned int *align);
128 int objc_aligned_size (const char *type);
131 return the size of an object specified by type
135 objc_sizeof_type (const char *type)
137 /* Skip the variable name if any */
138 if (*type == '"')
140 for (type++; *type++ != '"';)
141 /* do nothing */;
144 switch (*type) {
145 case _C_ID:
146 return sizeof (id);
147 break;
149 case _C_CLASS:
150 return sizeof (Class);
151 break;
153 case _C_SEL:
154 return sizeof (SEL);
155 break;
157 case _C_CHR:
158 return sizeof (char);
159 break;
161 case _C_UCHR:
162 return sizeof (unsigned char);
163 break;
165 case _C_SHT:
166 return sizeof (short);
167 break;
169 case _C_USHT:
170 return sizeof (unsigned short);
171 break;
173 case _C_INT:
174 return sizeof (int);
175 break;
177 case _C_UINT:
178 return sizeof (unsigned int);
179 break;
181 case _C_LNG:
182 return sizeof (long);
183 break;
185 case _C_ULNG:
186 return sizeof (unsigned long);
187 break;
189 case _C_LNG_LNG:
190 return sizeof (long long);
191 break;
193 case _C_ULNG_LNG:
194 return sizeof (unsigned long long);
195 break;
197 case _C_FLT:
198 return sizeof (float);
199 break;
201 case _C_DBL:
202 return sizeof (double);
203 break;
205 case _C_PTR:
206 case _C_ATOM:
207 case _C_CHARPTR:
208 return sizeof (char *);
209 break;
211 case _C_ARY_B:
213 int len = atoi (type + 1);
214 while (isdigit ((unsigned char)*++type))
216 return len * objc_aligned_size (type);
218 break;
220 case _C_BFLD:
222 /* The NeXT encoding of bitfields is _still_: b 'size' */
223 int size = atoi (type + 1);
224 /* Return an upper bound on byte size */
225 return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
228 case _C_STRUCT_B:
230 struct objc_struct_layout layout;
231 unsigned int size;
233 objc_layout_structure (type, &layout);
234 while (objc_layout_structure_next_member (&layout))
235 /* do nothing */ ;
236 objc_layout_finish_structure (&layout, &size, NULL);
238 return size;
241 case _C_UNION_B:
243 int max_size = 0;
244 while (*type != _C_UNION_E && *type++ != '=')
245 /* do nothing */;
246 while (*type != _C_UNION_E)
248 /* Skip the variable name if any */
249 if (*type == '"')
251 for (type++; *type++ != '"';)
252 /* do nothing */;
254 max_size = MAX (max_size, objc_sizeof_type (type));
255 type = objc_skip_typespec (type);
257 return max_size;
260 return 0; /* error */
265 Return the alignment of an object specified by type
269 objc_alignof_type (const char *type)
271 /* Skip the variable name if any */
272 if (*type == '"')
274 for (type++; *type++ != '"';)
275 /* do nothing */;
277 switch (*type) {
278 case _C_ID:
279 return __alignof__ (id);
280 break;
282 case _C_CLASS:
283 return __alignof__ (Class);
284 break;
286 case _C_SEL:
287 return __alignof__ (SEL);
288 break;
290 case _C_CHR:
291 return __alignof__ (char);
292 break;
294 case _C_UCHR:
295 return __alignof__ (unsigned char);
296 break;
298 case _C_SHT:
299 return __alignof__ (short);
300 break;
302 case _C_USHT:
303 return __alignof__ (unsigned short);
304 break;
306 case _C_INT:
307 case _C_BFLD: /* This is for the NeXT only */
308 return __alignof__ (int);
309 break;
311 case _C_UINT:
312 return __alignof__ (unsigned int);
313 break;
315 case _C_LNG:
316 return __alignof__ (long);
317 break;
319 case _C_ULNG:
320 return __alignof__ (unsigned long);
321 break;
323 case _C_LNG_LNG:
324 return __alignof__ (long long);
325 break;
327 case _C_ULNG_LNG:
328 return __alignof__ (unsigned long long);
329 break;
331 case _C_FLT:
332 return __alignof__ (float);
333 break;
335 case _C_DBL:
336 return __alignof__ (double);
337 break;
339 case _C_PTR:
340 case _C_ATOM:
341 case _C_CHARPTR:
342 return __alignof__ (char *);
343 break;
345 case _C_ARY_B:
346 while (isdigit ((unsigned char)*++type))
347 /* do nothing */;
348 return objc_alignof_type (type);
350 case _C_STRUCT_B:
352 struct objc_struct_layout layout;
353 unsigned int align;
355 objc_layout_structure (type, &layout);
356 while (objc_layout_structure_next_member (&layout))
357 /* do nothing */;
358 objc_layout_finish_structure (&layout, NULL, &align);
360 return align;
363 case _C_UNION_B:
365 int maxalign = 0;
366 while (*type != _C_UNION_E && *type++ != '=')
367 /* do nothing */;
368 while (*type != _C_UNION_E)
370 /* Skip the variable name if any */
371 if (*type == '"')
373 for (type++; *type++ != '"';)
374 /* do nothing */;
376 maxalign = MAX (maxalign, objc_alignof_type (type));
377 type = objc_skip_typespec (type);
379 return maxalign;
382 return 0; /* error */
386 The aligned size if the size rounded up to the nearest alignment.
390 objc_aligned_size (const char *type)
392 int size, align;
394 /* Skip the variable name */
395 if (*type == '"')
397 for (type++; *type++ != '"';)
398 /* do nothing */;
401 size = objc_sizeof_type (type);
402 align = objc_alignof_type (type);
404 return ROUND (size, align);
408 The size rounded up to the nearest integral of the wordsize, taken
409 to be the size of a void *.
413 objc_promoted_size (const char *type)
415 int size, wordsize;
417 /* Skip the variable name */
418 if (*type == '"')
420 for (type++; *type++ != '"';)
421 /* do nothing */;
424 size = objc_sizeof_type (type);
425 wordsize = sizeof (void *);
427 return ROUND (size, wordsize);
431 Skip type qualifiers. These may eventually precede typespecs
432 occurring in method prototype encodings.
435 inline const char *
436 objc_skip_type_qualifiers (const char *type)
438 while (*type == _C_CONST
439 || *type == _C_IN
440 || *type == _C_INOUT
441 || *type == _C_OUT
442 || *type == _C_BYCOPY
443 || *type == _C_BYREF
444 || *type == _C_ONEWAY
445 || *type == _C_GCINVISIBLE)
447 type += 1;
449 return type;
454 Skip one typespec element. If the typespec is prepended by type
455 qualifiers, these are skipped as well.
458 const char *
459 objc_skip_typespec (const char *type)
461 /* Skip the variable name if any */
462 if (*type == '"')
464 for (type++; *type++ != '"';)
465 /* do nothing */;
468 type = objc_skip_type_qualifiers (type);
470 switch (*type) {
472 case _C_ID:
473 /* An id may be annotated by the actual type if it is known
474 with the @"ClassName" syntax */
476 if (*++type != '"')
477 return type;
478 else
480 while (*++type != '"')
481 /* do nothing */;
482 return type + 1;
485 /* The following are one character type codes */
486 case _C_CLASS:
487 case _C_SEL:
488 case _C_CHR:
489 case _C_UCHR:
490 case _C_CHARPTR:
491 case _C_ATOM:
492 case _C_SHT:
493 case _C_USHT:
494 case _C_INT:
495 case _C_UINT:
496 case _C_LNG:
497 case _C_ULNG:
498 case _C_LNG_LNG:
499 case _C_ULNG_LNG:
500 case _C_FLT:
501 case _C_DBL:
502 case _C_VOID:
503 case _C_UNDEF:
504 return ++type;
505 break;
507 case _C_ARY_B:
508 /* skip digits, typespec and closing ']' */
510 while (isdigit ((unsigned char)*++type))
512 type = objc_skip_typespec (type);
513 if (*type == _C_ARY_E)
514 return ++type;
515 else
516 break; /* error */
518 case _C_BFLD:
519 /* The NeXT encoding for bitfields is _still_: b 'size' */
520 while (isdigit ((unsigned char)*++type))
521 ; /* skip type and size */
522 return type;
524 case _C_STRUCT_B:
525 /* skip name, and elements until closing '}' */
527 while (*type != _C_STRUCT_E && *type++ != '=')
529 while (*type != _C_STRUCT_E)
531 type = objc_skip_typespec (type);
533 return ++type;
535 case _C_UNION_B:
536 /* skip name, and elements until closing ')' */
538 while (*type != _C_UNION_E && *type++ != '=')
540 while (*type != _C_UNION_E)
542 type = objc_skip_typespec (type);
544 return ++type;
546 case _C_PTR:
547 /* Just skip the following typespec */
549 return objc_skip_typespec (++type);
551 return 0; /* error */
555 Skip an offset as part of a method encoding. This is prepended by a
556 '+' if the argument is passed in registers.
558 inline const char *
559 objc_skip_offset (const char *type)
561 if (*type == '+')
562 type++;
563 while (isdigit ((unsigned char) *++type))
565 return type;
569 Skip an argument specification of a method encoding.
571 const char *
572 objc_skip_argspec (const char *type)
574 type = objc_skip_typespec (type);
575 type = objc_skip_offset (type);
576 return type;
580 Return the number of arguments that the method MTH expects.
581 Note that all methods need two implicit arguments `self' and
582 `_cmd'.
585 method_get_number_of_arguments (struct objc_method *mth)
587 int i = 0;
588 const char *type = mth->method_types;
589 while (*type)
591 type = objc_skip_argspec (type);
592 i += 1;
594 return i - 1;
598 Return the size of the argument block needed on the stack to invoke
599 the method MTH. This may be zero, if all arguments are passed in
600 registers.
604 method_get_sizeof_arguments (struct objc_method *mth)
606 const char *type = objc_skip_typespec (mth->method_types);
607 return atoi (type);
611 Return a pointer to the next argument of ARGFRAME. type points to
612 the last argument. Typical use of this look like:
615 char *datum, *type;
616 for (datum = method_get_first_argument (method, argframe, &type);
617 datum; datum = method_get_next_argument (argframe, &type))
619 unsigned flags = objc_get_type_qualifiers (type);
620 type = objc_skip_type_qualifiers (type);
621 if (*type != _C_PTR)
622 [portal encodeData: datum ofType: type];
623 else
625 if ((flags & _F_IN) == _F_IN)
626 [portal encodeData: *(char **) datum ofType: ++type];
632 char *
633 method_get_next_argument (arglist_t argframe, const char **type)
635 const char *t = objc_skip_argspec (*type);
637 if (*t == '\0')
638 return 0;
640 *type = t;
641 t = objc_skip_typespec (t);
643 if (*t == '+')
644 return argframe->arg_regs + atoi (++t);
645 else
646 return argframe->arg_ptr + atoi (t);
650 Return a pointer to the value of the first argument of the method
651 described in M with the given argumentframe ARGFRAME. The type
652 is returned in TYPE. type must be passed to successive calls of
653 method_get_next_argument.
655 char *
656 method_get_first_argument (struct objc_method *m,
657 arglist_t argframe,
658 const char **type)
660 *type = m->method_types;
661 return method_get_next_argument (argframe, type);
665 Return a pointer to the ARGth argument of the method
666 M from the frame ARGFRAME. The type of the argument
667 is returned in the value-result argument TYPE
670 char *
671 method_get_nth_argument (struct objc_method *m,
672 arglist_t argframe, int arg,
673 const char **type)
675 const char *t = objc_skip_argspec (m->method_types);
677 if (arg > method_get_number_of_arguments (m))
678 return 0;
680 while (arg--)
681 t = objc_skip_argspec (t);
683 *type = t;
684 t = objc_skip_typespec (t);
686 if (*t == '+')
687 return argframe->arg_regs + atoi (++t);
688 else
689 return argframe->arg_ptr + atoi (t);
692 unsigned
693 objc_get_type_qualifiers (const char *type)
695 unsigned res = 0;
696 BOOL flag = YES;
698 while (flag)
699 switch (*type++)
701 case _C_CONST: res |= _F_CONST; break;
702 case _C_IN: res |= _F_IN; break;
703 case _C_INOUT: res |= _F_INOUT; break;
704 case _C_OUT: res |= _F_OUT; break;
705 case _C_BYCOPY: res |= _F_BYCOPY; break;
706 case _C_BYREF: res |= _F_BYREF; break;
707 case _C_ONEWAY: res |= _F_ONEWAY; break;
708 case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
709 default: flag = NO;
712 return res;
716 /* The following three functions can be used to determine how a
717 structure is laid out by the compiler. For example:
719 struct objc_struct_layout layout;
720 int i;
722 objc_layout_structure (type, &layout);
723 while (objc_layout_structure_next_member (&layout))
725 int position, align;
726 const char *type;
728 objc_layout_structure_get_info (&layout, &position, &align, &type);
729 printf ("element %d has offset %d, alignment %d\n",
730 i++, position, align);
733 These functions are used by objc_sizeof_type and objc_alignof_type
734 functions to compute the size and alignment of structures. The
735 previous method of computing the size and alignment of a structure
736 was not working on some architectures, particulary on AIX, and in
737 the presence of bitfields inside the structure. */
738 void
739 objc_layout_structure (const char *type,
740 struct objc_struct_layout *layout)
742 const char *ntype;
744 layout->original_type = ++type;
746 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
747 ntype = type;
748 while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
749 && *ntype++ != '=')
750 /* do nothing */;
752 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
753 if (*(ntype - 1) == '=')
754 type = ntype;
756 layout->type = type;
757 layout->prev_type = NULL;
758 layout->record_size = 0;
759 layout->record_align = MAX (BITS_PER_UNIT, STRUCTURE_SIZE_BOUNDARY);
763 BOOL
764 objc_layout_structure_next_member (struct objc_struct_layout *layout)
766 register int desired_align = 0;
768 /* The current type without the type qualifiers */
769 const char *type;
771 /* Add the size of the previous field to the size of the record. */
772 if (layout->prev_type)
774 type = objc_skip_type_qualifiers (layout->prev_type);
776 if (*type != _C_BFLD)
777 layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
778 else
779 layout->record_size += atoi (++type);
782 if (*layout->type == _C_STRUCT_E)
783 return NO;
785 /* Skip the variable name if any */
786 if (*layout->type == '"')
788 for (layout->type++; *layout->type++ != '"';)
789 /* do nothing */;
792 type = objc_skip_type_qualifiers (layout->type);
794 desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
796 /* Record must have at least as much alignment as any field.
797 Otherwise, the alignment of the field within the record
798 is meaningless. */
799 layout->record_align = MAX (layout->record_align, desired_align);
801 if (*type == _C_BFLD)
803 int bfld_size = atoi (++type);
804 int int_align = __alignof__ (int) * BITS_PER_UNIT;
805 /* If this bitfield would traverse a word alignment boundary, push it out
806 to that boundary instead. */
807 if (layout->record_size % int_align
808 && (layout->record_size / int_align
809 < (layout->record_size + bfld_size - 1) / int_align))
810 layout->record_size = ROUND (layout->record_size, int_align);
812 else if (layout->record_size % desired_align != 0)
814 /* We need to skip space before this field.
815 Bump the cumulative size to multiple of field alignment. */
816 layout->record_size = ROUND (layout->record_size, desired_align);
819 /* Jump to the next field in record. */
821 layout->prev_type = layout->type;
822 layout->type = objc_skip_typespec (layout->type); /* skip component */
824 return YES;
828 void objc_layout_finish_structure (struct objc_struct_layout *layout,
829 unsigned int *size,
830 unsigned int *align)
832 if (layout->type && *layout->type == _C_STRUCT_E)
834 /* Round the size up to be a multiple of the required alignment */
835 layout->record_size = ROUND (layout->record_size, layout->record_align);
836 layout->type = NULL;
838 if (size)
839 *size = layout->record_size / BITS_PER_UNIT;
840 if (align)
841 *align = layout->record_align / BITS_PER_UNIT;
845 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
846 unsigned int *offset,
847 unsigned int *align,
848 const char **type)
850 if (offset)
851 *offset = layout->record_size / BITS_PER_UNIT;
852 if (align)
853 *align = layout->record_align / BITS_PER_UNIT;
854 if (type)
855 *type = layout->prev_type;
858 /* A small, portable NSConstantString implementation for use with the NeXT
859 runtime.
861 On full-fledged Mac OS X systems, NSConstantString is provided
862 as part of the Foundation framework. However, on bare Darwin systems,
863 Foundation is not included, and hence there is no NSConstantString
864 implementation to link against.
866 This code is derived from the GNU runtime's NXConstantString implementation.
869 struct objc_class _NSConstantStringClassReference;
871 @interface NSConstantString : Object
873 char *c_string;
874 unsigned int len;
877 -(const char *) cString;
878 -(unsigned int) length;
880 @end
882 @implementation NSConstantString
884 -(const char *) cString
886 return (c_string);
889 -(unsigned int) length
891 return (len);
894 @end
896 /* The NSConstantString metaclass will need to be initialized before we can
897 send messages to strings. */
899 void objc_constant_string_init (void) __attribute__((constructor));
900 void objc_constant_string_init (void) {
901 memcpy (&_NSConstantStringClassReference,
902 objc_getClass ("NSConstantString"),
903 sizeof (_NSConstantStringClassReference));
906 #endif /* #ifdef __NEXT_RUNTIME__ */