OSDN Git Service

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