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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [objc-obj-c++-shared/] [objc-test-suite-next-encode-assist-impl.h] - Blame information for rev 705

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 705 jeremybenn
#ifndef _OBJC_TEST_SUITE_NEXT_ENCODE_ASSIST_IMPL_H_
2
#define _OBJC_TEST_SUITE_NEXT_ENCODE_ASSIST_IMPL_H_
3
 
4
#ifdef __NEXT_RUNTIME__
5
 
6
/* Determine which API to use.  */
7
#include "next-abi.h"
8
#ifdef NEXT_OBJC_USE_NEW_INTERFACE
9
#include <objc/runtime.h>
10
#else
11
#include <objc/objc-runtime.h>
12
#endif
13
 
14
/* ---- */
15
 
16
#undef  MAX
17
#undef  MIN
18
#undef  ROUND
19
 
20
#ifdef __cplusplus
21
#  define MAX(X, Y) ((X > Y) ? X : Y)
22
#  define MIN(X, Y) ((X < Y) ? X : Y)
23
#  define ROUND(V, A) (A * ((V + A - 1) / A))
24
#else
25
#  define MAX(X, Y)                    \
26
  ({ typeof (X) __x = (X), __y = (Y); \
27
     (__x > __y ? __x : __y); })
28
#  define MIN(X, Y)                    \
29
  ({ typeof (X) __x = (X), __y = (Y); \
30
     (__x < __y ? __x : __y); })
31
#  define ROUND(V, A) \
32
  ({ typeof (V) __v = (V); typeof (A) __a = (A); \
33
     __a * ((__v+__a - 1)/__a); })
34
#endif
35
 
36
#define BITS_PER_UNIT __CHAR_BIT__
37
typedef struct{ char a; } __small_struct;
38
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (__small_struct))
39
 
40
/*
41
  return the size of an object specified by type
42
*/
43
 
44
int
45
objc_sizeof_type (const char *type)
46
{
47
  /* Skip the variable name if any */
48
  if (*type == '"')
49
    {
50
      for (type++; *type++ != '"';)
51
        /* do nothing */;
52
    }
53
 
54
  switch (*type) {
55
  case _C_ID:
56
    return sizeof (id);
57
    break;
58
 
59
  case _C_CLASS:
60
    return sizeof (Class);
61
    break;
62
 
63
  case _C_SEL:
64
    return sizeof (SEL);
65
    break;
66
 
67
  case _C_CHR:
68
    return sizeof (char);
69
    break;
70
 
71
  case _C_UCHR:
72
    return sizeof (unsigned char);
73
    break;
74
 
75
  case _C_SHT:
76
    return sizeof (short);
77
    break;
78
 
79
  case _C_USHT:
80
    return sizeof (unsigned short);
81
    break;
82
 
83
  case _C_INT:
84
    return sizeof (int);
85
    break;
86
 
87
  case _C_UINT:
88
    return sizeof (unsigned int);
89
    break;
90
 
91
  case _C_LNG:
92
    return sizeof (long);
93
    break;
94
 
95
  case _C_ULNG:
96
    return sizeof (unsigned long);
97
    break;
98
 
99
  case _C_LNG_LNG:
100
    return sizeof (long long);
101
    break;
102
 
103
  case _C_ULNG_LNG:
104
    return sizeof (unsigned long long);
105
    break;
106
 
107
  case _C_FLT:
108
    return sizeof (float);
109
    break;
110
 
111
  case _C_DBL:
112
    return sizeof (double);
113
    break;
114
 
115
  case _C_PTR:
116
  case _C_ATOM:
117
  case _C_CHARPTR:
118
    return sizeof (char *);
119
    break;
120
 
121
  case _C_ARY_B:
122
    {
123
      int len = atoi (type + 1);
124
      while (isdigit ((unsigned char)*++type))
125
        ;
126
      return len * objc_aligned_size (type);
127
    }
128
    break;
129
 
130
  case _C_BFLD:
131
    {
132
      /* The NeXT encoding of bitfields is _still_: b 'size' */
133
      int size = atoi (type + 1);
134
      /* Return an upper bound on byte size */
135
      return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
136
    }
137
 
138
  case _C_STRUCT_B:
139
    {
140
      struct objc_struct_layout layout;
141
      unsigned int size;
142
 
143
      objc_layout_structure (type, &layout);
144
      while (objc_layout_structure_next_member (&layout))
145
        /* do nothing */ ;
146
      objc_layout_finish_structure (&layout, &size, NULL);
147
 
148
      return size;
149
    }
150
 
151
  case _C_UNION_B:
152
    {
153
      int max_size = 0;
154
      while (*type != _C_UNION_E && *type++ != '=')
155
        /* do nothing */;
156
      while (*type != _C_UNION_E)
157
        {
158
          /* Skip the variable name if any */
159
          if (*type == '"')
160
            {
161
              for (type++; *type++ != '"';)
162
                /* do nothing */;
163
            }
164
          max_size = MAX (max_size, objc_sizeof_type (type));
165
          type = objc_skip_typespec (type);
166
        }
167
      return max_size;
168
    }
169
  }
170
  return 0; /* error */
171
}
172
 
173
 
174
/*
175
  Return the alignment of an object specified by type
176
*/
177
 
178
int
179
objc_alignof_type (const char *type)
180
{
181
  /* Skip the variable name if any */
182
  if (*type == '"')
183
    {
184
      for (type++; *type++ != '"';)
185
        /* do nothing */;
186
    }
187
  switch (*type) {
188
  case _C_ID:
189
    return __alignof__ (id);
190
    break;
191
 
192
  case _C_CLASS:
193
    return __alignof__ (Class);
194
    break;
195
 
196
  case _C_SEL:
197
    return __alignof__ (SEL);
198
    break;
199
 
200
  case _C_CHR:
201
    return __alignof__ (char);
202
    break;
203
 
204
  case _C_UCHR:
205
    return __alignof__ (unsigned char);
206
    break;
207
 
208
  case _C_SHT:
209
    return __alignof__ (short);
210
    break;
211
 
212
  case _C_USHT:
213
    return __alignof__ (unsigned short);
214
    break;
215
 
216
  case _C_INT:
217
  case _C_BFLD: /* This is for the NeXT only */
218
    return __alignof__ (int);
219
    break;
220
 
221
  case _C_UINT:
222
    return __alignof__ (unsigned int);
223
    break;
224
 
225
  case _C_LNG:
226
    return __alignof__ (long);
227
    break;
228
 
229
  case _C_ULNG:
230
    return __alignof__ (unsigned long);
231
    break;
232
 
233
  case _C_LNG_LNG:
234
    return __alignof__ (long long);
235
    break;
236
 
237
  case _C_ULNG_LNG:
238
    return __alignof__ (unsigned long long);
239
    break;
240
 
241
  case _C_FLT:
242
    return __alignof__ (float);
243
    break;
244
 
245
  case _C_DBL:
246
    return __alignof__ (double);
247
    break;
248
 
249
  case _C_PTR:
250
  case _C_ATOM:
251
  case _C_CHARPTR:
252
    return __alignof__ (char *);
253
    break;
254
 
255
  case _C_ARY_B:
256
    while (isdigit ((unsigned char)*++type))
257
      /* do nothing */;
258
    return objc_alignof_type (type);
259
 
260
  case _C_STRUCT_B:
261
    {
262
      struct objc_struct_layout layout;
263
      unsigned int align;
264
 
265
      objc_layout_structure (type, &layout);
266
      while (objc_layout_structure_next_member (&layout))
267
        /* do nothing */;
268
      objc_layout_finish_structure (&layout, NULL, &align);
269
 
270
      return align;
271
    }
272
 
273
  case _C_UNION_B:
274
    {
275
      int maxalign = 0;
276
      while (*type != _C_UNION_E && *type++ != '=')
277
        /* do nothing */;
278
      while (*type != _C_UNION_E)
279
        {
280
          /* Skip the variable name if any */
281
          if (*type == '"')
282
            {
283
              for (type++; *type++ != '"';)
284
                /* do nothing */;
285
            }
286
          maxalign = MAX (maxalign, objc_alignof_type (type));
287
          type = objc_skip_typespec (type);
288
        }
289
      return maxalign;
290
    }
291
  }
292
  return 0; /* error */
293
}
294
 
295
/*
296
  The aligned size if the size rounded up to the nearest alignment.
297
*/
298
 
299
int
300
objc_aligned_size (const char *type)
301
{
302
  int size, align;
303
 
304
  /* Skip the variable name */
305
  if (*type == '"')
306
    {
307
      for (type++; *type++ != '"';)
308
        /* do nothing */;
309
    }
310
 
311
  size = objc_sizeof_type (type);
312
  align = objc_alignof_type (type);
313
 
314
  return ROUND (size, align);
315
}
316
 
317
/*
318
  The size rounded up to the nearest integral of the wordsize, taken
319
  to be the size of a void *.
320
*/
321
 
322
int
323
objc_promoted_size (const char *type)
324
{
325
  int size, wordsize;
326
 
327
  /* Skip the variable name */
328
  if (*type == '"')
329
    {
330
      for (type++; *type++ != '"';)
331
        /* do nothing */;
332
    }
333
 
334
  size = objc_sizeof_type (type);
335
  wordsize = sizeof (void *);
336
 
337
  return ROUND (size, wordsize);
338
}
339
 
340
/*
341
  Skip type qualifiers.  These may eventually precede typespecs
342
  occurring in method prototype encodings.
343
*/
344
 
345
const char *
346
objc_skip_type_qualifiers (const char *type)
347
{
348
  while (*type == _C_CONST
349
         || *type == _C_IN
350
         || *type == _C_INOUT
351
         || *type == _C_OUT
352
         || *type == _C_BYCOPY
353
         || *type == _C_BYREF
354
         || *type == _C_ONEWAY
355
         || *type == _C_GCINVISIBLE)
356
    {
357
      type += 1;
358
    }
359
  return type;
360
}
361
 
362
/*
363
  Skip one typespec element.  If the typespec is prepended by type
364
  qualifiers, these are skipped as well.
365
*/
366
 
367
const char *
368
objc_skip_typespec (const char *type)
369
{
370
  /* Skip the variable name if any */
371
  if (*type == '"')
372
    {
373
      for (type++; *type++ != '"';)
374
        /* do nothing */;
375
    }
376
 
377
  type = objc_skip_type_qualifiers (type);
378
 
379
  switch (*type) {
380
 
381
  case _C_ID:
382
    /* An id may be annotated by the actual type if it is known
383
       with the @"ClassName" syntax */
384
 
385
    if (*++type != '"')
386
      return type;
387
    else
388
      {
389
        while (*++type != '"')
390
          /* do nothing */;
391
        return type + 1;
392
      }
393
 
394
    /* The following are one character type codes */
395
  case _C_CLASS:
396
  case _C_SEL:
397
  case _C_CHR:
398
  case _C_UCHR:
399
  case _C_CHARPTR:
400
  case _C_ATOM:
401
  case _C_SHT:
402
  case _C_USHT:
403
  case _C_INT:
404
  case _C_UINT:
405
  case _C_LNG:
406
  case _C_ULNG:
407
  case _C_LNG_LNG:
408
  case _C_ULNG_LNG:
409
  case _C_FLT:
410
  case _C_DBL:
411
  case _C_VOID:
412
  case _C_UNDEF:
413
    return ++type;
414
    break;
415
 
416
  case _C_ARY_B:
417
    /* skip digits, typespec and closing ']' */
418
 
419
    while (isdigit ((unsigned char)*++type))
420
      ;
421
    type = objc_skip_typespec (type);
422
    if (*type == _C_ARY_E)
423
      return ++type;
424
    else
425
      break; /* error */
426
 
427
  case _C_BFLD:
428
      /* The NeXT encoding for bitfields is _still_: b 'size' */
429
    while (isdigit ((unsigned char)*++type))
430
      ; /* skip type and size */
431
    return type;
432
 
433
  case _C_STRUCT_B:
434
    /* skip name, and elements until closing '}'  */
435
 
436
    while (*type != _C_STRUCT_E && *type++ != '=')
437
      ;
438
    while (*type != _C_STRUCT_E)
439
      {
440
        type = objc_skip_typespec (type);
441
      }
442
    return ++type;
443
 
444
  case _C_UNION_B:
445
    /* skip name, and elements until closing ')'  */
446
 
447
    while (*type != _C_UNION_E && *type++ != '=')
448
      ;
449
    while (*type != _C_UNION_E)
450
      {
451
        type = objc_skip_typespec (type);
452
      }
453
    return ++type;
454
 
455
  case _C_PTR:
456
    /* Just skip the following typespec */
457
 
458
    return objc_skip_typespec (++type);
459
  }
460
  return 0; /* error */
461
}
462
 
463
/*
464
  Skip an offset as part of a method encoding.  This is prepended by a
465
  '+' if the argument is passed in registers.
466
*/
467
const char *
468
objc_skip_offset (const char *type)
469
{
470
  if (*type == '+')
471
    type++;
472
  while (isdigit ((unsigned char) *++type))
473
    ;
474
  return type;
475
}
476
 
477
/*
478
  Skip an argument specification of a method encoding.
479
*/
480
const char *
481
objc_skip_argspec (const char *type)
482
{
483
  type = objc_skip_typespec (type);
484
  type = objc_skip_offset (type);
485
  return type;
486
}
487
 
488
unsigned
489
objc_get_type_qualifiers (const char *type)
490
{
491
  unsigned res = 0;
492
  BOOL flag = YES;
493
 
494
  while (flag)
495
    switch (*type++)
496
      {
497
      case _C_CONST:    res |= _F_CONST; break;
498
      case _C_IN:       res |= _F_IN; break;
499
      case _C_INOUT:    res |= _F_INOUT; break;
500
      case _C_OUT:      res |= _F_OUT; break;
501
      case _C_BYCOPY:   res |= _F_BYCOPY; break;
502
      case _C_BYREF:  res |= _F_BYREF; break;
503
      case _C_ONEWAY:   res |= _F_ONEWAY; break;
504
      case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
505
      default: flag = NO;
506
    }
507
 
508
  return res;
509
}
510
 
511
 
512
/* The following three functions can be used to determine how a
513
   structure is laid out by the compiler. For example:
514
 
515
  struct objc_struct_layout layout;
516
  int i;
517
 
518
  objc_layout_structure (type, &layout);
519
  while (objc_layout_structure_next_member (&layout))
520
    {
521
      int position, align;
522
      const char *type;
523
 
524
      objc_layout_structure_get_info (&layout, &position, &align, &type);
525
      printf ("element %d has offset %d, alignment %d\n",
526
              i++, position, align);
527
    }
528
 
529
  These functions are used by objc_sizeof_type and objc_alignof_type
530
  functions to compute the size and alignment of structures. The
531
  previous method of computing the size and alignment of a structure
532
  was not working on some architectures, particulary on AIX, and in
533
  the presence of bitfields inside the structure. */
534
void
535
objc_layout_structure (const char *type,
536
                           struct objc_struct_layout *layout)
537
{
538
  const char *ntype;
539
 
540
  layout->original_type = ++type;
541
 
542
  /* Skip "<name>=" if any. Avoid embedded structures and unions. */
543
  ntype = type;
544
  while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
545
         && *ntype++ != '=')
546
    /* do nothing */;
547
 
548
  /* If there's a "<name>=", ntype - 1 points to '='; skip the name */
549
  if (*(ntype - 1) == '=')
550
    type = ntype;
551
 
552
  layout->type = type;
553
  layout->prev_type = NULL;
554
  layout->record_size = 0;
555
  layout->record_align = MAX (BITS_PER_UNIT, STRUCTURE_SIZE_BOUNDARY);
556
}
557
 
558
BOOL
559
objc_layout_structure_next_member (struct objc_struct_layout *layout)
560
{
561
  register int desired_align = 0;
562
 
563
  /* The current type without the type qualifiers */
564
  const char *type;
565
 
566
  /* Add the size of the previous field to the size of the record.  */
567
  if (layout->prev_type)
568
    {
569
      type = objc_skip_type_qualifiers (layout->prev_type);
570
 
571
      if (*type != _C_BFLD)
572
        layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
573
      else
574
        layout->record_size += atoi (++type);
575
    }
576
 
577
  if (*layout->type == _C_STRUCT_E)
578
    return NO;
579
 
580
  /* Skip the variable name if any */
581
  if (*layout->type == '"')
582
    {
583
      for (layout->type++; *layout->type++ != '"';)
584
        /* do nothing */;
585
    }
586
 
587
  type = objc_skip_type_qualifiers (layout->type);
588
 
589
  desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
590
 
591
  /* Record must have at least as much alignment as any field.
592
     Otherwise, the alignment of the field within the record
593
     is meaningless.  */
594
  layout->record_align = MAX (layout->record_align, desired_align);
595
 
596
  if (*type == _C_BFLD)
597
    {
598
      int bfld_size = atoi (++type);
599
      int int_align = __alignof__ (int) * BITS_PER_UNIT;
600
      /* If this bitfield would traverse a word alignment boundary, push it out
601
         to that boundary instead.  */
602
      if (layout->record_size % int_align
603
          && (layout->record_size / int_align
604
              < (layout->record_size + bfld_size - 1) / int_align))
605
        layout->record_size = ROUND (layout->record_size, int_align);
606
    }
607
  else if (layout->record_size % desired_align != 0)
608
    {
609
      /* We need to skip space before this field.
610
         Bump the cumulative size to multiple of field alignment.  */
611
      layout->record_size = ROUND (layout->record_size, desired_align);
612
    }
613
 
614
  /* Jump to the next field in record. */
615
 
616
  layout->prev_type = layout->type;
617
  layout->type = objc_skip_typespec (layout->type);      /* skip component */
618
 
619
  return YES;
620
}
621
 
622
 
623
void objc_layout_finish_structure (struct objc_struct_layout *layout,
624
                                   unsigned int *size,
625
                                   unsigned int *align)
626
{
627
  if (layout->type && *layout->type == _C_STRUCT_E)
628
    {
629
      /* Round the size up to be a multiple of the required alignment */
630
      layout->record_size = ROUND (layout->record_size, layout->record_align);
631
      layout->type = NULL;
632
    }
633
  if (size)
634
    *size = layout->record_size / BITS_PER_UNIT;
635
  if (align)
636
    *align = layout->record_align / BITS_PER_UNIT;
637
}
638
 
639
 
640
void objc_layout_structure_get_info (struct objc_struct_layout *layout,
641
                                     unsigned int *offset,
642
                                     unsigned int *align,
643
                                     const char **type)
644
{
645
  if (offset)
646
    *offset = layout->record_size / BITS_PER_UNIT;
647
  if (align)
648
    *align = layout->record_align / BITS_PER_UNIT;
649
  if (type)
650
    *type = layout->prev_type;
651
}
652
 
653
#endif /* __NEXT_RUNTIME__ */
654
#endif /* _OBJC_TEST_SUITE_NEXT_ENCODE_ASSIST_IMPL_H_ */

powered by: WebSVN 2.1.0

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