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