1 /* Encoding of types for Objective C.
2    Copyright (C) 1993-2022 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 /*
646   Skip type qualifiers.  These may eventually precede typespecs
647   occurring in method prototype encodings.
648 */
649 
650 const char *
objc_skip_type_qualifiers(const char * type)651 objc_skip_type_qualifiers (const char *type)
652 {
653   while (*type == _C_CONST
654            || *type == _C_IN
655            || *type == _C_INOUT
656            || *type == _C_OUT
657            || *type == _C_BYCOPY
658          || *type == _C_BYREF
659            || *type == _C_ONEWAY
660            || *type == _C_GCINVISIBLE)
661     {
662       type += 1;
663     }
664   return type;
665 }
666 
667 const char *
objc_skip_typespec(const char * type)668 objc_skip_typespec (const char *type)
669 {
670   type = objc_skip_variable_name (type);
671   type = objc_skip_type_qualifiers (type);
672 
673   switch (*type) {
674 
675   case _C_ID:
676     /* An id may be annotated by the actual type if it is known
677        with the @"ClassName" syntax */
678 
679     if (*++type != '"')
680       return type;
681     else
682       {
683           while (*++type != '"')
684             /* do nothing */;
685           return type + 1;
686       }
687 
688     /* The following are one character type codes */
689   case _C_CLASS:
690   case _C_SEL:
691   case _C_CHR:
692   case _C_UCHR:
693   case _C_CHARPTR:
694   case _C_ATOM:
695   case _C_SHT:
696   case _C_USHT:
697   case _C_INT:
698   case _C_UINT:
699   case _C_LNG:
700   case _C_BOOL:
701   case _C_ULNG:
702   case _C_LNG_LNG:
703   case _C_ULNG_LNG:
704   case _C_FLT:
705   case _C_DBL:
706   case _C_LNG_DBL:
707   case _C_VOID:
708   case _C_UNDEF:
709     return ++type;
710     break;
711 
712   case _C_COMPLEX:
713     return type + 2;
714     break;
715 
716   case _C_ARY_B:
717     /* skip digits, typespec and closing ']' */
718     while (isdigit ((unsigned char)*++type))
719       ;
720     type = objc_skip_typespec (type);
721     if (*type == _C_ARY_E)
722       return ++type;
723     else
724       {
725           _objc_abort ("bad array type %s\n", type);
726           return 0;
727       }
728 
729   case _C_VECTOR:
730     /* Skip '!' */
731     type++;
732     /* Skip '[' */
733     type++;
734     /* Skip digits (size) */
735     while (isdigit ((unsigned char)*type))
736       type++;
737     /* Skip ',' */
738     type++;
739     /* Skip digits (alignment) */
740     while (isdigit ((unsigned char)*type))
741       type++;
742     /* Skip typespec.  */
743     type = objc_skip_typespec (type);
744     /* Skip closing ']'.  */
745     if (*type == _C_ARY_E)
746       return ++type;
747     else
748       {
749           _objc_abort ("bad vector type %s\n", type);
750           return 0;
751       }
752 
753   case _C_BFLD:
754     /* The GNU encoding of bitfields is: b 'position' 'type'
755        'size'.  */
756     while (isdigit ((unsigned char)*++type))
757       ;   /* skip position */
758     while (isdigit ((unsigned char)*++type))
759       ;   /* skip type and size */
760     return type;
761 
762   case _C_STRUCT_B:
763     /* skip name, and elements until closing '}'  */
764 
765     while (*type != _C_STRUCT_E && *type++ != '=')
766       ;
767     while (*type != _C_STRUCT_E)
768       {
769           type = objc_skip_typespec (type);
770       }
771     return ++type;
772 
773   case _C_UNION_B:
774     /* skip name, and elements until closing ')'  */
775 
776     while (*type != _C_UNION_E && *type++ != '=')
777       ;
778     while (*type != _C_UNION_E)
779       {
780           type = objc_skip_typespec (type);
781       }
782     return ++type;
783 
784   case _C_PTR:
785     /* Just skip the following typespec */
786 
787     return objc_skip_typespec (++type);
788 
789   default:
790     {
791       _objc_abort ("unknown type %s\n", type);
792       return 0;
793     }
794   }
795 }
796 
797 /*
798   Skip an offset as part of a method encoding.  This is prepended by a
799   '+' if the argument is passed in registers.
800 */
801 const char *
objc_skip_offset(const char * type)802 objc_skip_offset (const char *type)
803 {
804   /* The offset is prepended by a '+' if the argument is passed in
805      registers.  PS: The compiler stopped generating this '+' in
806      version 3.4.  */
807   if (*type == '+')
808     type++;
809 
810   /* Some people claim that on some platforms, where the stack grows
811      backwards, the compiler generates negative offsets (??).  Skip a
812      '-' for such a negative offset.  */
813   if (*type == '-')
814     type++;
815 
816   /* Skip the digits that represent the offset.  */
817   while (isdigit ((unsigned char) *type))
818     type++;
819 
820   return type;
821 }
822 
823 const char *
objc_skip_argspec(const char * type)824 objc_skip_argspec (const char *type)
825 {
826   type = objc_skip_typespec (type);
827   type = objc_skip_offset (type);
828   return type;
829 }
830 
831 char *
method_copyReturnType(struct objc_method * method)832 method_copyReturnType (struct objc_method *method)
833 {
834   if (method == NULL)
835     return 0;
836   else
837     {
838       char *returnValue;
839       size_t returnValueSize;
840 
841       /* Determine returnValueSize.  */
842       {
843           /* Find the end of the first argument.  We want to return the
844              first argument spec, plus 1 byte for the \0 at the end.  */
845           const char *type = method->method_types;
846           if (*type == '\0')
847             return NULL;
848           type = objc_skip_argspec (type);
849           returnValueSize = type - method->method_types + 1;
850       }
851 
852       /* Copy the first argument into returnValue.  */
853       returnValue = malloc (sizeof (char) * returnValueSize);
854       memcpy (returnValue, method->method_types, returnValueSize);
855       returnValue[returnValueSize - 1] = '\0';
856 
857       return returnValue;
858     }
859 }
860 
861 char *
method_copyArgumentType(struct objc_method * method,unsigned int argumentNumber)862 method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber)
863 {
864   if (method == NULL)
865     return 0;
866   else
867     {
868       char *returnValue;
869       const char *returnValueStart;
870       size_t returnValueSize;
871 
872       /* Determine returnValueStart and returnValueSize.  */
873       {
874           const char *type = method->method_types;
875 
876           /* Skip the first argument (return type).  */
877           type = objc_skip_argspec (type);
878 
879           /* Now keep skipping arguments until we get to
880              argumentNumber.  */
881           while (argumentNumber > 0)
882             {
883               /* We are supposed to skip an argument, but the string is
884                  finished.  This means we were asked for a non-existing
885                  argument.  */
886               if (*type == '\0')
887                 return NULL;
888 
889               type = objc_skip_argspec (type);
890               argumentNumber--;
891             }
892 
893           /* If the argument does not exist, return NULL.  */
894           if (*type == '\0')
895             return NULL;
896 
897           returnValueStart = type;
898           type = objc_skip_argspec (type);
899           returnValueSize = type - returnValueStart + 1;
900       }
901 
902       /* Copy the argument into returnValue.  */
903       returnValue = malloc (sizeof (char) * returnValueSize);
904       memcpy (returnValue, returnValueStart, returnValueSize);
905       returnValue[returnValueSize - 1] = '\0';
906 
907       return returnValue;
908     }
909 }
910 
method_getReturnType(struct objc_method * method,char * returnValue,size_t returnValueSize)911 void method_getReturnType (struct objc_method * method, char *returnValue,
912                                  size_t returnValueSize)
913 {
914   if (returnValue == NULL  ||  returnValueSize == 0)
915     return;
916 
917   /* Zero the string; we'll then write the argument type at the
918      beginning of it, if needed.  */
919   memset (returnValue, 0, returnValueSize);
920 
921   if (method == NULL)
922     return;
923   else
924     {
925       size_t argumentTypeSize;
926 
927       /* Determine argumentTypeSize.  */
928       {
929           /* Find the end of the first argument.  We want to return the
930              first argument spec.  */
931           const char *type = method->method_types;
932           if (*type == '\0')
933             return;
934           type = objc_skip_argspec (type);
935           argumentTypeSize = type - method->method_types;
936           if (argumentTypeSize > returnValueSize)
937             argumentTypeSize = returnValueSize;
938       }
939       /* Copy the argument at the beginning of the string.  */
940       memcpy (returnValue, method->method_types, argumentTypeSize);
941     }
942 }
943 
method_getArgumentType(struct objc_method * method,unsigned int argumentNumber,char * returnValue,size_t returnValueSize)944 void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber,
945                                    char *returnValue, size_t returnValueSize)
946 {
947   if (returnValue == NULL  ||  returnValueSize == 0)
948     return;
949 
950   /* Zero the string; we'll then write the argument type at the
951      beginning of it, if needed.  */
952   memset (returnValue, 0, returnValueSize);
953 
954   if (method == NULL)
955     return;
956   else
957     {
958       const char *returnValueStart;
959       size_t argumentTypeSize;
960 
961       /* Determine returnValueStart and argumentTypeSize.  */
962       {
963           const char *type = method->method_types;
964 
965           /* Skip the first argument (return type).  */
966           type = objc_skip_argspec (type);
967 
968           /* Now keep skipping arguments until we get to
969              argumentNumber.  */
970           while (argumentNumber > 0)
971             {
972               /* We are supposed to skip an argument, but the string is
973                  finished.  This means we were asked for a non-existing
974                  argument.  */
975               if (*type == '\0')
976                 return;
977 
978               type = objc_skip_argspec (type);
979               argumentNumber--;
980             }
981 
982           /* If the argument does not exist, it's game over.  */
983           if (*type == '\0')
984             return;
985 
986           returnValueStart = type;
987           type = objc_skip_argspec (type);
988           argumentTypeSize = type - returnValueStart;
989           if (argumentTypeSize > returnValueSize)
990             argumentTypeSize = returnValueSize;
991       }
992       /* Copy the argument at the beginning of the string.  */
993       memcpy (returnValue, returnValueStart, argumentTypeSize);
994     }
995 }
996 
997 unsigned int
method_getNumberOfArguments(struct objc_method * method)998 method_getNumberOfArguments (struct objc_method *method)
999 {
1000   if (method == NULL)
1001     return 0;
1002   else
1003     {
1004       unsigned int i = 0;
1005       const char *type = method->method_types;
1006       while (*type)
1007           {
1008             type = objc_skip_argspec (type);
1009             i += 1;
1010           }
1011 
1012       if (i == 0)
1013           {
1014             /* This could only happen if method_types is invalid; in
1015                that case, return 0.  */
1016             return 0;
1017           }
1018       else
1019           {
1020             /* Remove the return type.  */
1021             return (i - 1);
1022           }
1023     }
1024 }
1025 
1026 unsigned
objc_get_type_qualifiers(const char * type)1027 objc_get_type_qualifiers (const char *type)
1028 {
1029   unsigned res = 0;
1030   BOOL flag = YES;
1031 
1032   while (flag)
1033     switch (*type++)
1034       {
1035       case _C_CONST:       res |= _F_CONST; break;
1036       case _C_IN:          res |= _F_IN; break;
1037       case _C_INOUT:       res |= _F_INOUT; break;
1038       case _C_OUT:         res |= _F_OUT; break;
1039       case _C_BYCOPY:      res |= _F_BYCOPY; break;
1040       case _C_BYREF:       res |= _F_BYREF; break;
1041       case _C_ONEWAY:      res |= _F_ONEWAY; break;
1042       case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1043       default: flag = NO;
1044     }
1045 
1046   return res;
1047 }
1048 
1049 /* The following three functions can be used to determine how a
1050    structure is laid out by the compiler. For example:
1051 
1052   struct objc_struct_layout layout;
1053   int i;
1054 
1055   objc_layout_structure (type, &layout);
1056   while (objc_layout_structure_next_member (&layout))
1057     {
1058       int position, align;
1059       const char *type;
1060 
1061       objc_layout_structure_get_info (&layout, &position, &align, &type);
1062       printf ("element %d has offset %d, alignment %d\n",
1063               i++, position, align);
1064     }
1065 
1066   These functions are used by objc_sizeof_type and objc_alignof_type
1067   functions to compute the size and alignment of structures. The
1068   previous method of computing the size and alignment of a structure
1069   was not working on some architectures, particularly on AIX, and in
1070   the presence of bitfields inside the structure.  */
1071 void
objc_layout_structure(const char * type,struct objc_struct_layout * layout)1072 objc_layout_structure (const char *type,
1073                            struct objc_struct_layout *layout)
1074 {
1075   const char *ntype;
1076 
1077   if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1078     {
1079       _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1080                        type);
1081     }
1082 
1083   type ++;
1084   layout->original_type = type;
1085 
1086   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1087   ntype = type;
1088   while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1089          && *ntype++ != '=')
1090     /* do nothing */;
1091 
1092   /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1093   if (*(ntype - 1) == '=')
1094     type = ntype;
1095 
1096   layout->type = type;
1097   layout->prev_type = NULL;
1098   layout->record_size = 0;
1099   layout->record_align = __CHAR_BIT__;
1100 
1101   layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1102 }
1103 
1104 BOOL
objc_layout_structure_next_member(struct objc_struct_layout * layout)1105 objc_layout_structure_next_member (struct objc_struct_layout *layout)
1106 {
1107   register int desired_align = 0;
1108 
1109   /* The following are used only if the field is a bitfield */
1110   register const char *bfld_type = 0;
1111 #ifdef HAVE_BITFIELD_TYPE_MATTERS
1112   register int bfld_type_align = 0;
1113 #endif
1114   register int bfld_field_size = 0;
1115 
1116   /* The current type without the type qualifiers */
1117   const char *type;
1118   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1119 
1120   /* Add the size of the previous field to the size of the record.  */
1121   if (layout->prev_type)
1122     {
1123       type = objc_skip_type_qualifiers (layout->prev_type);
1124       if (unionp)
1125         layout->record_size = MAX (layout->record_size,
1126                                            objc_sizeof_type (type) * __CHAR_BIT__);
1127 
1128       else if (*type != _C_BFLD)
1129           layout->record_size += objc_sizeof_type (type) * __CHAR_BIT__;
1130       else {
1131         /* Get the bitfield's type */
1132         for (bfld_type = type + 1;
1133              isdigit ((unsigned char)*bfld_type);
1134              bfld_type++)
1135           /* do nothing */;
1136 
1137 #ifdef HAVE_BITFIELD_TYPE_MATTERS
1138           bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1139 #endif
1140         bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1141         layout->record_size += bfld_field_size;
1142       }
1143     }
1144 
1145   if ((unionp && *layout->type == _C_UNION_E)
1146       || (!unionp && *layout->type == _C_STRUCT_E))
1147     return NO;
1148 
1149   /* Skip the variable name if any */
1150   layout->type = objc_skip_variable_name (layout->type);
1151   type = objc_skip_type_qualifiers (layout->type);
1152 
1153   if (*type != _C_BFLD)
1154     desired_align = objc_alignof_type (type) * __CHAR_BIT__;
1155   else
1156     {
1157       desired_align = 1;
1158       /* Skip the bitfield's offset */
1159       for (bfld_type = type + 1;
1160            isdigit ((unsigned char) *bfld_type);
1161            bfld_type++)
1162         /* do nothing */;
1163 
1164 #ifdef HAVE_BITFIELD_TYPE_MATTERS
1165       bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1166 #endif
1167       bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1168     }
1169 
1170   /* The following won't work for vectors.  */
1171 #ifdef BIGGEST_FIELD_ALIGNMENT
1172   desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1173 #endif
1174 #ifdef ADJUST_FIELD_ALIGN
1175   desired_align = ADJUST_FIELD_ALIGN (type, type, desired_align);
1176 #endif
1177 
1178   /* Record must have at least as much alignment as any field.
1179      Otherwise, the alignment of the field within the record
1180      is meaningless.  */
1181 #ifndef HAVE_BITFIELD_TYPE_MATTERS
1182   layout->record_align = MAX (layout->record_align, desired_align);
1183 #else     /* PCC_BITFIELD_TYPE_MATTERS */
1184   if (*type == _C_BFLD)
1185     {
1186       /* For these machines, a zero-length field does not
1187          affect the alignment of the structure as a whole.
1188          It does, however, affect the alignment of the next field
1189          within the structure.  */
1190       if (bfld_field_size)
1191         layout->record_align = MAX (layout->record_align, desired_align);
1192       else
1193           desired_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1194 
1195       /* A named bit field of declared type `int'
1196          forces the entire structure to have `int' alignment.
1197          Q1: How is encoded this thing and how to check for it?
1198          Q2: How to determine maximum_field_alignment at runtime? */
1199 
1200 /*          if (DECL_NAME (field) != 0) */
1201       {
1202         int type_align = bfld_type_align;
1203 #if 0
1204         if (maximum_field_alignment != 0)
1205           type_align = MIN (type_align, maximum_field_alignment);
1206         else if (DECL_PACKED (field))
1207             type_align = MIN (type_align, __CHAR_BIT__);
1208 #endif
1209 
1210         layout->record_align = MAX (layout->record_align, type_align);
1211       }
1212     }
1213   else
1214     layout->record_align = MAX (layout->record_align, desired_align);
1215 #endif    /* PCC_BITFIELD_TYPE_MATTERS */
1216 
1217   /* Does this field automatically have alignment it needs
1218      by virtue of the fields that precede it and the record's
1219      own alignment?  */
1220 
1221   if (*type == _C_BFLD)
1222     layout->record_size = atoi (type + 1);
1223   else if (layout->record_size % desired_align != 0)
1224     {
1225       /* No, we need to skip space before this field.
1226          Bump the cumulative size to multiple of field alignment.  */
1227       layout->record_size = ROUND (layout->record_size, desired_align);
1228     }
1229 
1230   /* Jump to the next field in record. */
1231 
1232   layout->prev_type = layout->type;
1233   layout->type = objc_skip_typespec (layout->type);      /* skip component */
1234 
1235   return YES;
1236 }
1237 
objc_layout_finish_structure(struct objc_struct_layout * layout,unsigned int * size,unsigned int * align)1238 void objc_layout_finish_structure (struct objc_struct_layout *layout,
1239                                    unsigned int *size,
1240                                    unsigned int *align)
1241 {
1242   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1243   if (layout->type
1244       && ((!unionp && *layout->type == _C_STRUCT_E)
1245             || (unionp && *layout->type == _C_UNION_E)))
1246     {
1247       /* Work out the alignment of the record as one expression and store
1248          in the record type.  Round it up to a multiple of the record's
1249          alignment. */
1250 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1251       layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1252                                                1,
1253                                                layout->record_align);
1254 #else
1255       layout->record_align = MAX (1, layout->record_align);
1256 #endif
1257 
1258       /* Round the size up to be a multiple of the required alignment */
1259       layout->record_size = ROUND (layout->record_size, layout->record_align);
1260 
1261       layout->type = NULL;
1262     }
1263   if (size)
1264     *size = layout->record_size / __CHAR_BIT__;
1265   if (align)
1266     *align = layout->record_align / __CHAR_BIT__;
1267 }
1268 
objc_layout_structure_get_info(struct objc_struct_layout * layout,unsigned int * offset,unsigned int * align,const char ** type)1269 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1270                                      unsigned int *offset,
1271                                      unsigned int *align,
1272                                      const char **type)
1273 {
1274   if (offset)
1275     *offset = layout->record_size / __CHAR_BIT__;
1276   if (align)
1277     *align = layout->record_align / __CHAR_BIT__;
1278   if (type)
1279     *type = layout->prev_type;
1280 }
1281