X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libobjc%2Fencoding.c;h=4ae29a769c110db48e3b933dbd161414b2e74030;hb=0767c2a88a20b393f653680acb0e6e7ac1da6f9f;hp=17bc8d4e2e149b62c41cfcdf5cfc3570a064a64f;hpb=d84c6db892405297a439598cc8b79753996dd2a8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libobjc/encoding.c b/libobjc/encoding.c index 17bc8d4e2e1..4ae29a769c1 100644 --- a/libobjc/encoding.c +++ b/libobjc/encoding.c @@ -1,5 +1,5 @@ /* Encoding of types for Objective C. - Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002 + Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2009 Free Software Foundation, Inc. Contributed by Kresten Krab Thorup Bitfield support by Ovidiu Predescu @@ -8,7 +8,7 @@ This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -16,24 +16,22 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ /* FIXME: This file has no business including tm.h. */ #include "tconfig.h" #include "coretypes.h" #include "tm.h" -#include "objc-api.h" -#include "encoding.h" +#include "objc/objc-api.h" +#include "objc/encoding.h" #include #undef MAX @@ -67,26 +65,45 @@ Boston, MA 02111-1307, USA. */ #define VECTOR_TYPE _C_VECTOR -#define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE) +#define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \ + while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \ + && *_field != _C_UNION_B && *_field++ != '=') \ + /* do nothing */; \ + _field;}) #define DECL_MODE(TYPE) *(TYPE) #define TYPE_MODE(TYPE) *(TYPE) #define DFmode _C_DBL -#define get_inner_array_type(TYPE) ((TYPE) + 1) +#define strip_array_types(TYPE) ({const char *_field = (TYPE); \ + while (*_field == _C_ARY_B)\ + {\ + while (isdigit ((unsigned char)*++_field))\ + ;\ + }\ + _field;}) /* Some ports (eg ARM) allow the structure size boundary to be selected at compile-time. We override the normal definition with one that has a constant value for this compilation. */ -#undef STRUCTURE_SIZE_BOUNDARY +#ifndef BITS_PER_UNIT +#define BITS_PER_UNIT 8 +#endif +#undef STRUCTURE_SIZE_BOUNDARY #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;})) /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently - target_flags. Define a dummy entry here to so we don't die. */ -/* ??? FIXME: As of 2002-06-21, the attribute `unused' doesn't seem to - eliminate the warning. */ -static int __attribute__ ((__unused__)) target_flags = 0; + target_flags. Define a dummy entry here to so we don't die. + We have to rename it because target_flags may already have been + declared extern. */ +#define target_flags not_target_flags +static int __attribute__ ((__unused__)) not_target_flags = 0; + +/* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin). + Define a dummy ALTIVEC_VECTOR_MODE so it will not die. */ +#undef ALTIVEC_VECTOR_MODE +#define ALTIVEC_VECTOR_MODE(MODE) (0) /* FIXME: while this file has no business including tm.h, this @@ -94,10 +111,15 @@ static int __attribute__ ((__unused__)) target_flags = 0; is only way around without really rewritting this file, should look after the branch of 3.4 to fix this. */ #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \ - ((TYPE_FIELDS (STRUCT) != 0 \ - && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode) \ + ({ const char *_fields = TYPE_FIELDS (STRUCT); \ + ((_fields != 0 \ + && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \ ? MAX (MAX (COMPUTED, SPECIFIED), 64) \ - : MAX (COMPUTED, SPECIFIED)) + : MAX (COMPUTED, SPECIFIED));}) +/* FIXME: The word 'fixme' is insufficient to explain the wrong-ness + of this next macro definition. */ +#define darwin_rs6000_special_round_type_align(S,C,S2) \ + rs6000_special_round_type_align(S,C,S2) /* return the size of an object specified by type @@ -114,6 +136,10 @@ objc_sizeof_type (const char *type) } switch (*type) { + case _C_BOOL: + return sizeof (_Bool); + break; + case _C_ID: return sizeof (id); break; @@ -209,6 +235,7 @@ objc_sizeof_type (const char *type) return endByte - startByte; } + case _C_UNION_B: case _C_STRUCT_B: { struct objc_struct_layout layout; @@ -221,24 +248,67 @@ objc_sizeof_type (const char *type) return size; } - - case _C_UNION_B: + + case _C_COMPLEX: { - int max_size = 0; - while (*type != _C_UNION_E && *type++ != '=') - /* do nothing */; - while (*type != _C_UNION_E) - { - /* Skip the variable name if any */ - if (*type == '"') - { - for (type++; *type++ != '"';) - /* do nothing */; - } - max_size = MAX (max_size, objc_sizeof_type (type)); - type = objc_skip_typespec (type); + type++; /* Skip after the 'j'. */ + switch (*type) + { + case _C_CHR: + return sizeof (_Complex char); + break; + + case _C_UCHR: + return sizeof (_Complex unsigned char); + break; + + case _C_SHT: + return sizeof (_Complex short); + break; + + case _C_USHT: + return sizeof (_Complex unsigned short); + break; + + case _C_INT: + return sizeof (_Complex int); + break; + + case _C_UINT: + return sizeof (_Complex unsigned int); + break; + + case _C_LNG: + return sizeof (_Complex long); + break; + + case _C_ULNG: + return sizeof (_Complex unsigned long); + break; + + case _C_LNG_LNG: + return sizeof (_Complex long long); + break; + + case _C_ULNG_LNG: + return sizeof (_Complex unsigned long long); + break; + + case _C_FLT: + return sizeof (_Complex float); + break; + + case _C_DBL: + return sizeof (_Complex double); + break; + + default: + { + objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown complex type %s\n", + type); + return 0; + } } - return max_size; } default: @@ -264,6 +334,10 @@ objc_alignof_type (const char *type) /* do nothing */; } switch (*type) { + case _C_BOOL: + return __alignof__ (_Bool); + break; + case _C_ID: return __alignof__ (id); break; @@ -336,6 +410,7 @@ objc_alignof_type (const char *type) return objc_alignof_type (type); case _C_STRUCT_B: + case _C_UNION_B: { struct objc_struct_layout layout; unsigned int align; @@ -347,24 +422,68 @@ objc_alignof_type (const char *type) return align; } - - case _C_UNION_B: + + + case _C_COMPLEX: { - int maxalign = 0; - while (*type != _C_UNION_E && *type++ != '=') - /* do nothing */; - while (*type != _C_UNION_E) - { - /* Skip the variable name if any */ - if (*type == '"') - { - for (type++; *type++ != '"';) - /* do nothing */; - } - maxalign = MAX (maxalign, objc_alignof_type (type)); - type = objc_skip_typespec (type); + type++; /* Skip after the 'j'. */ + switch (*type) + { + case _C_CHR: + return __alignof__ (_Complex char); + break; + + case _C_UCHR: + return __alignof__ (_Complex unsigned char); + break; + + case _C_SHT: + return __alignof__ (_Complex short); + break; + + case _C_USHT: + return __alignof__ (_Complex unsigned short); + break; + + case _C_INT: + return __alignof__ (_Complex int); + break; + + case _C_UINT: + return __alignof__ (_Complex unsigned int); + break; + + case _C_LNG: + return __alignof__ (_Complex long); + break; + + case _C_ULNG: + return __alignof__ (_Complex unsigned long); + break; + + case _C_LNG_LNG: + return __alignof__ (_Complex long long); + break; + + case _C_ULNG_LNG: + return __alignof__ (_Complex unsigned long long); + break; + + case _C_FLT: + return __alignof__ (_Complex float); + break; + + case _C_DBL: + return __alignof__ (_Complex double); + break; + + default: + { + objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown complex type %s\n", + type); + return 0; + } } - return maxalign; } default: @@ -487,6 +606,7 @@ objc_skip_typespec (const char *type) case _C_INT: case _C_UINT: case _C_LNG: + case _C_BOOL: case _C_ULNG: case _C_LNG_LNG: case _C_ULNG_LNG: @@ -496,6 +616,10 @@ objc_skip_typespec (const char *type) case _C_UNDEF: return ++type; break; + + case _C_COMPLEX: + return type + 2; + break; case _C_ARY_B: /* skip digits, typespec and closing ']' */ @@ -744,13 +868,14 @@ objc_layout_structure (const char *type, { const char *ntype; - if (*type++ != _C_STRUCT_B) + if (*type != _C_UNION_B && *type != _C_STRUCT_B) { objc_error (nil, OBJC_ERR_BAD_TYPE, - "record type expected in objc_layout_structure, got %s\n", + "record (or union) type expected in objc_layout_structure, got %s\n", type); } + type ++; layout->original_type = type; /* Skip "=" if any. Avoid embedded structures and unions. */ @@ -779,17 +904,21 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout) /* The following are used only if the field is a bitfield */ register const char *bfld_type = 0; - register int bfld_type_size, bfld_type_align = 0, bfld_field_size = 0; + register int bfld_type_align = 0, bfld_field_size = 0; /* The current type without the type qualifiers */ const char *type; + BOOL unionp = layout->original_type[-1] == _C_UNION_B; /* Add the size of the previous field to the size of the record. */ if (layout->prev_type) { type = objc_skip_type_qualifiers (layout->prev_type); + if (unionp) + layout->record_size = MAX (layout->record_size, + objc_sizeof_type (type) * BITS_PER_UNIT); - if (*type != _C_BFLD) + else if (*type != _C_BFLD) layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT; else { /* Get the bitfield's type */ @@ -798,14 +927,14 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout) bfld_type++) /* do nothing */; - bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT; bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT; bfld_field_size = atoi (objc_skip_typespec (bfld_type)); layout->record_size += bfld_field_size; } } - if (*layout->type == _C_STRUCT_E) + if ((unionp && *layout->type == _C_UNION_E) + || (!unionp && *layout->type == _C_STRUCT_E)) return NO; /* Skip the variable name if any */ @@ -828,7 +957,6 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout) bfld_type++) /* do nothing */; - bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT; bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT; bfld_field_size = atoi (objc_skip_typespec (bfld_type)); } @@ -905,14 +1033,16 @@ void objc_layout_finish_structure (struct objc_struct_layout *layout, unsigned int *size, unsigned int *align) { - if (layout->type && *layout->type == _C_STRUCT_E) + BOOL unionp = layout->original_type[-1] == _C_UNION_B; + if (layout->type + && ((!unionp && *layout->type == _C_STRUCT_E) + || (unionp && *layout->type == _C_UNION_E))) { /* Work out the alignment of the record as one expression and store in the record type. Round it up to a multiple of the record's alignment. */ - #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__) - layout->record_align = ROUND_TYPE_ALIGN (layout->original_type, + layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1, 1, layout->record_align); #else