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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libobjc/] [encoding.c] - Blame information for rev 793

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

Line No. Rev Author Line
1 739 jeremybenn
/* Encoding of types for Objective C.
2
   Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2009, 2010
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 3, 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
Under Section 7 of GPL version 3, you are granted additional
20
permissions described in the GCC Runtime Library Exception, version
21
3.1, as published by the Free Software Foundation.
22
 
23
You should have received a copy of the GNU General Public License and
24
a copy of the GCC Runtime Library Exception along with this program;
25
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
26
<http://www.gnu.org/licenses/>.  */
27
 
28
/* FIXME: This file has no business including tm.h.  */
29
 
30
/* FIXME: This file contains functions that will abort the entire
31
   program if they fail.  Is that really needed ?  */
32
 
33
#include "objc-private/common.h"
34
#include "objc-private/error.h"
35
#include "tconfig.h"
36
#include "coretypes.h"
37
#include "tm.h"
38
#include "objc/runtime.h"
39
#include "objc-private/module-abi-8.h" /* For struct objc_method */
40
#include <stdlib.h>
41
#include <ctype.h>
42
#include <string.h>                    /* For memcpy.  */
43
 
44
#undef  MAX
45
#define MAX(X, Y)                    \
46
  ({ typeof (X) __x = (X), __y = (Y); \
47
     (__x > __y ? __x : __y); })
48
 
49
#undef  MIN
50
#define MIN(X, Y)                    \
51
  ({ typeof (X) __x = (X), __y = (Y); \
52
     (__x < __y ? __x : __y); })
53
 
54
#undef  ROUND
55
#define ROUND(V, A) \
56
  ({ typeof (V) __v = (V); typeof (A) __a = (A); \
57
     __a * ((__v+__a - 1)/__a); })
58
 
59
 
60
/* Various hacks for objc_layout_record. These are used by the target
61
   macros. */
62
 
63
#define TREE_CODE(TYPE) *(TYPE)
64
#define TREE_TYPE(TREE) (TREE)
65
 
66
#define RECORD_TYPE     _C_STRUCT_B
67
#define UNION_TYPE      _C_UNION_B
68
#define QUAL_UNION_TYPE _C_UNION_B
69
#define ARRAY_TYPE      _C_ARY_B
70
 
71
#define REAL_TYPE       _C_DBL
72
 
73
#define VECTOR_TYPE     _C_VECTOR
74
 
75
#define TYPE_FIELDS(TYPE)           ({const char *_field = (TYPE)+1; \
76
    while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
77
           && *_field != _C_UNION_B && *_field++ != '=') \
78
    /* do nothing */; \
79
    _field;})
80
 
81
#define DECL_MODE(TYPE) *(TYPE)
82
#define TYPE_MODE(TYPE) *(TYPE)
83
 
84
#define DFmode          _C_DBL
85
 
86
#define strip_array_types(TYPE)      ({const char *_field = (TYPE); \
87
  while (*_field == _C_ARY_B)\
88
    {\
89
      while (isdigit ((unsigned char)*++_field))\
90
        ;\
91
    }\
92
    _field;})
93
 
94
/* Some ports (eg ARM) allow the structure size boundary to be
95
   selected at compile-time.  We override the normal definition with
96
   one that has a constant value for this compilation.  */
97
#ifndef BITS_PER_UNIT
98
#define BITS_PER_UNIT 8
99
#endif
100
#undef  STRUCTURE_SIZE_BOUNDARY
101
#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
102
 
103
/* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
104
   target_flags.  Define a dummy entry here to so we don't die.
105
   We have to rename it because target_flags may already have been
106
   declared extern.  */
107
#define target_flags not_target_flags
108
static int __attribute__ ((__unused__)) not_target_flags = 0;
109
 
110
/* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
111
   Define a dummy ALTIVEC_VECTOR_MODE so it will not die.  */
112
#undef ALTIVEC_VECTOR_MODE
113
#define ALTIVEC_VECTOR_MODE(MODE) (0)
114
 
115
/* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
116
 in their alignment macros. Currently[4.5/6], rs6000.h points this
117
 to a static variable, initialized by target overrides. This is reset
118
 in linux64.h but not in darwin64.h.  The macro is not used by *86*.  */
119
 
120
#if __MACH__ 
121
# if __LP64__
122
#  undef TARGET_ALIGN_NATURAL
123
#  define TARGET_ALIGN_NATURAL 1
124
# endif
125
 
126
/* On Darwin32, we need to recurse until we find the starting stuct type.  */
127
static int
128
_darwin_rs6000_special_round_type_align (const char *struc, int comp, int spec)
129
{
130
  const char *_stp , *_fields = TYPE_FIELDS (struc);
131
  if (!_fields)
132
    return MAX (comp, spec);
133
  _stp = strip_array_types (_fields);
134
  if (TYPE_MODE(_stp) == _C_COMPLEX)
135
   _stp++;
136
  switch (TYPE_MODE(_stp))
137
    {
138
      case RECORD_TYPE:
139
      case UNION_TYPE:
140
        return MAX (MAX (comp, spec), objc_alignof_type (_stp) * BITS_PER_UNIT);
141
        break;
142
      case DFmode:
143
      case _C_LNG_LNG:
144
      case _C_ULNG_LNG:
145
        return MAX (MAX (comp, spec), 64);
146
        break;
147
 
148
      default:
149
        return MAX (comp, spec);
150
        break;
151
    }
152
}
153
 
154
/* See comment below.  */
155
#define darwin_rs6000_special_round_type_align(S,C,S2)                  \
156
  (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2)))
157
#endif
158
 
159
/*  FIXME: while this file has no business including tm.h, this
160
    definitely has no business defining this macro but it
161
    is only way around without really rewritting this file,
162
    should look after the branch of 3.4 to fix this.   */
163
#define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED)    \
164
  ({ const char *_fields = TYPE_FIELDS (STRUCT);                        \
165
  ((_fields != 0                                                 \
166
    && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode)   \
167
   ? MAX (MAX (COMPUTED, SPECIFIED), 64)                                \
168
   : MAX (COMPUTED, SPECIFIED));})
169
 
170
 
171
/* Skip a variable name, enclosed in quotes (").  */
172
static inline
173
const char *
174
objc_skip_variable_name (const char *type)
175
{
176
  /* Skip the variable name if any.  */
177
  if (*type == '"')
178
    {
179
      /* FIXME: How do we know we won't read beyond the end of the
180
         string.  Here and in the rest of the file!  */
181
      /* Skip '"'.  */
182
      type++;
183
      /* Skip to the next '"'.  */
184
      while (*type != '"')
185
        type++;
186
      /* Skip '"'.  */
187
      type++;
188
    }
189
 
190
  return type;
191
}
192
 
193
int
194
objc_sizeof_type (const char *type)
195
{
196
  type = objc_skip_variable_name (type);
197
 
198
  switch (*type) {
199
  case _C_BOOL:
200
    return sizeof (_Bool);
201
    break;
202
 
203
  case _C_ID:
204
    return sizeof (id);
205
    break;
206
 
207
  case _C_CLASS:
208
    return sizeof (Class);
209
    break;
210
 
211
  case _C_SEL:
212
    return sizeof (SEL);
213
    break;
214
 
215
  case _C_CHR:
216
    return sizeof (char);
217
    break;
218
 
219
  case _C_UCHR:
220
    return sizeof (unsigned char);
221
    break;
222
 
223
  case _C_SHT:
224
    return sizeof (short);
225
    break;
226
 
227
  case _C_USHT:
228
    return sizeof (unsigned short);
229
    break;
230
 
231
  case _C_INT:
232
    return sizeof (int);
233
    break;
234
 
235
  case _C_UINT:
236
    return sizeof (unsigned int);
237
    break;
238
 
239
  case _C_LNG:
240
    return sizeof (long);
241
    break;
242
 
243
  case _C_ULNG:
244
    return sizeof (unsigned long);
245
    break;
246
 
247
  case _C_LNG_LNG:
248
    return sizeof (long long);
249
    break;
250
 
251
  case _C_ULNG_LNG:
252
    return sizeof (unsigned long long);
253
    break;
254
 
255
  case _C_FLT:
256
    return sizeof (float);
257
    break;
258
 
259
  case _C_DBL:
260
    return sizeof (double);
261
    break;
262
 
263
  case _C_LNG_DBL:
264
    return sizeof (long double);
265
    break;
266
 
267
  case _C_VOID:
268
    return sizeof (void);
269
    break;
270
 
271
  case _C_PTR:
272
  case _C_ATOM:
273
  case _C_CHARPTR:
274
    return sizeof (char *);
275
    break;
276
 
277
  case _C_ARY_B:
278
    {
279
      int len = atoi (type + 1);
280
      while (isdigit ((unsigned char)*++type))
281
        ;
282
      return len * objc_aligned_size (type);
283
    }
284
    break;
285
 
286
  case _C_VECTOR:
287
    {
288
      /* Skip the '!'.  */
289
      type++;
290
      /* Skip the '['.  */
291
      type++;
292
 
293
      /* The size in bytes is the following number.  */
294
      int size = atoi (type);
295
      return size;
296
    }
297
    break;
298
 
299
  case _C_BFLD:
300
    {
301
      /* The GNU encoding of bitfields is: b 'position' 'type'
302
         'size'.  */
303
      int position, size;
304
      int startByte, endByte;
305
 
306
      position = atoi (type + 1);
307
      while (isdigit ((unsigned char)*++type))
308
        ;
309
      size = atoi (type + 1);
310
 
311
      startByte = position / BITS_PER_UNIT;
312
      endByte = (position + size) / BITS_PER_UNIT;
313
      return endByte - startByte;
314
    }
315
 
316
  case _C_UNION_B:
317
  case _C_STRUCT_B:
318
    {
319
      struct objc_struct_layout layout;
320
      unsigned int size;
321
 
322
      objc_layout_structure (type, &layout);
323
      while (objc_layout_structure_next_member (&layout))
324
        /* do nothing */ ;
325
      objc_layout_finish_structure (&layout, &size, NULL);
326
 
327
      return size;
328
    }
329
 
330
  case _C_COMPLEX:
331
    {
332
      type++; /* Skip after the 'j'. */
333
      switch (*type)
334
        {
335
            case _C_CHR:
336
              return sizeof (_Complex char);
337
              break;
338
 
339
            case _C_UCHR:
340
              return sizeof (_Complex unsigned char);
341
              break;
342
 
343
            case _C_SHT:
344
              return sizeof (_Complex short);
345
              break;
346
 
347
            case _C_USHT:
348
              return sizeof (_Complex unsigned short);
349
              break;
350
 
351
            case _C_INT:
352
              return sizeof (_Complex int);
353
              break;
354
 
355
            case _C_UINT:
356
              return sizeof (_Complex unsigned int);
357
              break;
358
 
359
            case _C_LNG:
360
              return sizeof (_Complex long);
361
              break;
362
 
363
            case _C_ULNG:
364
              return sizeof (_Complex unsigned long);
365
              break;
366
 
367
            case _C_LNG_LNG:
368
              return sizeof (_Complex long long);
369
              break;
370
 
371
            case _C_ULNG_LNG:
372
              return sizeof (_Complex unsigned long long);
373
              break;
374
 
375
            case _C_FLT:
376
              return sizeof (_Complex float);
377
              break;
378
 
379
            case _C_DBL:
380
              return sizeof (_Complex double);
381
              break;
382
 
383
            case _C_LNG_DBL:
384
              return sizeof (_Complex long double);
385
              break;
386
 
387
            default:
388
              {
389
                /* FIXME: Is this so bad that we have to abort the
390
                   entire program ?  (it applies to all the other
391
                   _objc_abort calls in this file).
392
                */
393
                _objc_abort ("unknown complex type %s\n", type);
394
                return 0;
395
              }
396
        }
397
    }
398
 
399
  default:
400
    {
401
      _objc_abort ("unknown type %s\n", type);
402
      return 0;
403
    }
404
  }
405
}
406
 
407
int
408
objc_alignof_type (const char *type)
409
{
410
  type = objc_skip_variable_name (type);
411
 
412
  switch (*type) {
413
  case _C_BOOL:
414
    return __alignof__ (_Bool);
415
    break;
416
 
417
  case _C_ID:
418
    return __alignof__ (id);
419
    break;
420
 
421
  case _C_CLASS:
422
    return __alignof__ (Class);
423
    break;
424
 
425
  case _C_SEL:
426
    return __alignof__ (SEL);
427
    break;
428
 
429
  case _C_CHR:
430
    return __alignof__ (char);
431
    break;
432
 
433
  case _C_UCHR:
434
    return __alignof__ (unsigned char);
435
    break;
436
 
437
  case _C_SHT:
438
    return __alignof__ (short);
439
    break;
440
 
441
  case _C_USHT:
442
    return __alignof__ (unsigned short);
443
    break;
444
 
445
  case _C_INT:
446
    return __alignof__ (int);
447
    break;
448
 
449
  case _C_UINT:
450
    return __alignof__ (unsigned int);
451
    break;
452
 
453
  case _C_LNG:
454
    return __alignof__ (long);
455
    break;
456
 
457
  case _C_ULNG:
458
    return __alignof__ (unsigned long);
459
    break;
460
 
461
  case _C_LNG_LNG:
462
    return __alignof__ (long long);
463
    break;
464
 
465
  case _C_ULNG_LNG:
466
    return __alignof__ (unsigned long long);
467
    break;
468
 
469
  case _C_FLT:
470
    return __alignof__ (float);
471
    break;
472
 
473
  case _C_DBL:
474
    return __alignof__ (double);
475
    break;
476
 
477
  case _C_LNG_DBL:
478
    return __alignof__ (long double);
479
    break;
480
 
481
  case _C_PTR:
482
  case _C_ATOM:
483
  case _C_CHARPTR:
484
    return __alignof__ (char *);
485
    break;
486
 
487
  case _C_ARY_B:
488
    while (isdigit ((unsigned char)*++type))
489
      /* do nothing */;
490
    return objc_alignof_type (type);
491
 
492
  case _C_VECTOR:
493
    {
494
      /* Skip the '!'.  */
495
      type++;
496
      /* Skip the '['.  */
497
      type++;
498
 
499
      /* Skip the size.  */
500
      while (isdigit ((unsigned char)*type))
501
        type++;
502
 
503
      /* Skip the ','.  */
504
      type++;
505
 
506
      /* The alignment in bytes is the following number.  */
507
      return atoi (type);
508
    }
509
  case _C_STRUCT_B:
510
  case _C_UNION_B:
511
    {
512
      struct objc_struct_layout layout;
513
      unsigned int align;
514
 
515
      objc_layout_structure (type, &layout);
516
      while (objc_layout_structure_next_member (&layout))
517
        /* do nothing */;
518
      objc_layout_finish_structure (&layout, NULL, &align);
519
 
520
      return align;
521
    }
522
 
523
 
524
  case _C_COMPLEX:
525
    {
526
      type++; /* Skip after the 'j'. */
527
      switch (*type)
528
        {
529
            case _C_CHR:
530
              return __alignof__ (_Complex char);
531
              break;
532
 
533
            case _C_UCHR:
534
              return __alignof__ (_Complex unsigned char);
535
              break;
536
 
537
            case _C_SHT:
538
              return __alignof__ (_Complex short);
539
              break;
540
 
541
            case _C_USHT:
542
              return __alignof__ (_Complex unsigned short);
543
              break;
544
 
545
            case _C_INT:
546
              return __alignof__ (_Complex int);
547
              break;
548
 
549
            case _C_UINT:
550
              return __alignof__ (_Complex unsigned int);
551
              break;
552
 
553
            case _C_LNG:
554
              return __alignof__ (_Complex long);
555
              break;
556
 
557
            case _C_ULNG:
558
              return __alignof__ (_Complex unsigned long);
559
              break;
560
 
561
            case _C_LNG_LNG:
562
              return __alignof__ (_Complex long long);
563
              break;
564
 
565
            case _C_ULNG_LNG:
566
              return __alignof__ (_Complex unsigned long long);
567
              break;
568
 
569
            case _C_FLT:
570
              return __alignof__ (_Complex float);
571
              break;
572
 
573
            case _C_DBL:
574
              return __alignof__ (_Complex double);
575
              break;
576
 
577
            case _C_LNG_DBL:
578
              return __alignof__ (_Complex long double);
579
              break;
580
 
581
            default:
582
              {
583
                _objc_abort ("unknown complex type %s\n", type);
584
                return 0;
585
              }
586
        }
587
    }
588
 
589
  default:
590
    {
591
      _objc_abort ("unknown type %s\n", type);
592
      return 0;
593
    }
594
  }
595
}
596
 
597
int
598
objc_aligned_size (const char *type)
599
{
600
  int size, align;
601
 
602
  type = objc_skip_variable_name (type);
603
  size = objc_sizeof_type (type);
604
  align = objc_alignof_type (type);
605
 
606
  return ROUND (size, align);
607
}
608
 
609
int
610
objc_promoted_size (const char *type)
611
{
612
  int size, wordsize;
613
 
614
  type = objc_skip_variable_name (type);
615
  size = objc_sizeof_type (type);
616
  wordsize = sizeof (void *);
617
 
618
  return ROUND (size, wordsize);
619
}
620
 
621
inline
622
const char *
623
objc_skip_type_qualifiers (const char *type)
624
{
625
  while (*type == _C_CONST
626
         || *type == _C_IN
627
         || *type == _C_INOUT
628
         || *type == _C_OUT
629
         || *type == _C_BYCOPY
630
         || *type == _C_BYREF
631
         || *type == _C_ONEWAY
632
         || *type == _C_GCINVISIBLE)
633
    {
634
      type += 1;
635
    }
636
  return type;
637
}
638
 
639
inline
640
const char *
641
objc_skip_typespec (const char *type)
642
{
643
  type = objc_skip_variable_name (type);
644
  type = objc_skip_type_qualifiers (type);
645
 
646
  switch (*type) {
647
 
648
  case _C_ID:
649
    /* An id may be annotated by the actual type if it is known
650
       with the @"ClassName" syntax */
651
 
652
    if (*++type != '"')
653
      return type;
654
    else
655
      {
656
        while (*++type != '"')
657
          /* do nothing */;
658
        return type + 1;
659
      }
660
 
661
    /* The following are one character type codes */
662
  case _C_CLASS:
663
  case _C_SEL:
664
  case _C_CHR:
665
  case _C_UCHR:
666
  case _C_CHARPTR:
667
  case _C_ATOM:
668
  case _C_SHT:
669
  case _C_USHT:
670
  case _C_INT:
671
  case _C_UINT:
672
  case _C_LNG:
673
  case _C_BOOL:
674
  case _C_ULNG:
675
  case _C_LNG_LNG:
676
  case _C_ULNG_LNG:
677
  case _C_FLT:
678
  case _C_DBL:
679
  case _C_LNG_DBL:
680
  case _C_VOID:
681
  case _C_UNDEF:
682
    return ++type;
683
    break;
684
 
685
  case _C_COMPLEX:
686
    return type + 2;
687
    break;
688
 
689
  case _C_ARY_B:
690
    /* skip digits, typespec and closing ']' */
691
    while (isdigit ((unsigned char)*++type))
692
      ;
693
    type = objc_skip_typespec (type);
694
    if (*type == _C_ARY_E)
695
      return ++type;
696
    else
697
      {
698
        _objc_abort ("bad array type %s\n", type);
699
        return 0;
700
      }
701
 
702
  case _C_VECTOR:
703
    /* Skip '!' */
704
    type++;
705
    /* Skip '[' */
706
    type++;
707
    /* Skip digits (size) */
708
    while (isdigit ((unsigned char)*type))
709
      type++;
710
    /* Skip ',' */
711
    type++;
712
    /* Skip digits (alignment) */
713
    while (isdigit ((unsigned char)*type))
714
      type++;
715
    /* Skip typespec.  */
716
    type = objc_skip_typespec (type);
717
    /* Skip closing ']'.  */
718
    if (*type == _C_ARY_E)
719
      return ++type;
720
    else
721
      {
722
        _objc_abort ("bad vector type %s\n", type);
723
        return 0;
724
      }
725
 
726
  case _C_BFLD:
727
    /* The GNU encoding of bitfields is: b 'position' 'type'
728
       'size'.  */
729
    while (isdigit ((unsigned char)*++type))
730
      ; /* skip position */
731
    while (isdigit ((unsigned char)*++type))
732
      ; /* skip type and size */
733
    return type;
734
 
735
  case _C_STRUCT_B:
736
    /* skip name, and elements until closing '}'  */
737
 
738
    while (*type != _C_STRUCT_E && *type++ != '=')
739
      ;
740
    while (*type != _C_STRUCT_E)
741
      {
742
        type = objc_skip_typespec (type);
743
      }
744
    return ++type;
745
 
746
  case _C_UNION_B:
747
    /* skip name, and elements until closing ')'  */
748
 
749
    while (*type != _C_UNION_E && *type++ != '=')
750
      ;
751
    while (*type != _C_UNION_E)
752
      {
753
        type = objc_skip_typespec (type);
754
      }
755
    return ++type;
756
 
757
  case _C_PTR:
758
    /* Just skip the following typespec */
759
 
760
    return objc_skip_typespec (++type);
761
 
762
  default:
763
    {
764
      _objc_abort ("unknown type %s\n", type);
765
      return 0;
766
    }
767
  }
768
}
769
 
770
inline
771
const char *
772
objc_skip_offset (const char *type)
773
{
774
  /* The offset is prepended by a '+' if the argument is passed in
775
     registers.  PS: The compiler stopped generating this '+' in
776
     version 3.4.  */
777
  if (*type == '+')
778
    type++;
779
 
780
  /* Some people claim that on some platforms, where the stack grows
781
     backwards, the compiler generates negative offsets (??).  Skip a
782
     '-' for such a negative offset.  */
783
  if (*type == '-')
784
    type++;
785
 
786
  /* Skip the digits that represent the offset.  */
787
  while (isdigit ((unsigned char) *type))
788
    type++;
789
 
790
  return type;
791
}
792
 
793
const char *
794
objc_skip_argspec (const char *type)
795
{
796
  type = objc_skip_typespec (type);
797
  type = objc_skip_offset (type);
798
  return type;
799
}
800
 
801
char *
802
method_copyReturnType (struct objc_method *method)
803
{
804
  if (method == NULL)
805
    return 0;
806
  else
807
    {
808
      char *returnValue;
809
      size_t returnValueSize;
810
 
811
      /* Determine returnValueSize.  */
812
      {
813
        /* Find the end of the first argument.  We want to return the
814
           first argument spec, plus 1 byte for the \0 at the end.  */
815
        const char *type = method->method_types;
816
        if (*type == '\0')
817
          return NULL;
818
        type = objc_skip_argspec (type);
819
        returnValueSize = type - method->method_types + 1;
820
      }
821
 
822
      /* Copy the first argument into returnValue.  */
823
      returnValue = malloc (sizeof (char) * returnValueSize);
824
      memcpy (returnValue, method->method_types, returnValueSize);
825
      returnValue[returnValueSize - 1] = '\0';
826
 
827
      return returnValue;
828
    }
829
}
830
 
831
char *
832
method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber)
833
{
834
  if (method == NULL)
835
    return 0;
836
  else
837
    {
838
      char *returnValue;
839
      const char *returnValueStart;
840
      size_t returnValueSize;
841
 
842
      /* Determine returnValueStart and returnValueSize.  */
843
      {
844
        const char *type = method->method_types;
845
 
846
        /* Skip the first argument (return type).  */
847
        type = objc_skip_argspec (type);
848
 
849
        /* Now keep skipping arguments until we get to
850
           argumentNumber.  */
851
        while (argumentNumber > 0)
852
          {
853
            /* We are supposed to skip an argument, but the string is
854
               finished.  This means we were asked for a non-existing
855
               argument.  */
856
            if (*type == '\0')
857
              return NULL;
858
 
859
            type = objc_skip_argspec (type);
860
            argumentNumber--;
861
          }
862
 
863
        /* If the argument does not exist, return NULL.  */
864
        if (*type == '\0')
865
          return NULL;
866
 
867
        returnValueStart = type;
868
        type = objc_skip_argspec (type);
869
        returnValueSize = type - returnValueStart + 1;
870
      }
871
 
872
      /* Copy the argument into returnValue.  */
873
      returnValue = malloc (sizeof (char) * returnValueSize);
874
      memcpy (returnValue, returnValueStart, returnValueSize);
875
      returnValue[returnValueSize - 1] = '\0';
876
 
877
      return returnValue;
878
    }
879
}
880
 
881
void method_getReturnType (struct objc_method * method, char *returnValue,
882
                           size_t returnValueSize)
883
{
884
  if (returnValue == NULL  ||  returnValueSize == 0)
885
    return;
886
 
887
  /* Zero the string; we'll then write the argument type at the
888
     beginning of it, if needed.  */
889
  memset (returnValue, 0, returnValueSize);
890
 
891
  if (method == NULL)
892
    return;
893
  else
894
    {
895
      size_t argumentTypeSize;
896
 
897
      /* Determine argumentTypeSize.  */
898
      {
899
        /* Find the end of the first argument.  We want to return the
900
           first argument spec.  */
901
        const char *type = method->method_types;
902
        if (*type == '\0')
903
          return;
904
        type = objc_skip_argspec (type);
905
        argumentTypeSize = type - method->method_types;
906
        if (argumentTypeSize > returnValueSize)
907
          argumentTypeSize = returnValueSize;
908
      }
909
      /* Copy the argument at the beginning of the string.  */
910
      memcpy (returnValue, method->method_types, argumentTypeSize);
911
    }
912
}
913
 
914
void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber,
915
                             char *returnValue, size_t returnValueSize)
916
{
917
  if (returnValue == NULL  ||  returnValueSize == 0)
918
    return;
919
 
920
  /* Zero the string; we'll then write the argument type at the
921
     beginning of it, if needed.  */
922
  memset (returnValue, 0, returnValueSize);
923
 
924
  if (method == NULL)
925
    return;
926
  else
927
    {
928
      const char *returnValueStart;
929
      size_t argumentTypeSize;
930
 
931
      /* Determine returnValueStart and argumentTypeSize.  */
932
      {
933
        const char *type = method->method_types;
934
 
935
        /* Skip the first argument (return type).  */
936
        type = objc_skip_argspec (type);
937
 
938
        /* Now keep skipping arguments until we get to
939
           argumentNumber.  */
940
        while (argumentNumber > 0)
941
          {
942
            /* We are supposed to skip an argument, but the string is
943
               finished.  This means we were asked for a non-existing
944
               argument.  */
945
            if (*type == '\0')
946
              return;
947
 
948
            type = objc_skip_argspec (type);
949
            argumentNumber--;
950
          }
951
 
952
        /* If the argument does not exist, it's game over.  */
953
        if (*type == '\0')
954
          return;
955
 
956
        returnValueStart = type;
957
        type = objc_skip_argspec (type);
958
        argumentTypeSize = type - returnValueStart;
959
        if (argumentTypeSize > returnValueSize)
960
          argumentTypeSize = returnValueSize;
961
      }
962
      /* Copy the argument at the beginning of the string.  */
963
      memcpy (returnValue, returnValueStart, argumentTypeSize);
964
    }
965
}
966
 
967
unsigned int
968
method_getNumberOfArguments (struct objc_method *method)
969
{
970
  if (method == NULL)
971
    return 0;
972
  else
973
    {
974
      unsigned int i = 0;
975
      const char *type = method->method_types;
976
      while (*type)
977
        {
978
          type = objc_skip_argspec (type);
979
          i += 1;
980
        }
981
 
982
      if (i == 0)
983
        {
984
          /* This could only happen if method_types is invalid; in
985
             that case, return 0.  */
986
          return 0;
987
        }
988
      else
989
        {
990
          /* Remove the return type.  */
991
          return (i - 1);
992
        }
993
    }
994
}
995
 
996
unsigned
997
objc_get_type_qualifiers (const char *type)
998
{
999
  unsigned res = 0;
1000
  BOOL flag = YES;
1001
 
1002
  while (flag)
1003
    switch (*type++)
1004
      {
1005
      case _C_CONST:       res |= _F_CONST; break;
1006
      case _C_IN:          res |= _F_IN; break;
1007
      case _C_INOUT:       res |= _F_INOUT; break;
1008
      case _C_OUT:         res |= _F_OUT; break;
1009
      case _C_BYCOPY:      res |= _F_BYCOPY; break;
1010
      case _C_BYREF:       res |= _F_BYREF; break;
1011
      case _C_ONEWAY:      res |= _F_ONEWAY; break;
1012
      case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1013
      default: flag = NO;
1014
    }
1015
 
1016
  return res;
1017
}
1018
 
1019
/* The following three functions can be used to determine how a
1020
   structure is laid out by the compiler. For example:
1021
 
1022
  struct objc_struct_layout layout;
1023
  int i;
1024
 
1025
  objc_layout_structure (type, &layout);
1026
  while (objc_layout_structure_next_member (&layout))
1027
    {
1028
      int position, align;
1029
      const char *type;
1030
 
1031
      objc_layout_structure_get_info (&layout, &position, &align, &type);
1032
      printf ("element %d has offset %d, alignment %d\n",
1033
              i++, position, align);
1034
    }
1035
 
1036
  These functions are used by objc_sizeof_type and objc_alignof_type
1037
  functions to compute the size and alignment of structures. The
1038
  previous method of computing the size and alignment of a structure
1039
  was not working on some architectures, particulary on AIX, and in
1040
  the presence of bitfields inside the structure.  */
1041
void
1042
objc_layout_structure (const char *type,
1043
                       struct objc_struct_layout *layout)
1044
{
1045
  const char *ntype;
1046
 
1047
  if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1048
    {
1049
      _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1050
                   type);
1051
    }
1052
 
1053
  type ++;
1054
  layout->original_type = type;
1055
 
1056
  /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1057
  ntype = type;
1058
  while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1059
         && *ntype++ != '=')
1060
    /* do nothing */;
1061
 
1062
  /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1063
  if (*(ntype - 1) == '=')
1064
    type = ntype;
1065
 
1066
  layout->type = type;
1067
  layout->prev_type = NULL;
1068
  layout->record_size = 0;
1069
  layout->record_align = BITS_PER_UNIT;
1070
 
1071
  layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1072
}
1073
 
1074
BOOL
1075
objc_layout_structure_next_member (struct objc_struct_layout *layout)
1076
{
1077
  register int desired_align = 0;
1078
 
1079
  /* The following are used only if the field is a bitfield */
1080
  register const char *bfld_type = 0;
1081
  register int bfld_type_align = 0, bfld_field_size = 0;
1082
 
1083
  /* The current type without the type qualifiers */
1084
  const char *type;
1085
  BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1086
 
1087
  /* Add the size of the previous field to the size of the record.  */
1088
  if (layout->prev_type)
1089
    {
1090
      type = objc_skip_type_qualifiers (layout->prev_type);
1091
      if (unionp)
1092
        layout->record_size = MAX (layout->record_size,
1093
                                   objc_sizeof_type (type) * BITS_PER_UNIT);
1094
 
1095
      else if (*type != _C_BFLD)
1096
        layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
1097
      else {
1098
        /* Get the bitfield's type */
1099
        for (bfld_type = type + 1;
1100
             isdigit ((unsigned char)*bfld_type);
1101
             bfld_type++)
1102
          /* do nothing */;
1103
 
1104
        bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1105
        bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1106
        layout->record_size += bfld_field_size;
1107
      }
1108
    }
1109
 
1110
  if ((unionp && *layout->type == _C_UNION_E)
1111
      || (!unionp && *layout->type == _C_STRUCT_E))
1112
    return NO;
1113
 
1114
  /* Skip the variable name if any */
1115
  layout->type = objc_skip_variable_name (layout->type);
1116
  type = objc_skip_type_qualifiers (layout->type);
1117
 
1118
  if (*type != _C_BFLD)
1119
    desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
1120
  else
1121
    {
1122
      desired_align = 1;
1123
      /* Skip the bitfield's offset */
1124
      for (bfld_type = type + 1;
1125
           isdigit ((unsigned char) *bfld_type);
1126
           bfld_type++)
1127
        /* do nothing */;
1128
 
1129
      bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1130
      bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1131
    }
1132
 
1133
  /* The following won't work for vectors.  */
1134
#ifdef BIGGEST_FIELD_ALIGNMENT
1135
  desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1136
#endif
1137
#ifdef ADJUST_FIELD_ALIGN
1138
  desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
1139
#endif
1140
 
1141
  /* Record must have at least as much alignment as any field.
1142
     Otherwise, the alignment of the field within the record
1143
     is meaningless.  */
1144
#ifndef PCC_BITFIELD_TYPE_MATTERS
1145
  layout->record_align = MAX (layout->record_align, desired_align);
1146
#else   /* PCC_BITFIELD_TYPE_MATTERS */
1147
  if (*type == _C_BFLD)
1148
    {
1149
      /* For these machines, a zero-length field does not
1150
         affect the alignment of the structure as a whole.
1151
         It does, however, affect the alignment of the next field
1152
         within the structure.  */
1153
      if (bfld_field_size)
1154
        layout->record_align = MAX (layout->record_align, desired_align);
1155
      else
1156
        desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1157
 
1158
      /* A named bit field of declared type `int'
1159
         forces the entire structure to have `int' alignment.
1160
         Q1: How is encoded this thing and how to check for it?
1161
         Q2: How to determine maximum_field_alignment at runtime? */
1162
 
1163
/*        if (DECL_NAME (field) != 0) */
1164
      {
1165
        int type_align = bfld_type_align;
1166
#if 0
1167
        if (maximum_field_alignment != 0)
1168
          type_align = MIN (type_align, maximum_field_alignment);
1169
        else if (DECL_PACKED (field))
1170
          type_align = MIN (type_align, BITS_PER_UNIT);
1171
#endif
1172
 
1173
        layout->record_align = MAX (layout->record_align, type_align);
1174
      }
1175
    }
1176
  else
1177
    layout->record_align = MAX (layout->record_align, desired_align);
1178
#endif  /* PCC_BITFIELD_TYPE_MATTERS */
1179
 
1180
  /* Does this field automatically have alignment it needs
1181
     by virtue of the fields that precede it and the record's
1182
     own alignment?  */
1183
 
1184
  if (*type == _C_BFLD)
1185
    layout->record_size = atoi (type + 1);
1186
  else if (layout->record_size % desired_align != 0)
1187
    {
1188
      /* No, we need to skip space before this field.
1189
         Bump the cumulative size to multiple of field alignment.  */
1190
      layout->record_size = ROUND (layout->record_size, desired_align);
1191
    }
1192
 
1193
  /* Jump to the next field in record. */
1194
 
1195
  layout->prev_type = layout->type;
1196
  layout->type = objc_skip_typespec (layout->type);      /* skip component */
1197
 
1198
  return YES;
1199
}
1200
 
1201
void objc_layout_finish_structure (struct objc_struct_layout *layout,
1202
                                   unsigned int *size,
1203
                                   unsigned int *align)
1204
{
1205
  BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1206
  if (layout->type
1207
      && ((!unionp && *layout->type == _C_STRUCT_E)
1208
          || (unionp && *layout->type == _C_UNION_E)))
1209
    {
1210
      /* Work out the alignment of the record as one expression and store
1211
         in the record type.  Round it up to a multiple of the record's
1212
         alignment. */
1213
#if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1214
      layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1215
                                               1,
1216
                                               layout->record_align);
1217
#else
1218
      layout->record_align = MAX (1, layout->record_align);
1219
#endif
1220
 
1221
#ifdef ROUND_TYPE_SIZE
1222
      layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
1223
                                             layout->record_size,
1224
                                             layout->record_align);
1225
#else
1226
      /* Round the size up to be a multiple of the required alignment */
1227
      layout->record_size = ROUND (layout->record_size, layout->record_align);
1228
#endif
1229
 
1230
      layout->type = NULL;
1231
    }
1232
  if (size)
1233
    *size = layout->record_size / BITS_PER_UNIT;
1234
  if (align)
1235
    *align = layout->record_align / BITS_PER_UNIT;
1236
}
1237
 
1238
void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1239
                                     unsigned int *offset,
1240
                                     unsigned int *align,
1241
                                     const char **type)
1242
{
1243
  if (offset)
1244
    *offset = layout->record_size / BITS_PER_UNIT;
1245
  if (align)
1246
    *align = layout->record_align / BITS_PER_UNIT;
1247
  if (type)
1248
    *type = layout->prev_type;
1249
}

powered by: WebSVN 2.1.0

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