OSDN Git Service

2007-04-21 Andrew Ruder <andy@aeruder.net>
[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
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 2, 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 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.  */
23
24 /* As a special exception, if you link this library with files
25    compiled with GCC to produce an executable, this does not cause
26    the resulting executable to be covered by the GNU General Public License.
27    This exception does not however invalidate any other reasons why
28    the executable file might be covered by the GNU General Public License.  */
29
30 /* FIXME: This file has no business including tm.h.  */
31
32 #include "tconfig.h"
33 #include "coretypes.h"
34 #include "tm.h"
35 #include "objc/objc-api.h"
36 #include "objc/encoding.h"
37 #include <stdlib.h>
38
39 #undef  MAX
40 #define MAX(X, Y)                    \
41   ({ typeof (X) __x = (X), __y = (Y); \
42      (__x > __y ? __x : __y); })
43
44 #undef  MIN
45 #define MIN(X, Y)                    \
46   ({ typeof (X) __x = (X), __y = (Y); \
47      (__x < __y ? __x : __y); })
48
49 #undef  ROUND
50 #define ROUND(V, A) \
51   ({ typeof (V) __v = (V); typeof (A) __a = (A); \
52      __a * ((__v+__a - 1)/__a); })
53
54
55 /* Various hacks for objc_layout_record. These are used by the target
56    macros. */
57
58 #define TREE_CODE(TYPE) *(TYPE)
59 #define TREE_TYPE(TREE) (TREE)
60
61 #define RECORD_TYPE     _C_STRUCT_B
62 #define UNION_TYPE      _C_UNION_B
63 #define QUAL_UNION_TYPE _C_UNION_B
64 #define ARRAY_TYPE      _C_ARY_B
65
66 #define REAL_TYPE       _C_DBL
67
68 #define VECTOR_TYPE     _C_VECTOR
69
70 #define TYPE_FIELDS(TYPE)           ({const char *_field = (TYPE)+1; \
71     while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
72            && *_field != _C_UNION_B && *_field++ != '=') \
73     /* do nothing */; \
74     _field;})
75
76 #define DECL_MODE(TYPE) *(TYPE)
77 #define TYPE_MODE(TYPE) *(TYPE)
78
79 #define DFmode          _C_DBL
80
81 #define get_inner_array_type(TYPE)      ({const char *_field = (TYPE); \
82   while (*_field == _C_ARY_B)\
83     {\
84       while (isdigit ((unsigned char)*++_field))\
85         ;\
86     }\
87     _field;})
88
89 /* Some ports (eg ARM) allow the structure size boundary to be
90    selected at compile-time.  We override the normal definition with
91    one that has a constant value for this compilation.  */
92 #ifndef BITS_PER_UNIT
93 #define BITS_PER_UNIT 8
94 #endif
95 #undef  STRUCTURE_SIZE_BOUNDARY
96 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
97
98 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
99    target_flags.  Define a dummy entry here to so we don't die.
100    We have to rename it because target_flags may already have been
101    declared extern.  */
102 #define target_flags not_target_flags
103 static int __attribute__ ((__unused__)) not_target_flags = 0;
104
105 /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
106    Define a dummy ALTIVEC_VECTOR_MODE so it will not die.  */
107 #undef ALTIVEC_VECTOR_MODE
108 #define ALTIVEC_VECTOR_MODE(MODE) (0)
109
110
111 /*  FIXME: while this file has no business including tm.h, this
112     definitely has no business defining this macro but it
113     is only way around without really rewritting this file,
114     should look after the branch of 3.4 to fix this.  */
115 #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED)    \
116   ({ const char *_fields = TYPE_FIELDS (STRUCT);                                \
117   ((_fields != 0                                                        \
118     && TYPE_MODE (TREE_CODE (TREE_TYPE (_fields)) == ARRAY_TYPE         \
119                     ? get_inner_array_type (_fields)                    \
120                     : TREE_TYPE (_fields)) == DFmode)                   \
121    ? MAX (MAX (COMPUTED, SPECIFIED), 64)                                \
122    : MAX (COMPUTED, SPECIFIED));})
123 /* FIXME: The word 'fixme' is insufficient to explain the wrong-ness
124    of this next macro definition.  */
125 #define darwin_rs6000_special_round_type_align(S,C,S2) \
126   rs6000_special_round_type_align(S,C,S2)
127
128 /*
129   return the size of an object specified by type
130 */
131
132 int
133 objc_sizeof_type (const char *type)
134 {
135   /* Skip the variable name if any */
136   if (*type == '"')
137     {
138       for (type++; *type++ != '"';)
139         /* do nothing */;
140     }
141
142   switch (*type) {
143   case _C_BOOL:
144     return sizeof (_Bool);
145     break;
146
147   case _C_ID:
148     return sizeof (id);
149     break;
150
151   case _C_CLASS:
152     return sizeof (Class);
153     break;
154
155   case _C_SEL:
156     return sizeof (SEL);
157     break;
158
159   case _C_CHR:
160     return sizeof (char);
161     break;
162
163   case _C_UCHR:
164     return sizeof (unsigned char);
165     break;
166
167   case _C_SHT:
168     return sizeof (short);
169     break;
170
171   case _C_USHT:
172     return sizeof (unsigned short);
173     break;
174
175   case _C_INT:
176     return sizeof (int);
177     break;
178
179   case _C_UINT:
180     return sizeof (unsigned int);
181     break;
182
183   case _C_LNG:
184     return sizeof (long);
185     break;
186
187   case _C_ULNG:
188     return sizeof (unsigned long);
189     break;
190
191   case _C_LNG_LNG:
192     return sizeof (long long);
193     break;
194
195   case _C_ULNG_LNG:
196     return sizeof (unsigned long long);
197     break;
198
199   case _C_FLT:
200     return sizeof (float);
201     break;
202
203   case _C_DBL:
204     return sizeof (double);
205     break;
206
207   case _C_VOID:
208     return sizeof (void);
209     break;
210
211   case _C_PTR:
212   case _C_ATOM:
213   case _C_CHARPTR:
214     return sizeof (char *);
215     break;
216
217   case _C_ARY_B:
218     {
219       int len = atoi (type + 1);
220       while (isdigit ((unsigned char)*++type))
221         ;
222       return len * objc_aligned_size (type);
223     }
224     break;
225
226   case _C_BFLD:
227     {
228       /* The new encoding of bitfields is: b 'position' 'type' 'size' */
229       int position, size;
230       int startByte, endByte;
231
232       position = atoi (type + 1);
233       while (isdigit ((unsigned char)*++type))
234         ;
235       size = atoi (type + 1);
236
237       startByte = position / BITS_PER_UNIT;
238       endByte = (position + size) / BITS_PER_UNIT;
239       return endByte - startByte;
240     }
241
242   case _C_UNION_B:
243   case _C_STRUCT_B:
244     {
245       struct objc_struct_layout layout;
246       unsigned int size;
247
248       objc_layout_structure (type, &layout);
249       while (objc_layout_structure_next_member (&layout))
250         /* do nothing */ ;
251       objc_layout_finish_structure (&layout, &size, NULL);
252
253       return size;
254     }
255     
256   case _C_COMPLEX:
257     {
258       type++; /* Skip after the 'j'. */
259       switch (*type)
260         {
261             case _C_CHR:
262               return sizeof (_Complex char);
263               break;
264
265             case _C_UCHR:
266               return sizeof (_Complex unsigned char);
267               break;
268
269             case _C_SHT:
270               return sizeof (_Complex short);
271               break;
272
273             case _C_USHT:
274               return sizeof (_Complex unsigned short);
275               break;
276
277             case _C_INT:
278               return sizeof (_Complex int);
279               break;
280
281             case _C_UINT:
282               return sizeof (_Complex unsigned int);
283               break;
284
285             case _C_LNG:
286               return sizeof (_Complex long);
287               break;
288
289             case _C_ULNG:
290               return sizeof (_Complex unsigned long);
291               break;
292
293             case _C_LNG_LNG:
294               return sizeof (_Complex long long);
295               break;
296
297             case _C_ULNG_LNG:
298               return sizeof (_Complex unsigned long long);
299               break;
300
301             case _C_FLT:
302               return sizeof (_Complex float);
303               break;
304
305             case _C_DBL:
306               return sizeof (_Complex double);
307               break;
308             
309             default:
310               {
311                 objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown complex type %s\n",
312                             type);
313                 return 0;
314               }
315         }
316     }
317
318   default:
319     {
320       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
321       return 0;
322     }
323   }
324 }
325
326
327 /*
328   Return the alignment of an object specified by type
329 */
330
331 int
332 objc_alignof_type (const char *type)
333 {
334   /* Skip the variable name if any */
335   if (*type == '"')
336     {
337       for (type++; *type++ != '"';)
338         /* do nothing */;
339     }
340   switch (*type) {
341   case _C_BOOL:
342     return __alignof__ (_Bool);
343     break;
344
345   case _C_ID:
346     return __alignof__ (id);
347     break;
348
349   case _C_CLASS:
350     return __alignof__ (Class);
351     break;
352
353   case _C_SEL:
354     return __alignof__ (SEL);
355     break;
356
357   case _C_CHR:
358     return __alignof__ (char);
359     break;
360
361   case _C_UCHR:
362     return __alignof__ (unsigned char);
363     break;
364
365   case _C_SHT:
366     return __alignof__ (short);
367     break;
368
369   case _C_USHT:
370     return __alignof__ (unsigned short);
371     break;
372
373   case _C_INT:
374     return __alignof__ (int);
375     break;
376
377   case _C_UINT:
378     return __alignof__ (unsigned int);
379     break;
380
381   case _C_LNG:
382     return __alignof__ (long);
383     break;
384
385   case _C_ULNG:
386     return __alignof__ (unsigned long);
387     break;
388
389   case _C_LNG_LNG:
390     return __alignof__ (long long);
391     break;
392
393   case _C_ULNG_LNG:
394     return __alignof__ (unsigned long long);
395     break;
396
397   case _C_FLT:
398     return __alignof__ (float);
399     break;
400
401   case _C_DBL:
402     return __alignof__ (double);
403     break;
404
405   case _C_PTR:
406   case _C_ATOM:
407   case _C_CHARPTR:
408     return __alignof__ (char *);
409     break;
410
411   case _C_ARY_B:
412     while (isdigit ((unsigned char)*++type))
413       /* do nothing */;
414     return objc_alignof_type (type);
415
416   case _C_STRUCT_B:
417   case _C_UNION_B:
418     {
419       struct objc_struct_layout layout;
420       unsigned int align;
421
422       objc_layout_structure (type, &layout);
423       while (objc_layout_structure_next_member (&layout))
424         /* do nothing */;
425       objc_layout_finish_structure (&layout, NULL, &align);
426
427       return align;
428     }
429     
430     
431   case _C_COMPLEX:
432     {
433       type++; /* Skip after the 'j'. */
434       switch (*type)
435         {
436             case _C_CHR:
437               return __alignof__ (_Complex char);
438               break;
439
440             case _C_UCHR:
441               return __alignof__ (_Complex unsigned char);
442               break;
443
444             case _C_SHT:
445               return __alignof__ (_Complex short);
446               break;
447
448             case _C_USHT:
449               return __alignof__ (_Complex unsigned short);
450               break;
451
452             case _C_INT:
453               return __alignof__ (_Complex int);
454               break;
455
456             case _C_UINT:
457               return __alignof__ (_Complex unsigned int);
458               break;
459
460             case _C_LNG:
461               return __alignof__ (_Complex long);
462               break;
463
464             case _C_ULNG:
465               return __alignof__ (_Complex unsigned long);
466               break;
467
468             case _C_LNG_LNG:
469               return __alignof__ (_Complex long long);
470               break;
471
472             case _C_ULNG_LNG:
473               return __alignof__ (_Complex unsigned long long);
474               break;
475
476             case _C_FLT:
477               return __alignof__ (_Complex float);
478               break;
479
480             case _C_DBL:
481               return __alignof__ (_Complex double);
482               break;
483             
484             default:
485               {
486                 objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown complex type %s\n",
487                             type);
488                 return 0;
489               }
490         }
491     }
492
493   default:
494     {
495       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
496       return 0;
497     }
498   }
499 }
500
501 /*
502   The aligned size if the size rounded up to the nearest alignment.
503 */
504
505 int
506 objc_aligned_size (const char *type)
507 {
508   int size, align;
509
510   /* Skip the variable name */
511   if (*type == '"')
512     {
513       for (type++; *type++ != '"';)
514         /* do nothing */;
515     }
516
517   size = objc_sizeof_type (type);
518   align = objc_alignof_type (type);
519
520   return ROUND (size, align);
521 }
522
523 /*
524   The size rounded up to the nearest integral of the wordsize, taken
525   to be the size of a void *.
526 */
527
528 int
529 objc_promoted_size (const char *type)
530 {
531   int size, wordsize;
532
533   /* Skip the variable name */
534   if (*type == '"')
535     {
536       for (type++; *type++ != '"';)
537         /* do nothing */;
538     }
539
540   size = objc_sizeof_type (type);
541   wordsize = sizeof (void *);
542
543   return ROUND (size, wordsize);
544 }
545
546 /*
547   Skip type qualifiers.  These may eventually precede typespecs
548   occurring in method prototype encodings.
549 */
550
551 inline const char *
552 objc_skip_type_qualifiers (const char *type)
553 {
554   while (*type == _C_CONST
555          || *type == _C_IN
556          || *type == _C_INOUT
557          || *type == _C_OUT
558          || *type == _C_BYCOPY
559          || *type == _C_BYREF
560          || *type == _C_ONEWAY
561          || *type == _C_GCINVISIBLE)
562     {
563       type += 1;
564     }
565   return type;
566 }
567
568
569 /*
570   Skip one typespec element.  If the typespec is prepended by type
571   qualifiers, these are skipped as well.
572 */
573
574 const char *
575 objc_skip_typespec (const char *type)
576 {
577   /* Skip the variable name if any */
578   if (*type == '"')
579     {
580       for (type++; *type++ != '"';)
581         /* do nothing */;
582     }
583
584   type = objc_skip_type_qualifiers (type);
585
586   switch (*type) {
587
588   case _C_ID:
589     /* An id may be annotated by the actual type if it is known
590        with the @"ClassName" syntax */
591
592     if (*++type != '"')
593       return type;
594     else
595       {
596         while (*++type != '"')
597           /* do nothing */;
598         return type + 1;
599       }
600
601     /* The following are one character type codes */
602   case _C_CLASS:
603   case _C_SEL:
604   case _C_CHR:
605   case _C_UCHR:
606   case _C_CHARPTR:
607   case _C_ATOM:
608   case _C_SHT:
609   case _C_USHT:
610   case _C_INT:
611   case _C_UINT:
612   case _C_LNG:
613   case _C_BOOL:
614   case _C_ULNG:
615   case _C_LNG_LNG:
616   case _C_ULNG_LNG:
617   case _C_FLT:
618   case _C_DBL:
619   case _C_VOID:
620   case _C_UNDEF:
621     return ++type;
622     break;
623     
624   case _C_COMPLEX:
625     return type + 2;
626     break;
627
628   case _C_ARY_B:
629     /* skip digits, typespec and closing ']' */
630
631     while (isdigit ((unsigned char)*++type))
632       ;
633     type = objc_skip_typespec (type);
634     if (*type == _C_ARY_E)
635       return ++type;
636     else
637       {
638         objc_error (nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type);
639         return 0;
640       }
641
642   case _C_BFLD:
643     /* The new encoding of bitfields is: b 'position' 'type' 'size' */
644     while (isdigit ((unsigned char)*++type))
645       ; /* skip position */
646     while (isdigit ((unsigned char)*++type))
647       ; /* skip type and size */
648     return type;
649
650   case _C_STRUCT_B:
651     /* skip name, and elements until closing '}'  */
652
653     while (*type != _C_STRUCT_E && *type++ != '=')
654       ;
655     while (*type != _C_STRUCT_E)
656       {
657         type = objc_skip_typespec (type);
658       }
659     return ++type;
660
661   case _C_UNION_B:
662     /* skip name, and elements until closing ')'  */
663
664     while (*type != _C_UNION_E && *type++ != '=')
665       ;
666     while (*type != _C_UNION_E)
667       {
668         type = objc_skip_typespec (type);
669       }
670     return ++type;
671
672   case _C_PTR:
673     /* Just skip the following typespec */
674
675     return objc_skip_typespec (++type);
676
677   default:
678     {
679       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
680       return 0;
681     }
682   }
683 }
684
685 /*
686   Skip an offset as part of a method encoding.  This is prepended by a
687   '+' if the argument is passed in registers.
688 */
689 inline const char *
690 objc_skip_offset (const char *type)
691 {
692   if (*type == '+')
693     type++;
694   while (isdigit ((unsigned char) *++type))
695     ;
696   return type;
697 }
698
699 /*
700   Skip an argument specification of a method encoding.
701 */
702 const char *
703 objc_skip_argspec (const char *type)
704 {
705   type = objc_skip_typespec (type);
706   type = objc_skip_offset (type);
707   return type;
708 }
709
710 /*
711   Return the number of arguments that the method MTH expects.
712   Note that all methods need two implicit arguments `self' and
713   `_cmd'.
714 */
715 int
716 method_get_number_of_arguments (struct objc_method *mth)
717 {
718   int i = 0;
719   const char *type = mth->method_types;
720   while (*type)
721     {
722       type = objc_skip_argspec (type);
723       i += 1;
724     }
725   return i - 1;
726 }
727
728 /*
729   Return the size of the argument block needed on the stack to invoke
730   the method MTH.  This may be zero, if all arguments are passed in
731   registers.
732 */
733
734 int
735 method_get_sizeof_arguments (struct objc_method *mth)
736 {
737   const char *type = objc_skip_typespec (mth->method_types);
738   return atoi (type);
739 }
740
741 /*
742   Return a pointer to the next argument of ARGFRAME.  type points to
743   the last argument.  Typical use of this look like:
744
745   {
746     char *datum, *type;
747     for (datum = method_get_first_argument (method, argframe, &type);
748          datum; datum = method_get_next_argument (argframe, &type))
749       {
750         unsigned flags = objc_get_type_qualifiers (type);
751         type = objc_skip_type_qualifiers (type);
752         if (*type != _C_PTR)
753           [portal encodeData: datum ofType: type];
754         else
755           {
756             if ((flags & _F_IN) == _F_IN)
757               [portal encodeData: *(char **) datum ofType: ++type];
758           }
759       }
760   }
761 */
762
763 char *
764 method_get_next_argument (arglist_t argframe, const char **type)
765 {
766   const char *t = objc_skip_argspec (*type);
767
768   if (*t == '\0')
769     return 0;
770
771   *type = t;
772   t = objc_skip_typespec (t);
773
774   if (*t == '+')
775     return argframe->arg_regs + atoi (++t);
776   else
777     return argframe->arg_ptr + atoi (t);
778 }
779
780 /*
781   Return a pointer to the value of the first argument of the method
782   described in M with the given argumentframe ARGFRAME.  The type
783   is returned in TYPE.  type must be passed to successive calls of
784   method_get_next_argument.
785 */
786 char *
787 method_get_first_argument (struct objc_method *m,
788                            arglist_t argframe,
789                            const char **type)
790 {
791   *type = m->method_types;
792   return method_get_next_argument (argframe, type);
793 }
794
795 /*
796    Return a pointer to the ARGth argument of the method
797    M from the frame ARGFRAME.  The type of the argument
798    is returned in the value-result argument TYPE
799 */
800
801 char *
802 method_get_nth_argument (struct objc_method *m,
803                          arglist_t argframe, int arg,
804                          const char **type)
805 {
806   const char *t = objc_skip_argspec (m->method_types);
807
808   if (arg > method_get_number_of_arguments (m))
809     return 0;
810
811   while (arg--)
812     t = objc_skip_argspec (t);
813
814   *type = t;
815   t = objc_skip_typespec (t);
816
817   if (*t == '+')
818     return argframe->arg_regs + atoi (++t);
819   else
820     return argframe->arg_ptr + atoi (t);
821 }
822
823 unsigned
824 objc_get_type_qualifiers (const char *type)
825 {
826   unsigned res = 0;
827   BOOL flag = YES;
828
829   while (flag)
830     switch (*type++)
831       {
832       case _C_CONST:    res |= _F_CONST; break;
833       case _C_IN:       res |= _F_IN; break;
834       case _C_INOUT:    res |= _F_INOUT; break;
835       case _C_OUT:      res |= _F_OUT; break;
836       case _C_BYCOPY:   res |= _F_BYCOPY; break;
837       case _C_BYREF:  res |= _F_BYREF; break;
838       case _C_ONEWAY:   res |= _F_ONEWAY; break;
839       case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
840       default: flag = NO;
841     }
842
843   return res;
844 }
845
846
847 /* The following three functions can be used to determine how a
848    structure is laid out by the compiler. For example:
849
850   struct objc_struct_layout layout;
851   int i;
852
853   objc_layout_structure (type, &layout);
854   while (objc_layout_structure_next_member (&layout))
855     {
856       int position, align;
857       const char *type;
858
859       objc_layout_structure_get_info (&layout, &position, &align, &type);
860       printf ("element %d has offset %d, alignment %d\n",
861               i++, position, align);
862     }
863
864   These functions are used by objc_sizeof_type and objc_alignof_type
865   functions to compute the size and alignment of structures. The
866   previous method of computing the size and alignment of a structure
867   was not working on some architectures, particulary on AIX, and in
868   the presence of bitfields inside the structure. */
869 void
870 objc_layout_structure (const char *type,
871                            struct objc_struct_layout *layout)
872 {
873   const char *ntype;
874
875   if (*type != _C_UNION_B && *type != _C_STRUCT_B)
876     {
877       objc_error (nil, OBJC_ERR_BAD_TYPE,
878                  "record (or union) type expected in objc_layout_structure, got %s\n",
879                  type);
880     }
881
882   type ++;
883   layout->original_type = type;
884
885   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
886   ntype = type;
887   while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
888          && *ntype++ != '=')
889     /* do nothing */;
890
891   /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
892   if (*(ntype - 1) == '=')
893     type = ntype;
894
895   layout->type = type;
896   layout->prev_type = NULL;
897   layout->record_size = 0;
898   layout->record_align = BITS_PER_UNIT;
899
900   layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
901 }
902
903
904 BOOL
905 objc_layout_structure_next_member (struct objc_struct_layout *layout)
906 {
907   register int desired_align = 0;
908
909   /* The following are used only if the field is a bitfield */
910   register const char *bfld_type = 0;
911   register int bfld_type_size, bfld_type_align = 0, bfld_field_size = 0;
912
913   /* The current type without the type qualifiers */
914   const char *type;
915   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
916
917   /* Add the size of the previous field to the size of the record.  */
918   if (layout->prev_type)
919     {
920       type = objc_skip_type_qualifiers (layout->prev_type);
921       if (unionp)
922         layout->record_size = MAX (layout->record_size,
923                                    objc_sizeof_type (type) * BITS_PER_UNIT);
924
925       else if (*type != _C_BFLD)
926         layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
927       else {
928         /* Get the bitfield's type */
929         for (bfld_type = type + 1;
930              isdigit ((unsigned char)*bfld_type);
931              bfld_type++)
932           /* do nothing */;
933
934         bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
935         bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
936         bfld_field_size = atoi (objc_skip_typespec (bfld_type));
937         layout->record_size += bfld_field_size;
938       }
939     }
940
941   if ((unionp && *layout->type == _C_UNION_E)
942       || (!unionp && *layout->type == _C_STRUCT_E))
943     return NO;
944
945   /* Skip the variable name if any */
946   if (*layout->type == '"')
947     {
948       for (layout->type++; *layout->type++ != '"';)
949         /* do nothing */;
950     }
951
952   type = objc_skip_type_qualifiers (layout->type);
953
954   if (*type != _C_BFLD)
955     desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
956   else
957     {
958       desired_align = 1;
959       /* Skip the bitfield's offset */
960       for (bfld_type = type + 1;
961            isdigit ((unsigned char) *bfld_type);
962            bfld_type++)
963         /* do nothing */;
964
965       bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
966       bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
967       bfld_field_size = atoi (objc_skip_typespec (bfld_type));
968     }
969
970 #ifdef BIGGEST_FIELD_ALIGNMENT
971   desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
972 #endif
973 #ifdef ADJUST_FIELD_ALIGN
974   desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
975 #endif
976
977   /* Record must have at least as much alignment as any field.
978      Otherwise, the alignment of the field within the record
979      is meaningless.  */
980 #ifndef PCC_BITFIELD_TYPE_MATTERS
981   layout->record_align = MAX (layout->record_align, desired_align);
982 #else   /* PCC_BITFIELD_TYPE_MATTERS */
983   if (*type == _C_BFLD)
984     {
985       /* For these machines, a zero-length field does not
986          affect the alignment of the structure as a whole.
987          It does, however, affect the alignment of the next field
988          within the structure.  */
989       if (bfld_field_size)
990         layout->record_align = MAX (layout->record_align, desired_align);
991       else
992         desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
993
994       /* A named bit field of declared type `int'
995          forces the entire structure to have `int' alignment.
996          Q1: How is encoded this thing and how to check for it?
997          Q2: How to determine maximum_field_alignment at runtime? */
998
999 /*        if (DECL_NAME (field) != 0) */
1000       {
1001         int type_align = bfld_type_align;
1002 #if 0
1003         if (maximum_field_alignment != 0)
1004           type_align = MIN (type_align, maximum_field_alignment);
1005         else if (DECL_PACKED (field))
1006           type_align = MIN (type_align, BITS_PER_UNIT);
1007 #endif
1008
1009         layout->record_align = MAX (layout->record_align, type_align);
1010       }
1011     }
1012   else
1013     layout->record_align = MAX (layout->record_align, desired_align);
1014 #endif  /* PCC_BITFIELD_TYPE_MATTERS */
1015
1016   /* Does this field automatically have alignment it needs
1017      by virtue of the fields that precede it and the record's
1018      own alignment?  */
1019
1020   if (*type == _C_BFLD)
1021     layout->record_size = atoi (type + 1);
1022   else if (layout->record_size % desired_align != 0)
1023     {
1024       /* No, we need to skip space before this field.
1025          Bump the cumulative size to multiple of field alignment.  */
1026       layout->record_size = ROUND (layout->record_size, desired_align);
1027     }
1028
1029   /* Jump to the next field in record. */
1030
1031   layout->prev_type = layout->type;
1032   layout->type = objc_skip_typespec (layout->type);      /* skip component */
1033
1034   return YES;
1035 }
1036
1037
1038 void objc_layout_finish_structure (struct objc_struct_layout *layout,
1039                                    unsigned int *size,
1040                                    unsigned int *align)
1041 {
1042   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1043   if (layout->type
1044       && ((!unionp && *layout->type == _C_STRUCT_E)
1045           || (unionp && *layout->type == _C_UNION_E)))
1046     {
1047       /* Work out the alignment of the record as one expression and store
1048          in the record type.  Round it up to a multiple of the record's
1049          alignment. */
1050 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1051       layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1052                                                1,
1053                                                layout->record_align);
1054 #else
1055       layout->record_align = MAX (1, layout->record_align);
1056 #endif
1057
1058 #ifdef ROUND_TYPE_SIZE
1059       layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
1060                                              layout->record_size,
1061                                              layout->record_align);
1062 #else
1063       /* Round the size up to be a multiple of the required alignment */
1064       layout->record_size = ROUND (layout->record_size, layout->record_align);
1065 #endif
1066
1067       layout->type = NULL;
1068     }
1069   if (size)
1070     *size = layout->record_size / BITS_PER_UNIT;
1071   if (align)
1072     *align = layout->record_align / BITS_PER_UNIT;
1073 }
1074
1075
1076 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1077                                      unsigned int *offset,
1078                                      unsigned int *align,
1079                                      const char **type)
1080 {
1081   if (offset)
1082     *offset = layout->record_size / BITS_PER_UNIT;
1083   if (align)
1084     *align = layout->record_align / BITS_PER_UNIT;
1085   if (type)
1086     *type = layout->prev_type;
1087 }