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