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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [testsuite/] [objc-obj-c++-shared/] [next-mapping.h] - Blame information for rev 310

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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