OSDN Git Service

PR ada/60703
[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, 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 }