OSDN Git Service

libobjc:
[pf3gnuchains/gcc-fork.git] / libobjc / encoding.c
1 /* Encoding of types for Objective C.
2    Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2009
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 int
997 method_get_number_of_arguments (struct objc_method *mth)
998 {
999   return method_getNumberOfArguments (mth);
1000 }
1001
1002 /* Return the size of the argument block needed on the stack to invoke
1003    the method MTH.  This may be zero, if all arguments are passed in
1004    registers.  */
1005 int
1006 method_get_sizeof_arguments (struct objc_method *mth)
1007 {
1008   const char *type = objc_skip_typespec (mth->method_types);
1009   return atoi (type);
1010 }
1011
1012 /*
1013   Return a pointer to the next argument of ARGFRAME.  type points to
1014   the last argument.  Typical use of this look like:
1015
1016   {
1017     char *datum, *type;
1018     for (datum = method_get_first_argument (method, argframe, &type);
1019          datum; datum = method_get_next_argument (argframe, &type))
1020       {
1021         unsigned flags = objc_get_type_qualifiers (type);
1022         type = objc_skip_type_qualifiers (type);
1023         if (*type != _C_PTR)
1024           [portal encodeData: datum ofType: type];
1025         else
1026           {
1027             if ((flags & _F_IN) == _F_IN)
1028               [portal encodeData: *(char **) datum ofType: ++type];
1029           }
1030       }
1031   }
1032 */
1033 char *
1034 method_get_next_argument (arglist_t argframe, const char **type)
1035 {
1036   const char *t = objc_skip_argspec (*type);
1037
1038   if (*t == '\0')
1039     return 0;
1040
1041   *type = t;
1042   t = objc_skip_typespec (t);
1043
1044   if (*t == '+')
1045     return argframe->arg_regs + atoi (++t);
1046   else
1047     return argframe->arg_ptr + atoi (t);
1048 }
1049
1050 /* Return a pointer to the value of the first argument of the method
1051    described in M with the given argumentframe ARGFRAME.  The type
1052    is returned in TYPE.  type must be passed to successive calls of
1053    method_get_next_argument.  */
1054 char *
1055 method_get_first_argument (struct objc_method *m,
1056                            arglist_t argframe,
1057                            const char **type)
1058 {
1059   *type = m->method_types;
1060   return method_get_next_argument (argframe, type);
1061 }
1062
1063 /* Return a pointer to the ARGth argument of the method
1064    M from the frame ARGFRAME.  The type of the argument
1065    is returned in the value-result argument TYPE.  */
1066 char *
1067 method_get_nth_argument (struct objc_method *m,
1068                          arglist_t argframe, int arg,
1069                          const char **type)
1070 {
1071   const char *t = objc_skip_argspec (m->method_types);
1072
1073   if (arg > method_get_number_of_arguments (m))
1074     return 0;
1075
1076   while (arg--)
1077     t = objc_skip_argspec (t);
1078
1079   *type = t;
1080   t = objc_skip_typespec (t);
1081
1082   if (*t == '+')
1083     return argframe->arg_regs + atoi (++t);
1084   else
1085     return argframe->arg_ptr + atoi (t);
1086 }
1087
1088 unsigned
1089 objc_get_type_qualifiers (const char *type)
1090 {
1091   unsigned res = 0;
1092   BOOL flag = YES;
1093
1094   while (flag)
1095     switch (*type++)
1096       {
1097       case _C_CONST:       res |= _F_CONST; break;
1098       case _C_IN:          res |= _F_IN; break;
1099       case _C_INOUT:       res |= _F_INOUT; break;
1100       case _C_OUT:         res |= _F_OUT; break;
1101       case _C_BYCOPY:      res |= _F_BYCOPY; break;
1102       case _C_BYREF:       res |= _F_BYREF; break;
1103       case _C_ONEWAY:      res |= _F_ONEWAY; break;
1104       case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1105       default: flag = NO;
1106     }
1107
1108   return res;
1109 }
1110
1111 /* The following three functions can be used to determine how a
1112    structure is laid out by the compiler. For example:
1113
1114   struct objc_struct_layout layout;
1115   int i;
1116
1117   objc_layout_structure (type, &layout);
1118   while (objc_layout_structure_next_member (&layout))
1119     {
1120       int position, align;
1121       const char *type;
1122
1123       objc_layout_structure_get_info (&layout, &position, &align, &type);
1124       printf ("element %d has offset %d, alignment %d\n",
1125               i++, position, align);
1126     }
1127
1128   These functions are used by objc_sizeof_type and objc_alignof_type
1129   functions to compute the size and alignment of structures. The
1130   previous method of computing the size and alignment of a structure
1131   was not working on some architectures, particulary on AIX, and in
1132   the presence of bitfields inside the structure.  */
1133 void
1134 objc_layout_structure (const char *type,
1135                        struct objc_struct_layout *layout)
1136 {
1137   const char *ntype;
1138
1139   if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1140     {
1141       _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1142                    type);
1143     }
1144
1145   type ++;
1146   layout->original_type = type;
1147
1148   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1149   ntype = type;
1150   while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1151          && *ntype++ != '=')
1152     /* do nothing */;
1153
1154   /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1155   if (*(ntype - 1) == '=')
1156     type = ntype;
1157
1158   layout->type = type;
1159   layout->prev_type = NULL;
1160   layout->record_size = 0;
1161   layout->record_align = BITS_PER_UNIT;
1162
1163   layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1164 }
1165
1166 BOOL
1167 objc_layout_structure_next_member (struct objc_struct_layout *layout)
1168 {
1169   register int desired_align = 0;
1170
1171   /* The following are used only if the field is a bitfield */
1172   register const char *bfld_type = 0;
1173   register int bfld_type_align = 0, bfld_field_size = 0;
1174
1175   /* The current type without the type qualifiers */
1176   const char *type;
1177   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1178
1179   /* Add the size of the previous field to the size of the record.  */
1180   if (layout->prev_type)
1181     {
1182       type = objc_skip_type_qualifiers (layout->prev_type);
1183       if (unionp)
1184         layout->record_size = MAX (layout->record_size,
1185                                    objc_sizeof_type (type) * BITS_PER_UNIT);
1186
1187       else if (*type != _C_BFLD)
1188         layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
1189       else {
1190         /* Get the bitfield's type */
1191         for (bfld_type = type + 1;
1192              isdigit ((unsigned char)*bfld_type);
1193              bfld_type++)
1194           /* do nothing */;
1195
1196         bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1197         bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1198         layout->record_size += bfld_field_size;
1199       }
1200     }
1201
1202   if ((unionp && *layout->type == _C_UNION_E)
1203       || (!unionp && *layout->type == _C_STRUCT_E))
1204     return NO;
1205
1206   /* Skip the variable name if any */
1207   layout->type = objc_skip_variable_name (layout->type);
1208   type = objc_skip_type_qualifiers (layout->type);
1209
1210   if (*type != _C_BFLD)
1211     desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
1212   else
1213     {
1214       desired_align = 1;
1215       /* Skip the bitfield's offset */
1216       for (bfld_type = type + 1;
1217            isdigit ((unsigned char) *bfld_type);
1218            bfld_type++)
1219         /* do nothing */;
1220
1221       bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1222       bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1223     }
1224
1225   /* The following won't work for vectors.  */
1226 #ifdef BIGGEST_FIELD_ALIGNMENT
1227   desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1228 #endif
1229 #ifdef ADJUST_FIELD_ALIGN
1230   desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
1231 #endif
1232
1233   /* Record must have at least as much alignment as any field.
1234      Otherwise, the alignment of the field within the record
1235      is meaningless.  */
1236 #ifndef PCC_BITFIELD_TYPE_MATTERS
1237   layout->record_align = MAX (layout->record_align, desired_align);
1238 #else   /* PCC_BITFIELD_TYPE_MATTERS */
1239   if (*type == _C_BFLD)
1240     {
1241       /* For these machines, a zero-length field does not
1242          affect the alignment of the structure as a whole.
1243          It does, however, affect the alignment of the next field
1244          within the structure.  */
1245       if (bfld_field_size)
1246         layout->record_align = MAX (layout->record_align, desired_align);
1247       else
1248         desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1249
1250       /* A named bit field of declared type `int'
1251          forces the entire structure to have `int' alignment.
1252          Q1: How is encoded this thing and how to check for it?
1253          Q2: How to determine maximum_field_alignment at runtime? */
1254
1255 /*        if (DECL_NAME (field) != 0) */
1256       {
1257         int type_align = bfld_type_align;
1258 #if 0
1259         if (maximum_field_alignment != 0)
1260           type_align = MIN (type_align, maximum_field_alignment);
1261         else if (DECL_PACKED (field))
1262           type_align = MIN (type_align, BITS_PER_UNIT);
1263 #endif
1264
1265         layout->record_align = MAX (layout->record_align, type_align);
1266       }
1267     }
1268   else
1269     layout->record_align = MAX (layout->record_align, desired_align);
1270 #endif  /* PCC_BITFIELD_TYPE_MATTERS */
1271
1272   /* Does this field automatically have alignment it needs
1273      by virtue of the fields that precede it and the record's
1274      own alignment?  */
1275
1276   if (*type == _C_BFLD)
1277     layout->record_size = atoi (type + 1);
1278   else if (layout->record_size % desired_align != 0)
1279     {
1280       /* No, we need to skip space before this field.
1281          Bump the cumulative size to multiple of field alignment.  */
1282       layout->record_size = ROUND (layout->record_size, desired_align);
1283     }
1284
1285   /* Jump to the next field in record. */
1286
1287   layout->prev_type = layout->type;
1288   layout->type = objc_skip_typespec (layout->type);      /* skip component */
1289
1290   return YES;
1291 }
1292
1293 void objc_layout_finish_structure (struct objc_struct_layout *layout,
1294                                    unsigned int *size,
1295                                    unsigned int *align)
1296 {
1297   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1298   if (layout->type
1299       && ((!unionp && *layout->type == _C_STRUCT_E)
1300           || (unionp && *layout->type == _C_UNION_E)))
1301     {
1302       /* Work out the alignment of the record as one expression and store
1303          in the record type.  Round it up to a multiple of the record's
1304          alignment. */
1305 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1306       layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1307                                                1,
1308                                                layout->record_align);
1309 #else
1310       layout->record_align = MAX (1, layout->record_align);
1311 #endif
1312
1313 #ifdef ROUND_TYPE_SIZE
1314       layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
1315                                              layout->record_size,
1316                                              layout->record_align);
1317 #else
1318       /* Round the size up to be a multiple of the required alignment */
1319       layout->record_size = ROUND (layout->record_size, layout->record_align);
1320 #endif
1321
1322       layout->type = NULL;
1323     }
1324   if (size)
1325     *size = layout->record_size / BITS_PER_UNIT;
1326   if (align)
1327     *align = layout->record_align / BITS_PER_UNIT;
1328 }
1329
1330 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1331                                      unsigned int *offset,
1332                                      unsigned int *align,
1333                                      const char **type)
1334 {
1335   if (offset)
1336     *offset = layout->record_size / BITS_PER_UNIT;
1337   if (align)
1338     *align = layout->record_align / BITS_PER_UNIT;
1339   if (type)
1340     *type = layout->prev_type;
1341 }