OSDN Git Service

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