OSDN Git Service

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