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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [testsuite/] [objc/] [execute/] [next_mapping.h] - Blame information for rev 862

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 307 jeremybenn
/* This file "renames" various ObjC GNU runtime entry points
2
   (and fakes the existence of several others)
3
   if the NeXT runtime is being used.  */
4
/* Authors: Ziemowit Laski <zlaski@apple.com>  */
5
/*          David Ayers <d.ayers@inode.at>  */
6
 
7
#ifdef __NEXT_RUNTIME__
8
#include <objc/objc-class.h>
9
#include <objc/Object.h>
10
#include <ctype.h>
11
#include <stdlib.h>
12
#include <string.h>
13
 
14
#define objc_get_class(C)                       objc_getClass(C)
15
#define objc_get_meta_class(C)                  objc_getMetaClass(C)
16
#define class_get_class_method(C, S)            class_getClassMethod(C, S)
17
#define class_get_instance_method(C, S)         class_getInstanceMethod(C, S)
18
#define method_get_imp(M)                       (((Method)M)->method_imp)
19
#define sel_get_name(S)                         sel_getName(S)
20
#define class_create_instance(C)                class_createInstance(C, 0)
21
#define class_get_class_name(C)                 object_getClassName(C)
22
#define class_get_super_class(C)                (((struct objc_class *)C)->super_class)
23
#define object_get_super_class(O)               class_get_super_class(*(struct objc_class **)O)
24
#define objc_lookup_class(N)                    objc_lookUpClass(N)
25
#define object_get_class(O)                     (*(struct objc_class **)O)
26
#define class_is_class(C)                       (CLS_GETINFO((struct objc_class *)C, CLS_CLASS)? YES: NO)
27
#define class_is_meta_class(C)                  (CLS_GETINFO((struct objc_class *)C, CLS_META)? YES: NO)
28
#define object_is_class(O)                      class_is_meta_class(*(struct objc_class **)O)
29
#define object_is_meta_class(O)                 (class_is_meta_class(O) && class_is_meta_class(*(struct objc_class **)O))
30
 
31
/* You need either an empty +initialize method or an empty -forward:: method.
32
   The NeXT runtime unconditionally sends +initialize to classes when they are
33
   first used, and unconditionally tries to forward methods that the class
34
   doesn't understand (including +initialize). If you have neither +initialize
35
   nor -forward::, the runtime complains.
36
 
37
   The simplest workaround is to add
38
 
39
      + initialize { return self; }
40
 
41
   to every root class @implementation.  */
42
 
43
#ifndef NULL
44
#define NULL 0
45
#endif
46
 
47
/* The following is necessary to "cover" the bf*.m test cases on NeXT.  */
48
 
49
#undef  MAX
50
#undef  MIN
51
#undef  ROUND
52
 
53
#ifdef __cplusplus
54
#define MAX(X, Y) ((X > Y) ? X : Y)
55
#define MIN(X, Y) ((X < Y) ? X : Y)
56
#define ROUND(V, A) (A * ((V + A - 1) / A))
57
#else
58
#define MAX(X, Y)                    \
59
  ({ typeof (X) __x = (X), __y = (Y); \
60
     (__x > __y ? __x : __y); })
61
#define MIN(X, Y)                    \
62
  ({ typeof (X) __x = (X), __y = (Y); \
63
     (__x < __y ? __x : __y); })
64
#define ROUND(V, A) \
65
  ({ typeof (V) __v = (V); typeof (A) __a = (A); \
66
     __a * ((__v+__a - 1)/__a); })
67
#endif
68
 
69
#define BITS_PER_UNIT __CHAR_BIT__
70
typedef struct{ char a; } __small_struct;
71
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (__small_struct))
72
 
73
/* Not sure why the following are missing from NeXT objc headers... */
74
 
75
#ifndef _C_LNG_LNG
76
#define _C_LNG_LNG  'q'
77
#endif
78
#ifndef _C_ULNG_LNG
79
#define _C_ULNG_LNG 'Q'
80
#endif
81
#ifndef _C_ATOM
82
#define _C_ATOM     '%'
83
#endif
84
#ifndef _C_BOOL
85
#define _C_BOOL     'B'
86
#endif
87
 
88
#define _C_CONST        'r'
89
#define _C_IN           'n'
90
#define _C_INOUT        'N'
91
#define _C_OUT          'o'
92
#define _C_BYCOPY       'O'
93
#define _C_BYREF        'R'
94
#define _C_ONEWAY       'V'
95
#define _C_GCINVISIBLE  '!'
96
 
97
#define _F_CONST        0x01
98
#define _F_IN           0x01
99
#define _F_OUT          0x02
100
#define _F_INOUT        0x03
101
#define _F_BYCOPY       0x04  
102
#define _F_BYREF        0x08  
103
#define _F_ONEWAY       0x10
104
#define _F_GCINVISIBLE  0x20
105
 
106
struct objc_struct_layout
107
{
108
  const char *original_type;
109
  const char *type;
110
  const char *prev_type;
111
  unsigned int record_size;
112
  unsigned int record_align;
113
};
114
 
115
typedef union arglist {
116
  char *arg_ptr;
117
  char arg_regs[sizeof (char*)];
118
} *arglist_t;                   /* argument frame */
119
 
120
const char *objc_skip_typespec (const char *type);
121
void objc_layout_structure_get_info (struct objc_struct_layout *layout,
122
    unsigned int *offset, unsigned int *align, const char **type);
123
void objc_layout_structure (const char *type,
124
    struct objc_struct_layout *layout);
125
BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
126
void objc_layout_finish_structure (struct objc_struct_layout *layout,
127
    unsigned int *size, unsigned int *align);
128
int objc_aligned_size (const char *type);
129
 
130
/*
131
  return the size of an object specified by type
132
*/
133
 
134
int
135
objc_sizeof_type (const char *type)
136
{
137
  /* Skip the variable name if any */
138
  if (*type == '"')
139
    {
140
      for (type++; *type++ != '"';)
141
        /* do nothing */;
142
    }
143
 
144
  switch (*type) {
145
  case _C_ID:
146
    return sizeof (id);
147
    break;
148
 
149
  case _C_CLASS:
150
    return sizeof (Class);
151
    break;
152
 
153
  case _C_SEL:
154
    return sizeof (SEL);
155
    break;
156
 
157
  case _C_CHR:
158
    return sizeof (char);
159
    break;
160
 
161
  case _C_UCHR:
162
    return sizeof (unsigned char);
163
    break;
164
 
165
  case _C_SHT:
166
    return sizeof (short);
167
    break;
168
 
169
  case _C_USHT:
170
    return sizeof (unsigned short);
171
    break;
172
 
173
  case _C_INT:
174
    return sizeof (int);
175
    break;
176
 
177
  case _C_UINT:
178
    return sizeof (unsigned int);
179
    break;
180
 
181
  case _C_LNG:
182
    return sizeof (long);
183
    break;
184
 
185
  case _C_ULNG:
186
    return sizeof (unsigned long);
187
    break;
188
 
189
  case _C_LNG_LNG:
190
    return sizeof (long long);
191
    break;
192
 
193
  case _C_ULNG_LNG:
194
    return sizeof (unsigned long long);
195
    break;
196
 
197
  case _C_FLT:
198
    return sizeof (float);
199
    break;
200
 
201
  case _C_DBL:
202
    return sizeof (double);
203
    break;
204
 
205
  case _C_PTR:
206
  case _C_ATOM:
207
  case _C_CHARPTR:
208
    return sizeof (char *);
209
    break;
210
 
211
  case _C_ARY_B:
212
    {
213
      int len = atoi (type + 1);
214
      while (isdigit ((unsigned char)*++type))
215
        ;
216
      return len * objc_aligned_size (type);
217
    }
218
    break;
219
 
220
  case _C_BFLD:
221
    {
222
      /* The NeXT encoding of bitfields is _still_: b 'size' */
223
      int size = atoi (type + 1);
224
      /* Return an upper bound on byte size */
225
      return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
226
    }
227
 
228
  case _C_STRUCT_B:
229
    {
230
      struct objc_struct_layout layout;
231
      unsigned int size;
232
 
233
      objc_layout_structure (type, &layout);
234
      while (objc_layout_structure_next_member (&layout))
235
        /* do nothing */ ;
236
      objc_layout_finish_structure (&layout, &size, NULL);
237
 
238
      return size;
239
    }
240
 
241
  case _C_UNION_B:
242
    {
243
      int max_size = 0;
244
      while (*type != _C_UNION_E && *type++ != '=')
245
        /* do nothing */;
246
      while (*type != _C_UNION_E)
247
        {
248
          /* Skip the variable name if any */
249
          if (*type == '"')
250
            {
251
              for (type++; *type++ != '"';)
252
                /* do nothing */;
253
            }
254
          max_size = MAX (max_size, objc_sizeof_type (type));
255
          type = objc_skip_typespec (type);
256
        }
257
      return max_size;
258
    }
259
  }
260
  return 0; /* error */
261
}
262
 
263
 
264
/*
265
  Return the alignment of an object specified by type
266
*/
267
 
268
int
269
objc_alignof_type (const char *type)
270
{
271
  /* Skip the variable name if any */
272
  if (*type == '"')
273
    {
274
      for (type++; *type++ != '"';)
275
        /* do nothing */;
276
    }
277
  switch (*type) {
278
  case _C_ID:
279
    return __alignof__ (id);
280
    break;
281
 
282
  case _C_CLASS:
283
    return __alignof__ (Class);
284
    break;
285
 
286
  case _C_SEL:
287
    return __alignof__ (SEL);
288
    break;
289
 
290
  case _C_CHR:
291
    return __alignof__ (char);
292
    break;
293
 
294
  case _C_UCHR:
295
    return __alignof__ (unsigned char);
296
    break;
297
 
298
  case _C_SHT:
299
    return __alignof__ (short);
300
    break;
301
 
302
  case _C_USHT:
303
    return __alignof__ (unsigned short);
304
    break;
305
 
306
  case _C_INT:
307
  case _C_BFLD: /* This is for the NeXT only */
308
    return __alignof__ (int);
309
    break;
310
 
311
  case _C_UINT:
312
    return __alignof__ (unsigned int);
313
    break;
314
 
315
  case _C_LNG:
316
    return __alignof__ (long);
317
    break;
318
 
319
  case _C_ULNG:
320
    return __alignof__ (unsigned long);
321
    break;
322
 
323
  case _C_LNG_LNG:
324
    return __alignof__ (long long);
325
    break;
326
 
327
  case _C_ULNG_LNG:
328
    return __alignof__ (unsigned long long);
329
    break;
330
 
331
  case _C_FLT:
332
    return __alignof__ (float);
333
    break;
334
 
335
  case _C_DBL:
336
    return __alignof__ (double);
337
    break;
338
 
339
  case _C_PTR:
340
  case _C_ATOM:
341
  case _C_CHARPTR:
342
    return __alignof__ (char *);
343
    break;
344
 
345
  case _C_ARY_B:
346
    while (isdigit ((unsigned char)*++type))
347
      /* do nothing */;
348
    return objc_alignof_type (type);
349
 
350
  case _C_STRUCT_B:
351
    {
352
      struct objc_struct_layout layout;
353
      unsigned int align;
354
 
355
      objc_layout_structure (type, &layout);
356
      while (objc_layout_structure_next_member (&layout))
357
        /* do nothing */;
358
      objc_layout_finish_structure (&layout, NULL, &align);
359
 
360
      return align;
361
    }
362
 
363
  case _C_UNION_B:
364
    {
365
      int maxalign = 0;
366
      while (*type != _C_UNION_E && *type++ != '=')
367
        /* do nothing */;
368
      while (*type != _C_UNION_E)
369
        {
370
          /* Skip the variable name if any */
371
          if (*type == '"')
372
            {
373
              for (type++; *type++ != '"';)
374
                /* do nothing */;
375
            }
376
          maxalign = MAX (maxalign, objc_alignof_type (type));
377
          type = objc_skip_typespec (type);
378
        }
379
      return maxalign;
380
    }
381
  }
382
  return 0; /* error */
383
}
384
 
385
/*
386
  The aligned size if the size rounded up to the nearest alignment.
387
*/
388
 
389
int
390
objc_aligned_size (const char *type)
391
{
392
  int size, align;
393
 
394
  /* Skip the variable name */
395
  if (*type == '"')
396
    {
397
      for (type++; *type++ != '"';)
398
        /* do nothing */;
399
    }
400
 
401
  size = objc_sizeof_type (type);
402
  align = objc_alignof_type (type);
403
 
404
  return ROUND (size, align);
405
}
406
 
407
/*
408
  The size rounded up to the nearest integral of the wordsize, taken
409
  to be the size of a void *.
410
*/
411
 
412
int
413
objc_promoted_size (const char *type)
414
{
415
  int size, wordsize;
416
 
417
  /* Skip the variable name */
418
  if (*type == '"')
419
    {
420
      for (type++; *type++ != '"';)
421
        /* do nothing */;
422
    }
423
 
424
  size = objc_sizeof_type (type);
425
  wordsize = sizeof (void *);
426
 
427
  return ROUND (size, wordsize);
428
}
429
 
430
/*
431
  Skip type qualifiers.  These may eventually precede typespecs
432
  occurring in method prototype encodings.
433
*/
434
 
435
inline const char *
436
objc_skip_type_qualifiers (const char *type)
437
{
438
  while (*type == _C_CONST
439
         || *type == _C_IN
440
         || *type == _C_INOUT
441
         || *type == _C_OUT
442
         || *type == _C_BYCOPY
443
         || *type == _C_BYREF
444
         || *type == _C_ONEWAY
445
         || *type == _C_GCINVISIBLE)
446
    {
447
      type += 1;
448
    }
449
  return type;
450
}
451
 
452
 
453
/*
454
  Skip one typespec element.  If the typespec is prepended by type
455
  qualifiers, these are skipped as well.
456
*/
457
 
458
const char *
459
objc_skip_typespec (const char *type)
460
{
461
  /* Skip the variable name if any */
462
  if (*type == '"')
463
    {
464
      for (type++; *type++ != '"';)
465
        /* do nothing */;
466
    }
467
 
468
  type = objc_skip_type_qualifiers (type);
469
 
470
  switch (*type) {
471
 
472
  case _C_ID:
473
    /* An id may be annotated by the actual type if it is known
474
       with the @"ClassName" syntax */
475
 
476
    if (*++type != '"')
477
      return type;
478
    else
479
      {
480
        while (*++type != '"')
481
          /* do nothing */;
482
        return type + 1;
483
      }
484
 
485
    /* The following are one character type codes */
486
  case _C_CLASS:
487
  case _C_SEL:
488
  case _C_CHR:
489
  case _C_UCHR:
490
  case _C_CHARPTR:
491
  case _C_ATOM:
492
  case _C_SHT:
493
  case _C_USHT:
494
  case _C_INT:
495
  case _C_UINT:
496
  case _C_LNG:
497
  case _C_ULNG:
498
  case _C_LNG_LNG:
499
  case _C_ULNG_LNG:
500
  case _C_FLT:
501
  case _C_DBL:
502
  case _C_VOID:
503
  case _C_UNDEF:
504
    return ++type;
505
    break;
506
 
507
  case _C_ARY_B:
508
    /* skip digits, typespec and closing ']' */
509
 
510
    while (isdigit ((unsigned char)*++type))
511
      ;
512
    type = objc_skip_typespec (type);
513
    if (*type == _C_ARY_E)
514
      return ++type;
515
    else
516
      break; /* error */
517
 
518
  case _C_BFLD:
519
      /* The NeXT encoding for bitfields is _still_: b 'size' */
520
    while (isdigit ((unsigned char)*++type))
521
      ; /* skip type and size */
522
    return type;
523
 
524
  case _C_STRUCT_B:
525
    /* skip name, and elements until closing '}'  */
526
 
527
    while (*type != _C_STRUCT_E && *type++ != '=')
528
      ;
529
    while (*type != _C_STRUCT_E)
530
      {
531
        type = objc_skip_typespec (type);
532
      }
533
    return ++type;
534
 
535
  case _C_UNION_B:
536
    /* skip name, and elements until closing ')'  */
537
 
538
    while (*type != _C_UNION_E && *type++ != '=')
539
      ;
540
    while (*type != _C_UNION_E)
541
      {
542
        type = objc_skip_typespec (type);
543
      }
544
    return ++type;
545
 
546
  case _C_PTR:
547
    /* Just skip the following typespec */
548
 
549
    return objc_skip_typespec (++type);
550
  }
551
  return 0; /* error */
552
}
553
 
554
/*
555
  Skip an offset as part of a method encoding.  This is prepended by a
556
  '+' if the argument is passed in registers.
557
*/
558
inline const char *
559
objc_skip_offset (const char *type)
560
{
561
  if (*type == '+')
562
    type++;
563
  while (isdigit ((unsigned char) *++type))
564
    ;
565
  return type;
566
}
567
 
568
/*
569
  Skip an argument specification of a method encoding.
570
*/
571
const char *
572
objc_skip_argspec (const char *type)
573
{
574
  type = objc_skip_typespec (type);
575
  type = objc_skip_offset (type);
576
  return type;
577
}
578
 
579
/*
580
  Return the number of arguments that the method MTH expects.
581
  Note that all methods need two implicit arguments `self' and
582
  `_cmd'.
583
*/
584
int
585
method_get_number_of_arguments (struct objc_method *mth)
586
{
587
  int i = 0;
588
  const char *type = mth->method_types;
589
  while (*type)
590
    {
591
      type = objc_skip_argspec (type);
592
      i += 1;
593
    }
594
  return i - 1;
595
}
596
 
597
/*
598
  Return the size of the argument block needed on the stack to invoke
599
  the method MTH.  This may be zero, if all arguments are passed in
600
  registers.
601
*/
602
 
603
int
604
method_get_sizeof_arguments (struct objc_method *mth)
605
{
606
  const char *type = objc_skip_typespec (mth->method_types);
607
  return atoi (type);
608
}
609
 
610
/*
611
  Return a pointer to the next argument of ARGFRAME.  type points to
612
  the last argument.  Typical use of this look like:
613
 
614
  {
615
    char *datum, *type;
616
    for (datum = method_get_first_argument (method, argframe, &type);
617
         datum; datum = method_get_next_argument (argframe, &type))
618
      {
619
        unsigned flags = objc_get_type_qualifiers (type);
620
        type = objc_skip_type_qualifiers (type);
621
        if (*type != _C_PTR)
622
          [portal encodeData: datum ofType: type];
623
        else
624
          {
625
            if ((flags & _F_IN) == _F_IN)
626
              [portal encodeData: *(char **) datum ofType: ++type];
627
          }
628
      }
629
  }
630
*/
631
 
632
char *
633
method_get_next_argument (arglist_t argframe, const char **type)
634
{
635
  const char *t = objc_skip_argspec (*type);
636
 
637
  if (*t == '\0')
638
    return 0;
639
 
640
  *type = t;
641
  t = objc_skip_typespec (t);
642
 
643
  if (*t == '+')
644
    return argframe->arg_regs + atoi (++t);
645
  else
646
    return argframe->arg_ptr + atoi (t);
647
}
648
 
649
/*
650
  Return a pointer to the value of the first argument of the method
651
  described in M with the given argumentframe ARGFRAME.  The type
652
  is returned in TYPE.  type must be passed to successive calls of
653
  method_get_next_argument.
654
*/
655
char *
656
method_get_first_argument (struct objc_method *m,
657
                           arglist_t argframe,
658
                           const char **type)
659
{
660
  *type = m->method_types;
661
  return method_get_next_argument (argframe, type);
662
}
663
 
664
/*
665
   Return a pointer to the ARGth argument of the method
666
   M from the frame ARGFRAME.  The type of the argument
667
   is returned in the value-result argument TYPE
668
*/
669
 
670
char *
671
method_get_nth_argument (struct objc_method *m,
672
                         arglist_t argframe, int arg,
673
                         const char **type)
674
{
675
  const char *t = objc_skip_argspec (m->method_types);
676
 
677
  if (arg > method_get_number_of_arguments (m))
678
    return 0;
679
 
680
  while (arg--)
681
    t = objc_skip_argspec (t);
682
 
683
  *type = t;
684
  t = objc_skip_typespec (t);
685
 
686
  if (*t == '+')
687
    return argframe->arg_regs + atoi (++t);
688
  else
689
    return argframe->arg_ptr + atoi (t);
690
}
691
 
692
unsigned
693
objc_get_type_qualifiers (const char *type)
694
{
695
  unsigned res = 0;
696
  BOOL flag = YES;
697
 
698
  while (flag)
699
    switch (*type++)
700
      {
701
      case _C_CONST:    res |= _F_CONST; break;
702
      case _C_IN:       res |= _F_IN; break;
703
      case _C_INOUT:    res |= _F_INOUT; break;
704
      case _C_OUT:      res |= _F_OUT; break;
705
      case _C_BYCOPY:   res |= _F_BYCOPY; break;
706
      case _C_BYREF:  res |= _F_BYREF; break;
707
      case _C_ONEWAY:   res |= _F_ONEWAY; break;
708
      case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
709
      default: flag = NO;
710
    }
711
 
712
  return res;
713
}
714
 
715
 
716
/* The following three functions can be used to determine how a
717
   structure is laid out by the compiler. For example:
718
 
719
  struct objc_struct_layout layout;
720
  int i;
721
 
722
  objc_layout_structure (type, &layout);
723
  while (objc_layout_structure_next_member (&layout))
724
    {
725
      int position, align;
726
      const char *type;
727
 
728
      objc_layout_structure_get_info (&layout, &position, &align, &type);
729
      printf ("element %d has offset %d, alignment %d\n",
730
              i++, position, align);
731
    }
732
 
733
  These functions are used by objc_sizeof_type and objc_alignof_type
734
  functions to compute the size and alignment of structures. The
735
  previous method of computing the size and alignment of a structure
736
  was not working on some architectures, particulary on AIX, and in
737
  the presence of bitfields inside the structure. */
738
void
739
objc_layout_structure (const char *type,
740
                           struct objc_struct_layout *layout)
741
{
742
  const char *ntype;
743
 
744
  layout->original_type = ++type;
745
 
746
  /* Skip "<name>=" if any. Avoid embedded structures and unions. */
747
  ntype = type;
748
  while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
749
         && *ntype++ != '=')
750
    /* do nothing */;
751
 
752
  /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
753
  if (*(ntype - 1) == '=')
754
    type = ntype;
755
 
756
  layout->type = type;
757
  layout->prev_type = NULL;
758
  layout->record_size = 0;
759
  layout->record_align = MAX (BITS_PER_UNIT, STRUCTURE_SIZE_BOUNDARY);
760
}
761
 
762
 
763
BOOL
764
objc_layout_structure_next_member (struct objc_struct_layout *layout)
765
{
766
  register int desired_align = 0;
767
 
768
  /* The current type without the type qualifiers */
769
  const char *type;
770
 
771
  /* Add the size of the previous field to the size of the record.  */
772
  if (layout->prev_type)
773
    {
774
      type = objc_skip_type_qualifiers (layout->prev_type);
775
 
776
      if (*type != _C_BFLD)
777
        layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
778
      else
779
        layout->record_size += atoi (++type);
780
    }
781
 
782
  if (*layout->type == _C_STRUCT_E)
783
    return NO;
784
 
785
  /* Skip the variable name if any */
786
  if (*layout->type == '"')
787
    {
788
      for (layout->type++; *layout->type++ != '"';)
789
        /* do nothing */;
790
    }
791
 
792
  type = objc_skip_type_qualifiers (layout->type);
793
 
794
  desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
795
 
796
  /* Record must have at least as much alignment as any field.
797
     Otherwise, the alignment of the field within the record
798
     is meaningless.  */
799
  layout->record_align = MAX (layout->record_align, desired_align);
800
 
801
  if (*type == _C_BFLD)
802
    {
803
      int bfld_size = atoi (++type);
804
      int int_align = __alignof__ (int) * BITS_PER_UNIT;
805
      /* If this bitfield would traverse a word alignment boundary, push it out
806
         to that boundary instead.  */
807
      if (layout->record_size % int_align
808
          && (layout->record_size / int_align
809
              < (layout->record_size + bfld_size - 1) / int_align))
810
        layout->record_size = ROUND (layout->record_size, int_align);
811
    }
812
  else if (layout->record_size % desired_align != 0)
813
    {
814
      /* We need to skip space before this field.
815
         Bump the cumulative size to multiple of field alignment.  */
816
      layout->record_size = ROUND (layout->record_size, desired_align);
817
    }
818
 
819
  /* Jump to the next field in record. */
820
 
821
  layout->prev_type = layout->type;
822
  layout->type = objc_skip_typespec (layout->type);      /* skip component */
823
 
824
  return YES;
825
}
826
 
827
 
828
void objc_layout_finish_structure (struct objc_struct_layout *layout,
829
                                   unsigned int *size,
830
                                   unsigned int *align)
831
{
832
  if (layout->type && *layout->type == _C_STRUCT_E)
833
    {
834
      /* Round the size up to be a multiple of the required alignment */
835
      layout->record_size = ROUND (layout->record_size, layout->record_align);
836
      layout->type = NULL;
837
    }
838
  if (size)
839
    *size = layout->record_size / BITS_PER_UNIT;
840
  if (align)
841
    *align = layout->record_align / BITS_PER_UNIT;
842
}
843
 
844
 
845
void objc_layout_structure_get_info (struct objc_struct_layout *layout,
846
                                     unsigned int *offset,
847
                                     unsigned int *align,
848
                                     const char **type)
849
{
850
  if (offset)
851
    *offset = layout->record_size / BITS_PER_UNIT;
852
  if (align)
853
    *align = layout->record_align / BITS_PER_UNIT;
854
  if (type)
855
    *type = layout->prev_type;
856
}
857
 
858
/* A small, portable NSConstantString implementation for use with the NeXT
859
   runtime.
860
 
861
   On full-fledged Mac OS X systems, NSConstantString is provided
862
   as part of the Foundation framework.  However, on bare Darwin systems,
863
   Foundation is not included, and hence there is no NSConstantString
864
   implementation to link against.
865
 
866
   This code is derived from the GNU runtime's NXConstantString implementation.
867
*/
868
 
869
struct objc_class _NSConstantStringClassReference;
870
 
871
@interface NSConstantString : Object
872
{
873
  char *c_string;
874
  unsigned int len;
875
}
876
 
877
-(const char *) cString;
878
-(unsigned int) length;
879
 
880
@end
881
 
882
@implementation NSConstantString
883
 
884
-(const char *) cString
885
{
886
  return (c_string);
887
}
888
 
889
-(unsigned int) length
890
{
891
  return (len);
892
}
893
 
894
@end
895
 
896
/* The NSConstantString metaclass will need to be initialized before we can
897
   send messages to strings.  */
898
 
899
void objc_constant_string_init (void) __attribute__((constructor));
900
void objc_constant_string_init (void) {
901
  memcpy (&_NSConstantStringClassReference,
902
          objc_getClass ("NSConstantString"),
903
          sizeof (_NSConstantStringClassReference));
904
}
905
 
906
#endif  /* #ifdef __NEXT_RUNTIME__ */

powered by: WebSVN 2.1.0

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