source: trunk/third/gcc/libobjc/encoding.c @ 21199

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