OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libobjc/] [encoding.c] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.