OSDN Git Service

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