OSDN Git Service

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