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