xref: /netbsd-src/external/gpl3/gcc.old/dist/libobjc/encoding.c (revision 53b02e147d4ed531c0d2a5ca9b3e8026ba3e99b5)
1 /* Encoding of types for Objective C.
2    Copyright (C) 1993-2019 Free Software Foundation, Inc.
3    Contributed by Kresten Krab Thorup
4    Bitfield support by Ovidiu Predescu
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12 
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21 
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25 <http://www.gnu.org/licenses/>.  */
26 
27 /* FIXME: This file has no business including tm.h.  */
28 
29 /* FIXME: This file contains functions that will abort the entire
30    program if they fail.  Is that really needed ?  */
31 
32 #include "config.h"
33 #include "objc-private/common.h"
34 #include "objc-private/error.h"
35 #include "tconfig.h"
36 #include "coretypes.h"
37 #include "tm.h"
38 #include "objc/runtime.h"
39 #include "objc-private/module-abi-8.h" /* For struct objc_method */
40 #include <stdlib.h>
41 #include <ctype.h>
42 #include <string.h>                    /* For memcpy.  */
43 
44 #undef  MAX
45 #define MAX(X, Y)                    \
46   ({ typeof (X) __x = (X), __y = (Y); \
47      (__x > __y ? __x : __y); })
48 
49 #undef  MIN
50 #define MIN(X, Y)                    \
51   ({ typeof (X) __x = (X), __y = (Y); \
52      (__x < __y ? __x : __y); })
53 
54 #undef  ROUND
55 #define ROUND(V, A) \
56   ({ typeof (V) __v = (V); typeof (A) __a = (A); \
57      __a * ((__v+__a - 1)/__a); })
58 
59 
60 /* Various hacks for objc_layout_record. These are used by the target
61    macros. */
62 
63 #define TREE_CODE(TYPE) *(TYPE)
64 #define TREE_TYPE(TREE) (TREE)
65 
66 #define RECORD_TYPE     _C_STRUCT_B
67 #define UNION_TYPE      _C_UNION_B
68 #define QUAL_UNION_TYPE _C_UNION_B
69 #define ARRAY_TYPE      _C_ARY_B
70 
71 #define REAL_TYPE       _C_DBL
72 
73 #define VECTOR_TYPE	_C_VECTOR
74 
75 #define TYPE_FIELDS(TYPE)           ({const char *_field = (TYPE)+1; \
76     while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
77            && *_field != _C_UNION_B && *_field++ != '=') \
78     /* do nothing */; \
79     _field;})
80 
81 #define DECL_MODE(TYPE) *(TYPE)
82 #define TYPE_MODE(TYPE) *(TYPE)
83 
84 #undef  DFmode
85 #define DFmode          _C_DBL
86 
87 #define strip_array_types(TYPE)      ({const char *_field = (TYPE); \
88   while (*_field == _C_ARY_B)\
89     {\
90       while (isdigit ((unsigned char)*++_field))\
91 	;\
92     }\
93     _field;})
94 
95 /* Some ports (eg ARM) allow the structure size boundary to be
96    selected at compile-time.  We override the normal definition with
97    one that has a constant value for this compilation.  */
98 #undef  STRUCTURE_SIZE_BOUNDARY
99 #define STRUCTURE_SIZE_BOUNDARY (__CHAR_BIT__ * sizeof (struct{char a;}))
100 
101 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
102    target_flags.  Define a dummy entry here to so we don't die.
103    We have to rename it because target_flags may already have been
104    declared extern.  */
105 #define target_flags not_target_flags
106 static int __attribute__ ((__unused__)) not_target_flags = 0;
107 
108 /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
109    Define a dummy ALTIVEC_VECTOR_MODE so it will not die.  */
110 #undef ALTIVEC_VECTOR_MODE
111 #define ALTIVEC_VECTOR_MODE(MODE) (0)
112 
113 /* Replace TARGET_VSX, TARGET_ALTIVEC, and TARGET_64BIT with constants based on
114    the current switches, rather than looking in the options structure.  */
115 #ifdef _ARCH_PPC
116 #undef TARGET_VSX
117 #undef TARGET_ALTIVEC
118 #undef TARGET_64BIT
119 
120 #ifdef __VSX__
121 #define TARGET_VSX 1
122 #else
123 #define TARGET_VSX 0
124 #endif
125 
126 #ifdef __ALTIVEC__
127 #define TARGET_ALTIVEC 1
128 #else
129 #define TARGET_ALTIVEC 0
130 #endif
131 
132 #ifdef _ARCH_PPC64
133 #define TARGET_64BIT 1
134 #else
135 #define TARGET_64BIT 0
136 #endif
137 #endif
138 
139 /* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
140  in their alignment macros. Currently[4.5/6], rs6000.h points this
141  to a static variable, initialized by target overrides. This is reset
142  in linux64.h but not in darwin64.h.  The macro is not used by *86*.  */
143 
144 #if __MACH__
145 # if __LP64__
146 #  undef TARGET_ALIGN_NATURAL
147 #  define TARGET_ALIGN_NATURAL 1
148 # endif
149 
150 /* On Darwin32, we need to recurse until we find the starting stuct type.  */
151 static int
152 _darwin_rs6000_special_round_type_align (const char *struc, int comp, int spec)
153 {
154   const char *_stp , *_fields = TYPE_FIELDS (struc);
155   if (!_fields)
156     return MAX (comp, spec);
157   _stp = strip_array_types (_fields);
158   if (TYPE_MODE(_stp) == _C_COMPLEX)
159    _stp++;
160   switch (TYPE_MODE(_stp))
161     {
162       case RECORD_TYPE:
163       case UNION_TYPE:
164 	return MAX (MAX (comp, spec), objc_alignof_type (_stp) * __CHAR_BIT__);
165 	break;
166       case E_DFmode:
167       case _C_LNG_LNG:
168       case _C_ULNG_LNG:
169 	return MAX (MAX (comp, spec), 64);
170 	break;
171 
172       default:
173 	return MAX (comp, spec);
174 	break;
175     }
176 }
177 
178 /* See comment below.  */
179 #define darwin_rs6000_special_round_type_align(S,C,S2)			\
180   (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2)))
181 #endif
182 
183 /*  FIXME: while this file has no business including tm.h, this
184     definitely has no business defining this macro but it
185     is only way around without really rewritting this file,
186     should look after the branch of 3.4 to fix this.   */
187 #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED)	\
188   ({ const char *_fields = TYPE_FIELDS (STRUCT);			\
189   ((_fields != 0							\
190     && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode)	\
191    ? MAX (MAX (COMPUTED, SPECIFIED), 64)				\
192    : MAX (COMPUTED, SPECIFIED));})
193 
194 #define rs6000_special_adjust_field_align_p(FIELD, COMPUTED) 0
195 
196 /* Skip a variable name, enclosed in quotes (").  */
197 static inline
198 const char *
199 objc_skip_variable_name (const char *type)
200 {
201   /* Skip the variable name if any.  */
202   if (*type == '"')
203     {
204       /* FIXME: How do we know we won't read beyond the end of the
205 	 string.  Here and in the rest of the file!  */
206       /* Skip '"'.  */
207       type++;
208       /* Skip to the next '"'.  */
209       while (*type != '"')
210 	type++;
211       /* Skip '"'.  */
212       type++;
213     }
214 
215   return type;
216 }
217 
218 int
219 objc_sizeof_type (const char *type)
220 {
221   type = objc_skip_variable_name (type);
222 
223   switch (*type) {
224   case _C_BOOL:
225     return sizeof (_Bool);
226     break;
227 
228   case _C_ID:
229     return sizeof (id);
230     break;
231 
232   case _C_CLASS:
233     return sizeof (Class);
234     break;
235 
236   case _C_SEL:
237     return sizeof (SEL);
238     break;
239 
240   case _C_CHR:
241     return sizeof (char);
242     break;
243 
244   case _C_UCHR:
245     return sizeof (unsigned char);
246     break;
247 
248   case _C_SHT:
249     return sizeof (short);
250     break;
251 
252   case _C_USHT:
253     return sizeof (unsigned short);
254     break;
255 
256   case _C_INT:
257     return sizeof (int);
258     break;
259 
260   case _C_UINT:
261     return sizeof (unsigned int);
262     break;
263 
264   case _C_LNG:
265     return sizeof (long);
266     break;
267 
268   case _C_ULNG:
269     return sizeof (unsigned long);
270     break;
271 
272   case _C_LNG_LNG:
273     return sizeof (long long);
274     break;
275 
276   case _C_ULNG_LNG:
277     return sizeof (unsigned long long);
278     break;
279 
280   case _C_FLT:
281     return sizeof (float);
282     break;
283 
284   case _C_DBL:
285     return sizeof (double);
286     break;
287 
288   case _C_LNG_DBL:
289     return sizeof (long double);
290     break;
291 
292   case _C_VOID:
293     return sizeof (void);
294     break;
295 
296   case _C_PTR:
297   case _C_ATOM:
298   case _C_CHARPTR:
299     return sizeof (char *);
300     break;
301 
302   case _C_ARY_B:
303     {
304       int len = atoi (type + 1);
305       while (isdigit ((unsigned char)*++type))
306 	;
307       return len * objc_aligned_size (type);
308     }
309     break;
310 
311   case _C_VECTOR:
312     {
313       /* Skip the '!'.  */
314       type++;
315       /* Skip the '['.  */
316       type++;
317 
318       /* The size in bytes is the following number.  */
319       int size = atoi (type);
320       return size;
321     }
322     break;
323 
324   case _C_BFLD:
325     {
326       /* The GNU encoding of bitfields is: b 'position' 'type'
327 	 'size'.  */
328       int position, size;
329       int startByte, endByte;
330 
331       position = atoi (type + 1);
332       while (isdigit ((unsigned char)*++type))
333 	;
334       size = atoi (type + 1);
335 
336       startByte = position / __CHAR_BIT__;
337       endByte = (position + size) / __CHAR_BIT__;
338       return endByte - startByte;
339     }
340 
341   case _C_UNION_B:
342   case _C_STRUCT_B:
343     {
344       struct objc_struct_layout layout;
345       unsigned int size;
346 
347       objc_layout_structure (type, &layout);
348       while (objc_layout_structure_next_member (&layout))
349         /* do nothing */ ;
350       objc_layout_finish_structure (&layout, &size, NULL);
351 
352       return size;
353     }
354 
355   case _C_COMPLEX:
356     {
357       type++; /* Skip after the 'j'. */
358       switch (*type)
359         {
360 	    case _C_CHR:
361 	      return sizeof (_Complex char);
362 	      break;
363 
364 	    case _C_UCHR:
365 	      return sizeof (_Complex unsigned char);
366 	      break;
367 
368 	    case _C_SHT:
369 	      return sizeof (_Complex short);
370 	      break;
371 
372 	    case _C_USHT:
373 	      return sizeof (_Complex unsigned short);
374 	      break;
375 
376 	    case _C_INT:
377 	      return sizeof (_Complex int);
378 	      break;
379 
380 	    case _C_UINT:
381 	      return sizeof (_Complex unsigned int);
382 	      break;
383 
384 	    case _C_LNG:
385 	      return sizeof (_Complex long);
386 	      break;
387 
388 	    case _C_ULNG:
389 	      return sizeof (_Complex unsigned long);
390 	      break;
391 
392 	    case _C_LNG_LNG:
393 	      return sizeof (_Complex long long);
394 	      break;
395 
396 	    case _C_ULNG_LNG:
397 	      return sizeof (_Complex unsigned long long);
398 	      break;
399 
400 	    case _C_FLT:
401 	      return sizeof (_Complex float);
402 	      break;
403 
404 	    case _C_DBL:
405 	      return sizeof (_Complex double);
406 	      break;
407 
408 	    case _C_LNG_DBL:
409 	      return sizeof (_Complex long double);
410 	      break;
411 
412 	    default:
413 	      {
414 		/* FIXME: Is this so bad that we have to abort the
415 		   entire program ?  (it applies to all the other
416 		   _objc_abort calls in this file).
417 		*/
418 		_objc_abort ("unknown complex type %s\n", type);
419 		return 0;
420 	      }
421 	}
422     }
423 
424   default:
425     {
426       _objc_abort ("unknown type %s\n", type);
427       return 0;
428     }
429   }
430 }
431 
432 int
433 objc_alignof_type (const char *type)
434 {
435   type = objc_skip_variable_name (type);
436 
437   switch (*type) {
438   case _C_BOOL:
439     return __alignof__ (_Bool);
440     break;
441 
442   case _C_ID:
443     return __alignof__ (id);
444     break;
445 
446   case _C_CLASS:
447     return __alignof__ (Class);
448     break;
449 
450   case _C_SEL:
451     return __alignof__ (SEL);
452     break;
453 
454   case _C_CHR:
455     return __alignof__ (char);
456     break;
457 
458   case _C_UCHR:
459     return __alignof__ (unsigned char);
460     break;
461 
462   case _C_SHT:
463     return __alignof__ (short);
464     break;
465 
466   case _C_USHT:
467     return __alignof__ (unsigned short);
468     break;
469 
470   case _C_INT:
471     return __alignof__ (int);
472     break;
473 
474   case _C_UINT:
475     return __alignof__ (unsigned int);
476     break;
477 
478   case _C_LNG:
479     return __alignof__ (long);
480     break;
481 
482   case _C_ULNG:
483     return __alignof__ (unsigned long);
484     break;
485 
486   case _C_LNG_LNG:
487     return __alignof__ (long long);
488     break;
489 
490   case _C_ULNG_LNG:
491     return __alignof__ (unsigned long long);
492     break;
493 
494   case _C_FLT:
495     return __alignof__ (float);
496     break;
497 
498   case _C_DBL:
499     return __alignof__ (double);
500     break;
501 
502   case _C_LNG_DBL:
503     return __alignof__ (long double);
504     break;
505 
506   case _C_PTR:
507   case _C_ATOM:
508   case _C_CHARPTR:
509     return __alignof__ (char *);
510     break;
511 
512   case _C_ARY_B:
513     while (isdigit ((unsigned char)*++type))
514       /* do nothing */;
515     return objc_alignof_type (type);
516 
517   case _C_VECTOR:
518     {
519       /* Skip the '!'.  */
520       type++;
521       /* Skip the '['.  */
522       type++;
523 
524       /* Skip the size.  */
525       while (isdigit ((unsigned char)*type))
526 	type++;
527 
528       /* Skip the ','.  */
529       type++;
530 
531       /* The alignment in bytes is the following number.  */
532       return atoi (type);
533     }
534   case _C_STRUCT_B:
535   case _C_UNION_B:
536     {
537       struct objc_struct_layout layout;
538       unsigned int align;
539 
540       objc_layout_structure (type, &layout);
541       while (objc_layout_structure_next_member (&layout))
542         /* do nothing */;
543       objc_layout_finish_structure (&layout, NULL, &align);
544 
545       return align;
546     }
547 
548 
549   case _C_COMPLEX:
550     {
551       type++; /* Skip after the 'j'. */
552       switch (*type)
553         {
554 	    case _C_CHR:
555 	      return __alignof__ (_Complex char);
556 	      break;
557 
558 	    case _C_UCHR:
559 	      return __alignof__ (_Complex unsigned char);
560 	      break;
561 
562 	    case _C_SHT:
563 	      return __alignof__ (_Complex short);
564 	      break;
565 
566 	    case _C_USHT:
567 	      return __alignof__ (_Complex unsigned short);
568 	      break;
569 
570 	    case _C_INT:
571 	      return __alignof__ (_Complex int);
572 	      break;
573 
574 	    case _C_UINT:
575 	      return __alignof__ (_Complex unsigned int);
576 	      break;
577 
578 	    case _C_LNG:
579 	      return __alignof__ (_Complex long);
580 	      break;
581 
582 	    case _C_ULNG:
583 	      return __alignof__ (_Complex unsigned long);
584 	      break;
585 
586 	    case _C_LNG_LNG:
587 	      return __alignof__ (_Complex long long);
588 	      break;
589 
590 	    case _C_ULNG_LNG:
591 	      return __alignof__ (_Complex unsigned long long);
592 	      break;
593 
594 	    case _C_FLT:
595 	      return __alignof__ (_Complex float);
596 	      break;
597 
598 	    case _C_DBL:
599 	      return __alignof__ (_Complex double);
600 	      break;
601 
602 	    case _C_LNG_DBL:
603 	      return __alignof__ (_Complex long double);
604 	      break;
605 
606 	    default:
607 	      {
608 		_objc_abort ("unknown complex type %s\n", type);
609 		return 0;
610 	      }
611 	}
612     }
613 
614   default:
615     {
616       _objc_abort ("unknown type %s\n", type);
617       return 0;
618     }
619   }
620 }
621 
622 int
623 objc_aligned_size (const char *type)
624 {
625   int size, align;
626 
627   type = objc_skip_variable_name (type);
628   size = objc_sizeof_type (type);
629   align = objc_alignof_type (type);
630 
631   return ROUND (size, align);
632 }
633 
634 int
635 objc_promoted_size (const char *type)
636 {
637   int size, wordsize;
638 
639   type = objc_skip_variable_name (type);
640   size = objc_sizeof_type (type);
641   wordsize = sizeof (void *);
642 
643   return ROUND (size, wordsize);
644 }
645 
646 /*
647   Skip type qualifiers.  These may eventually precede typespecs
648   occurring in method prototype encodings.
649 */
650 
651 const char *
652 objc_skip_type_qualifiers (const char *type)
653 {
654   while (*type == _C_CONST
655 	 || *type == _C_IN
656 	 || *type == _C_INOUT
657 	 || *type == _C_OUT
658 	 || *type == _C_BYCOPY
659          || *type == _C_BYREF
660 	 || *type == _C_ONEWAY
661 	 || *type == _C_GCINVISIBLE)
662     {
663       type += 1;
664     }
665   return type;
666 }
667 
668 const char *
669 objc_skip_typespec (const char *type)
670 {
671   type = objc_skip_variable_name (type);
672   type = objc_skip_type_qualifiers (type);
673 
674   switch (*type) {
675 
676   case _C_ID:
677     /* An id may be annotated by the actual type if it is known
678        with the @"ClassName" syntax */
679 
680     if (*++type != '"')
681       return type;
682     else
683       {
684 	while (*++type != '"')
685 	  /* do nothing */;
686 	return type + 1;
687       }
688 
689     /* The following are one character type codes */
690   case _C_CLASS:
691   case _C_SEL:
692   case _C_CHR:
693   case _C_UCHR:
694   case _C_CHARPTR:
695   case _C_ATOM:
696   case _C_SHT:
697   case _C_USHT:
698   case _C_INT:
699   case _C_UINT:
700   case _C_LNG:
701   case _C_BOOL:
702   case _C_ULNG:
703   case _C_LNG_LNG:
704   case _C_ULNG_LNG:
705   case _C_FLT:
706   case _C_DBL:
707   case _C_LNG_DBL:
708   case _C_VOID:
709   case _C_UNDEF:
710     return ++type;
711     break;
712 
713   case _C_COMPLEX:
714     return type + 2;
715     break;
716 
717   case _C_ARY_B:
718     /* skip digits, typespec and closing ']' */
719     while (isdigit ((unsigned char)*++type))
720       ;
721     type = objc_skip_typespec (type);
722     if (*type == _C_ARY_E)
723       return ++type;
724     else
725       {
726 	_objc_abort ("bad array type %s\n", type);
727 	return 0;
728       }
729 
730   case _C_VECTOR:
731     /* Skip '!' */
732     type++;
733     /* Skip '[' */
734     type++;
735     /* Skip digits (size) */
736     while (isdigit ((unsigned char)*type))
737       type++;
738     /* Skip ',' */
739     type++;
740     /* Skip digits (alignment) */
741     while (isdigit ((unsigned char)*type))
742       type++;
743     /* Skip typespec.  */
744     type = objc_skip_typespec (type);
745     /* Skip closing ']'.  */
746     if (*type == _C_ARY_E)
747       return ++type;
748     else
749       {
750 	_objc_abort ("bad vector type %s\n", type);
751 	return 0;
752       }
753 
754   case _C_BFLD:
755     /* The GNU encoding of bitfields is: b 'position' 'type'
756        'size'.  */
757     while (isdigit ((unsigned char)*++type))
758       ;	/* skip position */
759     while (isdigit ((unsigned char)*++type))
760       ;	/* skip type and size */
761     return type;
762 
763   case _C_STRUCT_B:
764     /* skip name, and elements until closing '}'  */
765 
766     while (*type != _C_STRUCT_E && *type++ != '=')
767       ;
768     while (*type != _C_STRUCT_E)
769       {
770 	type = objc_skip_typespec (type);
771       }
772     return ++type;
773 
774   case _C_UNION_B:
775     /* skip name, and elements until closing ')'  */
776 
777     while (*type != _C_UNION_E && *type++ != '=')
778       ;
779     while (*type != _C_UNION_E)
780       {
781 	type = objc_skip_typespec (type);
782       }
783     return ++type;
784 
785   case _C_PTR:
786     /* Just skip the following typespec */
787 
788     return objc_skip_typespec (++type);
789 
790   default:
791     {
792       _objc_abort ("unknown type %s\n", type);
793       return 0;
794     }
795   }
796 }
797 
798 /*
799   Skip an offset as part of a method encoding.  This is prepended by a
800   '+' if the argument is passed in registers.
801 */
802 const char *
803 objc_skip_offset (const char *type)
804 {
805   /* The offset is prepended by a '+' if the argument is passed in
806      registers.  PS: The compiler stopped generating this '+' in
807      version 3.4.  */
808   if (*type == '+')
809     type++;
810 
811   /* Some people claim that on some platforms, where the stack grows
812      backwards, the compiler generates negative offsets (??).  Skip a
813      '-' for such a negative offset.  */
814   if (*type == '-')
815     type++;
816 
817   /* Skip the digits that represent the offset.  */
818   while (isdigit ((unsigned char) *type))
819     type++;
820 
821   return type;
822 }
823 
824 const char *
825 objc_skip_argspec (const char *type)
826 {
827   type = objc_skip_typespec (type);
828   type = objc_skip_offset (type);
829   return type;
830 }
831 
832 char *
833 method_copyReturnType (struct objc_method *method)
834 {
835   if (method == NULL)
836     return 0;
837   else
838     {
839       char *returnValue;
840       size_t returnValueSize;
841 
842       /* Determine returnValueSize.  */
843       {
844 	/* Find the end of the first argument.  We want to return the
845 	   first argument spec, plus 1 byte for the \0 at the end.  */
846 	const char *type = method->method_types;
847 	if (*type == '\0')
848 	  return NULL;
849 	type = objc_skip_argspec (type);
850 	returnValueSize = type - method->method_types + 1;
851       }
852 
853       /* Copy the first argument into returnValue.  */
854       returnValue = malloc (sizeof (char) * returnValueSize);
855       memcpy (returnValue, method->method_types, returnValueSize);
856       returnValue[returnValueSize - 1] = '\0';
857 
858       return returnValue;
859     }
860 }
861 
862 char *
863 method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber)
864 {
865   if (method == NULL)
866     return 0;
867   else
868     {
869       char *returnValue;
870       const char *returnValueStart;
871       size_t returnValueSize;
872 
873       /* Determine returnValueStart and returnValueSize.  */
874       {
875 	const char *type = method->method_types;
876 
877 	/* Skip the first argument (return type).  */
878 	type = objc_skip_argspec (type);
879 
880 	/* Now keep skipping arguments until we get to
881 	   argumentNumber.  */
882 	while (argumentNumber > 0)
883 	  {
884 	    /* We are supposed to skip an argument, but the string is
885 	       finished.  This means we were asked for a non-existing
886 	       argument.  */
887 	    if (*type == '\0')
888 	      return NULL;
889 
890 	    type = objc_skip_argspec (type);
891 	    argumentNumber--;
892 	  }
893 
894 	/* If the argument does not exist, return NULL.  */
895 	if (*type == '\0')
896 	  return NULL;
897 
898 	returnValueStart = type;
899 	type = objc_skip_argspec (type);
900 	returnValueSize = type - returnValueStart + 1;
901       }
902 
903       /* Copy the argument into returnValue.  */
904       returnValue = malloc (sizeof (char) * returnValueSize);
905       memcpy (returnValue, returnValueStart, returnValueSize);
906       returnValue[returnValueSize - 1] = '\0';
907 
908       return returnValue;
909     }
910 }
911 
912 void method_getReturnType (struct objc_method * method, char *returnValue,
913 			   size_t returnValueSize)
914 {
915   if (returnValue == NULL  ||  returnValueSize == 0)
916     return;
917 
918   /* Zero the string; we'll then write the argument type at the
919      beginning of it, if needed.  */
920   memset (returnValue, 0, returnValueSize);
921 
922   if (method == NULL)
923     return;
924   else
925     {
926       size_t argumentTypeSize;
927 
928       /* Determine argumentTypeSize.  */
929       {
930 	/* Find the end of the first argument.  We want to return the
931 	   first argument spec.  */
932 	const char *type = method->method_types;
933 	if (*type == '\0')
934 	  return;
935 	type = objc_skip_argspec (type);
936 	argumentTypeSize = type - method->method_types;
937 	if (argumentTypeSize > returnValueSize)
938 	  argumentTypeSize = returnValueSize;
939       }
940       /* Copy the argument at the beginning of the string.  */
941       memcpy (returnValue, method->method_types, argumentTypeSize);
942     }
943 }
944 
945 void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber,
946 			     char *returnValue, size_t returnValueSize)
947 {
948   if (returnValue == NULL  ||  returnValueSize == 0)
949     return;
950 
951   /* Zero the string; we'll then write the argument type at the
952      beginning of it, if needed.  */
953   memset (returnValue, 0, returnValueSize);
954 
955   if (method == NULL)
956     return;
957   else
958     {
959       const char *returnValueStart;
960       size_t argumentTypeSize;
961 
962       /* Determine returnValueStart and argumentTypeSize.  */
963       {
964 	const char *type = method->method_types;
965 
966 	/* Skip the first argument (return type).  */
967 	type = objc_skip_argspec (type);
968 
969 	/* Now keep skipping arguments until we get to
970 	   argumentNumber.  */
971 	while (argumentNumber > 0)
972 	  {
973 	    /* We are supposed to skip an argument, but the string is
974 	       finished.  This means we were asked for a non-existing
975 	       argument.  */
976 	    if (*type == '\0')
977 	      return;
978 
979 	    type = objc_skip_argspec (type);
980 	    argumentNumber--;
981 	  }
982 
983 	/* If the argument does not exist, it's game over.  */
984 	if (*type == '\0')
985 	  return;
986 
987 	returnValueStart = type;
988 	type = objc_skip_argspec (type);
989 	argumentTypeSize = type - returnValueStart;
990 	if (argumentTypeSize > returnValueSize)
991 	  argumentTypeSize = returnValueSize;
992       }
993       /* Copy the argument at the beginning of the string.  */
994       memcpy (returnValue, returnValueStart, argumentTypeSize);
995     }
996 }
997 
998 unsigned int
999 method_getNumberOfArguments (struct objc_method *method)
1000 {
1001   if (method == NULL)
1002     return 0;
1003   else
1004     {
1005       unsigned int i = 0;
1006       const char *type = method->method_types;
1007       while (*type)
1008 	{
1009 	  type = objc_skip_argspec (type);
1010 	  i += 1;
1011 	}
1012 
1013       if (i == 0)
1014 	{
1015 	  /* This could only happen if method_types is invalid; in
1016 	     that case, return 0.  */
1017 	  return 0;
1018 	}
1019       else
1020 	{
1021 	  /* Remove the return type.  */
1022 	  return (i - 1);
1023 	}
1024     }
1025 }
1026 
1027 unsigned
1028 objc_get_type_qualifiers (const char *type)
1029 {
1030   unsigned res = 0;
1031   BOOL flag = YES;
1032 
1033   while (flag)
1034     switch (*type++)
1035       {
1036       case _C_CONST:       res |= _F_CONST; break;
1037       case _C_IN:          res |= _F_IN; break;
1038       case _C_INOUT:       res |= _F_INOUT; break;
1039       case _C_OUT:         res |= _F_OUT; break;
1040       case _C_BYCOPY:      res |= _F_BYCOPY; break;
1041       case _C_BYREF:       res |= _F_BYREF; break;
1042       case _C_ONEWAY:      res |= _F_ONEWAY; break;
1043       case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1044       default: flag = NO;
1045     }
1046 
1047   return res;
1048 }
1049 
1050 /* The following three functions can be used to determine how a
1051    structure is laid out by the compiler. For example:
1052 
1053   struct objc_struct_layout layout;
1054   int i;
1055 
1056   objc_layout_structure (type, &layout);
1057   while (objc_layout_structure_next_member (&layout))
1058     {
1059       int position, align;
1060       const char *type;
1061 
1062       objc_layout_structure_get_info (&layout, &position, &align, &type);
1063       printf ("element %d has offset %d, alignment %d\n",
1064               i++, position, align);
1065     }
1066 
1067   These functions are used by objc_sizeof_type and objc_alignof_type
1068   functions to compute the size and alignment of structures. The
1069   previous method of computing the size and alignment of a structure
1070   was not working on some architectures, particularly on AIX, and in
1071   the presence of bitfields inside the structure.  */
1072 void
1073 objc_layout_structure (const char *type,
1074 		       struct objc_struct_layout *layout)
1075 {
1076   const char *ntype;
1077 
1078   if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1079     {
1080       _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1081 		   type);
1082     }
1083 
1084   type ++;
1085   layout->original_type = type;
1086 
1087   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1088   ntype = type;
1089   while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1090          && *ntype++ != '=')
1091     /* do nothing */;
1092 
1093   /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1094   if (*(ntype - 1) == '=')
1095     type = ntype;
1096 
1097   layout->type = type;
1098   layout->prev_type = NULL;
1099   layout->record_size = 0;
1100   layout->record_align = __CHAR_BIT__;
1101 
1102   layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1103 }
1104 
1105 BOOL
1106 objc_layout_structure_next_member (struct objc_struct_layout *layout)
1107 {
1108   register int desired_align = 0;
1109 
1110   /* The following are used only if the field is a bitfield */
1111   register const char *bfld_type = 0;
1112 #ifdef HAVE_BITFIELD_TYPE_MATTERS
1113   register int bfld_type_align = 0;
1114 #endif
1115   register int bfld_field_size = 0;
1116 
1117   /* The current type without the type qualifiers */
1118   const char *type;
1119   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1120 
1121   /* Add the size of the previous field to the size of the record.  */
1122   if (layout->prev_type)
1123     {
1124       type = objc_skip_type_qualifiers (layout->prev_type);
1125       if (unionp)
1126         layout->record_size = MAX (layout->record_size,
1127 				   objc_sizeof_type (type) * __CHAR_BIT__);
1128 
1129       else if (*type != _C_BFLD)
1130 	layout->record_size += objc_sizeof_type (type) * __CHAR_BIT__;
1131       else {
1132         /* Get the bitfield's type */
1133         for (bfld_type = type + 1;
1134              isdigit ((unsigned char)*bfld_type);
1135              bfld_type++)
1136           /* do nothing */;
1137 
1138 #ifdef HAVE_BITFIELD_TYPE_MATTERS
1139 	bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1140 #endif
1141         bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1142         layout->record_size += bfld_field_size;
1143       }
1144     }
1145 
1146   if ((unionp && *layout->type == _C_UNION_E)
1147       || (!unionp && *layout->type == _C_STRUCT_E))
1148     return NO;
1149 
1150   /* Skip the variable name if any */
1151   layout->type = objc_skip_variable_name (layout->type);
1152   type = objc_skip_type_qualifiers (layout->type);
1153 
1154   if (*type != _C_BFLD)
1155     desired_align = objc_alignof_type (type) * __CHAR_BIT__;
1156   else
1157     {
1158       desired_align = 1;
1159       /* Skip the bitfield's offset */
1160       for (bfld_type = type + 1;
1161            isdigit ((unsigned char) *bfld_type);
1162            bfld_type++)
1163         /* do nothing */;
1164 
1165 #ifdef HAVE_BITFIELD_TYPE_MATTERS
1166       bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1167 #endif
1168       bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1169     }
1170 
1171   /* The following won't work for vectors.  */
1172 #ifdef BIGGEST_FIELD_ALIGNMENT
1173   desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1174 #endif
1175 #ifdef ADJUST_FIELD_ALIGN
1176   desired_align = ADJUST_FIELD_ALIGN (type, type, desired_align);
1177 #endif
1178 
1179   /* Record must have at least as much alignment as any field.
1180      Otherwise, the alignment of the field within the record
1181      is meaningless.  */
1182 #ifndef HAVE_BITFIELD_TYPE_MATTERS
1183   layout->record_align = MAX (layout->record_align, desired_align);
1184 #else	/* PCC_BITFIELD_TYPE_MATTERS */
1185   if (*type == _C_BFLD)
1186     {
1187       /* For these machines, a zero-length field does not
1188          affect the alignment of the structure as a whole.
1189          It does, however, affect the alignment of the next field
1190          within the structure.  */
1191       if (bfld_field_size)
1192         layout->record_align = MAX (layout->record_align, desired_align);
1193       else
1194 	desired_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1195 
1196       /* A named bit field of declared type `int'
1197          forces the entire structure to have `int' alignment.
1198          Q1: How is encoded this thing and how to check for it?
1199          Q2: How to determine maximum_field_alignment at runtime? */
1200 
1201 /*	  if (DECL_NAME (field) != 0) */
1202       {
1203         int type_align = bfld_type_align;
1204 #if 0
1205         if (maximum_field_alignment != 0)
1206           type_align = MIN (type_align, maximum_field_alignment);
1207         else if (DECL_PACKED (field))
1208 	  type_align = MIN (type_align, __CHAR_BIT__);
1209 #endif
1210 
1211         layout->record_align = MAX (layout->record_align, type_align);
1212       }
1213     }
1214   else
1215     layout->record_align = MAX (layout->record_align, desired_align);
1216 #endif	/* PCC_BITFIELD_TYPE_MATTERS */
1217 
1218   /* Does this field automatically have alignment it needs
1219      by virtue of the fields that precede it and the record's
1220      own alignment?  */
1221 
1222   if (*type == _C_BFLD)
1223     layout->record_size = atoi (type + 1);
1224   else if (layout->record_size % desired_align != 0)
1225     {
1226       /* No, we need to skip space before this field.
1227          Bump the cumulative size to multiple of field alignment.  */
1228       layout->record_size = ROUND (layout->record_size, desired_align);
1229     }
1230 
1231   /* Jump to the next field in record. */
1232 
1233   layout->prev_type = layout->type;
1234   layout->type = objc_skip_typespec (layout->type);      /* skip component */
1235 
1236   return YES;
1237 }
1238 
1239 void objc_layout_finish_structure (struct objc_struct_layout *layout,
1240                                    unsigned int *size,
1241                                    unsigned int *align)
1242 {
1243   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1244   if (layout->type
1245       && ((!unionp && *layout->type == _C_STRUCT_E)
1246        	  || (unionp && *layout->type == _C_UNION_E)))
1247     {
1248       /* Work out the alignment of the record as one expression and store
1249          in the record type.  Round it up to a multiple of the record's
1250          alignment. */
1251 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1252       layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1253                                                1,
1254                                                layout->record_align);
1255 #else
1256       layout->record_align = MAX (1, layout->record_align);
1257 #endif
1258 
1259       /* Round the size up to be a multiple of the required alignment */
1260       layout->record_size = ROUND (layout->record_size, layout->record_align);
1261 
1262       layout->type = NULL;
1263     }
1264   if (size)
1265     *size = layout->record_size / __CHAR_BIT__;
1266   if (align)
1267     *align = layout->record_align / __CHAR_BIT__;
1268 }
1269 
1270 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1271                                      unsigned int *offset,
1272                                      unsigned int *align,
1273                                      const char **type)
1274 {
1275   if (offset)
1276     *offset = layout->record_size / __CHAR_BIT__;
1277   if (align)
1278     *align = layout->record_align / __CHAR_BIT__;
1279   if (type)
1280     *type = layout->prev_type;
1281 }
1282